2200H — sequence_generator_limit_exceeded
2200H
速览
序列在尝试取得下一个值时遇到了配置的边界。PostgreSQL 18.6 的 sequence.c 路径同时有最大值和最小值的源码模板;端点值本身可以是合法返回值。数值使用 C 的 PRId64 格式宏,因此源码写法是 nextval: reached maximum value of sequence "%s" (%" PRId64 ")(最小值形式相应替换为 minimum),不能把它误写成字面量 (%s) 占位符。这里的限制属于序列属性,不是一般整数溢出。
| 字段 | 值 |
|---|---|
| SQLSTATE | 2200H |
| 条件名 | sequence_generator_limit_exceeded |
| 状态 | 有效 |
| 已知存在于 | 10.0 |
| 锁定快照 | 10.23, 11.22, 12.22, 13.23, 14.24, 15.19, 16.15, 17.11, 18.6, 19beta3 |
| 宏 | ERRCODE_SEQUENCE_GENERATOR_LIMIT_EXCEEDED |
| 别名 | — |
含义
本条件表示 nextval 的 fetch loop 无法在配置的最小值或最大值之外再分配下一个值。在递增路径中,源码检查最大值边界;在递减路径中,源码检查最小值边界。触及边界时,若 rescnt > 0,循环会先停止并返回已经取得的合法值;只有没有可返回结果时,未启用 CYCLE 的分支才报告 2200H。启用 CYCLE 时,固定源码会绕回另一个配置端点。这是序列边界策略,不是一般整数溢出。
报文
未启用循环的递增 guard 以 ERROR 报告 primary 源码模板 nextval: reached maximum value of sequence "%s" (%" PRId64 ");递减 guard 使用 nextval: reached minimum value of sequence "%s" (%" PRId64 ")。端点本身不是错误:如果 fetch loop 已取得合法结果,会先停止抓取而不进入错误分支。PRId64 是拼接进已编译数值占位符的 C 格式宏,最终显示的数字是运行时限制值。引用分支没有独立 DETAIL 或 HINT。
诊断
检查报文点名的序列、步长、MINVALUE/MAXVALUE、CYCLE 设置以及调用是否为 nextval,先判断触及的是最大值还是最小值、是否仍有合法端点或缓存值可返回,以及循环是否是有意策略。CYCLE 只是序列策略,不是所有生成 ID 的通用修复:开启它可能与依赖键冲突,或违反应用的分配约束。若不应循环,应在核对依赖键后选择安全的新范围、调整序列或轮换到新序列。
处理
有意修复序列策略:核对键语义后调整安全限制、决定是否启用 CYCLE,或迁移到新序列。重复同一个 nextval、转换其结果或把本码当成整数溢出,都不能越过固定端点。
该分支抛出 ERROR 时,显式事务应先用 ROLLBACK 恢复,或对语句前已建立的保存点执行 ROLLBACK TO SAVEPOINT,再重试;自动提交下只在失败语句结束后重试修正后的动作。事务边界规则见事务与重试指南。
版本
锁定目录从 10.0 起记录该条件;固定源码覆盖 PostgreSQL 18.6。
相关
来源
固定源码:src/backend/commands/sequence.c#L731-769。结构化证据记录保留两种端点报文和范围边界。固定源码确认递增/递减 guard、CYCLE 回绕和 C 的 PRId64 格式宏;序列名和限制值是运行时字段。锁定目录从 10.0 起记录该条件,但不据此断言精确的实现引入提交。