引言
postgresql数据库有一个基于时间线回滚日志的一个技术方法(PITR),但是我发现很多人操作的时候经常会有以下报错信息。
本文基于postgresql15.3版本模拟
报错信息:cannot stat ‘/home/postgres/archivedir/00000002.history
00000002.history是一个备份基于时间线恢复结束后的信息文件。
解决方法
select pg_wal_replay_resume(); --打开备份库读写模式
启动读写模式后,备份库会终止 recovery,并执行checkpoint,恢复的LSN停在0/2501D440上并生成00000002.history (恢复终止标识文件)
archive recovery complete
checkpoint starting: end-of-recovery immediate wait
原因探查
分析原因
查看一下备份库的postgresql.conf相关参数信息
\! sed '/^[[:blank:]]*#/d;s/#.*//' /home/postgres/backup/postgresql.conf | grep -vE '^#|^$'
##如果是在postgresql的命令交互行,需要加\! 。如何是操作系统的命令交互就不需要 ,路径选择备份库
\! sed '/^[[:blank:]]*#/d;s/#.*//' /home/postgres/pgdata/data/postgresql.conf | grep -vE '^#|^$'
##查看运行主库的参数配置
参数的配置上来说都很常规,
查看进程 发现一直在恢复recovering 000000010000000000000026,并产生了一条锁记录,
显示已经 consistent recovery state reached at 0/2501D440 在这个LSN上已经达到数据一致性
通过所记录可以看到text_dt表被锁住了
查询也确实被hold住了
通过等待事件的进程信息 进入归档日志反查询
通过上图的
consistent recovery state reached at 0/2501D440
recovering 000000010000000000000026
两条信息反查询,
pg_waldump /home/postgres/archivedir/000000010000000000000025 |grep 0/2501D440
--在归档中查询
desc: RUNNING_XACTS nextXid 1221 latestCompletedXid 1220 oldestRunningXid 1221:提供了一些描述性信息。“RUNNING_XACTS” 表明正在执行的事务信息,后面的字段包含与事务相关的一些标识号:nextXid 1221 表示下一个要分配的事务ID是1221,latestCompletedXid 1220 表示已经完成的最新事务ID是1220,oldestRunningXid 1221 表示正在运行的最旧事务ID是1221。
总结
由于进程号1640一直在恢复recovering 000000010000000000000026,而这个进程又锁住表text_dt,回话中就一直有一个等待事件RecoveryPause,recovery_target_time 指定的恢复时间戳, 并是不能在归档信息中找到一个完全一致时间戳的记录并进行归档结束停靠。所以备份库会一直去找。
而正好consistent recovery state reached at 0/2501D440 达到的这个LSN记录使得备份的恢复状态处于一个正在运行未结束的一个事务机制中,在原运行主库中这个running的事务ID 就锁住了这个表 使得在备份库中启动PITR,无法停靠到完全一致的时间戳记录上,出在了一个running事务的记录上,所以恢复无法停止,事务也就无法前进,不会停止,所以表会一直被锁住。就不会产生PITR的结束文件00000002.history.。
建议:
使用recovery_target_name (要在创建前保持无running 的事务ID ),
使用recovery_target_time (不太推荐,恢复点较为精确,但是无法精准的停在有记录的相同时间戳上)
recovery_target_xid (事务ID会有乱序,要确保指定恢复的事务ID前段没有running 的事务ID)
recovery_target_lsn (推荐)