54011 — too_many_columns
54011
速览
54011 表示物理 tuple descriptor 或相关对象定义超过固定列数上限。源码路径决定计数对象是表属性、索引键加 INCLUDE 列、分区键、统计维度还是产生行的定义。
| 字段 | 值 |
|---|---|
| SQLSTATE | 54011 |
| 条件名 | too_many_columns |
| 状态 | 有效 |
| 已知存在于 | 7.4 |
| 锁定快照 | 9.0.23, 9.1.24, 9.2.24, 9.3.25, 9.4.26, 9.5.25, 9.6.24, 10.23, 11.22, 12.22, 13.23, 14.24, 15.19, 16.15, 17.11, 18.6, 19beta3 |
| 宏 | ERRCODE_TOO_MANY_COLUMNS |
| 别名 | — |
含义
固定消息包括实际/上限列数、表最多列数、索引最多列数、分区键上限和统计专用变体。表计数使用物理属性号:已删除列仍占 tuple descriptor 槽位,所以可见列数可能低于 relnatts。索引键与 INCLUDE、分区键和统计维度各有独立上限,虽然都使用此 SQLSTATE。
锁定的 18.6 构建中,相关常量分别是用户表属性 MaxHeapAttributeNumber = 1600、tuple 属性 MaxTupleAttributeNumber = 1664、INDEX_MAX_KEYS = 32、PARTITION_MAX_KEYS = 32 以及 STATS_MAX_DIMENSIONS = 8。这些数值属于不同 guard;服务器诊断中的实际 count 和 limit 字段仍是判断依据。
诊断
从消息和上下文读取对象类型、实际数、上限和 DDL 操作。表或继承表要检查 pg_class.relnatts 与包含 attisdropped 的 pg_attribute,不能只数可见列名。索引 DDL 要把 INCLUDE 列算入,分区和 extended statistics 则检查各自的键/维度数;FROM 中函数的 column definition list 也有 54011 的行形状上限。
处理
减少或拆分对象定义,改用其他索引/分区设计,或把派生数据移到关联表。若原因是 dropped 的物理槽位,再删除可见列并不会回收它们;普通物理重写(如 VACUUM FULL 或 CLUSTER)也会在 tuple descriptor 中保留这些 dropped attribute。应新建具有目标逻辑列布局的表,在保留依赖的前提下迁移数据,再有选择地减少索引键/INCLUDE 列或统计维度并验证 DDL。显式事务中若发生 ERROR,重试前执行 ROLLBACK 或 ROLLBACK TO SAVEPOINT;自动提交只有在 schema 变更真正消除上限后才能重试。
版本
锁定目录从 7.4 记录;引用 heap、index、table、partition、statistics 和 row-shape 路径来自 PostgreSQL 18.6,未创建超大 schema。
相关
来源
src/backend/access/common/heaptuple.c#L1131-L1134
src/backend/access/common/indextuple.c#L87-L90
src/backend/catalog/heap.c#L461-L464
src/backend/commands/tablecmds.c#L2567-L2582
src/backend/commands/indexcmds.c#L640-L664
src/backend/commands/statscmds.c#L215-L224
src/backend/parser/parse_relation.c#L1935-L1946
src/include/access/htup_details.h#L34-L48
src/include/pg_config_manual.h#L63-L74
src/include/statistics/statistics.h#L19
结构化证据记录保存固定消息以及源码/运行边界。