此博客旨在帮助您理解章节的内侧概念: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或更早) 在下图中描述了:
:
XLOG记录的数据部分(版本9.5或更高版本)
-
在版本9.4或更早的版本中,Xlog记录的格式没有 common ,因此每个资源经理都必须定义自己的格式。在这种情况下,越来越难以维护源代码并实施与WAL相关的新功能变得越来越困难。
-
为了解决这个问题,一种不依赖资源经理的常见结构化格式已在版本 9.5 中引入。。。 p>
-
XLOG记录的数据部分可以分为两个部分:标题和 data 。
PostgreSQL中的常见Xlog记录格式如下图所示:
-
标题零件 包含零或更多 xlogrocordblockheaders 和零或一个 xlogrecorddataheadershort 。
-
它必须至少包含其中的一个。当其记录存储完整图像(即备份块)时, xlogrocordblockheader 包括 xlogrecordblockimageheader ,并且还包括 xlogrecordblockcompressheader 如果其块被压缩。 /p>
-
数据零件 由零或更多块数据和零或一个主要数据组成,这对应于 xlogrecordblockheader(s) strong>和 xlogrocorddataheader 。
XLOG记录的示例(版本9.5或更高版本)在PostgreSQL中的图表如下图:
:
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中的写入如下:
* XLOG记录的写入 - 序列(续) *在PostgreSQL中显示:
:
我希望,这个博客帮助您理解了postresql中的前进伐木(WAL)的内侧概念。
的摘要如果您想了解PostgreSQL In-Depth。