前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Oracle、MySQL、PG是如何处理数据库“半页写”的问题的?

Oracle、MySQL、PG是如何处理数据库“半页写”的问题的?

作者头像
数据库架构之美
发布2020-11-05 20:27:02
1.6K0
发布2020-11-05 20:27:02
举报
文章被收录于专栏:数据库架构之美

数据库“断页”是个很有意思的话题,目前任何数据库应该都绕不过去。我们知道数据库的块大小一般是8k、16k、32k,而操作系统块大小是4k,那么在数据库刷内存中的数据页到磁盘上的时候,就有可能中途遭遇类似操作系统异常断电而导致数据页部分写的情况,进而造成数据块损坏,数据块损坏对于某些数据库是致命的,可能导致数据库无法启动。既然对于断页问题数据库都可能遇到,那么再来看看主流数据库是如何避免发生断页的。

先看看mysql,innodb的page size一般是16k,innodb的数据行发生变更时,将buffer pool中的page更新,并且将这次变更写入redolog中,buffer pool中发生改变的dirty page再择机刷新到磁盘。脏页刷到磁盘的过程中就可能发生断页问题。mysql为了解决这个问题,引入了“双写”double write,也就是说在将数据页写入磁盘之前先写入一个共享的空间,然后再写入数据文件中。这个共享的空间大小是2M,当然为了加速写也引入了innodb double write buffer,也是2M,总体写流程如下图

2M的大小共包含128个页面,前120个页面是批量刷脏使用的空间,后8个页面是单页面刷脏使用的空间,批量刷脏是后台线程发起,而单页面刷脏是用户线程发起,单页面刷脏需要同步完成,要求实时性,值得注意的是double write是页面顺序写,速度很快,而buffer pool刷脏是随机写,效率较低。如果刷脏过程中发生写断页问题,存储引擎会从2M共享表空间中找到该页面的副本,然后恢复到数据文件中,然后应用redo进行恢复。innodb双写对性能的影响还是比较大的,相当于每次都要写两份数据。

再看看oracle,oracle对于断页比较“看得开”,他不会从数据库层面去避免发生断页问题,数据库内部没有机制保证断页的处理,它通过其他方面比如rman恢复、adg等方式保证出了问题进行恢复。

最后看看pg的处理,pg通过开启full_page_writes参数(默认开启)来避免断页问题。具体原理是当checkpoint发生后,某个块第一次被更改时将整个页面写入xlog文件中,如果发生块折断,从checkpoint开始从xlog中找到这个数据块的初始完整副本,然后应用redo日志进行恢复。这种方式对性能也有一定影响,但是相比mysql的方式我觉得要好一些,mysql相当于任何一个脏页刷盘前都需要写两份,pg只是在数据块第一次发生变更的时候写入xlog中。

full_page_writes还有一个作用是用于在线备份,因为basebackup是物理备份,那么有可能发生数据写一半的时候数据块被拷走的情况,这样备份是不可用、不可恢复的。而full_page_writes避免了这一点。

当然开启full_page_writes的副作用就是增加了xlog的日志量,因为要记录完整页面,另外对性能也有影响,有人测试过大概会有20%-30%的性能影响。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-11-02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 数据库架构 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云数据库 SQL Server
腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档