第9章的摘要:“写入前伐木(WAL)”书中的“ postgresql的内部”第3部分
#postgres #database #apacheage #agenssql

此博客旨在帮助您理解章节的内侧概念:9 [书面记录(WAL)]

注意:确保您对
有透彻的了解 Chapter 9 Part-2和posttresql的基础知识在我们继续第9章第3章之前,因为它构成了我们的探索基础。

所以,让我们继续:

Xlog记录的内部布局

XLOG记录的标题部分

  • 所有XLOG记录都有由结构定义的一般标题部分 Xlogrocord

  • Xlogrocord的结构如下:

typedef struct XLogRecord
{
   uint32          xl_tot_len;   /* total len of entire record */
   TransactionId   xl_xid;       /* xact id */
   uint32          xl_len;       /* total len of rmgr data */
   uint8           xl_info;      /* flag bits, see below */
   RmgrId          xl_rmid;      /* resource manager for this record */
   /* 2 bytes of padding here, initialize to zero */
   XLogRecPtr      xl_prev;      /* ptr to previous record in log */
   pg_crc32        xl_crc;       /* CRC for this record */
} XLogRecord;

  • xl_rmid xl_info 都是与资源管理者相关的变量,它们是与WAL功能相关的操作集合,例如编写和重播Xlog Records。

XLOG记录的数据部分(版本9.4或更早)

  • XLOG记录的数据部分分为备份块(整个页面)或 non-backup block (通过操作不同的数据)。

XLOG记录的示例(版本9.4或更早) 在下图中描述了:

Image description

XLOG记录的数据部分(版本9.5或更高版本)

  • 在版本9.4或更早的版本中,Xlog记录的格式没有 common ,因此每个资源经理都必须定义自己的格式。在这种情况下,越来越难以维护源代码并实施与WAL相关的新功能变得越来越困难。

  • 为了解决这个问题,一种不依赖资源经理的常见结构化格式已在版本 9.5 中引入。。。 p>

  • XLOG记录的数据部分可以分为两个部分:标题 data

PostgreSQL中的常见Xlog记录格式如下图所示:

Image description

  • 标题零件 包含零或更多 xlogrocordblockheaders 和零或一个 xlogrecorddataheadershort

  • 它必须至少包含其中的一个。当其记录存储完整图像(即备份块)时, xlogrocordblockheader 包括 xlogrecordblockimageheader ,并且还包括 xlogrecordblockcompressheader 如果其块被压缩。 /p>

  • 数据零件 由零或更多块数据和零或一个主要数据组成,这对应于 xlogrecordblockheader(s) xlogrocorddataheader

XLOG记录的示例(版本9.5或更高版本)在PostgreSQL中的图表如下图:

Image description


Xlog记录的写作

  • 首先,发出以下语句探索postgresql内部:

testdb=# INSERT INTO tbl VALUES ('A');

  • pseudo-code exec_simple_query()如下:
exec_simple_query() @postgres.c

(1) ExtendCLOG() @clog.c                  /* Write the state of this transaction
                                           * "IN_PROGRESS" to the CLOG.
                                           */
(2) heap_insert()@heapam.c                /* Insert a tuple, creates a XLOG record,
                                           * and invoke the function XLogInsert.
                                           */
(3)   XLogInsert() @xlog.c (9.5 or later, xloginsert.c)
                                          /* Write the XLOG record of the inserted tuple
                                           *  to the WAL buffer, and update page's pd_lsn.
                                           */
(4) finish_xact_command() @postgres.c     /* Invoke commit action.*/   
      XLogInsert() @xlog.c  (9.5 or later, xloginsert.c)
                                          /* Write a XLOG record of this commit action 
                                           * to the WAL buffer.
                                           */
(5)   XLogWrite() @xlog.c                 /* Write and flush all XLOG records on 
                                           * the WAL buffer to WAL segment.
                                           */
(6) TransactionIdCommitTree() @transam.c  /* Change the state of this transaction 
                                           * from "IN_PROGRESS" to "COMMITTED" on the CLOG.
                                           */
  • 上述伪代码的说明:

  • (1)函数ExtendClog()在(内存)堵塞中写入此事务的状态'in_progress'。

  • (2)函数HEAP_INSERT()在共享缓冲池的目标页中插入一个堆元组,创建此页面的XLOG记录,并调用函数xloginsert()。

  • (3)函数xloginsert()写下由
    创建的XLOG记录 HAPE_INSERT()到LSN_1处的WAL Buffer,然后将修改后的PD_LSN从LSN_0更新为LSN_1。

  • (4)函数finer_xact_command()调用要进行此交易,创建此Commit Action的XLOG记录,然后函数Xloginsert()将此记录写入LSN_2的WAL Buffer。

  • (5)函数xlogwrite()将WAL BUFFER上的所有XLOG记录写入WAL段文件。如果参数wal_sync_method设置为'open_sync'或'Open_dataSync',则记录是同步编写的,因为该函数使用open()系统调用指定了所有记录,指定了所有记录。如果将参数设置为“ fsync”,“ fsync_writeThrough”或“ fdataSync”,则将执行相应的系统调用。无论如何,所有XLOG记录均确保写入存储中。

  • (6)函数TransActionIdCommitTree()将此交易的状态从“ in_progress”更改为堵塞上的“犯罪”。

xlog记录的写入序列 postgresql中的写入如下:

Image description

* XLOG记录的写入 - 序列(续) *在PostgreSQL中显示:

Image description


我希望,这个博客帮助您理解了postresql中的前进伐木(WAL)的内侧概念。

查看Chapter : 9 Part-4

的摘要

如果您想了解PostgreSQL In-Depth