PostgreSQL | WAL文件与LSN

wal

PostgreSQL的第一个 WAL 段文件是 00000001 0000000 0000000 01如果第一个已被写入 的XLOG 记录填满,则将提供第二个 00000001 00000000 000000 02后继文件按升序顺序使用,00000001 00000000 000000 FF填满后,将提供下一个 00000001 00000001 000000 00 。这样,每当最后 2 位结转时,中间 8 位数字就会增加 1。

同样,在 00000001 00000001 000000 FF被填满后,将提供 00000001 00000002 000000 00,以此类推。

WAL的名称由三部分组成,每个部分代表8个数字。首先是TimeLine ID,从1开始。第二部分是逻辑文件ID,从0开始。第3部分是物理文件ID,从00开始,直到 FF,周而复始的循环。

LSN

lsn在官方文档中的解释为:在内部,一个LSN是一个64位整数,表示预写式日志流中的一个字节位置。它被打印成两个最高 8 位的十六进制数,中间用斜线分隔,例如16/B374D848。当执行 PIRP (基于时间点回复)时,我们可以指定一个 LSN号来进行恢复。

test=# select pg_current_wal_lsn(),pg_walfile_name(pg_current_wal_lsn()),pg_walfile_name_offset(pg_current_wal_lsn());
 pg_current_wal_lsn |     pg_walfile_name      |       pg_walfile_name_offset
--------------------+--------------------------+------------------------------------
 1/8052D4E0         | 000000010000000100000080 | (000000010000000100000080,5428448)
(1 row)

LSN与WAL

如何计算Logical File ID和 Physical File ID呢?先看一下Physical File ID,默认是从00开始写,一直写到 FF,然后再循环再次从00开始。在完成00到FF一个循环再到00的转换后, Logical File ID就会增加1。

尽管如此,但他们仍然有一个复杂的公式。

 

计算示例:

test=# select pg_current_wal_lsn(),pg_walfile_name(pg_current_wal_lsn()),pg_walfile_name_offset(pg_current_wal_lsn());
 pg_current_wal_lsn |     pg_walfile_name      |       pg_walfile_name_offset
--------------------+--------------------------+------------------------------------
 1/8052D4E0         | 000000010000000100000080 | (000000010000000100000080,5428448)
(1 row)

test=# select x'18052D4E0'::bigint;
    int8
------------
 6447879392
(1 row)

test=# select ((6447879392 - 1) / (16*1024*1024*256::bigint));
 ?column?
----------
        1
(1 row)

test=# select mod(((6447879392 - 1) / (16*1024*1024)),256);
 mod
-----
 128
(1 row)

test=# SELECT to_hex(128);
 to_hex
--------
 80
(1 row)

如何快速切换wal

Basic usage example for pg_switch_wal():

test=# SELECT pg_switch_wal();
 pg_switch_wal
---------------
 1/8052D4F8
(1 row)

如果自上次 WAL 文件切换以来没有生成 WAL 的活动,则不会创建新的 WAL 文件:

下面的方法会导致 WAL 文件活动,因此总是会导致 WAL 文件切换:

test=# SELECT pg_walfile_name(pg_switch_wal()), now(), pg_walfile_name(pg_switch_wal());
     pg_walfile_name      |              now              |     pg_walfile_name
--------------------------+-------------------------------+--------------------------
 000000010000000100000083 | 2022-06-08 22:56:29.148719+08 | 000000010000000100000083
(1 row)

 

posted @ 2022-06-08 22:58  明矾  阅读(910)  评论(0编辑  收藏  举报