玩转MySQL:深入解析InnoDB引擎存储结构+特性分析( 三 )


double write也是由两部分组成 , 一部分是内存中的double write buffer,大小为2MB , 另一部分是物理磁盘上的共享表空间中的连续128个页 , 大小也是2MB , 写入流程如下图(图片来源于《MySQL技术内幕 InnoDB存储引擎》):
玩转MySQL:深入解析InnoDB引擎存储结构+特性分析文章插图
double write机制会使得数据写入两次磁盘 , 但是其并不需要两倍的I/O开销或两倍的I/O操作 。 通过对操作系统的单个fsync()调用 , 数据以一个大的顺序块的形式写入到双写入缓冲区 。
在大多数情况下默认启用了doublewrite缓冲区 。 要禁用doublewrite缓冲区 , 可通过将变量innodb_doublewrite设置为0即可 。
Undo Logsundo log记录了单个事务对聚集索引数据记录的最近一次修改信息 , 用来保证在必要时实现回滚 , 如果另一个事务需要在一致性读操作中查看原始数据 , 则从undo日志记录中检索未修改的数据 , 也就是说MVCC机制也依赖于undo log来实现 。
与redo log不同的是 , undo log存储的是逻辑日志 , undo log分为两种类型:

  • insert undo log由insert操作产生 , 由于插入数据操作只对当前事务可见 , 所以事务提交之后可以直接删除
  • update undo log由update和delete操作产生 , 由于要实现MVCC多版本并发控制 , 故而update undo log在事务提交之后不能直接删除 , 而是最后由后台线程(Purge Thread或者Master Thread)来最终判断是否可以删除
注意 , update undo log最终到底由哪个线程来执行purge操作 , 可以通过配置文件来配置实现,:
[mysqld]innodb_purge_thread=11表示由独立线程Purge Thread来实现 , 否则由主线程Master Thread来实现
File-Per-Table Tablespaces独占表空间 , 通过变量innodb_file_per_table控制 , 在MySQL5.6开始 , 默认是开启的
innodb_file_per_table=ON开启后 , 则每张表会开辟一个表空间 , 这个文件就是数据目录下的 ibd 文件 , 不同引擎生成的文件不一样 。 独占表空间存放表的索引和数据 , 其他数据如回滚(undo)信息 , 插入缓冲索引页、系统事务信息 , 二次写缓冲(Double write buffer)等还是存放在原来的共享表空间内 。
General TablespacesGeneral Tablespaces , 通用表空间 , 和系统表空间idata1类似 , 一般指的是我们自己使用CREATE tablespace语法创建的共享InnoDB表空间 。 创建语法为:
CREATE TABLESPACE tablespace_nameADD DATAFILE 'file_name'[FILE_BLOCK_SIZE = value][ENGINE [=] engine_name]在数据目录中创建一个通用表空间:
CREATE TABLESPACE `ts1` ADD DATAFILE 'ts1.ibd' Engine=InnoDB;在数据目录之外创建一个通用表空间:
CREATE TABLESPACE `ts1` ADD DATAFILE '/my/tablespace/directory/ts1.ibd' Engine=InnoDB;然后我们再创建或者修改表的时候可以指定为创建的通用表空间:
CREATE TABLE t1 (c1 INT PRIMARY KEY) TABLESPACE ts1;ALTER TABLE t2 TABLESPACE ts1;Undo TablespacesUndo表空间包含Undo日志 。 Undo日志可以存储在一个或多个Undo表空间中 , 而不是系统表空间中 。 这种布局不同于默认配置 , 在默认配置中 , undo log保存在系统表空间中 。
Undo表空间的数量由innodb_undo_tablespaces变量定义 。 默认值是0:
SELECT @@innodb_undo_tablespaces;Temporary Tablespace在共享临时表空间中创建非压缩的或者用户创建的临时表和磁盘上的内部临时表会存储在临时表空间 。 innodb_temp_data_file_path配置选项定义临时表空间数据文件的相对路径、名称、大小和属性 。 如果没有为innodb_temp_data_file_path指定值 , 默认行为是在innodb_data_home_dir目录中创建一个名为ibtmp1的自动扩展数据文件 , 该文件略大于12MB 。
临时表空间在正常关闭或初始化失败时被删除 , 并在每次服务器启动时重新创建 。 临时表空间在创建时会动态生成一个空间ID 。 如果无法创建临时表空间 , MySQL会拒绝启动 。 如果服务器意外停止 , 临时表空间不会被删除 。 在这种情况下 , 我们可以进行手动删除临时表空间 , 或者重新启动服务器 , 从而自动删除和重新创建临时表空间 。
可以通过如下语句查询临时表空间信息:
SELECT * FROM INFORMATION_SCHEMA.FILES WHERE TABLESPACE_NAME='innodb_temporary';默认情况下 , 临时表空间数据文件会自动扩展和增加大小 , 以适应磁盘上的临时表,临时表的大小和ibdata1文件一样可以通过变量修改 。
SHOW VARIABLES LIKE 'innodb_temp_data_file_path';-- 默认12MB大 , 可扩展innodb_temp_data_file_path=ibtmp1:12M:autoextend为了防止临时数据文件变得太大 , 可以配置innodb_temp_data_file_path选项来指定最大文件大小 。 例如: