转自PG社区志愿者唐成的博客户,原文地址: http://blog.osdba.net/534.html

PostgreSQL的WAL日志文件在pg_xlog目录下,一般情况下,每个文件为16M大小:

osdba-mac:~ osdba$ ls -l  $PGDATA/pg_xlog
total 262144
-rw-------  1 osdba  osdba  16777216 Oct  8 10:57 0000000100000000000000B6
-rw-------  1 osdba  osdba  16777216 Jun 17 22:12 0000000100000000000000B7
-rw-------  1 osdba  osdba  16777216 Jun 17 22:12 0000000100000000000000B8
-rw-------  1 osdba  osdba  16777216 Jun 17 22:12 0000000100000000000000B9
-rw-------  1 osdba  osdba  16777216 Jun 17 22:12 0000000100000000000000BA
-rw-------  1 osdba  osdba  16777216 Jun 17 22:12 0000000100000000000000BB
-rw-------  1 osdba  osdba  16777216 Jun 17 22:13 0000000100000000000000BC
-rw-------  1 osdba  osdba  16777216 Jul 23 19:01 0000000100000000000000BD
drwx------  2 osdba  osdba        68 Mar  9  2015 archive_status

文件名称为16进制的24个字符组成,每8个字符一组,每组的意义如下:


    00000001 00000000 000000BC
    -------- -------- --------
     时间线    LogId    LogSeg

时间线:英文为timeline,是以1开始的递增数字,如1,2,3...
LogId:32bit长的一个数字,是以0开始递增的数字,如0,1,2,3...
LogSeg:32bit长的一个数字,是以0开始递增的数字,如0,1,2,3...

然而需要注意的是,数据库刚建好时,LogSeg第一次是从1开始的数字,到达一个最大的数字后,会重头开始,但以后再从头开始时,不再从1开始,而是从0开始。为什么这样呢?下面我们会讲解到这个问题。

WAL日志的位置是一个无限长的位置,数据库一建立后,不断的开始写WAL日志,此位置就不断的增加,即使数据库重启后,此位置也不会重新开始,只会一直增加,所以这个位置值显然如果用32bit的一个数字是不够的,32bit最多表示4GB的日志,所以大家很容易可以想到用一个64bit的数字来表示这个WAL日志的位置,这当然就足够了(因为要写4G*4G的数据才会用完64bit的长度)。

这个WAL日志的位置称之为LSN,即Log Sequence Number。

看起来,LogId+LogSeg好象刚好组成一个64bit的LSN,是否是LogId是这个64bit的LSN中的高32bit字节,而LogSeg就是低32bit的字节呢?LogId确实是LSN的高32字节,但LogSeg却不是低32bit的字节,另我们可以观察到LogSeg的值是从00000000到000000FF后,就重新从00000000开始了,并不会出现00000100这样的数值,也就是LogSeg的8个字符中,前6个字符始终是0,这是为什么?

原来LogSeg是按文件递增,每增加一个文件,LogSeg就增加1,而每个WAL文件的大小是16M,LogSeg是LSN的低32bit的字节的值再除以16M的结果,这样4G/16M结果是256,所以LogSeg最大的值为256,即16进制的0xFF,这样就解释了LogSeg的前6字节都是零的原因。

另原本LSN起始位置可以从0开始,但为了表示一些无效的位置,LSN的起始值并不是从0开始,也不是从1开始,而是跳过了一个WAL文件大小,即16M的位置开始,这样第一次时LogSeg是从1开始的,而不是从0开始了。

我们知道了WAL日志文件名中的意义,但很多时候我们会发现在PostgreSQL中会用两个十六进制的数字中间用斜杠“/”分隔表示WAL日志位置,即表示LSN,如函数pg_current_xlog_location、pg_current_xlog_insert_locatione及pg_start_backup的返回结果,如下所示:

postgres=# select pg_current_xlog_location(), pg_current_xlog_insert_location();
 pg_current_xlog_location | pg_current_xlog_insert_location
--------------------------+---------------------------------
 0/12B00B48               | 0/12B00B48
(1 row)
  
postgres=# select pg_start_backup('osdba_backup201510082130');
 pg_start_backup
-----------------
 0/14000100
(1 row)

