暂无图片
暂无图片
1
暂无图片
暂无图片
暂无图片

PostgreSql从库xlog文件丢失解决办法

叶同学专栏 2021-04-16
2541

在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进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论