xlogさまざま

Mikage Yuziki 发布于 15 天前 37 次阅读


1 xlog

1.1 简介

在PG中,任何修改数据库的操作都会记录一份日志,这个日志就叫做xlog。在9.2.4版本中,xlog日志的目录是PGDATA/pg_xlog,在更高的版本里,该目录变成了$PGDATA/pg_wal

WAL(Write-Ahead Logging,预写日志)是一种用于确保数据库数据一致性和恢复能力的技术。XLOG 文件就是 WAL 的物理存储形式,它记录了所有修改数据库内容的操作,包括数据的插入、更新、删除以及元数据的变更等

wal_level参数影响wal日志的详细程度:

minimal:最低的日志级别,仅记录足以保证崩溃恢复的信息。

Replica:提供足够日志信息支持热备和流复制,记录所有事务的变更,包括索引变更和行版本信息

Logical:提供最详细的日志记录,包括所有逻辑变更

1.2 Xlog的大小

Wal由多个segment组成,而一个segment又是由多个page组成的,其大小定义在src/include/pg_config.h 中

默认大小:XLOG_BLCKSZ   8K:一次写入8K

XLOG_SEG_SIZE 16M:一个seg写满为16MB

只允许在编译的时候修改。

wal segment的大小由参数wal_block_size控制,编译之后无法修改

1.3 Xlog的初始化

对应于xlog,其初始化的入口函数是BootStrapXLOG,该函数只会在初始化的时候调用一次,主要用于创建pg_control文件和初始化第一个xlog segment。

Xlog的命名规则:

在PG10之前的版本中,由3个参数组成共24位的十六进制字符串,每个参数占8位。

三个参数分别为:tli、log、seg

-rw------- 1 postgres postgres 16777216 Jul 22 18:27 00000001000000000000003B

对应这个文件

Tli(完整名称是timeline:表示数据库的状态,在数据恢复后会发生变化):00000001

Log file ID:00000000

Segment:0000003B

而在PG10之后,Log file ID和segment合并为一个参数(Log_segment_number)

1.4 Xlog文件的作用

  • 数据恢复

在系统崩溃或发生故障后,XLOG 文件可以用来恢复数据库到一致的状态。PostgreSQL 通过重放(replay)XLOG 中的记录来重建事务,确保数据的完整性。

  • 复制

在流复制(streaming replication)中,XLOG 文件的内容会被发送到从服务器(standby server),以便从服务器可以同步主服务器(master server)的状态。

  • 归档

XLOG 文件可以被归档(archiving),这样即使在磁盘空间有限的情况下,也可以保留一定时间的历史日志记录。

1.5 什么时候会产生新的xlog segment

  • 当前的WAL段文件已满

当前的wal segment文件写满时,Postgresql会创建新的segment文件,默认大小是16MB

  • 检查点

检查点期间,会强制将内存中的数据写入磁盘,并生成新的segment文件。

检查点的触发条件包括:

时间间隔:默认情况下,检查点每5min触发一次(checkpoint_timeout)

WAL文件大小:当wal文件的大小达到一定阈值时,也会触发检查点

手动触发:checkpoint命令

置换脏页(隐性条件):内存中置换脏页也会触发检查点

  • Wal日志切换

select pg_switch_wal();

1.6 什么样的wal segment会被清理

1.在开启归档archive_mode=on的情况下:归档成功(.done)的wal segment会被删除。

2.在有复制槽的情况下,当所有复制槽的restart_lsn已经超过了当前wal_segment的lsn,那么该wal会被删除。

3.检查点触发,确定该segment不被任何事务或恢复操作需要

4.流复制:与参数synchronous_commit有关

  • off:事务提交不需要等待任何确认,即不等待WAL记录被写入磁盘或备库。
  • local:事务提交需要等待WAL记录被写入本地磁盘。
  • remote_write:事务提交需要等待WAL记录被写入至少一个备库的磁盘。
  • remote_apply:事务提交需要等待WAL记录被至少一个备库接收并应用。
  • on:等同于 remote_write,事务提交需要等待WAL记录被至少一个备库写入磁盘。

