在PostgreSql主从模式的数据库运行中,如果从库丢失了从主库同步过来的xlog文件的话,会报以下错误:
LOG: started streaming WAL from primary at 0/1D000000 on timeline 1
FATAL: could not receive data from WAL stream: ERROR: requested WAL segment 00000001000000000000001D has already been removed
以下是实践亲测的几种方法总结
一、从归档文件中重做事务
前提是主库的配置文件postgresql.conf
有打开归档设置
archive_mode = on
archive_command = 'test ! -f /data/pgdata/pg_xlog/archive_status/%f && cp %p /data/pgdata/pg_xlog/archive_status/%f'
从保存的归档的文件中复制到从库,从库重做事务,流复制恢复正常
scp /data/pgdata/pg_xlog/archive_status/00000001000000000000001D sdw4:/data/pgdata/pg_xlog
二、使用rsync增量同步
当主库没有配置做归档设置时,可使用rsync增量同步数据库的目录。
首先在从库上添加认证文件
[postgres@sdw4 ~]$ cat .pgpass
192.168.43.175:6432:replication:rep:rep123
sdw3:6432:replication:rep:rep123
在主库上创建脚本rsync_standby.sh
#/bin/sh -x
PRIMARY_PORT=6432
STANDBY_PORT=6432
SOURCE_CLUSTER=/data/pgdata
DEST_CLUSTER=/data/pgdata
PGCTL=/usr/local/pgsql/bin/pg_ctl
recovery_node_host_name=sdw4
primary_host_name=sdw3
psql -p $PRIMARY_PORT -c "SELECT pg_start_backup('file_based_log_shipping', true)" postgres
/usr/bin/rsync -C -a -c --delete --exclude postmaster.pid \
--exclude postgresql.trigger.* --exclude postmaster.opts --exclude pg_log \
--exclude recovery.conf --exclude recovery.done \
--exclude pg_xlog \
$SOURCE_CLUSTER/ $recovery_node_host_name:$DEST_CLUSTER/
ssh -T $recovery_node_host_name /bin/rm -rf $DEST_CLUSTER/pg_xlog
ssh -T $recovery_node_host_name /bin/mkdir $DEST_CLUSTER/pg_xlog
ssh -T $recovery_node_host_name /bin/chmod 700 $DEST_CLUSTER/pg_xlog
ssh -T $recovery_node_host_name /bin/rm -rf $DEST_CLUSTER/recovery.*
ssh -T $recovery_node_host_name /bin/echo "hot_standby = on >>$DEST_CLUSTER/postgresql.conf"
ssh -T $recovery_node_host_name "/bin/cat > $DEST_CLUSTER/recovery.conf <<EOF
standby_mode = on
primary_conninfo = 'port=$PRIMARY_PORT user=rep host=$primary_host_name'
trigger_file = '$DEST_CLUSTER/pgsql.recovery.trigger'
recovery_target_timeline = 'latest'
EOF"
ssh -T $recovery_node_host_name "sed -i 's/$PRIMARY_PORT/$STANDBY_PORT/g' $DEST_CLUSTER/postgresql.conf"
psql -p $PRIMARY_PORT -c "SELECT pg_stop_backup()" postgres
ssh -T $recovery_node_host_name $PGCTL -w -D $DEST_CLUSTER start 2>/dev/null 1>/dev/null < /dev/null &
脚本解读
先执行pg_start_backup,告诉数据库我要开始执行备份操作了,XLOG日志你暂时不要写到文件里了,不然我一边读你一边写会有问题
ssh到从库,删除一些不必要的文件和目录,因为rsync只会同步变更的数据,如果从库有其它数据文件的话,rsync命令是不会删除的。
重新生成recovery.conf文件,设置recovery_target_timeline = 'latest'告诉从库要重做事务到最新时间状态。
同步完成后,在主库执行pg_stop_backup告诉数据库我备份完啦,然后启动从库
执行命令,会增量同步并且启动从库
[postgres@sdw3 ~]$ sh rsync_standby.sh
pg_start_backup
-----------------
0/2E000028
(1 row)
NOTICE: pg_stop_backup complete, all required WAL segments have been archived
pg_stop_backup
----------------
0/2E0000F8
(1 row)
三、重建从库
使用pg_basebackup重新搭建备库,最佳实践见之前文章PostgreSql数据库Standby的搭建
四、设置参数避免
主库修改配置postgresql.conf ,添加参数wal_keep_segments,能够减少这情况的发生
wal_keep_segments = 10
参数解析
设置pg_xlog 目录下保留日志文件最小数,默认每个文件16MB,空间充足情况下考虑合适配置。
文章转载自叶同学专栏,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




