Author: 巴彦
首先我们介绍一下mysql5.6 undo tablespace独立表空间的内容,然后我们看一下后续5.6 8.0,mysql对独立表空间做出了那些修改。
从mysql5.6开始支持把undo log分开配置到独立的表空间,并放到单独的文件中;这给我们带来很多便利,对于该并发的写入,我们可以把undo文件单独部署到高速存储设备上。
用于设定undo独立表空间的个数,在install db时初始化并创建,之后便不能修改。
默认值为0,表示不独立设置undo tablespace,默认记录到ibdata中;否则创建多个undo文件;加入设定值为8,那么就会创建命名为undo001~undo08的undo tablespace文件,每个文件大小10M。
用于设定回滚段的个数;该变量动态可调,但是物理上的回滚段不会减少,只是控制当前使用回滚段的个数;默认值128。
当我们开启独立undo tablespace 独立表空间时,这个用来设定存放undo文件的目录。
在inndo启动时(innobase_start_or_create_for_mysql),会调用srv_undo_tablespaces_init来对undo表空间进行初始化。具体流程如下:
如果是新实例,并且打开了独立表空间;则会去创建undo log文件,表空间的space id从1开始,文件大小默认10M,由SRV_UNDO_TABLESPACE_SIZE_IN_PAGES来控制;并记录space id。
mysql5.7对于undo tablespace独立表空间的改动不大;只增加了一个功能,在线truncate undo log文件。具体参数可查看官方文档:innodb_undo_log_truncate ,官方博客对online-truncate-of-innodb-undo-tablespaces的介绍。
这个功能在生产环境的某些情况下比较有用,尤其是如果有长时间未提交事务导致浪费大量undo空间的情形。
标记需要truncate的undo tablespace。
这个动作实际上是由purge的协调线程发起的,默认情况下每做128次purge后,会调用函数trx_purge_truncate进行清理,trx_purge_truncate的调用流程如下:
trx_purge_truncate()
|
->trx_purge_truncate_history()
|
->trx_purge_truncate_rseg_history
|
->trx_purge_mark_undo_for_truncate()
|
->trx_purge_initiate_truncate()
trx_purge_mark_undo_for_truncate 是标记truncate undo tablespace的入口函数,主要步骤如下。
在标记truncate完成后,需要检查需要删除的回滚段是否是可释放的,也就是没有任何活跃的事务会应用到启动的undo log,入口函数为trx_purge_initiate_truncate,此函数的流程如下:
mysql8.0对undo tablespace做了进一步的优化;不仅仅支持更多的回滚段,而且还可以动态的增删undo tablespace。具体可查看mysql8.0 undo tablespace 官方文档,以及 官方博客 More Flexible Undo Tablespace Management, 官方博客 CREATE UNDO TABLESPACE
SELECT * FROM INFORMATION_SCHEMA.INNODB_TABLESPACES WHERE ROW_FORMAT = 'Undo';
SHOW GLOBAL STATUS LIKE '%UNDO_TABLESPACE%';
CREATE UNDO TABLESPACE myundo ADD DATAFILE 'myundo.ibu';
ALTER UNDO TABLESPACE myundo SET INACTIVE;
DROP UNDO TABLESPACE myundo;
undo tablespace的创建。
undo tablespace的修改
server层接口类:Sql_cmd_alter_undo_tablespace
在崩溃恢复dd后,需要调用apply_dd_undo_state将undo tablespace状态更新到内存。
innodb的接口是innodb_alter_undo_tablespace
innodb_alter_undo_tablespace()
|
->innodb_alter_undo_tablespace_active()
|
->innodb_alter_undo_tablespace_inactive()
undo tablespace的删除
Sql_cmd_drop_undo_tablespace
undo tablespace的truncate
由purge线程发起,入口函数:trx_purge_truncate_marked_undo()
具体流程如下:
这里使用新的space id的原因是删除重建的过程中没有做checkpoint,这时如果crash,那么可能就会存在redo修改已经不存在的page。
InndoDB的undo log从5.6开始可以存储到单独的tablespace文件中。到5.7版本支持了在线undo文件truncate,解决了undo膨胀问题。而到了8.0,对undo tablespace做了进一步的优化,每个undo tablespace可以有128个回滚段,以此来减少事务使用回滚段时的锁冲突;可以在线动态增删undo tablespace,使得undo tablespace管理更加灵活。总体来看undo tablespace是朝着更加灵活的方向发展,以后会慢慢废弃掉通过配置文件配置的方式。