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文件大小已经收缩