WAL日志扮演着一个什么样的角色?

61 阅读4分钟

WAL日志扮演着一个什么样的角色?

Whoami:5年+金融、政府、医疗领域工作经验的DBA
Certificate:OCP、PCP
Skill:Oracle、Mysql、PostgreSQL
Platform:CSDN、墨天伦、公众号(呆呆的私房菜)

阅读本文可以了解到wal日志概念、写日志机制、日志存储方式及作用等内容。

01 wal日志概述

wal日志全称是write ahead log,类似于oracle数据库的在线重做日志。它是一种保证数据完整性的标准方法。

数据文件的改变必须先写入日志,即日志记录刷新到永久存储之后,才能写到磁盘。通过这种方式就可以避免每个事务提交时都刷新数据页到磁盘上,提高了性能。

数据库宕机的时候可以用wal日志做数据库恢复。任何还没有应用到数据页上的改动都可以根据wal日志记录进行重做。

02 wal日志机制

  1. 数据修改:当数据库接收到一个DML操作时,首先在data buffer进行数据的变更;
  2. 生成wal记录:数据库将变更的数据生成对应的wal日志记录;
  3. 写入到wal buffer:生成的wal记录被写入到wal buffer中;
  4. 刷新wal buffer到磁盘:根据配置的刷新策略,wal buffer中的内容会被刷新到磁盘上的wal日志中;
  5. 事务提交:一旦wal日志记录被刷新到磁盘,事务就可以提交了。此时即使系统发生崩溃,变更的事务也不会丢失;
  6. 数据文件变更:在wal日志记录已经安全写入磁盘后,数据库可以继续将data buffer中变更的数据异步刷新到磁盘上的数据文件。(这一步不是wal机制的一部分,但是它是保证数据一致性的必要步骤)
  7. checkpoint:数据库周期性执行checkpoint操作,将内存中的data buffer刷新到磁盘上的数据文件,以清理不再需要的wal日志记录。

03 wal日志存储

wal日志存储在$PGDATA/pg_wal内。

每个xlog文件,大小为4G(16*256),由256个segment组成;
segment由2048个block组成,大小为16M;
block为wal日志的最小单位,大小为8k。


第一个页面包含了由XlogLongPageHeaderData定义的头部数据,其他的页面包含了由XlogPageHeaderData定义的头部数据。
每个页面头部数据后边紧接着就是以降序写入的xlog记录。

04 wal日志归档条件

  1. 手动强制归档
# PostgreSQL 9.6及之前
select pg_switch_xlog();

# PostgreSQL 9.6之后
select pg_switch_wal();

2. wal日志写满后会自动归档
wal日志文件默认为16MB;
这个值可以在编译Postgresql时通过参数“--with-wal-segsize"更改,编译后不能修改。 3. 参数archive_timeout
在postgresql.conf 文件中的参数archive_timeout;
如果设置archive_timeout=60s,意思是wal日志60s切换一次,同时会触发日志归档。

05 wal日志优势

  1. 当宕机发生时,data buffer的内容还没有全部写入到永久存储中,数据丢失,但是wal buffer的内容已写入磁盘,根据WAL日志的内容,可以恢复库丢失的内容;
  2. 在提交时,仅把wal刷新到了磁盘,而不是data刷新:
    从IO次数来说,wal刷新是少量IO,data 刷新是大量IO,wal刷新次数少得多;
    从IO花销来说,wal刷新是连续IO,data 刷新是随机IO,wal刷新花销小得多;
    wal机制在保证事务持久性和数据完整性的同时,成功地提升了系统性能。

06 wal日志应用场景

  1. 基于时间点恢复:通过使用归档的wal日志文件,可以重放到指定的时间点,从而恢复数据库到那个时刻的状态。这对于恢复由于误删除或其他原因导致的数据丢失非常有用。
  2. 主从流复制:在主从复制架构中,wal日志用于同步主数据库(Primary)上的更改到一个或多个从数据库(Standby)。主数据库上的每个事务更改首先记录在wal日志中,然后这些日志被发送到从数据库,从数据库根据这些日志应用更改,从而保持数据的一致性。
  3. 逻辑复制:允许将更改以逻辑形式(即可以跨数据库和表的方式)复制到另一个数据库。wal日志在此过程中用于捕捉和记录更改,然后这些更改可以被订阅者(Subscriber)以逻辑形式接收和应用。
  4. 误操作删除:wal日志对于恢复因误操作(如意外删除或更新)导致的数据丢失至关重要。如果操作后立即识别出错误,可以在事务日志中找到对应的操作,然后使用wal日志进行恢复操作,从而撤销误操作的影响。