PG默认每个page的大小为8K,PG数据页写入是以page为单位,但是在断电等情况下,操作系统往往不能保证单个page原子地写入磁盘,这样就极有可能导致部分数据块只写到4K(操作系统是一般以4K为单位),这些“部分写”的页面包含新旧数据的混合。在崩溃后的恢复期间,xlog 里面存储的记录变化信息不够完整,无法完全恢复该页。PG为了解决这类问题,full_page_write机制孕育而生。

什么是full_page_write?

PostgreSQL 在 checkpoint 之后在对数据页面的第一次写的时候会将整个数据页面写到 xlog 里面。当出现主机断电或者OS崩溃时,redo操作时通过checksum发现“部分写”的数据页,并将xlog中保存的这个完整数据页覆盖当前损坏的数据页,然后再继续redo就可以恢复整个数据库了。
除了能够解决断电等带来坏数据页问题外,full_page_write 还应用在在线备份功能上。PG进行全量备份数据库一般通过pg_basebackup工具实现,pg_basebackup类似于copy操作,在此期间,也会出现部分数据页写到一半时文件被copy走了,正是因为full_page_write存在,备份出来的数据库才可以成功恢复启动。所以即便full_page_write=off,在备份时也会被强制自动打开,保证备份成功。

实现原理

full_page_write主要在XLogInsert(插入一条xlog记录)时发挥作用,通过full_page_writer开关状态以及是否是checkpoint后对数据页面的第一次修改(lsn<RedoRecPtr)判断是否需要备份数据页。如果需要备份,那么则把数据页存放在这条记录的末尾,最终写入到xlog中。

doPageWrites = Insert->fullPageWrites || Insert->forcePageWrites;
/* Find info for buffer */
for (i = 0; i < XLR_MAX_BKP_BLOCKS; i++)
{if (dtbuf[i] == InvalidBuffer){/* OK, put it in this slot */dtbuf[i] = rdt->buffer;if (doPageWrites && XLogCheckBuffer(rdt, true,&(dtbuf_lsn[i]), &(dtbuf_xlg[i]))){dtbuf_bkp[i] = true;rdt->data = NULL;rdt->len = 0;}break;}......
}

在redo恢复的时候只要数据块有备份,那么就是用备份的数据。

/* If we have a full-page image, restore it and we're done */
if (record->xl_info & XLR_BKP_BLOCK(0))
{(void) RestoreBackupBlock(lsn, record, 0, false, false);return;
}

full_page_write不足之处

因为full_page_write需要在xlog中记录数据页,会写更多xlog文件,不仅有数据变化信息,还有数据页本身信息,这样会增加额外的IO和磁盘消耗,同时也会引起主备延迟变大。
为了优化full_page_write,社区提供了一个patch,它的主要设计是创建两个共享内存块队列,checkpoint专用buffer队列和非checkpoint专用buffer队列,同时关闭full_page_write。当用户DML产生的数据buffer需要刷盘时,并不是立即刷到磁盘,而是先进入double write的buffer队列,当buffer队列满时,则将buffer队列里面的数据首先刷到特别的double write文件,然后再将数据刷到数据库文件。通过这种设计就不需要在checkpoint 之后在对数据页面的第一次写的时候会将整个数据页面写到 xlog 里面。当数据库需要恢复的时候,遍历所有double write文件里面的记录块,找到每个记录块对应的数据库page,然后对这个page进行checksum,如果page损坏,那么直接把记录块里面的内容覆盖到buffer数据。最后把double write文件删除,重新初始化buffer队列。

总结

把full_page_write这个选项关闭会提高数据库执行速度以及减少xlog数量,但是可能导致系统崩溃或者掉电之后的数据库损坏。如果有减小部分页面写入风险的硬件支持(比如电池供电的磁盘控制器),或者文件系统支持(能够保证page写入原子性),可以把风险降低到一个可以接受的范围,那么可以考虑关闭这个选项,其他情况下建议打开这个选择。

