PostgreSQL磁盘满致复制槽损坏及数据库恢复问题咨询
PostgreSQL 13.7 Docker部署故障解决方案
一、无需登录psql停止复制的方法
有两种直接可行的方式,无需进入psql shell操作:
临时启动参数关闭复制
启动PostgreSQL容器时,添加临时配置参数强制关闭复制功能:docker run -d --name postgres-main -v /your/data/path:/var/lib/postgresql/data -e POSTGRES_PASSWORD=xxx postgres:13.7 -c wal_level=minimal -c max_replication_slots=0此方式无需修改配置文件,临时生效,方便后续修复操作。
修改配置文件永久关闭
直接编辑PostgreSQL数据目录下的postgresql.conf:- 将
wal_level的值从replica或logical改为minimal - 将
max_replication_slots设为0
保存后重启容器,复制功能会被彻底关闭。
- 将
二、当前状态的完整恢复方案
1. 主库恢复步骤
(1)修复独立表空间的数据库可见性
- 进入容器或直接在宿主机访问PostgreSQL数据目录,检查
pg_tblspc下的符号链接:
确认每个链接都指向正确的独立表空间挂载路径(比如自定义的ls -l /your/data/path/pg_tblspc/var/lib/postgresql/tblspc/mydb),若链接损坏,重新创建:ln -s /your/tblspc/path /your/data/path/pg_tblspc/[表空间OID] - 检查表空间目录的权限,确保容器内
postgres用户(UID/GID通常为999)拥有读写权限:chown -R 999:999 /your/tblspc/path - 重启容器后,执行
psql -U postgres -c "\l",自定义数据库应该会恢复显示。
(2)恢复密码认证
- 将
pg_hba.conf中临时设置的trust改回默认的scram-sha-256(PostgreSQL13默认认证方式)或md5:host all all 0.0.0.0/0 scram-sha-256 - 重置postgres用户密码:
docker exec -it postgres-main psql -U postgres -c "ALTER USER postgres WITH PASSWORD 'new_password';" - 重启容器使配置生效。
(3)重新配置复制(可选,若需要恢复主备)
- 先恢复主库的复制配置,修改
postgresql.conf:wal_level = replica max_replication_slots = 1 wal_keep_segments = 32 - 创建新的复制槽:
docker exec -it postgres-main psql -U postgres -c "SELECT pg_create_physical_replication_slot('new_slot_name');"
2. 备库恢复步骤
由于原备库的复制槽已损坏且数据可能不一致,需重新初始化:
- 停止并删除备库容器及旧数据目录:
docker stop postgres-replica && docker rm postgres-replica rm -rf /your/replica/data/path - 使用
pg_basebackup从主库拉取最新数据:docker run --rm -v /your/replica/data/path:/var/lib/postgresql/data postgres:13.7 pg_basebackup -h [主库IP] -U replicator -D /var/lib/postgresql/data -P -X stream -S new_slot_name - 在备库数据目录下创建
standby.signal文件,启用备库模式:touch /your/replica/data/path/standby.signal - 修改备库的
postgresql.conf,添加主备同步配置:primary_conninfo = 'host=[主库IP] port=5432 user=replicator password=repl_password application_name=postgres-replica' primary_slot_name = 'new_slot_name' - 启动备库容器,验证同步状态:
docker run -d --name postgres-replica -v /your/replica/data/path:/var/lib/postgresql/data postgres:13.7 docker exec -it postgres-replica psql -U postgres -c "SELECT pg_is_in_recovery();"
内容的提问来源于stack exchange,提问作者Anto
相关产品推荐
相关产品推荐

