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日志机制
- 数据修改:当数据库接收到一个DML操作时,首先在data buffer进行数据的变更;
- 生成wal记录:数据库将变更的数据生成对应的wal日志记录;
- 写入到wal buffer:生成的wal记录被写入到wal buffer中;
- 刷新wal buffer到磁盘:根据配置的刷新策略,wal buffer中的内容会被刷新到磁盘上的wal日志中;
- 事务提交:一旦wal日志记录被刷新到磁盘,事务就可以提交了。此时即使系统发生崩溃,变更的事务也不会丢失;
- 数据文件变更:在wal日志记录已经安全写入磁盘后,数据库可以继续将data buffer中变更的数据异步刷新到磁盘上的数据文件。(这一步不是wal机制的一部分,但是它是保证数据一致性的必要步骤)
- 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日志归档条件
- 手动强制归档
# 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日志优势
- 当宕机发生时,data buffer的内容还没有全部写入到永久存储中,数据丢失,但是wal buffer的内容已写入磁盘,根据WAL日志的内容,可以恢复库丢失的内容;
- 在提交时,仅把wal刷新到了磁盘,而不是data刷新:
从IO次数来说,wal刷新是少量IO,data 刷新是大量IO,wal刷新次数少得多;
从IO花销来说,wal刷新是连续IO,data 刷新是随机IO,wal刷新花销小得多;
wal机制在保证事务持久性和数据完整性的同时,成功地提升了系统性能。
06 wal日志应用场景
- 基于时间点恢复:通过使用归档的wal日志文件,可以重放到指定的时间点,从而恢复数据库到那个时刻的状态。这对于恢复由于误删除或其他原因导致的数据丢失非常有用。
- 主从流复制:在主从复制架构中,wal日志用于同步主数据库(Primary)上的更改到一个或多个从数据库(Standby)。主数据库上的每个事务更改首先记录在wal日志中,然后这些日志被发送到从数据库,从数据库根据这些日志应用更改,从而保持数据的一致性。
- 逻辑复制:允许将更改以逻辑形式(即可以跨数据库和表的方式)复制到另一个数据库。wal日志在此过程中用于捕捉和记录更改,然后这些更改可以被订阅者(Subscriber)以逻辑形式接收和应用。
- 误操作删除:wal日志对于恢复因误操作(如意外删除或更新)导致的数据丢失至关重要。如果操作后立即识别出错误,可以在事务日志中找到对应的操作,然后使用wal日志进行恢复操作,从而撤销误操作的影响。