PgSQL · 特性分析 · full page write 机制相关推荐

  1. pgsql执行分析explain结果分析

    EXPLAIN 的输出结构 阅读到这里,我们已经知道了如何使用EXPLAIN 命令.接下来,我们将学习如何理解EXPLAIN 的输出,从而快速地定位问题. 以下面的输出为例(该例子选自PostgreS ...

  2. Linux SVA特性分析

    Linux SVA特性分析 -v0.1 2019.9.15 Sherlock init -v0.2 2019.9.18 Sherlock update数据结构和动态分析 -v0.3 2019.10.1 ...

  3. 蓝牙协议分析(11)_BLE安全机制之Security Manager

    1. 前言 书接上文,我们在"蓝牙协议分析(10)_BLE安全机制之LE Encryption"中介绍了BLE安全机制中的终极武器----数据加密.不过使用这把武器有个前提,那就是 ...

  4. STM32L051 低功耗特性分析

    STM32L051 低功耗特性分析 32MHz 2.7mW功耗 low power sleep mode大概只有4.5uA stop mode大概 0.4uA stop mode能比low power ...

  5. 通过源码分析Android 的消息处理机制

    2019独角兽企业重金招聘Python工程师标准>>> #通过源码分析Android 的消息处理机制 我们知道,Android应用是通过消息来驱动的,每一个进程被fork之后,都会在 ...

  6. 【Android 事件分发】事件分发源码分析 ( ViewGroup 事件传递机制 七 )

    Android 事件分发 系列文章目录 [Android 事件分发]事件分发源码分析 ( 驱动层通过中断传递事件 | WindowManagerService 向 View 层传递事件 ) [Andr ...

  7. 【Android 事件分发】事件分发源码分析 ( ViewGroup 事件传递机制 六 )

    Android 事件分发 系列文章目录 [Android 事件分发]事件分发源码分析 ( 驱动层通过中断传递事件 | WindowManagerService 向 View 层传递事件 ) [Andr ...

  8. 【Android 事件分发】事件分发源码分析 ( ViewGroup 事件传递机制 五 )

    Android 事件分发 系列文章目录 [Android 事件分发]事件分发源码分析 ( 驱动层通过中断传递事件 | WindowManagerService 向 View 层传递事件 ) [Andr ...

  9. 【Android 事件分发】事件分发源码分析 ( ViewGroup 事件传递机制 四 | View 事件传递机制 )

    Android 事件分发 系列文章目录 [Android 事件分发]事件分发源码分析 ( 驱动层通过中断传递事件 | WindowManagerService 向 View 层传递事件 ) [Andr ...

最新文章

  1. Linux Kernel TCP/IP Stack — L1 Layer — Physical NIC
  2. MyBatis-动态SQL
  3. linux基础—课堂随笔_03 SHELL脚本编程基础
  4. vector的求和用法accumulate
  5. 【英语学习】【Level 07】U01 Making friends L2 A new friend from the past
  6. TOJ 2353: Billiard
  7. 【转】性能测试设计和LR原理的探讨
  8. 使用jquery检查/取消选中复选框? [重复]
  9. 小白学数据分析-----留存率的三个普适原则
  10. Cisco 静态nat配置
  11. 你要“老婆”不?谷歌程序员20行代码送你一个!
  12. karma看fits文件软件操作汇总【第三个维度的变化】【查看某个范围的RMS值】
  13. 炭足迹计算机的火车好处,碳足迹与碳足迹计算器.pdf
  14. 安装QT5.14.2(wins10, vs2015社区版,已安装minGW-w64)
  15. 熵值法、灰色关联分析与层次分析法
  16. InnoDB引擎--事务持久性
  17. MybatisPlus字段名为mysql保留关键字处理
  18. 如何减少手机辐射?——七招减少手机对您的危害
  19. 凯撒密码-CTF(Crypto)
  20. 智能生产调度系统代码

热门文章

  1. PLSQL developer 连接不上64位Oracle 解决办法
  2. Openoffice 安装与配置
  3. POJO、VO、PO、FormBean区别:
  4. PL/SQL三种集合类型的比较
  5. swift 错误集合 ------持续更新中
  6. STM32中EXTI和NVIC的关系
  7. Kruskal算法 - C语言详解
  8. 【转载】云计算的三种服务模式:IaaS,PaaS和SaaS
  9. html input不可编辑
  10. 曲苑杂坛--收缩数据库文件