暂无图片
暂无图片
1
暂无图片
暂无图片
暂无图片

PostgreSQL WAL解析:构建WAL记录准备

yanzongshuaiDBA 2019-09-08
1652

以heap_insert为例,简述WAL的插入过程。

在构建WAL日志记录的过程中主要涉及2个数据变量:static XLogRecData *rdatas数组和static registered_buffer *registered_buffers数组。这两个数组分别用来保存WAL数据和管理rdatas链表。

主要涉及3个重要的函数:XLogRegisterData、XLogRegisterBuffer和XLogRegisterBufData。这三个函数的作用分别是将WAL记录的特殊结构体数据注册到WAL,比如heap_insert中的xl_heap_insert结构体;将涉及到的buf注册到wal记录,比如heap_insert中page页赋予regbuf->page;将元组内容注册到WAL记录,比如insert语句的元组数据等。


下面首先介绍相关数据结构。


1、数据结构

HeapTupleData

    typedef struct HeapTupleData
    {
    uint32 t_len; /* length of *t_data */
    ItemPointerData t_self; /* SelfItemPointer */
    Oid t_tableOid; /* table the tuple came from */
    HeapTupleHeader t_data; /* -> tuple header and data */
    } HeapTupleData;
    复制

    xl_heap_header

      /*
      * We don't store the whole fixed part (HeapTupleHeaderData) of an inserted
      * or updated tuple in WAL; we can save a few bytes by reconstructing the
      * fields that are available elsewhere in the WAL record, or perhaps just
      * plain needn't be reconstructed. These are the fields we must store.
      * NOTE: t_hoff could be recomputed, but we may as well store it because
      * it will come for free due to alignment considerations.
      */
      typedef struct xl_heap_header
      {
      uint16 t_infomask2;
      uint16 t_infomask;
      uint8 t_hoff;
      } xl_heap_header;
      复制

      xl_heap_insert

        /* This is what we need to know about insert */
        typedef struct xl_heap_insert
        {
        OffsetNumber offnum; /* inserted tuple's offset */
        uint8 flags;

        /* xl_heap_header & TUPLE DATA in backup block 0 */
        } xl_heap_insert;
        复制

        XLogRecData

          /*
          * The functions in xloginsert.c construct a chain of XLogRecData structs
          * to represent the final WAL record.
          */
          typedef struct XLogRecData
          {
          struct XLogRecData *next; /* next struct in chain, or NULL */
          char *data; /* start of rmgr data to include */
          uint32 len; /* length of rmgr data to include */
          } XLogRecData;
          复制

          registered_buffer

            /*
            * For each block reference registered with XLogRegisterBuffer, we fill in
            * a registered_buffer struct.
            */
            typedef struct
            {
            bool in_use; /* is this slot in use? */
            uint8 flags; /* REGBUF_* flags */
            RelFileNode rnode; /* identifies the relation and block */
            ForkNumber forkno;
            BlockNumber block;
            Page page; /* page content */
            uint32 rdata_len; /* total length of data in rdata chain */
            XLogRecData *rdata_head; /* head of the chain of data registered with this block */
            XLogRecData *rdata_tail; /* last entry in the chain, or &rdata_head if empty */
            XLogRecData bkp_rdatas[2]; /* temporary rdatas used to hold references to
            * backup block data in XLogRecordAssemble() */
            /* buffer to store a compressed version of backup block image */
            char compressed_page[PGLZ_MAX_BLCKSZ];
            } registered_buffer;
            复制

            2、heap_insert涉及WAL的流程

             

            第一步中,得到如下结果,mainrdata_last保存rdata[0],存储的是xl_heap_insert结构:

            第二步,得到如下结果,取registered_buffer[0],其rdata_head->next指向rdata[1],存储tuple记录的头信息:

            接着进入第三步,取rdata[2],将其放到rdata[1]->next中,即加入registered_buffers[0]的rdata_head链表中,存储TUPLE值:

            以上是构建WAL记录的准备阶段,下一节介绍WAL的构建及其通用结构。


            最后修改时间:2019-11-24 18:35:12
            文章转载自yanzongshuaiDBA,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

            评论