Purge

Purge

InnoDB由于要支持多版本协议,因此无论是更新,删除,都只是设置记录上的deleted bit标记位,而不是真正的删除记录。后续这些记录的真正删除,是通过Purge后台进程实现的。Purge进程定期扫描InnoDBundo,按照先读老undo,再读新undo的顺序,读取每条undo record。对于每一条undo record,判断其对应的记录是否可以被purge(purge进程有自己的read view,等同于进程开始时最老的活动事务之前的view,保证purge的数据,一定是不可见数据,对任何人来说),如果可以purge,则构造完整记录(row_purge_parse_undo_rec)。然后按照先purge二级索引,最后purge聚簇索引的顺序,purge一个操作生成的旧版本完整记录。

row_purge_step->row_purge->trx_purge_fetch_next_rec->row_purge_parse_undo_rec

                     ->row_purge_del_mark->row_purge_remove_sec_if_poss

                                      ->row_purge_remove_clust_if_poss
# 查看初始共享表空间文件,ibdata1 的大小为 76M。
mysql> system ls -lh /usr/local/var/mysql/ibdata1

# 执行大量更新操作
mysql> set autocommit=0;
mysql> update mytest set salary=0;
mysql> system ls -lh /usr/local/var/mysql/ibdata1;

# 最后执行回滚
mysql> rollback;

我们执行会产生大量Undo操作的语句 update mytest set salary=0,完成后我们再观察共享表空间,会发现ibdata1已经增长到了114MB,这就说明了共享表空间中还包含有Undo信息。rollback这个事务,ibdata1这个表空间不会立刻减少,MySQL会自动判断这些Undo信息是否需要,如果不需要,则会将这些空间标记为可用空间,供下次Undo使用。master thread10秒会执行一次full purge操作。因此很有可能的一种情况是,你再次执行上述的UPDATE语句后,会发现ibdata1不会再增大了,那就是这个原因了。

上一页
下一页