innodb为什么需要doublewrite(转)
InnoDB的page size默认是16KB,而操作系统的一个block size是4KB,磁盘io block则更小。那么InnoDB的page刷到磁盘上要写4个操作系统block,在极端情况下(比如断电)不一定能保证4个块的写入原子性,假如只有一部分写是成功的,那么innodb的数据page就不是一个完整的page(break page),这种现象称为partial write。
innodb怎么解决partial write?
innodb采用的是doublewrite机制,在写数据page时,会写两遍到磁盘上,第一遍是写到doublewrite buffer(实际上是共享表空间的一块区域),第二遍是从doublewrite buffer写到真正的数据文件中。如果发生了partial write,InnoDB再次启动后就可以从doublewrite buffer中进行page的恢复。由于第一遍page落盘与第二遍page落盘在不同的时间点,所以不会出现doublewrite page和数据page同时发生partial write的情况。
innodb为什么不用redo log来恢复break page?
redo log的页大小一般设计为512个字节,因此redo log page本身不会发生break page。用redo log来解决partial write 理论上是可行的,不过innodb的redo log是逻辑物理日志(不做展开),并不是物理日志,因此发生partial write后崩溃恢复过程中不能直接应用redo log ,innodb发现break page后实际上会报错。
innodb能否通过其他方式解决partial write?
可以,如果系统表空间文件(“ibdata文件”)位于支持原子写入的Fusion-io设备上,就能避免partial write ,可以不用doublewrite机制。还有大名鼎鼎的阿里云polardb,在底层分布式文件系统PolarFS能提供页大小(如16)KB小的原子写入,无需double write 机制来避免partial write。还有XDB的DBFS也类似实现了原子写。
可以总结数据库为了解决partial write问题,一般有4种手段:
- 事后恢复:innodb doublewirite 机制,事先存一份page的副本,当partial write发生需要恢复时,先通过page的副本来还原该page,再进行重做;
- 事后恢复:物理redo log 恢复机制,物理redo log里面存有完整的数据page,当partial write发生需要恢复时,先通过redo log page的副本来还原该page,再进行重做可以保证幂等性;
- 事先避免:底层存储来实现原子写入避免partial write;
- 事先避免:数据库的page size 设置为块设备扇区大小512字节保证原子写避免partial write,如:innodb redo log 。
下面来看下常见的存储引擎或者数据库系统他们是怎么解决partial write的。
PostgreSQL
PG采用的是第二种方式。通过full_page_write机制,在物理redo log中写dirty page的full page解决了数据页的partial write问题。然而pg的redo log page size默认是8K的,不是512字节对齐物理磁盘block,所以理论上PG的redo log 也会存在partial write。不过redo log 的partial write并不会带来数据一致性的问题,因为假如出现了partial write说明事务未提交成功,那么崩溃恢复的时候对PG来说也是不会去恢复的。
MongoDB WiredTiger
WiredTiger中刷脏页是通过将内存中的btree修改过的PAGE做一次checkpoint并写入持久化存储,每个btree对应磁盘上一个物理文件,btree的每个PAGE以文件里的extent形式上的page。很显然checkpoint是一个append only方式,也就是说WiredTiger会保存多个checkpoint版本。由于原page并没有被更新,所以即使发生partial write,不管从哪个版本的checkpoint开始都可以通过重演journal log恢复来保证page的完整性。值得一提的是MongoDB 3.5.12中WiredTiger在内存和journal log中实现了in-place update,但数据写磁盘的机制并未改变,因此依然可以解决partial write。
RocksDB & InfluxDB
存储引擎采用LSM或者TSM(类LSM)的结构,数据page采用append only方式写入,而不是像innodb或PG一样采用in-place update的方式写入page,所以即使出现了partial write,由于原page没有变更,可以通过原page重做wal log恢复来保证page的完整性。
innodb为什么需要doublewrite(转)的更多相关文章
- MySQL Doublewrite Buffer及业务评估
1. 关于Doublewrite Buffe的总结 Doublewrite Buffer:Doublewrite Buffer出现的初衷是防止buffer pool中的脏页刷新到磁盘中,出现部分写的问 ...
- Mysql Innodb体系结构
Innodb体系结构 Innodb存储引擎主要包括内存池以及后台线程. 内存池:多个内存块组成一个内存池,主要维护进程/线程的内部数据.缓存磁盘数据,修改文件前先修改内存.redo log 后台线程: ...
- Innodb 状态的部分解释
Innodb_buffer_pool_pages_data Innodb buffer pool缓存池中包含数据的页的数目,包括脏页.单位是page. Innodb_buffer_pool_pages ...
- 《Mysql技术内幕,Innodb存储引擎》——Innodb体系结构
Innodb体系结构 Innodb存储引擎主要包括内存池以及后台线程. 内存池:多个内存块组成一个内存池,主要维护进程/线程的内部数据.缓存磁盘数据,修改文件前先修改内存.redo log 后台线程: ...
- mysql 异常宕机 ..InnoDB: Database page corruption on disk or a failed,,InnoDB: file read of page 8.
mysql 测试环境异常宕机 系统:\nKylin 3.3 mysql版本:5.6.15--yum安装,麒麟提供的yum源数据库版本 error日志 181218 09:38:52 mysqld_sa ...
- Innodb整体架构
如下图展示了Innodb内存中和磁盘的结构: 内存中结构主要有如下几种: buffer pool change buffer adaptive hash index (自适应的hash索引) Log ...
- 【3.4】innodb存储引擎
[1]Innodb 与 Myisam 的区别 1.InnoDB支持事物,而MyISAM不支持事物 2.InnoDB支持行级锁,而MyISAM支持表级锁 3.InnoDB支持MVCC, 而MyISAM不 ...
- 【InnoDB】插入缓存,两次写,自适应hash索引
InnoDB存储引擎的关键特性包括插入缓冲.两次写(double write).自适应哈希索引(adaptive hash index).这些特性为InnoDB存储引擎带来了更好的性能和更高的可靠性. ...
- innodb状态
Innodb_buffer_pool_pages_data Innodb buffer pool缓存池中包含数据的页的数目,包括脏页.单位是page. Innodb_buffer_pool_pages ...
随机推荐
- 扫描仪扫描文件处理-Photoshop批处理无响应问题
问题描述:Photoshop批处理时候卡死.卡住.无响应问题(出现在处理60M及以上TIFF文件的时候) 解决办法: 调整系统虚拟内存见<扫描-Photoshop批处理内存不足问题解决> ...
- k8s node上查看节点
node执行 mkdir -p /root/.kube master执行 scp admin.conf node1:/root/.kube/config
- linux(centos8):kubernetes安装的准备工作
一,安装docker-ce19.03.11 1,卸载podman [root@kubemaster ~]# dnf remove podman podman是红帽系os自带的容器,卸载是为了避免冲突 ...
- centos8平台使用pstree查看进程树
一,pstree用途 Linux pstree命令将所有行程以树状图显示,树状图将会以 pid (如果有指定) 或是以 systemd 这个基本行程为根 (root) 说明:centos6及更旧版本为 ...
- PHP7下的协程实现 转
前言 相信大家都听说过『协程』这个概念吧. 但是有些同学对这个概念似懂非懂,不知道怎么实现,怎么用,用在哪,甚至有些人认为yield就是协程! 我始终相信,如果你无法准确地表达出一个知识点的话 ...
- java-类和数组
java内存划分 Java的内存划分为5个部分: 1.栈 (Stack) : 存放的都是方法中的局部变量,方法的运行一定要在栈当中 局部变量: 方法的参数,或者是方法()内部的变量 作用域: 一旦超出 ...
- Nexus 安装教程
Nexus 安装教程 一. CentOS设置 1. 更换阿里源 curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/ ...
- ERROR [RMI TCP Connection(3)-127.0.0.1] - init datasource error
运行报错 ERROR [RMI TCP Connection(3)-127.0.0.1] - init datasource error, url: jdbc:mysql://localhost:33 ...
- vue-cli 工程目录结构介绍 详细介绍
vue-cli目录结构: vue-cli目录解析: build 文件夹:用于存放 webpack 相关配置和脚本.开发中仅 偶尔使用 到此文件夹下 webpack.base.conf.js 用于配置 ...
- Hadoop框架:HDFS高可用环境配置
本文源码:GitHub·点这里 || GitEE·点这里 一.HDFS高可用 1.基础描述 在单点或者少数节点故障的情况下,集群还可以正常的提供服务,HDFS高可用机制可以通过配置Active/Sta ...