postgresql , 10.0 , wal , wal_consistency_checking
10.0 新增了一个debug参数,用于检测recovery过程中,由于wal replay bug或者备库的物理数据块异常导致的wal replay回放出来的块不正确的问题。
当产生脏页时,在wal记录中,可能有两种信息:
1. 只记录了数据变更的部分。
2. full page,记录了整个数据块。(发生时机:当开启了full page write参数,checkpoint后第一次变更的块)
在postgresql进入恢复过程(或者standby)时,postgresql startup进程会从wal日志中读取wal record与数据文件的块进行回放组合,生成变更后的块。如果wal是full page,则直接使用full page。回放后的块覆盖老的数据块,实现恢复的目的。
但是有可能因为各种原因,导致回放后的数据块是不对的,比如前面提到的原因:(由于wal replay bug或者备库的物理数据块异常导致的wal replay回放出来的块不正确)。
postgresql 10.0新增的wal_consistency_checking参数,可以用于发现这种问题。
为什么postgresql 10.0要加这个参数呢?
因为postgresql的扩展功能极强,已经支持了wal generic record,也就是说,用户可以自定义往wal中写数据,开放这样的功能,有利于开发者调试自己扩展的wal generic writer的正确性。
wal_consistency_checking 参数可以设置为如下值:
参数内容表示当主库产生wal对应的resource manger record时,自动将当时脏页的full page写入wal中。在startup进程回放日志时,会比较 "这个full page" 与 "wal partial record+data page replay出来的page" 是否一致,如果不一致,说明wal回放有问题。startup 进程将会fatal,停止恢复。
对于正常的差异(例如hint bit)是不会报错的。
<a href="https://github.com/digoal/blog/blob/master/201509/20150905_01.md">《为什么postgresql查询语句也可能产生 xlog, 并且可能对buffer有write操作 ? hint bits》</a>
这个patch的讨论,详见邮件组,本文末尾url。
postgresql社区的作风非常严谨,一个patch可能在邮件组中讨论几个月甚至几年,根据大家的意见反复的修正,patch合并到master已经非常成熟,所以postgresql的稳定性也是远近闻名的。
<a href="https://git.postgresql.org/gitweb/?p=postgresql.git;a=commitdiff;h=a507b86900f695aacc8d52b7d2cfcb65f58862a2">https://git.postgresql.org/gitweb/?p=postgresql.git;a=commitdiff;h=a507b86900f695aacc8d52b7d2cfcb65f58862a2</a>
<a href="https://www.postgresql.org/docs/devel/static/runtime-config-developer.html">https://www.postgresql.org/docs/devel/static/runtime-config-developer.html</a>