
Postgres 的 ID 为什么会跳号,以及如何修复导入数据后的「duplicate key」错误
PostgreSQL 的 serial 列和 identity 列中的空洞从何而来(回滚、ON CONFLICT、崩溃、CACHE),为什么导入数据后插入会报 duplicate key value violates unique constraint,一条重置所有序列的查询,integer ID 用完时会发生什么,以及无空洞的发票编号。每条语句都在 Postgres 17.11 上复现过。
博客
Relyt One 团队关于「工程实践」的文章。

PostgreSQL 的 serial 列和 identity 列中的空洞从何而来(回滚、ON CONFLICT、崩溃、CACHE),为什么导入数据后插入会报 duplicate key value violates unique constraint,一条重置所有序列的查询,integer ID 用完时会发生什么,以及无空洞的发票编号。每条语句都在 Postgres 17.11 上复现过。

如何在 PostgreSQL 17 中用 SELECT ... FOR UPDATE SKIP LOCKED 构建后台任务队列:为什么朴素的「先 SELECT 再 UPDATE」会把同一个任务领取两次,为什么只用 FOR UPDATE 会让工作进程互相等待,以及租约与重试、LISTEN/NOTIFY、vacuum,还有轮询的工作进程会对 Serverless 计算实例造成什么影响。每条语句都在 Postgres 17.11 上复现过。

在 PostgreSQL 17 中何时用 INSERT ... ON CONFLICT 做 upsert、何时用 MERGE;为什么 MERGE 在并发下会报重复键错误;以及如何修复 'cannot affect row a second time'、RETURNING 为空和 'no unique or exclusion constraint matching the ON CONFLICT specification'。每条语句都在 Postgres 17.11 上复现过。

为什么在事务级连接池后面会遇到 'prepared statement already exists'、设置在请求之间泄漏、advisory lock 什么也锁不住?本文在 PgBouncer 1.24 和 PostgreSQL 17 上逐一复现,给出每个问题的修复方法,以及何时改用直连连接的判断规则。

为什么一条单行 ALTER TABLE 就能让整张表的查询全部卡住?本文列出 PostgreSQL 17 上常见迁移各自获取的锁、哪些会重写整张表,以及用 lock_timeout、NOT VALID 和 CONCURRENTLY 让生产环境不停服的做法。

明明建了索引,EXPLAIN 里还是 Seq Scan?本文梳理 PostgreSQL 忽略索引(索引不生效)的 7 个原因:函数、类型转换、通配符、选择性、统计信息过期、列顺序、小表,每个都附复现步骤和修复方法。

Relyt One 运行的是 PostgreSQL 17。如果你的 schema 或使用习惯来自 Postgres 18,本文告诉你哪些写法在 17 上会失败、应该改成什么,以及如何导入在 18 上生成的转储,每个代码片段都在两个版本上运行过。

行级安全是防范漏写 WHERE 子句的最佳防线,直到它悄无声息地不再生效。本文讲解在 PostgreSQL 17 上 RLS 失效放行的五种情形,每种都附带复现步骤、修复方法,以及一条能在 CI 中发现它的系统目录查询。

一步步在 Relyt One 上搭建一个多用户的 Next.js 应用:为分支启用托管认证、让用户登录、用 @relyt/auth 验证他们的 JWT,并由 Postgres 行级安全把每个用户的行隔离开。
更多文章仅有英文版。 英文文章