postgreSQL WAL简介

PostgreSQL通过预写式日志(wal日志)来保证数据不丢失

没有WAL机制的场景

没有 WAL 的数据库容易受到系统故障的影响,如下图,如果操作系统或 PostgreSQL 服务器发生故障,则所有插入的数据都可能丢失
在这里插入图片描述
(1) 发出第一条 INSERT 语句,PostgreSQL 将 TABLE_A 的页面从数据库集群加载到内存共享缓冲池中,并在页面中插入一个元组。此页面不会立即写入数据库。

(2) 发出第二条 INSERT 语句,PostgreSQL 在缓冲池上的页中插入一个新的元组。此页尚未写入存储。

(3) 如果操作系统或PostgreSQL服务器因停电等任何原因出现故障,所有插入的数据都将丢失。

引入WAL机制后

XLOG 将更改操作(例如插入、删除或提交操作)写入内存中的WAL 缓冲区。当事务提交/中止时,它们会立即写入存储上的WAL 段文件

XLOG 记录的LSN(日志序列号)表示其记录在事务日志上的写入位置。记录的 LSN 用作 XLOG 记录的唯一 ID。

在崩溃发生后重新启动数据库,PG会从redo point开始恢复
下图为使用 WAL 进行插入操作
在这里插入图片描述
(1) checkpointe是一个后台进程,周期性地执行checkpoint。每当检查点启动时,它都会将一个名为检查点记录的 XLOG 记录写入当前 WAL 段。此记录包含最新REDO 点的位置。

(2) 发出第一条INSERT语句,PostgreSQL将TABLE_A的页面加载到共享缓冲池中,在页面中插入元组,在位置LSN_1处创建并写入该语句的XLOG记录到WAL缓冲区中,并更新TABLE_A的LSN从LSN_0到LSN_1。
(3) 当这个事务提交时,PostgreSQL 会创建这个提交操作的 XLOG 记录并将其写入 WAL 缓冲区,然后,将 WAL 缓冲区上的所有 XLOG 记录写入并刷新到 WAL 段文件,更新LSN_0为LSN_1。

(4) 发出第二条 INSERT 语句,PostgreSQL 在页面中插入一个新的元组,创建并写入这个元组的 XLOG 记录到LSN_2处的 WAL 缓冲区,并将 TABLE_A 的 LSN 从LSN_1更新为LSN_2。

(5) 当这条语句的事务提交时,PostgreSQL 的操作方式与步骤 (3) 中相同。

(6) 此时即使共享缓冲池上的所有数据都丢失了,页面的所有修改也已作为历史数据写入 WAL 段文件。

下图为使用 WAL 进行数据库恢复
在这里插入图片描述
(1) PostgreSQL 从相应的 WAL 段文件中读取第一个 INSERT 语句的 XLOG 记录,将 TABLE_A 的页面加载到共享缓冲池中。

(2) 在尝试重放XLOG 记录之前,PostgreSQL 会比较XLOG 记录的LSN 与对应页面的LSN

  1. 如果 XLOG 记录的 LSN 大于页面的 LSN,则将 XLOG 记录的数据部分插入到页面中,并将页面的 LSN 更新为 XLOG
    记录的 LSN
  2. 如果 XLOG 记录的 LSN 较小,则只能读取下一个 WAL 数据

在此示例中,由于XLOG记录的 LSN ( LSN_1 ) 大于 TABLE_A 的 LSN ( LSN_0 ),因此重放 XLOG 记录;

(3) PostgreSQL 以同样的方式重放剩余的 XLOG 记录。

整页写入

上面的恢复是基于从存储中拿到的页面是未被破坏的场景,WAL机制当前无法在损坏的页面上重放 XLOG 记录

为了支持这一能力,PG引入了整页写入(full-page writes )的功能来处理此类故障。如果启用,PostgreSQL在每个检查点后每个页面的第一次更改期间写入一对 header-data 和整个页面作为 XLOG 记录;
在这里插入图片描述
(1) checkpointer启动一个checkpoint进程。
(2) 在第一条INSERT语句的插入中,虽然PostgreSQL的操作方式与上一小节几乎相同,但这条XLOG记录是该页的备份块(即它包含了整个页),因为这是在最新的检查点之后首次写入此页面。
(3) 当这个事务提交时,PostgreSQL 以与上一小节相同的方式运行。
(4) 在第二条INSERT语句的插入中,由于这条XLOG记录不是备份块,PostgreSQL的操作方式与上一小节相同。
(5) 当这条语句的事务提交时,PostgreSQL 以与上一小节相同的方式运行。
(6) 为了证明整页写入的有效性,这里我们考虑在后台写入器一直在将其写入硬盘时,由于操作系统发生故障,存储上的TABLE_A页面已损坏的情况。

使用备份块进行数据库恢复
在这里插入图片描述
(1) PostgreSQL 读取第一个 INSERT 语句的 XLOG 记录,并将损坏的 TABLE_A 页面从数据库集群加载到共享缓冲池中。在这个例子中,XLOG记录是一个备份块,因为按照整页写的写规则,每页的第一个XLOG记录总是它的备份块。

(2) 当 XLOG 记录是它的备份块时,应用另一个重放规则:

无论两个 LSN 的值如何,记录的数据部分(即页面本身)都将被覆盖到页面上,并且页面的 LSN 更新到 XLOG 记录的 LSN。

在此示例中,PostgreSQL 将记录的数据部分覆盖到损坏的页面,并将 TABLE_A 的 LSN 更新为LSN_1。通过这种方式,损坏的页面由其备份块恢复。

(3) 由于第二条 XLOG 记录是一个非备份块,PostgreSQL 的操作方式与上一小节中的指令相同。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值