引言
痛点引入:博客文章越来越多,读者找不到想看的内容;评论区冷清,互动少;自己没时间回复每一条留言。
解决方案:给博客装一个 AI 智能助手,24 小时在线,能聊天、能搜文章、能回答问题。
项目介绍核心功能:
智能对话(基于大语言模型)
博客文章搜索与推荐
FAQ 知识库自动匹配
支持多模型切换(聊天/图像生成)
限流保护,防止滥用
技术栈:Node.js + Express + Axios + 大模型 API
关键技术实现文章索引与搜索1234// 从 Hexo 的 _posts 目录读取文章// 解析 front-matter(标题、日期、标签、分类)// 构建可搜索的文章对象数组const POSTS_DIR = '/www/wwwroot/myblog/source/_posts';
亮点:直接读取源文件,无需数据库,部署简单。
FAQ 知识库设计1234// JSON 格式存储常见问题// 关键词匹配 + 评分机制// 匹配成功直接返回,无需调用大模型(省钱+快速)const FAQ_FILE = path.join(__dirna ...
在 PostgreSQL 的 pg_hba.conf 文件中,METHOD(认证方法)决定了服务器如何验证客户端的身份。
PostgreSQL 支持多种认证方法,主要可以分为以下几类:
基于密码的认证 (Password-Based)这是最常用的方式,客户端需要提供密码。
方法
说明
安全性
适用场景
scram-sha-256
推荐。使用 SCRAM-SHA-256 挑战-响应机制。密码不以明文传输,也不存储哈希值,而是存储 Salted Hash。
最高 PG 10+ 默认首选
生产环境首选
md5
使用 MD5 哈希进行挑战-响应。比明文安全,但 MD5 已被认为不够强壮易受碰撞攻击。
中等
旧版本兼容或内部网络
password
明文传输。密码以未加密形式通过网络发送。
极低
严禁在生产环境使用,仅限 SSL 隧道内或测试
注意:从 PostgreSQL 14 开始,默认认证方法已改为 scram-sha-256。
基于操作系统的认证 (OS-Based)利用操作系统的用户身份进行映射,通常用于本地连接,无需输入数据库密码。
方法
...
PostgreSQL
未读pg_basebackup(物理备份)常用参数速查
参数
简写
说明
示例
–pgdata=DIRECTORY
-D
备份目标目录(必需)
-D /backup/base
–format=p|t
-F
输出格式:plain/tar
–wal-method=METHOD
-X
WAL 处理方式
-Xs流复制
–checkpoint=fast|spread
检查点模式
–progress
-P
显示进度
-P
–verbose
-v
详细输出
-v
–jobs=NUM
-j
并行压缩/传输
-j 4
–compress=METHOD
-z
压缩方法
-z 9
–host=HOSTNAME
-h
主机地址
-h 192.168.1.1
–port=PORT
-p
端口
-p 5432
–username=NAME
-U
用户名
-U rep
–no-password
-w
不提示密码
-w
–pass ...
这个报错和ROW_FORMAT有关,在 MySQL 的 InnoDB 存储引擎中,ROW_FORMAT主要有4种格式,但在较旧的版本或特定语境下,常讨论的是前三种。以下是这四种格式的详细介绍和区别:
REDUNDANT (冗余格式)来源:MySQL 5.0 之前的旧格式。
现状:不推荐使用,除非你需要迁移非常古老的数据库。
特点:
为了向后兼容保留。
每个列都存储了长度前缀,即使定长字段也存。
缺点:占用空间大,性能较差。
COMPACT(紧凑格式) MySQL 5.0 - 5.7 默认来源:MySQL 5.0 引入。
现状:在 MySQL 5.7 及之前是默认格式。现在依然广泛使用,但不如 DYNAMIC 灵活。
特点:
去掉了 REDUNDANT中不必要的长度前缀。
NULL 值和长度为 0 的字段不占用存储空间 只占位标记 。
比 REDUNDANT更节省空间,CPU 开销更小。
DYNAMIC(动态格式)MySQL 5.7 / 8.0 默认来源:MySQL 5.7 引入,8.0 成为默认值。
现状:现代 MySQL 的推荐默认格式。
基于COMPACT格式改 ...
SET_USER_ID 是 MySQL 8.0 引入的一个细粒度权限 Granular Privilege ,旨在解决“最小权限原则”与“指定 DEFINER”之间的矛盾。
在 MySQL 5.7 及以前,如果你想创建一个 DEFINER 为其他用户 非当前
然而,SUPER 权限过大,它包含了重启服务器、修改全局变量、杀死任意线程等高危操作。为了安全起见,云数据库 如阿里云 RDS、AWS Aurora 通常禁止给用户授予 SUPER 权限。
这就导致了一个困境:普通管理员无法创建指定其他用户为 DEFINER 的对象。
MySQL 8.0 引入 SET_USER_ID就是为了解决这个问题。
SET_USER_ID 的核心作用拥有 SET_USER_ID 权限的用户,可以执行以下操作:
在创建存储过程、函数、视图、触发器时,指定任意其他用户作为 DEFINER。
使用 SET ROLE 语句切换角色。
本质上,它允许你“冒充”另一个用户的身份来定义对象,但不赋予你该用户的其他特权 如删除数据、重启服务等 。
为什么需要它? 场景举例假设你是一个 DevOps 工程师,负责部署应 ...
PostgreSQL
未读MVCC原理多版本并发控制(Multi-Version Concurrency Control,MVCC),是数据库中并发访问数据时保证数据一致性的一种方法。
在并发操作中,当正在写时,如果有用户在读,这时写可能只写了一半,如一行的前半部分刚写入,后半部分还没有写入,这时可能读的用户读取到的数据行的前半部分数据是新的,后半部分数据是原来的,这就导致了数据一致性问题。
解决这个问题的最简单的方法是使用读写锁,写的时候不允许读,正在读的时候也不允许写,但这种方法会导致读和写的操作不能并发执行。
于是,有人想到了一种能够让读写并发执行的方法,这种方法就是MVCC。
MVCC方法是写数据时,原数据并不删除,并发的读还能读到原数据,这样就不会有数据一致性问题了。
实现MVCC的方法有以下两种:
第一种:写新数据时,把原数据移到一个单独的位置,如回滚段中,其他用户读数据时,从回滚段中把原数据读出来。
第二种:写新数据时,原数据不删除,而是把新数据插入进来。
PostgreSQL数据库使用的是第二种方法,而Oracle数据库和MySQL数据库中的InnoDB引擎使用的是第一种方法。
Post ...
PostgreSQL
未读PG 内核本身不包含所有扩展的文件,许多发行版将扩展拆分为独立包,仅安装 postgresql-server 是不够的,启用插件之前需要在宿主机上安装 *-contrib 软件包,但是安装 *-contrib 软件包的话,需要使用到 pgdg 仓库,没有则需要先部署仓库:
123dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-$(rpm -E %{rhel})-x86_64/pgdg-redhat-repo-latest.noarch.rpmdnf install postgresql16-contrib
第三方插件需要单独安装,例如 postgis:
1ls /usr/pgsql-16/share/extension
1dnf install -y postgis34_16
PostgreSQL
未读事务 ID 回卷(Transaction ID Wraparound)是 PostgreSQL 中最严重、最致命的潜在故障之一。如果处理不当,它会导致数据库停止服务,甚至造成数据永久丢失。
简单来说,这是因为 PostgreSQL 用来标记事务的”计数器”用完了,不得不从头开始数,从而导致新旧数据混淆。
核心原理:32位整数的限制PostgreSQL 使用一个 32位无符号整数 (xid) 来标识每一个事务。
最大值:2^32-1 ≈ 42.9亿。
含义:PG 最多只能容纳约 42 亿个事务。
为什么回卷会导致数据丢失?PostgreSQL 依靠 MVCC(多版本并发控制)来判断哪行数据对当前事务可见。判断逻辑依赖于比较当前事务 ID 和数据行的创建/删除事务 ID。
正常情况:
当前事务 ID = 100。
数据行 A 由事务 50 创建。
因为 100 > 50,所以事务 100 能看到数据行 A。
回卷发生时(灾难场景):
假设事务 ID 已经跑到了 42 亿,然后回卷到了 10。
旧数据:由事务 40 亿创建(在物理时间上是很久以前创建的,逻 ...
PostgreSQL
未读为什么会有死元组?(MVCC机制)PostgreSQL 使用 MVCC(多版本并发控制)来实现高并发和事务隔离。这与 MySQL (InnoDB) 的机制有很大不同。
当你执行 UPDATE 时:
PG 不会直接修改原来的那一行数据。
PG 会将旧行标记为”死亡”(设置 xmax 事务ID)。
PG 会插入一个全新的行,包含更新后的数据。
结果:表中同时存在”旧版本(死元组)”和”新版本(活元组)”。
当你执行 DELETE 时:
PG 不会直接从磁盘移除该行。
PG 只是将该行标记为”死亡”(设置 xmax 事务ID)。
结果:该行变成了死元组,依然占据磁盘空间。
为什么要这样做?为了事务隔离。
假设事务 A 正在读取某行数据,此时事务 B 更新了这行数据。
如果 PG 直接覆盖了旧数据,事务 A 就会读到不一致的数据(违反了隔离性)。
通过保留旧版本(死元组),事务 A 可以继续读取它启动时看到的那个版本,而事务 B 读取新版本。互不干扰。
死元组的危害如果死元组不及时清理,会带来严重后果:
表膨胀(Table Bloat):
表文件越来越大,即使你只存了 1GB 的 ...
部署 img2color-go 所需的环境非常轻量,主要包含的核心组件
go语言环境编译用(Go 1.21+ (建议最新稳定版)。)
docker拉起redis容器缓存用(Docker 20.10+, Docker Compose V2。)
拉起Redis容器做缓存在 /val/lib/docker/redis-img2color目录下创建 docker-compose.yml:
12345678910services: redis-img2color: image: redis:7-alpine container_name: redis-img2color restart: always ports: - "127.0.0.1:6380:6379" volumes: - /val/lib/docker/redis-img2color:/data command: redis-server --appendonly yes
执行启动:
1docker compose up -d
克隆代码12git ...








