mysql5.5
在mysql5.5和之前,innodb的undo log是存放在ibdata1(共享表空间)中,当开启事务后,事务所使用的undo log会存放在ibdata1中,即使这个事务被关闭,undo log也会一直占用空间
此时的ibdata1为58M,然后执行undo操作
将自动提交设为0,接着执行update语句后,发现ibdata1增长到了114M
接下来回滚该事务,发现并没有去收缩该表空间的大小。
mysql5.6
在mysql5.6中可以通过以下三个参数将undo log单独存放:
1.innodb_undo_directory,指定单独存放undo表空间的目录,该参数实例初始化之后不可直接改动,但是可以通过先停库,修改配置文件,然后移动undo表空间文件的方式去修改该参数;
2.innodb_undo_tablespaces,指定单独存放的undo表空间个数,该参数我们推荐设置为大于等于3;
3.innodb_undo_logs,指定回滚段的个数, 默认为128个。
mysql5.7
MySQL 5.7引入了新的参数,innodb_undo_log_truncate,开启后可在线收缩拆分出来的undo表空间。满足以下条件,undo表空间文件可在线收缩。
1.innodb_undo_tablespaces>=2。因为truncate undo表空间时,该文件处于inactive状态,如果只有1个undo表空间,那么整个系统在此过程中将处于不可用状态。为了尽可能降低truncate对系统的影响,建议将该参数最少设置为3;
2.innodb_undo_logs>=35(默认128)。因为在MySQL 5.7中,第一个undo log永远在系统表空间中,另外32个undo log分配给了临时表空间,即ibtmp1,至少还有2个undo log才能保证2个undo表空间中每个里面至少有1个undo log;
满足以上2个条件后,把innodb_undo_log_truncate设置为ON即可开启undo表空间的自动truncate,这还跟如下2个参数有关:
(1)innodb_max_undo_log_size,undo表空间文件超过此值即标记为可收缩,默认1G,可在线修改;
(2)innodb_purge_rseg_truncate_frequency,指定purge操作被唤起多少次之后才释放rollback segments。当undo表空间里面的rollback segments被释放时,undo表空间才会被truncate。由此可见,该参数越小,undo表空间被尝试truncate的频率越高。
(1)确保参数被正确设置
此时undo表空间大小
执行delete语句
此时undo文件大小已经收缩