数据库 Xlog 知识整理与代码走读

数据库 Xlog 知识整理与代码走读本文详细介绍了 XLOG Write AheadLogging 在 PostgreSQL 中的作用 包括其作为数据库更改持久化记录的核心机制 文件管理结构 如固定大小段和循环使用 以及关键数据结构

大家好,欢迎来到IT知识分享网。

XLOG

一些概念

基本概念

XLOG(也称为WAL日志)是预写日志(Write-Ahead Logging)的一部分。XLOG是一种持久化的、顺序记录的日志,用于记录数据库系统中对数据进行的更改。

具体来说,XLOG用于确保数据库的持久性和一致性。其工作原理如下:

  1. 当对数据库中的数据进行修改时,首先将数据变更写入XLOG中。
  2. 接着,将数据变更写入实际的数据文件。
  3. 事务提交时,不要求发生变化的数据页面罗盘,但必须要求本事务的xlog落盘。

在数据库崩溃或服务器故障时,可以使用XLOG中的信息来恢复数据,确保数据库完整性。因此,XLOG是数据库事务持久性的关键组成部分,它确保了即使在出现意外情况时,数据库也能够在重新启动后恢复到一个一致的状态。

总而言之,XLOG(WAL日志)是PostgreSQL中用于持久化记录数据更改的机制,它是数据库性能、一致性和可靠性的重要保障。

文件管理结构

XLOG日志一条一条的顺序写入XLOG文件。文件是以固定大小的段(segment)的方式组织的。每个 XLOG 段的大小是固定的,通常是 16MB。XLOG 文件是循环使用的,一旦填满一个段,它将被标记为已用,并且新的 XLOG 记录将写入下一个可用的 XLOG 段中。

XLOG 段的组织方式通常是这样的:

  1. XLOG 文件名格式:XLOG 文件的命名格式通常是 XLOG+数字+段位置,例如,XLOG 文件名可能是 XLOG0000000D,其中 0000000D 是 XLOG 段的位置。
  2. XLOG 文件目录结构:XLOG 文件通常存储在数据库的数据目录下的 pg_xlog 子目录中。每个数据库都有自己的 pg_xlog 目录。
  3. XLOG 段的循环使用:一旦一个 XLOG 段被写满,新的 XLOG 记录将被写入下一个可用的 XLOG 段中。当所有 XLOG 段都被写满后,旧的 XLOG 段会被标记为可重用。
  4. 检查点:定期进行检查点操作来确保部分 XLOG 段中的数据已经写入数据文件中,这样可以释放已经写入数据文件中的 XLOG 段。检查点操作也有助于限制重做日志(WAL)的增长速度。

总的来说,XLOG 文件以固定大小的段的形式组织,通过循环使用这些段,确保了持久化记录数据库更改的机制。这个机制保证了即使在数据库崩溃或服务器故障情况下,都能够进行数据恢复和一致性保障。

16M文件1: XLog1 XLog2 XLog3 ... 16M文件2: XLog888 XLog889 XLog890 ... 

LSN(Log Sequence Number)

日志序列号,是一种用于标识事务日志中位置的特殊序号,主要用于在数据库恢复过程中跟踪和管理 xlog 日志文件的位置。

因为XLOG是一条条顺序写入文件的,那么每条xlog的起始位置,也就是在所有xlog文件中的偏移量,就是这条xlog的LSN,所以不难看出 LSN 是一个递增的数字。

对于xlog来说,lsn是它的位置,也是唯一标识;对于页面来说,LSN相当于页面的版本号。

XLOG结构

 {XLogRecord} + {XLogRecordBlockHeader}*N + {(Short/Long)XLogRecordDataHeader} + {Block data}*N + {main data} 

共5部分,其中第二或四部分不涉及的话可能没有。

数据结构与接口

关键数据结构

struct XLogRecord: 一条XLog

{ uint32 xl_tot_len; xlog的总长度 xl_term; TransactionId xl_xid; 事务号 XLogRecPtr xl_prev; 前边那条xlog的lsn RmgrId xl_rmid; xlog的类型 ... xl_crc; CRC校验码 } 这只是个xlog的头部,在这个后面物理空间上会紧跟这剩余的xlog内容 

struct XLogRecData: 一条Xlog中的某种数据的容器。

struct XLogRecData { struct XLogRecData* next; char* data; uint32 len; Buffer buffer; } 

是一个通用的容器,可以存放很多东西。例如xlog本身的一些元信息、具体的某段数据(如insert的某行元组)等。

struct registered_buffer: xlog所操作的页面的注册信息

一条xlog里面相关的页面操作,这个结构用于存放页面的相关元信息,如页面位置、lastlsn。

其中还有一个链表,rdata,存放这个页面上的操作的具体数据,如insert的元组等。一个xlog上可能会有多个操作,例如update,可能会delete+insert元组在同一个页面等。

knl_t_xlog_context: xlog上下文,有很多xlog的相关数据结构。

 // 一个数组,构造xlog的时候使用,用于存放xlog所操作的页面的很多元信息。 registered_buffer* registered_buffers; int max_registered_buffers; int max_registered_block_id; // 一个单链表,构造xlog的时候使用,用于存放xlog内的数据内容。 XLogRecData* mainrdata_header; XLogRecData* mainrdata_last; uint32 mainrdata_len; // 一个数组,用于存放registered_buffers的页面数据。物理上是一个数组,逻辑上是好多链表,不同的链表归不同的registered_buffers。 XLogRecData* rdatas; int max_rdatas; int num_rdatas; 

关键接口

XlogBeginInsert():

做Xlog插入的准备工作,主要是检查状态、初始化一些变量等。

XlogRegisterData(char *data, int len)

创建一个XLogRecData,注册到链表manrdata之中。

XlogRegisterBuffer(uint8 block_id, Buffer buffer, uint8 flags, TdeInfo* tdeinfo):

根据buffer构造struct registered_buffer,注册到registered_buffers数组。

其中block_id是registered_buffers数组的下标。

这里的数据,主要是页面的元信息,例如lsn等。

XlogRegisterBufData(uint8 block_id, Buffer buffer, uint8 flags, TdeInfo* tdeinfo):

根据buffer构造struct registered_buffer,注册到rdatas数组。

这里的数据指的就是具体的元组了。

XLogInsert():

根据前面接口注册的各种信息,构造出一条xlog,写入xlog缓冲区,返回lsn。

代码流程

 检查些有的没的 GetFullPageWriteInfo() # 将之前注册的所有信息(链表manrdata、registered_buffers数组等),整理成一个链表 XlogRecData* rdt = XLogRecordAssemble() # 插入xlog到缓冲区,并获取LSN EndPos = XLogInsertRecord(); # 返回LSN return EndPos; 

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/125410.html

(0)
上一篇 2025-09-27 16:45
下一篇 2025-09-27 17:10

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信