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

oracle,mysql,pg,如何,处理,数据库,半页,问题 · 浏览次数 : 0

小编点评

**数据库断页问题解决方案** 数据库的断页问题是指当数据页写入磁盘时,由于操作系统异常导致部分数据页被写不完整时,导致数据块损坏的情况。 **主流数据库的处理方法** 1. **MySQL**:引入了“双写”double write,将数据页写入磁盘之前先写入一个共享空间,然后再写入数据文件中。 2. **Oracle**:不会从数据库层面去避免发生断页问题,通过其他方面比如rman恢复、adg等方式保证出了问题进行恢复。 3. **PostgreSQL**:开启了full_page_writes参数,当checkpoint发生后,某个块第一次被更改时将整个页面写入xlog文件中,如果发生块折断,从checkpoint开始从xlog中找到这个数据块的初始完整副本,然后应用redo日志进行恢复。 **性能影响** * **MySQL**:脏页刷到磁盘的过程中就可能发生写断页问题。 * **Oracle**:不会从数据库层面去避免发生断页问题。 * **PostgreSQL**:开启了full_page_writes参数,当checkpoint发生后,某个块第一次被更改时将整个页面写入xlog文件中,如果发生块折断,从checkpoint开始从xlog中找到这个数据块的初始完整副本,然后应用redo日志进行恢复。

正文

数据库“断页”是个很有意思的话题,目前任何数据库应该都绕不过去。我们知道数据库的块大小一般是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%的性能影响。

文章知识点与官方知识档案匹配,可进一步学习相关知识
PostgreSQL技能树查询数据psql4111 人正在系统学习中

与[转帖]Oracle、MySQL、PG是如何处理数据库“半页写”的问题的?相似的内容:

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

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

[转帖]十年后数据库还是不敢拥抱NUMA?

https://zhuanlan.zhihu.com/p/387117470 导语 在2010年前后MySQL、PG、Oracle数据库在使用NUMA的时候碰到了性能问题,流传最广的这篇 MySQL – The MySQL “swap insanity” problem and the effect

[转帖]Oracle迁移到MySQL时数据类型转换问题

https://www.cnblogs.com/yeyuzhuanjia/p/17431979.html 最近在做“去O”(去除Oracle数据库)的相关工作,需要将Oracle表结构转换成MySQL的表结构。这里面最重要的一点就是字段数据类型的变化。 1.ORACLE常用的数据类型与MySQL的对

[转帖]Oracle、SQL Server、MySQL数据类型对比

Oracle、SQL Server、MySQL数据类型对比 - 知乎 (zhihu.com) 1,标准SQL数据类型 BINARY 每个字符占一个字节 任何类型的数据都可存储在这种类型的字段中。不需数据转换(例如,转换到文本数据)。数据输入二进制字段的方式决定了它的输出方式。BIT 1 个字节0 和

[转帖]Oracle参数解析(parallel_force_local)

https://www.modb.pro/db/122032 是否需要增加这个参数? 往期专题请查看www.zhaibibei.cn这是一个坚持Oracle,Python,MySQL原创内容的公众号 前面介绍了Oracle的基本参数,从这节开始讲其他的参数,参数从v$parameter中提取 基本参

[转帖]使用JAYDEBEAPI同时连接两个不同数据库(ORACLE+MYSQL)的问题

jaydebeapi 同时连接两种数据库 在使用jaydebeapi只连接一种数据库时,是没问题的,但是如果需要同时连接两种数据库,比如同时连接oracle和mysql 例如以下测试代码: import jaydebeapi ##使用jdbc驱动连接数据库 import pandas as pd d

[转帖]一文搞懂各种数据库SQL执行计划:MySQL、Oracle等

https://zhuanlan.zhihu.com/p/99331255 MySQL 执行计划 Oracle 执行计划 SQL Server 执行计划 PostgreSQL 执行计划 执行计划(execution plan,也叫查询计划或者解释计划)是数据库执行 SQL 语句的具体步骤,例如通过索

[转帖]USQL

usql is a universal command-line interface for PostgreSQL, MySQL, Oracle Database, SQLite3, Microsoft SQL Server, and many other databases including N

[转帖]Mysql DBA运维命令大全

Mysql DBA运维命令大全 https://www.modb.pro/db/97499 中国DBA联盟(ACDU)成员,目前从事DBA及程序编程(Web\java\Python)工作,主要服务于生产制造 现拥有 Oracle 11g OCP/OCM、Mysql、Oceanbase(OBCA)认证

[转帖]一文看懂mysql数据库事务隔离级别

概述 我们都知道除了MySQL默认采用RR隔离级别之外,其它几大数据库都是采用RC隔离级别。那为啥mysql要这样设置呢?其实是MySQL为了规避一个数据复制场景中的缺陷,而选择 Repeatable Read 作为默认隔离级别。不过不同数据库实现方式还是不太一样。 Oracle仅仅实现了RC 和