15.2.12 . 多版本的实施

因为InnoDB是多版本化的数据库, 它必须保持关于表空间中旧版本行的信息。这个信息被存在名为rollback segment(在Oracle中模拟数据结构之后)的数据结构中。

内部地,InnoDB往存在数据库中的每一行中添加两个域。一个6字节的域说明插入或更新该行的最后一个事务的事务识别符。同时,一个删除也被内部处理为一个更新,其中行中一个特殊的位被设置来标注该行为已删除。每一行也包含一个称为滚动指针的7字节域。滚动指针指向一个被写到回滚片断的撤销日志记录。如果该行被更新,撤销日志记录包含在该行被更新之前重建该行的内容必需的的信息。

InnoDB使用在回滚片断中的信息来执行在事务回滚中需要的撤销操作。它也使用这个信息来为一个持续读构建更早版本的行。

在回滚片断中的撤销日志被分为插入和更新撤销日志。插入撤销日志仅在事务回滚中需要,且只要事务一提交就可以被丢弃。更新撤销日志也被用在持续读中,而且它们仅在 当前没有被InnoDB分配给一个快照的事务之后被丢弃,这个快照在持续读中可能会需要更新撤销日志的信息来建立一个数据库行的早期版本。

你必须记得规律地提交你的事务,包括那些只发布持续读的事务。否则, InnoDB不能从更新撤销日志丢弃数据,并且回滚片断可能变得太大,填满你的表空间。

在一个回滚片断里,一个撤销日志记录的物理尺寸典型地小于相应的已插入行或已更新行。你可以用这个信息来计算回滚片断需要的空间。

在InnoDB多版本化方案中,当你用SQL语句删除一行之时,该行没有被从数据库立即物理删除掉。 只有当InnoDB可以丢弃为删除而被写的更新撤销日志记录时,InnoDB也物理地从数据库删除相应行和它的索引记录。这个删除操作被成为精华,它运行得很快,通常与做删除的SQL语句花的时间在一个数量级

在某一情景下,在那里,用户以几乎相同的比率,小批次地在表中插入和删除行,净化线程开始滞后 是可能的,并且表变得越来越大,使得每样事都是磁盘绑定的而且非常慢。即使表仅载有10MB有用的数据,它可能变得用所有的死行占据10GB空间。在这种情况下,节流新操作,并分配更多的资源来净化线程可能是比较好的。启动选项和可设置全球变量innodb_max_purge_lag就是为这个目的而存在的。请参阅15.2.4节,“InnoDB 启动选项” 以获得更多信息。

关注编程学问公众号