同时我们在主库上通过查询视图pg_stat_replication来看replication的状态时,一些字段也显示成这样的格式:

postgres=# select sent_location, write_location, flush_location, replay_location, sync_state from pg_stat_replication;
 sent_location | write_location | flush_location | replay_location | sync_state
---------------+----------------+----------------+-----------------+------------
 0/1177A9F0    | 0/1177A9F0     | 0/1177A320     | 0/11779818      | async
(1 row)

以上这些表示WAL日志位置的方法,就是用两个32bit的数字来表示LSN,前一个数字LSN的高32bit,而另一个数字则是LSN的低32bit。在PostgreSQL9.4之后,增加了一个专门的类型pg_lsn用于表示WAL日志的位置,在PostgreSQL9.4之前,则用字符串来表示这个位置。

象上面的例子中,函数pg_current_xlog_location返回0/12B00B48,如果当前timeline为1,那么当前的WAL日志文件名是什么呢?

logId就是“0/12B00B48”中的第一个数字,即0
logSeg就是“0/12B00B48”中的第二个数字除以16M的大小,即12B00B48除以16M,而16M相当于2的24次方,相当于十六进制数“12B00B48”右移6位,即“12B00B48”中的最高两位“12”
那么根据WAL文件的格式timeline+logId+logSeg,则相当于:“00000001”+“00000000”+“00000012”,即为:“000000010000000000000012” 写的位置是在文件“000000010000000000000012”中的偏移量是多少呢?实际上是在“0/12B00B48”中第二个数字“12B00B48”后六位“B00B48”,换算成十进制为“11537224”。
当然PostgreSQL已准备了函数pg_xlogfile_name_offset帮我们做以上的转换,如下所示:

postgres=# select pg_xlogfile_name_offset('0/12B00B48');
       pg_xlogfile_name_offset
-------------------------------------
 (000000010000000000000012,11537224)
(1 row)
请在登录后发表评论,否则无法保存。
1楼 xiaowu
2024-04-21 07:32:07+08

有寓意的网名:https://www.nanss.com/mingcheng/825.html 带猫的网名:https://www.nanss.com/mingcheng/844.html 谁是卧底词汇:https://www.nanss.com/shenghuo/734.html 工作简报:https://www.nanss.com/gongzuo/821.html 乖乖网名:https://www.nanss.com/mingcheng/1421.html 哭过后的心情说说:https://www.nanss.com/wenan/1500.html 幼儿园户外100种游戏:https://www.nanss.com/gongzuo/711.html 无情冷血霸气的名字:https://www.nanss.com/mingcheng/846.html 非主流繁体网名:https://www.nanss.com/mingcheng/1387.html 唯美的个性签名:https://www.nanss.com/yulu/1258.html 四个字的名字:https://www.nanss.com/mingcheng/1251.html 女人最好的状态语录:https://www.nanss.com/yulu/921.html 中专自我鉴定:https://www.nanss.com/xuexi/925.html 播音稿:https://www.nanss.com/xuexi/942.html 请假的好理由:https://www.nanss.com/gongzuo/892.html 传奇个性名字:https://www.nanss.com/mingcheng/1198.html 天龙八部好听的名字:https://www.nanss.com/mingcheng/1189.html 比较文艺的昵称:https://www.nanss.com/mingcheng/613.html 古韵网名:https://www.nanss.com/mingcheng/1385.html 超市实习报告:https://www.nanss.com/gongzuo/558.html 女儿小棉袄赞美句子:https://www.nanss.com/wenan/1257.html 诗句网名:https://www.nanss.com/mingcheng/504.html 游戏昵称骚而不俗的:https://www.nanss.com/mingcheng/653.html 最好的网名:https://www.nanss.com/mingcheng/1176.html qq女生网名:https://www.nanss.com/mingcheng/1178.html 童话作文:https://www.nanss.com/xuexi/862.html 求职自荐信:https://www.nanss.com/gongzuo/905.html qq名称昵称男:https://www.nanss.com/mingcheng/934.html 男网名:https://www.nanss.com/mingcheng/940.html 放弃一个人的经典句子:https://www.nanss.com/yulu/800.html

2楼 GUEST
2017-02-16 14:48:55+08

© 2010 PostgreSQL中文社区