背景

InnoDB作为事务性引擎,使用write-ahead logging(WAL)机制保证ACID中的Atomicity和Durability,使用undo机制保证ACID中的Consistency和Isolation。

按照WAL和undo的机制,形成以下两个原则:

1. 数据块的更改需要先记录redo日志。
2. 数据块的更改需要先写入undo。

根据这两个原则,InnoDB更新数据的基本流程可以简单的总结为:

1. 记录需要更改undo record的redo log
2. 记录需要更改data record的redo log
3. 写入redo log
4. 写入undo record
5. 更新data record

这5个步骤。

InnoDB Recovery

如果MySQL实例异常crash,那么重启过程中首先会进行InnoDB recovery。 即:根据last checkpoint点,顺序读取后面的redo log,按照先前滚,再回滚的原则, 应用所有的redo log。

因为redo record中记录着数据块的地址(space_id+page_no),所以recovery的过程首先会执行合并相同数据块的操作,以加快recovery的过程。

那么问题来了

根据space_id怎么找到对应IDB数据文件?

因为在恢复的过程中,InnoDB只load了redo文件和系统表空间文件,如何查找InnoDB的数据文件呢?

1. InnoDB的数据字典dict_table_t结构中也保存了对应关系,但数据字典受redo保护,recovery的过程中不可用。
2. 扫描datadir的所有数据文件,读取page中保存的space_id,建立space_id和数据文件的对应关系。

MySQL目前采用第二种方式,但带来了一个问题,当设置了innodb_file_per_table后,每一个表对应一个表空间,那么需要读取所有的目录下的所有Innodb数据文件,这样就会严重的影响了recovery的时间。

MySQL 5.7改进策略:

MySQL 5.7中,在redo log中增加了一种新的record类型,即MLOG_FILE_NAME,记录了自last checkpoint以来更改的数据文件的file name。 这样在应用的时候,直接根据文件名就可以找到数据文件。

Oracle的设计机制:

Oracle数据库recovery的过程中,有没有这个问题呢? 答案是没有。

我们来看下Oracle的设计机制:

oracle同样在系统表空间中记录了数据字典,受redo保护,可以通过DBA_开头的表来查询。但Oracle还维护了一个control file,控制文件中记录了database name,redo file,datafile,backup等信息,通过v$开头的表查询。
当Oracle在recovery的过程中,需要数据库在mount状态下,即打开了控制文件,这时数据字典还不可用(DB没有open),在应用redo log的时候,根据控制文件中的v$datafile,检索file_id和file_name的对应关系。

MySQL是根据datadir,innodb_data_home_dir,innodb_log_group_home_dir等几个目录配置,通过文件系统的查找,找到相应文件的,而Oracle维护了一个集中式的control file管理这些初始加载的文件地址。

