2023年7月10日发(作者:)
PostgreSQL时间线(timeline)和HistoryFile的⽤法说明:在pg中,当我们进⾏了基于时间点的还原(PITR)后,数据库会启⽤新的时间线并继续进⾏操作。但是,当我们进⾏基于时间点的还原后如果发现⼜出现错误,想要继续还原数据库该如何操作呢?如何还原到原先旧的时间线呢?我们可以使⽤recovery_target_timeline参数来指定数据库还原到某⼀个时间线上。如果你还不清楚这个参数该如何使⽤,或者说压根不知道时间线是啥,那么请继续往下看。PostgreSQL 时间线:每当我们在数据库中完成⼀个事务时,所做的操作都会记录到$PGDATA/pg_wal⽬录下的wal⽇志⽂件中。wal⽇志⽂件⼀般都是下⾯这种格式:当⼀个wal⽇志被写满后,便会创建新的wal⽇志,以此类推。该⽂件中前8位,即:00000001表⽰的便是数据库的时间线。从控制⽂件中也可以看到:-bash-4.1$-> pg_controldata |grep TimeLineIDLatest checkpoint's TimeLineID: 1Latest checkpoint's PrevTimeLineID: 1每当我们进⾏基于时间点的还原后,时间线便会加1,并创建⼀个名为y的新⽂件。这个⽂件是⼲什么⽤的我们后⾯会介绍。recovery_target_timeline是⼀个参数,它可以帮助我们将集群带⼊历史记录中的任何时间线,只要有效的基本备份和所有存档⽇志都到位。我们来看看下⾯的例⼦:⾸先,重新初始化⼀个新的数据库集群。-bash-4.1$-> ls pg_wal archive_status然后创建⼀张表并插⼊数据。bill=# create table timeline(tid int, remarks varchar(1000));CREATE TABLEbill=# insert into timeline values('1','This is timeline id 1');INSERT 0 1bill=# checkpoint;CHECKPOINTbill=# select pg_switch_wal();pg_switch_wal---------------0/15D4B70(1 row)刚刚插⼊的数据便记录在的wal⽇志中。当wal⽇志写到时,进⾏⼀次完整的备份,接着再产⽣⼀些新的wal⽇志。-bash-4.1$ ls -rlttotal 147460-rw------- 1 postgres postgres 16777216 Nov 22 13:03 -rw------- 1 postgres postgres 16777216 Nov 22 13:03 -rw------- 1 postgres postgres 16777216 Nov 22 13:03 -rw------- 1 postgres postgres 16777216 Nov 22 13:05 -rw------- 1 postgres postgres 16777216 Nov 22 13:05 -rw------- 1 postgres postgres 337 Nov 22 13:05 -rw------- 1 postgres postgres 16777216 Nov 22 13:06 -rw------- 1 postgres postgres 16777216 Nov 22 13:06 可以看到,现在最新的wal⽇志是接着插⼊⼀条新的数据。bill=# insert into timeline values('1','This is timeline id 1 after basebackup');INSERT 0 1bill=# checkpoint;CHECKPOINT-bash-4.1$ pg_waldump | grep INSERTrmgr: Heap len (rec/tot): 54/ 214, tx:487, lsn: 0/08000110, prev 0/080000D8, desc: INSERT off 2 flags 0x00,blkref #0: rel 1663/13530/16384 blk 0 FPW然后再产⽣⼏个wal⽇志,现在的情况如下:-bash-4.1$ ls -rlttotal 311308-rw------- 1 16777216 Nov 22 13:03 -rw------- 1 16777216 Nov 22 13:03 -rw------- 1 16777216 Nov 22 13:03 -rw------- 1 16777216 Nov 22 13:05 -rw------- 1 16777216 Nov 22 13:05 -rw------- 1 337 Nov 22 13:05 -rw------- 1 16777216 Nov 22 13:06 -rw------- 1 16777216 Nov 22 13:06 -rw------- 1 16777216 Nov 22 13:07 -rw------- 1 16777216 Nov 22 13:07 -rw------- 1 16777216 Nov 22 13:09 A如下图所⽰:此时,在我插⼊第⼆条数据前,我想要把数据还原到这个点。因此我在⽂件中将恢复⽬标lsn设置为“ 0/07000060”。接着进⾏还原,当我们还原之后,数据库切换到了新的时间线。除此之外还有哪些改变呢?恢复结束是指数据库打开进⾏写⼊的点。创建了新的时间线的 history file⽂件,如y。前⼀个时间线上的部分WAL⽂件已被新时间线的ID复制。检查点记录写在新的时间线上。⽇志中会记录下列信息:LOG: starting point-in-time recovery to WAL location (LSN) "0/7000060"LOG: restored log file "" from archiveLOG: redo starts at 0/5000028LOG: consistent recovery state reached at 0/5000138LOG: database system is ready to accept read only connectionsLOG: restored log file "" from archiveLOG: restored log file "" from archiveLOG: recovery stopping after WAL location (LSN) "0/7000060"LOG: pausing at the end of recoveryHINT: Execute pg_wal_replay_resume() to promote.此时,PostgreSQL已在wal⽇志7处分⽀到新的时间线,并开始创建时间线ID为2的新wal⽇志。我们可以下wal⽇志⽬录下看到y⽂件。该⽂件是可读⽂件,内容⼤致为:1
NEWTL_A (xlog)y (history file)例如备库1当前已接收到的XLOG位置是 D ⽂件中的某个位置 0/2D15D7D0,现在promote它 。将会在pg_xlog⽬录中产⽣3个⽂件:lD
(l 的内容会拷贝到 D)y 1 0/2D15D7D0 no recovery target specified假设还有⼀个备库叫备库2,备库2如何能顺利的对接到已激活的备库1呢?有个前提条件备库2在TL1这条时间线上,还没有接收到D 这个⽂件。把y拷贝到备库2的pg_xlog。备库2会在应⽤完C后请求下⼀个时间线的 D ⽂件。这样就能完美对接。以上为个⼈经验,希望能给⼤家⼀个参考,也希望⼤家多多⽀持。如有错误或未考虑完全的地⽅,望不吝赐教。
发布者:admin,转转请注明出处:http://www.yc00.com/web/1688985655a191732.html
评论列表(0条)