简单分析mysql的InnoDB存储引擎的磁盘架构


在这里插入图片描述

上图是mysql官方文档中提供的InnoDB架构图,左侧是内存架构,右侧则是磁盘架构。本文主要对磁盘架构简单分析下。

如上图右侧所示,可以看到InnoDB的磁盘结构由6部分组成:

1.系统表空间(System Tablespace)

默认所有表都会共享的表空间,对应磁盘文件ibdata1。里面包含四部分:
(1)InnoDB Data Dictionary:数据字典,记录表和索引的元信息。
(2)Doublewrite Buffer:双写缓冲,下边详细会说。
(3)change Buffer:写缓冲区,上文中说过。
(4)undo log:实现mysql事务的原子性,后边会单独说。

双写缓冲(Doublewrite Buffer)

上篇文章中我们知道了InnoDB每次IO默认为1页即16kb,但是操作系统的页一般是4kb,所以InnoDB的一个页要写入到磁盘就要分四次了。
那么问题来了。
:如果数据写入到磁盘的时候发生了宕机,而InnoDB只写入了第一个4kb的时候。那剩下的12kb没写进去,这就叫做“部分写失效”,这就会导致数据丢失。注意redo log日志进行数据恢复时发现这个页已经不完成了,所以是恢复不了的。怎么解决?
:很直观的答案,保证数据页的完整性就好了。那怎么保证。它是这么做的,在要刷盘之前,也就是redo log应用到磁盘之前,会先拷贝一个副本到doublewrite buffer中。如果出现了部分页失效,就可以用这个副本还原这个数据页的内容,然后在恢复数据。这个页的副本就成为双写缓冲技术,主要靠它来实现数据页的可靠性完成性
查看Doublewrite Buffer信息的命令:show variables like '%innodb_doublewrite%';,默认就是开启状态。
在这里插入图片描述

2.独占表空间(File-Per-Table Tablespace)

因为系统的表空间是共享的,为了防止系统表空间越来越大,才有的独占表空间。该文件为每个表的表空间提供了一种更灵活的选择,其中,每个InnoDB表被存储在其自己的表空间的数据文件(.ibd文件)。也就是有一个表就有一个ibd文件,该文件只存放数据和索引。
show variables like '%innodb_file_per_table%';,可以查看信息,默认就是开启状态。
在这里插入图片描述

3.通用表空间(General Tablespaces)

也是共享的表空间,跟系统表空间类似。不过它可以自己创建并使用。使用CREATE TABLESPACE语法创建。

4.临时表空间(Temporary Tablespace)

存储临时表的数据,对应文件ibTmp1。在正常关闭或初始化中止时,将删除临时表空间,并在每次启动服务器时重新创建

5.重做日志(redo log)

提供崩溃恢复。上一篇文章中说过。

6.撤销表空间(undo Tablespaces)

也就是undo log,默认配置中,是放在系统表空间的,也可以独立出来。
redo log + undo log合起来就是mysql的事务日志,redo log 实现持久性,undo log实现原子性。
查看undo log信息的命令:show global variables like '%undo%';
在这里插入图片描述

undo log

undo log又叫回滚日志,记录了我们事务发生前的一个状态,比如,我们在修改的时候发生了异常,就可以用undo log 来实现回滚的操作。
有了redo log 和undo log后,那么一条更新语句的执行流程为:
(1)从内存或磁盘读取到这条数据,返回给server层
(2)执行器把这条数据修改
(3)记录undo log
(4)记录redo log并将这条数据状态设为 prepare
(5)调用存储引擎的api,在buffer pool修改数据
???????????(总感觉这里少点啥)??????????????
(6)事务提交将redo log中这条数据的状态改为commit,再由后台线程刷到磁盘
那么问题来了。
:如上述流程中,如果事务正在提交的时候mysql挂了咋办?

这就引出了新的东西 binary log

binary log

又称 binlog,二进制日志。主要记录了我们所有的DDL(创建表库和删除表库的操作)、DML(增删改的操作)语句。
作用:
(1)数据恢复,可以将binlog日志解析出来,应用到全量备份中。必须依赖全量备份,不然很难恢复
(2)主从复制,主从之间数据如何保持同步的?就是基于binlog去实现的。
上个问题的解答:有了binlog,那么在commit之前先将更新语句写入到binlog中。就算在提交事务的时候mysql崩溃重启了,那也会以binlog为准,将语句在执行commit一次就行了。所以只要写入到binlog后,就意味着语句执行成功了。

一条更新语句的完成执行流程图

在这里插入图片描述
<<上一篇:InnoDB存储引擎的内存架构
>>下一篇:mysql索引及索引的存储结构

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值