1.7 wal segment的自动清理的时机

检查点会触发WAL段文件的清理

1.8 wal segment的保留受什么参数影响

wal日志的保留受多个参数影响:

  1. archive_mode:控制是否开启WAL归档。当设置为on或always时,会触发archive_command进行WAL文件的归档操作。
  2. archive_command:指定将WAL复制到外部介质的Shell命令。如果命令返回非0,PostgreSQL会无限重试,导致WAL堆积。
  3. archive_timeout:当某个segment最后一次写入距今超过该秒数时强制切换WAL,防止低负载下WAL长时间不归档,但会增加文件数量。
  4. max_wal_size:WAL目录软上限。当WAL累积超过该值时,强制触发checkpoint,期望通过回收/删除降低大小。
  5. min_wal_size:WAL目录软下限。一次checkpoint结束后,PostgreSQL会尝试将WAL大小收缩到不低于该值。
  6. wal_keep_segments:即使归档/复制均已完成,也必须在pg_wal中保留最近N个segment。
  7. max_slot_wal_keep_size:在PostgreSQL 13及以上版本中,用于控制复制槽保留的最大日志量。
  8. wal_keep_size:在PostgreSQL 13及以上版本中,以MB定义的替代wal_keep_segments,同样属于硬约束窗口。
  9. checkpoint_timeout:两次checkpoint最长间隔。间隔越长,WAL越多;但过短会导致I/O抖动。
  10. checkpoint_completion_target:checkpoint持续时间占间隔比例。较大值可平滑I/O,降低WAL峰值。

2 归档xlog

2.1为什么要归档

将wal日志移动到一个安全的位置。

通过合理配置和管理wal归档,可以显著提高数据库的可靠性和安全性。

pg_wal/archive_status/下的文件表示对应wal的归档状态:

.done:表示已经归档

.ready:表示可以进行归档,归档完成后,.ready会变为.done

这些文件都没有内容,只是个空文件

2.2什么时候触发归档

产生新的wal segment

达到archive_timeout参数设置的超时时间

检查点触发:会将内存中的数据写入磁盘,可能因此产生新的wal segment

2.3归档日志的清理

归档目录的xlog文件的自动清理主要依赖于参数archive_cleanup_command的配置,在每次wal segment成功归档后自动执行,清理不再需要的旧日志文件。

具体哪些文件会被清理,要看archive_cleanup_command的具体配置。

若未配置以上参数,则需要在操作系统层面设置定时任务来清理。

若两者都未配置,则归档目录下的xlog会不断堆积。

3 Xlog内容解析

从xlog文件中可以获取如下信息:

  1. 操作对象:索引还是表
  2. 记录长度
  3. 事务编号
  4. Lsn
  5. 操作类型:增、删、改
  6. 实际操作对象

举例:

下面是使用pg_waldump解析一个xlog文件后得到的结果

pg_waldump 000000xxxxxxx

下面是对每一行输出的解释:

rmgr:B-tree表示这个记录是由B-Tree索引管理器生成的
rmgr: Heap表示这条记录是由Heap表管理器生成的。 Heap表示操作对象是表、而B-Tree表示操作对象是索引。
len (rec/tot): 64/64表示这个记录的长度是64字节,总共也是64字节
tx:表示事务编号
lsn表示这条记录的日志序列号
prev表示这条记录的前一条记录的LSN
desc描述了这个记录的操作类型。 INSERT_LEAF off 324表示在B-Tree的叶子节点上执行了一个INSERT操作,偏移量是324
blkref表示这个操作涉及到的关系或者索引的oid,以及对应的块号

有了以上的信息,主要是有了desc和oid,我们就能够具体到数据库的某一张表上的具体操作。

4 流复制和复制槽

4.1 流复制

流复制是一种机制,主库将wal实时发送到从库,实时同步

从库通过pg_basebackup或其他工具从主库获取初始备份,通过postgresql.conf连接到主库,实时接收WAL并应用

4.2 复制槽

主备通过复制槽接收和推送wal日志,有一定延迟