• 由pg_xlogdump统计信息想到的问题


    最近深入理解了Checkpoint的相关逻辑,再来看WAL日志的一些设置,又有了新的收获。

    1.回顾pg_xlogdump出来的wal日志信息;

    2.wal中FPI的占比很高问题分析;

    3.重申full_page_writes的作用;

    4.解决wal日志很大的问题,使用压缩更靠谱。不建议将full_page_writes设置为false来提升性能,就像把fsync设置为false提升性能一样是不合理的。

    先来看一段WAL日志记录,我们通过pg_xlogdump来解析:

    apple=# create table test(id int);
    CREATE TABLE
    execute query success, query is create table test(id int);
    apple=# select pg_current_xlog_location();
     pg_current_xlog_location
    --------------------------
     0/8004B738
    (1 row)
    
    apple=# insert into test values(1);
    INSERT 0 1
    apple=# insert into test values(2);
    INSERT 0 1
    apple=# insert into test values(3);
    INSERT 0 1
    execute query success, query is select pg_current_xlog_location();
    apple=# checkpoint;
    CHECKPOINT
    apple=# select pg_current_xlog_location();
     pg_current_xlog_location
    --------------------------
     0/8004B8E0
    (1 row)
    apple=# q
    appledeMacBook-Pro-2:pg_xlog apple$ pg_xlogdump -p ./ -s 0/8004B738 -e 0/8004B8E0
    rmgr: Heap        len (rec/tot):      3/    59, tx:     718239, lsn: 0/8004B738, prev 0/8004B710, desc: INSERT+INIT off 1, blkref #0: rel 1663/16384/53523 blk 0
    rmgr: Transaction len (rec/tot):      8/    34, tx:     718239, lsn: 0/8004B778, prev 0/8004B738, desc: COMMIT 2019-03-28 11:02:44.115417 CST
    rmgr: Heap        len (rec/tot):      3/    59, tx:     718240, lsn: 0/8004B7A0, prev 0/8004B778, desc: INSERT off 2, blkref #0: rel 1663/16384/53523 blk 0
    rmgr: Transaction len (rec/tot):      8/    34, tx:     718240, lsn: 0/8004B7E0, prev 0/8004B7A0, desc: COMMIT 2019-03-28 11:02:46.022003 CST
    rmgr: Heap        len (rec/tot):      3/    59, tx:     718241, lsn: 0/8004B808, prev 0/8004B7E0, desc: INSERT off 3, blkref #0: rel 1663/16384/53523 blk 0
    rmgr: Transaction len (rec/tot):      8/    34, tx:     718241, lsn: 0/8004B848, prev 0/8004B808, desc: COMMIT 2019-03-28 11:02:48.293447 CST
    rmgr: XLOG        len (rec/tot):     80/   106, tx:          0, lsn: 0/8004B870, prev 0/8004B848, desc: CHECKPOINT_ONLINE redo 0/8004B870; tli 1; prev tli 1; fpw true; xid 0/718242; oid 61709; multi 1; offset 0; oldest xid 931 in DB 19697; oldest multi 1 in DB 19697; oldest/newest commit timestamp xid: 0/0; oldest running xid 0; online
    

    解释一下pg_xlogdump各个字段的意思:

    rmgr: Heap 
    	PostgreSQL内部将WAL日志归类到20多种不同的资源管理器。这条WAL记录所属资源管理器为Heap,即堆表。除了Heap还有Btree,Transaction等。
    len (rec/tot): 3/    59
    	WAL记录的总长度是59字节,其中main data部分是3字节(只计数main data可能并不合理,本文的后面会有说明)。
    tx: 718239
    	事务号
    lsn: 0/8004B738
    	本WAL记录的LSN
    prev 0/8004B710
    	上条WAL记录的LSN
    desc: INSERT+INIT off 1
    	这是一条insert类型的记录(每个资源管理器最多包含16种不同的WAL记录类型,),tuple在page中的位置为1。
    blkref #0: rel 1663/16384/53523 blk 0
    	引用的第一个page所属的对表文件为1663/16384/53523,块号为0(即ctid的前半部分)。通过oid2name可以查到是哪个堆表。
    
    apple=# select pg_relation_filepath('test');
     pg_relation_filepath
    ----------------------
     base/16384/53523
    (1 row)
    

    再回顾一下pg_xlogdump的使用方法:

    appledeMacBook-Pro-2:service_list apple$ pg_xlogdump --help
    pg_xlogdump decodes and displays PostgreSQL transaction logs for debugging.
    
    Usage:
      pg_xlogdump [OPTION]... [STARTSEG [ENDSEG]]
    
    Options:
      -b, --bkp-details      output detailed information about backup blocks
      -e, --end=RECPTR       stop reading at log position RECPTR
      -f, --follow           keep retrying after reaching end of WAL
      -n, --limit=N          number of records to display
      -p, --path=PATH        directory in which to find log segment files
                             (default: ./pg_xlog)
      -r, --rmgr=RMGR        only show records generated by resource manager RMGR
                             use --rmgr=list to list valid resource manager names
      -s, --start=RECPTR     start reading at log position RECPTR
      -t, --timeline=TLI     timeline from which to read log records
                             (default: 1 or the value used in STARTSEG)
      -V, --version          output version information, then exit
      -x, --xid=XID          only show records with TransactionId XID
      -z, --stats[=record]   show statistics instead of records
                             (optionally, show per-record statistics)
      -?, --help             show this help, then exit

     --对-b说明一下:Data portion of XLOG record is classified into either backup block (entire page) or non-backup block (different data by operation).

    我们再关注一下对WAL的统计信息:

    appledeMacBook-Pro-2:data apple$ pg_xlogdump -p pg_xlog -z -s 0/80000098 -e 0/8001B9D0
    Type                                           N      (%)          Record size      (%)             FPI size      (%)        Combined size      (%)
    ----                                           -      ---          -----------      ---             --------      ---        -------------      ---
    XLOG                                           1 (  1.08)                   28 (  1.01)                    0 (  0.00)                   28 (  0.03)
    Transaction                                    5 (  5.38)                  216 (  7.76)                    0 (  0.00)                  216 (  0.20)
    Storage                                        1 (  1.08)                   40 (  1.44)                    0 (  0.00)                   40 (  0.04)
    CLOG                                           0 (  0.00)                    0 (  0.00)                    0 (  0.00)                    0 (  0.00)
    Database                                       0 (  0.00)                    0 (  0.00)                    0 (  0.00)                    0 (  0.00)
    Tablespace                                     0 (  0.00)                    0 (  0.00)                    0 (  0.00)                    0 (  0.00)
    MultiXact                                      0 (  0.00)                    0 (  0.00)                    0 (  0.00)                    0 (  0.00)
    RelMap                                         0 (  0.00)                    0 (  0.00)                    0 (  0.00)                    0 (  0.00)
    Standby                                        0 (  0.00)                    0 (  0.00)                    0 (  0.00)                    0 (  0.00)
    Heap2                                          2 (  2.15)                   64 (  2.30)                 6236 (  5.89)                 6300 (  5.80)
    Heap                                          57 ( 61.29)                 1734 ( 62.28)                37060 ( 35.00)                38794 ( 35.69)
    Btree                                         27 ( 29.03)                  702 ( 25.22)                62604 ( 59.12)                63306 ( 58.25)
    Hash                                           0 (  0.00)                    0 (  0.00)                    0 (  0.00)                    0 (  0.00)
    Gin                                            0 (  0.00)                    0 (  0.00)                    0 (  0.00)                    0 (  0.00)
    Gist                                           0 (  0.00)                    0 (  0.00)                    0 (  0.00)                    0 (  0.00)
    Sequence                                       0 (  0.00)                    0 (  0.00)                    0 (  0.00)                    0 (  0.00)
    SPGist                                         0 (  0.00)                    0 (  0.00)                    0 (  0.00)                    0 (  0.00)
    BRIN                                           0 (  0.00)                    0 (  0.00)                    0 (  0.00)                    0 (  0.00)
    CommitTs                                       0 (  0.00)                    0 (  0.00)                    0 (  0.00)                    0 (  0.00)
    ReplicationOrigin                              0 (  0.00)                    0 (  0.00)                    0 (  0.00)                    0 (  0.00)
                                            --------                      --------                      --------                      --------
    Total                                         93                          2784 [2.56%]                105900 [97.44%]               108684 [100%]
    

    各个列的解释:

    各个列的解释:
    Type:xlog中的日志类型
    N: 次数及占比
    Record size:记录的大小及占比
    FPI size:      full page image大小及占比
    combined size: 记录和FPI的大小总和
    

    我们看到WAL中的FPI占比非常大,到了97.44%,真正记录Record的信息才2.56%,那么为什么会这样呢,这样合理吗?

    FPI的来源是设置了full_page_writes=on,每个Checkpoint之后的修改的数据页都会记录到wal中,导致wal中的FPI占比就很大。

    因此,有人就说加大两个Checkpoint点之间的时间间隔,可以减少FPI的占比,这是不合理的,官网上说是每个Checkpoint之后改变的page都会写入到wal,而很多人理解为Checkpoint之后,第一个被修改的page才会写入到wal,这是错误的的理解:

    When this parameter is on, the PostgreSQL server writes the entire content of each disk page to WAL during the first modification of that page after a checkpoint.
    

    那么这里又引申出为什么要设置full_page_writes=on?

    当一个崩溃发生在Checkpoint过程中,导致部分page中数据已经刷新了,某些page中的数据可能才写了一半。那么我们在重启数据库进行恢复时,会从上一个完成的Checkpoint点开始回放,如果没有FPI,则会基于已经刷新的page进行修改,这是错误的。
    

    这是典型的部分写问题,我们应该从两个方面理解部分写:

    1)某个page只写了一部分,就发生了crash;

    2)这一批要刷新的page,只有一部分被更新了,仍然有一部分没有写入。

    针对1)中的情况,我们可以选用支持原子写的文件系统来解决,我们保证写page的操作是原子的,要么失败,要么成功。目前有ZFS文件系统,ext4的事务写也可以解决,设置data=journal。

    针对2)中的情况,单纯使用文件系统的原子写还是无法解决,因此只有通过full_page_writes=on来解决。

    针对2)的情况,可以使用集群的方式,从备库进行恢复。

    那么说到最后,我们可以这么总结吗:如果有高可用集群,那么我们可以将full_page_writes设置为false来提升性能???

    下面是一个非官方的统计:设置了full_page_writes=on,数据库的TPS会减少30%以上,WAL日志大小会增加500%以上,对page更新越稀疏,问题越严重。

    针对WAL日志增加太多的情况,我们可以使用wal_compression=on来进行压缩,一般可以减少50%左右,且TPS也有少量的提升。

    再次强调,设置checkpoint_timeout没有用处,因为每个被改变的page都会写入到wal中。

    后续引申出Checkpoint的工作原理、fsync的设置问题、double write来替代full_page_writes,找机会再记录一下。

     

  • 相关阅读:
    HTML5 Application Cache
    一个页面多个bootstrip轮播以及一个页面多个swiper轮播 冲突问题
    jquery中attr和prop的区别
    eval函数的工作原理
    JSON.parse 函数
    JS知识体系
    闭包
    io输入输出与反射机制2
    IO输入输出与反射机制1
    项目-超市会员管理系统
  • 原文地址:https://www.cnblogs.com/kuang17/p/10613938.html
Copyright © 2020-2023  润新知