Skip to content

PostgreSQL 错误码速查

错误码分类

PostgreSQL错误码采用5个字符的字母数字格式,前两个字符表示错误类别,后三个字符表示具体错误。常见的错误类别包括:

类别描述示例错误码
00成功完成00000
01警告01000
02无数据02000
03sql状态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
2FSQL例程异常2F000
34无效游标名称34000
38外部例程异常38000
39外部例程包含39000
3B保存点异常3B000
3D无效目录名3D000
3F无效模式名3F000
40事务回滚40000, 40002, 40P01
42语法错误或访问规则违规42601, 42501, 42P01
44WITH 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_connections1. 增加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服务器日志会记录所有错误,包括错误码、错误信息和详细堆栈信息。可以通过查看日志文件获取完整的错误上下文。

错误处理最佳实践

  1. 详细记录错误信息:在应用程序中捕获并记录完整的错误信息,包括错误码、错误信息和上下文。

  2. 使用参数化查询:避免SQL注入,减少语法错误。

  3. 实现重试机制:对于临时性错误(如死锁、资源不足),实现自动重试机制。

  4. 监控错误模式:定期分析错误日志,识别频繁出现的错误,及时优化。

  5. 合理设置超时:根据业务需求设置合适的statement_timeout和lock_timeout。

  6. 使用连接池:减少连接创建开销,避免连接数超过限制。

  7. 定期维护数据库:执行VACUUM、ANALYZE等维护操作,保持数据库健康。

常见问题(FAQ)

Q1:如何查看PostgreSQL错误日志?

A1:PostgreSQL错误日志位置由log_directorylog_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:避免常见错误的建议:

  1. 始终使用参数化查询,避免SQL注入
  2. 为所有表创建主键
  3. 合理设计索引,避免过度索引
  4. 实现连接池,管理数据库连接
  5. 定期执行VACUUM和ANALYZE
  6. 监控数据库性能和错误日志
  7. 为关键操作设置合理的超时
  8. 测试应用程序在各种错误场景下的行为

Q5:如何调试复杂的PostgreSQL错误?

A5:调试复杂错误的步骤:

  1. 查看完整的错误信息和错误码
  2. 检查服务器日志,获取更多上下文信息
  3. 重现错误,分析执行计划
  4. 使用EXPLAIN ANALYZE分析查询性能
  5. 检查数据库状态,包括锁、连接和资源使用情况
  6. 考虑使用pg_stat_statements等扩展工具进行性能分析
  7. 对于内部错误,考虑升级PostgreSQL版本或联系支持

Q6:如何处理PostgreSQL中的死锁?

A6:处理死锁的建议:

  1. 实现自动重试机制,对于死锁错误自动重试
  2. 优化事务逻辑,减少锁持有时间
  3. 确保所有事务以相同的顺序访问资源
  4. 使用较低的事务隔离级别(如READ COMMITTED)
  5. 监控死锁事件,使用log_lock_waits参数记录长时间锁等待
  6. 考虑使用pg_blocking_pids函数识别阻塞的会话