MySQL内核月报 2014.11-MySQL· 5.7改进·Recovery改进相关推荐

  1. MySQL内核月报 2014.11-MySQL· 5.7特性·在线Truncate undo log 表空间

    背景 Innodb使用undo log来实现MVCC,这意味着如果一个很老的事务长时间不提交,那么新产生的undo log都无法被及时清理掉.在MySQL 5.5及之前版本中,undo log是存储在 ...

  2. MySQL内核月报 2014.09-MySQL· 捉虫动态·auto_increment

    背景: Innodb引擎使用B_tree结构保存表数据,这样就需要一个唯一键表示每一行记录(比如二级索引记录引用). Innodb表定义中处理主键的逻辑是: 1.如果表定义了主键,就使用主键唯一定位一 ...

  3. MySQL内核月报 2014.10-MySQL· 捉虫动态·binlog重放失败

    背景 在 MySQL 日常维护中,要回滚或者恢复数据,我们经常会用 binlog 来在数据库上重放,执行类似下面的语句: mysqlbinlog mysql-bin.000001 | mysql -h ...

  4. MySQL内核月报 2014.08-TokuDB·社区八卦·TokuDB团队

    第一期先介绍下TokuDB团队吧. TokuDB自从开源后(更赞的是开源了所有的commits),逐渐被大家所熟悉,MariaDB 5.5系列和Percona Server 5.6的GA版本中,都以p ...

  5. mysql内核架构_热血江湖mysql内核技术之门派数据库表结构说明

    小编之前已经多次和大家说过了一个概念,不管你打算架设的是什么游戏什么版本都必须熟悉它的数据库整体结构.今天小编要说的是热血江湖私服游戏中最难的MYSQL内核技术,对于玩家来说MYSQL技术无疑是最难的 ...

  6. mysql server id为0_MySQL内核月报 2014.12-MySQL· 答疑释惑·server_id为0的Rotate-阿里云开发者社区...

    背景 在MySQL的M-S结构里面,event是binlog日志的基本单位.每个event来源于主库,每个Event都包含了serverid,用于表示该event是哪个实例生成的. 在5.6里面,细心 ...

  7. MySQL内核月报 2015.02-MySQL · 答疑释惑· InnoDB丢失自增值

    背景 在上一期的月报中,我们在InnoDB自增列重复值问题 中提到,InnoDB 自增列在重启后会丢失,因为MySQL没有持久化自增值,平时是存在内存表对象中的.如果实例重启的话,内存值丢失,其初始化 ...

  8. MySQL内核月报 2015.01-MySQL · 捉虫动态· InnoDB自增列重复值问题

    问题重现 先从问题入手,重现下这个bug 这里我们关闭mysql,再启动mysql,然后再插入一条数据 我们看到插入了(2,2),而如果我没有重启,插入同样数据我们得到的应该是(4,2). 上面的测试 ...

  9. MySQL内核月报 2015.01-MySQL · 捉虫动态· replicate filter 和 GTID 一起使用的问题

    问题描述 当单个 MySQL 实例的数据增长到很多的时候,就会考虑通过库或者表级别的拆分,把当前实例的数据分散到多个实例上去,假设原实例为A,想把其中的5个库(db1/db2/db3/db4/db5) ...

  10. 阿里内核月报2014年3月

    目前Linux内核急需的一项功能是在线打补丁的特性.此前被Oracle收购的ksplice一度是Linux上唯一的解决方案.但是在被Oracle收购后,ksplice就闭源了,并且成为了Oracle ...

最新文章

  1. C++高精度运算类bign (重载操作符)
  2. 控件无法安装,windows已经阻止此软件因为无法验证发行者
  3. 德州阿尔法计算机技术有限公司,德州扑克被人工智能完美攻陷 为什么比阿尔法狗还值得关注?...
  4. myeclipse和输入法冲突的问题
  5. golang sync WaitGroup
  6. [数论]拓展中国剩余定理
  7. [android] 百度地图开发 (一).申请AK显示地图及解决显示空白网格问题
  8. HTTP协议中的Content-Encoding
  9. 【动态规划】机器分配 (ssl 1639)
  10. 第八十七期:爬了知乎“沙雕问题”,笑死个人!
  11. Docker 方式安装 Nginx 、阿里云服务器上装 Ngnix
  12. python去空格的函数_Python中用于去除空格的三个函数的使用小结
  13. python自己写包_封装属于自己的Python包
  14. hdu 5144 NPY and shot(三分)
  15. android 4实例分析,OpenGL Shader实例分析(4)闪光效果
  16. adobe怎么统计字数,在Adobe Reader中统计PDF中的文字数
  17. visio画任意形状图形
  18. Elastic-Job分布式任务调度
  19. 立创开源 WCHLink/DapLink下载器 沁恒
  20. python开发工程师是干嘛的-python工程师是做什么的

热门文章

  1. STUCTS LABLE ‘S BENEFIT
  2. CMD获取当前目录的绝对路径
  3. java中static和final修饰符
  4. 第一次作业 三班20
  5. web@css盒模型详解
  6. 解决ASP.NET中Redis 每小时6000次访问请求的问题
  7. 2017.10.26-构建之法:现代软件工程-阅读笔记
  8. C# Windows 服务
  9. 听一下牛人是怎样自学MIT计算机系全部课程的[转]
  10. eclipse配置文件