开头还是介绍一下群,如果感兴趣PolarDB ,MongoDB ,MySQL ,PostgreSQL ,Redis, Oceanbase, Sql Server等有问题,有需求都可以加群群内有各大数据库行业大咖,CTO,可以解决你的问题。加群请联系 liuaustin3 ,(共2150人左右 1 + 2 + 3 + 4 +5) 新人奖直接分配到5群,另欢迎 OpenGauss 的技术人员加入。
PostgreSQL 中可以通过时间线的概念在日志中标记数据库中操作的一切。通过调用pg_controldata,查看当前的数据库的wal日志正在使用的是哪个,这里的是 000000010000000000000012 。但注意看下面两个部分,非常短的时间,WAL日志有了变化,这里我做了一个操作,恢复数据库。今天的讨论就从恢复数据库后的 history 文件开始。
root@pg16:~# su - postgres
postgres@pg16:~$ pg_controldata
pg_control version number: 1300
Catalog version number: 202307071
Database system identifier: 7309003792944632868
Database cluster state: in production
pg_control last modified: Wed 06 Mar 2024 08:59:38 AM UTC
Latest checkpoint location: 0/120000C0
Latest checkpoint's REDO location: 0/12000088
Latest checkpoint's REDO WAL file: 000000010000000000000012
Latest checkpoint's TimeLineID: 1
Latest checkpoint's PrevTimeLineID: 1
Latest checkpoint's full_page_writes: on
Latest checkpoint's NextXID: 0:770
Latest checkpoint's NextOID: 16400
Latest checkpoint's NextMultiXactId: 1
Latest checkpoint's NextMultiOffset: 0
postgres@pg16:/pgdata/data/pg_wal$ pg_controldata
pg_control version number: 1300
Catalog version number: 202307071
Database system identifier: 7309003792944632868
Database cluster state: in production
pg_control last modified: Wed 06 Mar 2024 09:05:38 AM UTC
Latest checkpoint location: 0/15000028
Latest checkpoint's REDO location: 0/15000028
Latest checkpoint's REDO WAL file: 000000020000000000000015
Latest checkpoint's TimeLineID: 2
Latest checkpoint's PrevTimeLineID: 1
Latest checkpoint's full_page_writes: on
Latest checkpoint's NextXID: 0:771
Latest checkpoint's NextOID: 16400
Latest checkpoint's NextMultiXactId: 1
Latest checkpoint's NextMultiOffset: 0
Latest checkpoint's oldestXID: 722
Latest checkpoint's oldestXID's DB: 1
Latest checkpoint's oldestActiveXID: 0
Latest checkpoint's oldestMultiXid: 1
Latest checkpoint's oldestMulti's DB: 1
postgres@pg16:/pgdata/data/pg_wal$ cat 00000002.history
1 0/15000000 no recovery target specified
postgres@pg16:/pgdata/data/pg_wal$
postgres@pg16:/pgdata/data/pg_wal$
在history文件里面存储这一些文字内容,而这些文字的内容到底是干什么的,我们为了去获得更多的内容,
postgres@pg16:/pgdata/data$ cd pg_wal/
postgres@pg16:/pgdata/data/pg_wal$ ls
000000030000000000000015 000000030000000000000017 archive_status
000000030000000000000016 00000003.history
postgres@pg16:/pgdata/data/pg_wal$
postgres@pg16:/pgdata/data/pg_wal$
postgres@pg16:/pgdata/data/pg_wal$ cat 00000003.history
1 0/15000000 no recovery target specified
postgres@pg16:/pgdata/data/pg_wal$
在操作完毕,里面的内容没有变,但是编号变了。变成了0000003.history
postgres@pg16:/pgdata/data$ cd pg_wal/
postgres@pg16:/pgdata/data/pg_wal$ ls
00000003.history 000000040000000000000019 00000004.history
000000040000000000000018 00000004000000000000001A archive_status
postgres@pg16:/pgdata/data/pg_wal$ cat 00000004.history
1 0/15000000 no recovery target specified
3 0/18000000 no recovery target specified
postgres@pg16:/pgdata/data/pg_wal$ ls
00000003.history 000000040000000000000019 00000004.history
000000040000000000000018 00000004000000000000001A archive_status
postgres@pg16:/pgdata/data/pg_wal$
当我这次备份数据库,后在进行恢复,给我的信息和之前又不一样,那么问题来了,为什么每次在数据库恢复后,都会多一个history文件,他的功能是什么,同时为什么每次恢复一次数据库,其中的0000000?会有变化每次恢复后都会加1 ,这些问题都是怎么回事。
实际上在上面提出的第一个问题,这个位置的数字相当于WAL中的分歧点,代表一个数据库恢复后的WAL开始的LSN的分歧。
例如:pg_wal/000000010000000000000001,表示这个 WAL 段属于时间线 ID = 1以及pg_wal/000000020000000000000001,表示这个 WAL 段属于时间线 ID = 2
上马的例子就说明这个数据库恢复过一次,所以从1变成2了. 他这里有点像git的分支,但是不能合并的那种,
那么为什么会这样,我们可以理解为数据库最早的时间线是ID 1 ,后面所有的数据都是在时间线1 上进行的当我们备份数据库后在数据库上进行恢复后,则创建了时间线2 ,此后的操作都是属于时间线2的,每次进行备份后恢复都会创建新的时间线。
那么当恢复数据库的时候,会在数据库中的pg_wal 中建立一个新.history 的文件,该文件描述了回放数据库中的分歧点,如果没有这个文件就无法确定数据恢复的时间线的来源,也就无法确定PITR的恢复的相关需要的信息。通过这样的概念,如果有相同的LSN号,或相同的WAL存在多个时间线中,在数据恢复中会根据当前的时间轴来进行数据的恢复。
这点在PG中非常重要尤其适用通过archive 来对WAL日志进行归档的情况下,归档文件中可能会存在多个时间线的wal 文件,通过确定是否是一个时间线来进行数据的恢复。