PostgreSQL 数据库连接失败与崩溃排查总结
摘要:本笔记总结了 PostgreSQL 数据库连接失败和频繁崩溃的常见原因及解决方案,包括密码认证失败、健康检查配置问题、内存不足、连接数过多、日志分析等关键点。
一、连接失败问题分析
根据日志显示,即使没有程序主动连接数据库,也存在大量连接失败记录,主要原因是:
- 客户端使用了错误的密码或未提供密码。
- 健康检查脚本(如 Docker Compose 中的 healthcheck)尝试连接数据库。
- 其他服务或定时任务自动连接数据库。
- pg_hba.conf 配置限制了访问方式,但未正确设置密码。
二、Docker 容器中 PostgreSQL 崩溃原因
在使用 Docker 启动 PostgreSQL 时,若数据目录非空(即已有旧数据),PostgreSQL 会跳过初始化流程,导致环境变量(如 POSTGRES_PASSWORD)不生效,进而引发密码认证失败。
volumes:
- /root/dockerdata/postgres:/var/lib/postgresql/data
此配置可能导致容器启动后忽略密码设置。
三、解决方案
1. 清除数据目录并重新初始化
如果数据目录中已有数据,建议清空后再启动容器:
docker-compose down
rm -rf /root/dockerdata/postgres/*
docker-compose up -d
2. 手动修改密码
如果不想清除数据,可以进入容器手动修改密码:
docker exec -it bitmagnet-postgres psql -U postgres
ALTER USER postgres WITH PASSWORD 'postgres';
3. 检查健康检查命令
确保健康检查命令完整且带上用户名,避免权限问题:
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
四、PostgreSQL 崩溃排查方法
1. 查看日志
使用以下命令查看 PostgreSQL 容器日志:
docker logs bitmagnet-postgres
重点关注以下关键词:FATAL
, PANIC
, Segmentation fault
, out of memory
, Aborted
。
2. 检查系统资源使用情况
检查是否因内存不足被 OOM Killer 杀掉:
dmesg | grep -i kill | grep -i postgres
如果看到类似以下内容,则说明内存不足:
Out of memory: Kill process 12345 (postgres) ...
3. 调整 PostgreSQL 内存配置
在 postgresql.conf
文件中调整以下参数,以减少内存占用:
shared_buffers = 256MB
work_mem = 16MB
maintenance_work_mem = 128MB
effective_cache_size = 512MB
max_connections = 20
推荐使用 [PGTune](https://pgtune.leopard.in.ua/) 工具生成适合你服务器配置的推荐值。
4. 检查连接数与事务
执行以下 SQL 查询查看当前连接数和慢查询:
SELECT count(*) FROM pg_stat_connections;
SELECT pid, now() - query_start AS duration, query
FROM pg_stat_statements
WHERE now() - query_start > interval '5 minutes';
五、监控与预防措施
建议为 PostgreSQL 设置监控机制,例如:
- 使用 Prometheus + Grafana 监控性能指标。
- 启用
pg_stat_statements
插件记录慢查询。 - 使用
pgBadger
分析日志,找出慢查询和异常行为。
六、总结
PostgreSQL 连接失败和崩溃的主要原因包括:密码错误、健康检查配置不当、内存不足、连接数过多、磁盘 I/O 性能差等。通过日志分析、资源监控和合理配置,可以有效解决这些问题。