外观
PostgreSQL 错误码速查
错误码分类
PostgreSQL错误码采用5个字符的字母数字格式,前两个字符表示错误类别,后三个字符表示具体错误。常见的错误类别包括:
| 类别 | 描述 | 示例错误码 |
|---|---|---|
| 00 | 成功完成 | 00000 |
| 01 | 警告 | 01000 |
| 02 | 无数据 | 02000 |
| 03 | sql状态 | 03000 |
| 08 | 连接异常 | 08001, 08006 |
| 09 | 触发动作异常 | 09000 |
| 0A | 功能不受支持 | 0A000 |
| 0B | 无效事务初始化 | 0B000 |
| 0F | 无效授权规范 | 0F000 |
| 0L | 无效授权标识 | 0L000 |
| 0P | 无效角色规范 | 0P000 |
| 20 | 无效事务状态 | 20000 |
| 21 | 无效游标状态 | 21000 |
| 22 | 数据异常 | 22001, 22003, 22P02 |
| 23 | 约束违规 | 23502, 23503, 23505 |
| 24 | 无效游标名称 | 24000 |
| 25 | 无效事务状态 | 25000 |
| 26 | 无效SQL语句名 | 26000 |
| 27 | 触发器异常 | 27000 |
| 28 | 无效授权标识 | 28000 |
| 2B | 依赖特权描述符不存在 | 2B000 |
| 2D | 无效事务终止 | 2D000 |
| 2F | SQL例程异常 | 2F000 |
| 34 | 无效游标名称 | 34000 |
| 38 | 外部例程异常 | 38000 |
| 39 | 外部例程包含 | 39000 |
| 3B | 保存点异常 | 3B000 |
| 3D | 无效目录名 | 3D000 |
| 3F | 无效模式名 | 3F000 |
| 40 | 事务回滚 | 40000, 40002, 40P01 |
| 42 | 语法错误或访问规则违规 | 42601, 42501, 42P01 |
| 44 | WITH CHECK OPTION违规 | 44000 |
| 53 | 不足的资源 | 53100, 53200, 53300 |
| 54 | 程序限制超出 | 54000, 54011, 54023 |
| 55 | 对象状态异常 | 55000, 55P02, 55P03 |
| 57 | 操作符干预 | 57014, 57P01, 57P02 |
| 58 | 系统错误 | 58000, 58P01, 58P02 |
| F0 | 配置文件错误 | F0000 |
| HV | 外部表错误 | HV000, HV005, HV010 |
| P0 | 触发器协议违规 | P0000, P0001, P0002 |
| XX | 内部错误 | XX000, XX001, XX002 |
常见错误码详细说明
连接与认证错误
| 错误码 | 错误信息 | 可能原因 | 解决方法 |
|---|---|---|---|
| 08001 | 无法连接到服务器 | 1. 服务器未运行 2. 网络连接问题 3. 监听地址配置错误 4. 端口配置错误 | 1. 检查PostgreSQL服务状态 2. 检查网络连接和防火墙设置 3. 检查listen_addresses参数 4. 检查port参数 |
| 08004 | 数据库拒绝连接 | 1. 数据库不存在 2. 用户无连接权限 3. 连接数超过max_connections | 1. 检查数据库名称是否正确 2. 检查pg_hba.conf配置 3. 增加max_connections或使用连接池 |
| 08006 | 连接失败 | 1. 密码错误 2. 用户不存在 3. SSL配置错误 | 1. 检查密码是否正确 2. 检查用户名是否存在 3. 检查SSL配置 |
| 28000 | 无效的授权标识 | 1. 用户名或密码错误 2. 认证方法配置错误 | 1. 检查用户名和密码 2. 检查pg_hba.conf中的认证方法 |
| 28P01 | 密码认证失败 | 密码错误 | 检查密码是否正确,或重置密码 |
语法与语义错误
| 错误码 | 错误信息 | 可能原因 | 解决方法 |
|---|---|---|---|
| 42601 | 语法错误在或附近 "..." | SQL语句语法错误 | 检查SQL语句语法,特别是错误提示中指出的位置 |
| 42703 | 列 "..." 不存在 | 1. 列名拼写错误 2. 表名错误 3. 列名大小写问题 | 1. 检查列名拼写 2. 检查表名是否正确 3. 确认列名大小写是否匹配 |
| 42P01 | 关系 "..." 不存在 | 1. 表名或视图名拼写错误 2. 表或视图不存在 3. 模式名错误 | 1. 检查表名或视图名拼写 2. 确认对象是否存在 3. 检查模式名或search_path设置 |
| 42P02 | 无效的游标名称 | 游标名称不存在或已关闭 | 检查游标名称是否正确,或确认游标是否已关闭 |
| 42501 | 权限被拒绝 | 用户没有执行该操作的权限 | 授予用户相应的权限,或使用具有足够权限的用户 |
数据与约束错误
| 错误码 | 错误信息 | 可能原因 | 解决方法 |
|---|---|---|---|
| 22001 | 字符串数据,右截断 | 插入的数据超过了列定义的长度 | 1. 缩短数据长度 2. 增加列长度限制 |
| 22003 | 数值超出范围 | 插入的数值超过了列定义的范围 | 1. 调整插入的数值 2. 增加列范围限制 |
| 22P02 | 无效的输入语法 | 输入数据类型与列类型不匹配 | 检查输入数据类型是否与列类型一致 |
| 23502 | 空值违反了非空约束 | 向定义为NOT NULL的列插入NULL值 | 1. 插入非空值 2. 修改列定义,允许NULL值 |
| 23503 | 外键约束违反 | 插入或更新的数据违反了外键约束 | 1. 确保引用的记录存在 2. 检查外键关系 3. 考虑使用级联操作 |
| 23505 | 唯一约束违反 | 插入的数据违反了唯一约束 | 1. 确保数据唯一性 2. 检查唯一约束定义 |
| 23514 | 检查约束违反 | 插入或更新的数据违反了CHECK约束 | 1. 调整数据以满足CHECK约束 2. 修改CHECK约束定义 |
事务与并发错误
| 错误码 | 错误信息 | 可能原因 | 解决方法 |
|---|---|---|---|
| 40000 | 事务回滚 | 事务被回滚 | 检查事务中的SQL语句,查找导致回滚的原因 |
| 40001 | 序列化失败 | 并发事务冲突,无法序列化 | 1. 重试事务 2. 优化事务逻辑,减少锁持有时间 |
| 40002 | 事务完整性约束违反 | 事务中的操作违反了完整性约束 | 检查事务中的操作,确保符合完整性约束 |
| 40P01 | 死锁检测到 | 两个或多个事务相互等待对方释放锁 | 1. 重试事务 2. 优化事务逻辑,减少锁竞争 3. 调整事务隔离级别 |
| 55P03 | 无法获取锁 | 无法在指定时间内获取锁 | 1. 重试操作 2. 增加lock_timeout设置 3. 优化查询,减少锁持有时间 |
| 57014 | 语句被取消 | 查询被用户或系统取消 | 1. 检查查询是否过于复杂 2. 优化查询性能 3. 增加statement_timeout设置 |
资源与系统错误
| 错误码 | 错误信息 | 可能原因 | 解决方法 |
|---|---|---|---|
| 53100 | 磁盘已满 | 数据库所在磁盘空间不足 | 1. 清理磁盘空间 2. 扩展磁盘容量 3. 检查WAL日志和临时文件 |
| 53200 | 内存不足 | 系统内存不足 | 1. 增加系统内存 2. 优化work_mem和maintenance_work_mem设置 3. 减少并发连接数 |
| 53300 | 达到连接限制 | 连接数超过max_connections | 1. 增加max_connections 2. 使用连接池 3. 关闭空闲连接 |
| 54000 | 程序限制超出 | 超出了PostgreSQL内部限制 | 1. 简化查询 2. 调整相关配置参数 3. 升级PostgreSQL版本 |
| 54011 | 语句太长 | SQL语句超过了max_allowed_packet限制 | 1. 拆分为多个语句 2. 增加相关限制参数 |
| 55000 | 对象正在使用中 | 尝试修改或删除正在使用的对象 | 1. 等待对象不再被使用 2. 强制终止使用该对象的会话 3. 使用DROP ... CASCADE |
| 58000 | 系统错误 | PostgreSQL内部系统错误 | 1. 检查服务器日志 2. 重启PostgreSQL服务 3. 联系PostgreSQL支持 |
错误码查找方法
1. 从错误信息中提取
PostgreSQL错误信息通常包含错误码,例如:
ERROR: 23505: 重复键违反唯一约束 "users_pkey"
DETAIL: 键 (id)=(1) 已经存在。
LOCATION: _bt_check_unique, nbtinsert.c:434在这个例子中,错误码是23505。
2. 使用SQL查询错误码
可以使用pg_get_serial_sequence或直接查询系统视图来获取错误码信息:
sql
-- 查询所有错误码
SELECT sqlstate, message FROM pg_catalog.pg_error_codes;
-- 查询特定错误码
SELECT sqlstate, message FROM pg_catalog.pg_error_codes WHERE sqlstate = '23505';3. 从服务器日志中查找
PostgreSQL服务器日志会记录所有错误,包括错误码、错误信息和详细堆栈信息。可以通过查看日志文件获取完整的错误上下文。
错误处理最佳实践
详细记录错误信息:在应用程序中捕获并记录完整的错误信息,包括错误码、错误信息和上下文。
使用参数化查询:避免SQL注入,减少语法错误。
实现重试机制:对于临时性错误(如死锁、资源不足),实现自动重试机制。
监控错误模式:定期分析错误日志,识别频繁出现的错误,及时优化。
合理设置超时:根据业务需求设置合适的statement_timeout和lock_timeout。
使用连接池:减少连接创建开销,避免连接数超过限制。
定期维护数据库:执行VACUUM、ANALYZE等维护操作,保持数据库健康。
常见问题(FAQ)
Q1:如何查看PostgreSQL错误日志?
A1:PostgreSQL错误日志位置由log_directory和log_filename参数控制。可以使用以下命令查看当前配置:
sql
SHOW log_directory;
SHOW log_filename;默认情况下,日志文件位于PostgreSQL数据目录下的log子目录中。
Q2:如何将错误码转换为可读的错误信息?
A2:可以使用pg_get_error_message函数或直接查询pg_error_codes系统视图:
sql
-- 使用函数获取错误信息
SELECT pg_get_error_message('23505');
-- 或查询系统视图
SELECT message FROM pg_catalog.pg_error_codes WHERE sqlstate = '23505';Q3:如何捕获和处理PostgreSQL错误?
A3:在应用程序中,可以使用try-catch块捕获PostgreSQL异常,并根据错误码进行相应处理。例如,在Python中使用psycopg2:
python
import psycopg2
from psycopg2 import Error
try:
# 连接到PostgreSQL
connection = psycopg2.connect(
user="postgres",
password="password",
host="127.0.0.1",
port="5432",
database="mydb"
)
cursor = connection.cursor()
# 执行SQL语句
cursor.execute("INSERT INTO users (id, name) VALUES (1, 'test')")
connection.commit()
except Error as e:
# 捕获并处理错误
error_code = e.pgcode
error_message = str(e)
print(f"错误码: {error_code}")
print(f"错误信息: {error_message}")
# 根据错误码进行不同处理
if error_code == '23505':
print("处理唯一约束冲突...")
finally:
# 关闭连接
if connection:
cursor.close()
connection.close()Q4:如何避免常见的PostgreSQL错误?
A4:避免常见错误的建议:
- 始终使用参数化查询,避免SQL注入
- 为所有表创建主键
- 合理设计索引,避免过度索引
- 实现连接池,管理数据库连接
- 定期执行VACUUM和ANALYZE
- 监控数据库性能和错误日志
- 为关键操作设置合理的超时
- 测试应用程序在各种错误场景下的行为
Q5:如何调试复杂的PostgreSQL错误?
A5:调试复杂错误的步骤:
- 查看完整的错误信息和错误码
- 检查服务器日志,获取更多上下文信息
- 重现错误,分析执行计划
- 使用EXPLAIN ANALYZE分析查询性能
- 检查数据库状态,包括锁、连接和资源使用情况
- 考虑使用pg_stat_statements等扩展工具进行性能分析
- 对于内部错误,考虑升级PostgreSQL版本或联系支持
Q6:如何处理PostgreSQL中的死锁?
A6:处理死锁的建议:
- 实现自动重试机制,对于死锁错误自动重试
- 优化事务逻辑,减少锁持有时间
- 确保所有事务以相同的顺序访问资源
- 使用较低的事务隔离级别(如READ COMMITTED)
- 监控死锁事件,使用log_lock_waits参数记录长时间锁等待
- 考虑使用pg_blocking_pids函数识别阻塞的会话
