pg_basebackup执行成功无数据复制 源端检查点为空故障排查
故障根本原因
远程执行pg_basebackup时,复制连接实际接入的是源端服务器上另一套无业务数据的空PostgreSQL 14实例,并非存储92G业务数据的生产实例,这是唯一完全匹配所有故障特征的根因。
核心证据
- pg_basebackup输出显示待传输总数据量仅70435kB(约69M),和目标端最终落盘大小完全一致,说明发送端walsender进程枚举到的待备份文件总大小就是69M,不存在传输截断、文件权限读失败类问题——这类问题会直接抛出错误中断备份,不可能返回0退出码、显示100%进度。
- 源端记录的备份触发检查点日志显示
wrote 0 buffers、sync files=0、总耗时仅0.022s,完全符合刚初始化、无业务写入的空实例特征:空实例无业务脏页需要刷盘,检查点无文件需要同步属于正常表现,并非异常。 - 本地执行备份正常,是因为未指定
-h参数时,pg_basebackup默认走Unix Socket连接,接入的是存储92G数据的生产实例;远程连接指定-h source.host.com走TCP协议时,接入的是监听该IP:5432的空测试实例。 - 空实例如果提前创建过OID为19399的业务库(仅执行CREATE DATABASE、未导入业务数据),就会出现base目录子结构和生产端完全一致、但缺失1GB规格业务数据段文件的现象。
验证方法
在源端服务器本地,分别用Unix Socket、TCP两种方式连接数据库,执行以下命令对比结果:
-- 本地默认Unix Socket连接(本地备份正常时用的连接方式) psql -U postgres -p 5432 -c "show data_directory; select pg_size_pretty(pg_database_size(19399));" -- TCP连接(和远程备份使用完全一致的连接参数) psql -h source.host.com -U postgres -p 5432 -c "show data_directory; select pg_size_pretty(pg_database_size(19399));"
如果两次查询返回的data_directory路径不同,且TCP连接查到的19399库大小仅几十MB,即可实锤多实例监听/转发配置错误。
常见触发场景
- 源端同时部署两套PG14实例:生产实例仅监听127.0.0.1或Unix Socket,测试实例监听对外业务IP的5432端口。
- 源端通过docker、containerd等容器部署PG时,端口映射配置错误,导致宿主机对外IP:5432映射到了空测试容器,而非生产容器。
- 源端配置了iptables/nftables端口转发规则,将对外IP:5432的流量转发到了其他空实例的监听端口。
修复方案
- 修改生产实例
postgresql.conf中的listen_addresses参数为'*'或对应业务IP,重启生产实例使其对外正常监听5432端口。 - 停掉占用对外IP:5432端口的空测试实例,或修改测试实例监听端口为其他未占用端口,避免端口冲突。
- 调整防火墙、端口转发规则,确保目标端访问
source.host.com:5432的流量直达生产实例。 - 清空目标端错误的备份数据目录,重新执行pg_basebackup命令即可完成全量数据复制。
内容的提问来源于stack exchange,提问作者abaelter
相关产品推荐
相关产品推荐

