zoukankan      html  css  js  c++  java
  • WAL日志文件名称格式详解

    转自:http://blog.osdba.net/534.html

    WAL日志文件名称格式详解


    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)
    
     
  • 相关阅读:
    错误与异常_2-11选择题
    错误与异常_2-10选择题
    错误与异常_2-8选择题
    错误与异常_2-7选择题
    C#定时器
    C#动态webservice调用接口
    C# webservice返回Xml格式文件
    C#创建简单的Xml文件
    获取数据库中指定类型的数据库名称
    C#生成Xml以UTF-8无BOM格式编码
  • 原文地址:https://www.cnblogs.com/kuang17/p/6831144.html
Copyright © 2011-2022 走看看