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 ...
随机推荐
- 多测试_linux_003_肖sir
一.linux 介绍os 操作系统:windows,dos,android ,ios,unix ,linux linux系统:是一个免费,开源的操作系统,能多cpu,多用户,多线程的操作系统,比win ...
- sop服务治理
一,为什么需要服务治理: 我们最先接触的单体架构, 整个系统就只有一个工程, 打包往往是打成了 war 包, 然后部署到单一 tomcat 上面, 这种就是单体架构, 如图: 假如系统按照功能划分了, ...
- Mac zsh中所有命令失效
参考文章 https://blog.csdn.net/hujincai_55/article/details/95680245?utm_medium=distribute.pc_relevant.no ...
- day46 Pyhton 数据库Mysql 03
一内容回顾 存储引擎:主要描述的是数据存储的不同方式 innodb 支持事务\支持外键\行级锁\聚焦索引 myisam 不支持事务\不支持外键\表级锁\非聚焦索引 memory 只能在内存中存储表数据 ...
- intellij idea:设置java方法注释模板(intellij idea 2019.2)
一,打开方法注释模板的编辑窗口 菜单file->打开settings editor栏目下->打开Live Templates 说明:刘宏缔的架构森林是一个专注架构的博客,地址:http ...
- dubbo-config-spring自定义xml标签扩展
要实现自定义自定义标签扩展,需要有如下步骤(在spring中定义了两个接口NamespaceHandler.BeanDefinitionParser,用来实现扩展) 1.设计配置属性和JavaBean ...
- 浅析软件测试人员如何对JVM进行内存溢出检测
一.什么是JVM,检测JVM的意义 JVM是java virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各 ...
- 续 Eureka+Hystrix+Zuul(Zuul API网关)
概述: 服务的合并,转发,验证,异构协议.将上百个请求融为一个发送到后台,返回大的JSON返回处理: 作用:这减少了客户端与应用程序间的交互次数,还简化了客户端代码. Zuul可以通过加载动态过滤机制 ...
- 世界碰撞算法原理和总结(sat gjk)
序言 此文出于作者的想法,从各处文章和论文中,总结和设计项目中碰撞结构处理方法.如有其它见解,可以跟作者商讨.(杨子剑,zijian_yang@yeah.net). 在一个世界中,有多个物体,物体可以 ...
- jquery里面的一些方法使用
prop("属性名"); //获取属性名 prop("属性名","属性值"); //设置属性名 change(fucntion(){ ...