暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

从PostgreSQL的热备谈起

白鳝的洞穴 2020-06-24
1396
如果我们要对PG做一个热备,那么我们必须先执行 pg_start_backup,然后对整个PG数据库与相关的集群环境做一个SNAPSHOT,然后再执行 pg_stop_backup。看到这些,搞过ORACLE 5/6的DBA可能会回忆起点什么,当年Oracle在没有RMAN或者RMAN功能没那么强的时候,不也是这么做备份的吗。
我们先来看看 pg_start_backup会对PG有哪些影响:
  • 进入FULL PAGE WRITE模式

  • 切换WAL日志段

  • 做一个CHECKPOINT

  • 创建一个backup_lable文件

除了最后一点,是不是和Oracle的BEGIN BACKUP类似?Oracle 的一个数据库或者表空间进入begin backup状态的时候,也有类似的处置:
  • 相关数据文件会马上进行一次CHECKPOINT

  • 首次在处于热备份模式的数据文件中更改块时,整个块(而不仅仅是更改的字节)被写入重做日志文件

  • 当文件处于热备份模式时,包含最后完成的检查点的SCN的数据文件头不会更新。这使恢复过程了解完全恢复此文件可能需要哪些归档重做日志文件

此时我们就可以去拷贝PG的文件了,并把这些文件作为基础备份集了。当拷贝完成后,我们需要执行 pg_stop_backup让PG实例结束热备模式,恢复到正常模式。执行了pg_stop_backup后,数据库实例做如下调整:
  • 重新回到non-full-page writes模式

  • 在WAL中写一个BACKUP END的日志

  • 切换WAL日志段文件

  • 创建一个备份历史文件,这个文件包含backup_label文件的内容和pg_stop_backup执行的时间戳

  • 删除backup_label文件

这些都和Oracle的begin/end backup类似,只是backup_label文件和backup_history文件在oracle中不需要,因为Oracle是把这些存储在control file中的。

很多朋友喜欢把PG的这种Full Page Write当成PG库的double write,实际上不是的,这种机制和使用Double Write Buffer机制的数据库还是不同的。但是都能够达到类似的作用。除了pg_begin_backup可以触发Full Page Write机制外,如果你在PG库上打开full_page_writes开关,就可以在每次Checkpoint后的每个数据块第一次写入XLOG的时候写入整块,从而起到类似于其他数据库Double write Buffer的作用,确保在硬件故障的时候,数据库不会出现坏块。

不过任何好处都是有代价的,Full Page Write的代价似乎比Double Write Buffer更高,所以当我们在一个不支持原子操作的,不安全的基础设施上(比如云平台)去跑PG数据库,而且数据库的WAL日志压力不大的时候,我们可以通过打开full_page_writes来提高系统的可靠性,但是如果我们使用的是一个支持PG原子写操作的基础设施环境的时候,或者WAL日志量已经压力巨大的时候,就要慎重考虑了。实际上在大多数环境中,建一个备库是获得数据安全的最有效和最简单的方法。

由于Full Page Write刚刚开始的时候,会有大量的整页写入WAL,因此会对系统的IO产生一定的影响,WAL日志的量也会变大,因此数据库系统的整体性能还是会受到一定的影响的,所以我们在做类似备份的时候,一定要避开业务高峰,避开晚上跑批批量修改数据的时段,从而让热备工作对系统影响最小化。实际上大家也不用怕Full Page Write,当年Oracle也是这么走过来的,用户也没觉得就不方便了。不过老白在20年前也遇到过用户执行begin backup后,备份脚本没有执行完,end backup没执行,第二天业务高峰期系统就撑不住了。所以热备脚本跑完后,检查数据库是不是还处于Full Page Write状态十分重要。

文章转载自白鳝的洞穴,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论