mysql-innodb-MVCC

概述

MVCC是“ 多版本并发控制 ”的 缩写。
这种技术可以使具有特定 隔离级别的InnoDB 事务执行 一致的读取操作。也就是说,查询其他事务正在更新的行,并查看发生这些更新之前的值。通过允许查询继续进行而无需等待其他事务持有的锁, 这是增加并发性的强大技术 。
此技术在数据库领域并不普遍。其他一些数据库产品和其他一些MySQL存储引擎不支持它。

InnoDB是一个 多版本的存储引擎:它保留有关已更改行的旧版本的信息,以支持诸如并发和回滚之类的事务功能 。此信息存储在表空间中的数据结构中,该数据结构称为 回滚段(在Oracle中类似的数据结构之后)。InnoDB 使用回滚段中的信息来执行事务回滚中所需的撤消操作。它还使用该信息来构建行的早期版本,以实现 一致的读取。

在内部,InnoDB向数据库中存储的每一行添加三个字段。6个字节的DB_TRX_ID字段表示插入或更新该行的最后一个事务的事务标识符。同样,删除在内部被视为更新,在该更新中,行中的特殊位被设置为将其标记为已删除。
每行还包含一个7字节的 DB_ROLL_PTR字段,称为滚动指针。
回滚指针指向写入回滚段的撤消日志记录。如果行已更新,则撤消日志记录将包含在更新行之前重建行内容所必需的信息。

一个6字节的DB_ROW_ID字段包含一个行ID,该行ID随着插入新行而单调增加。如果 InnoDB自动生成聚集索引,该索引包含行ID值。否则,该 DB_ROW_ID列不会出现在任何索引中。

回滚段中的撤消日志分为插入和更新撤消日志。插入撤消日志仅在事务回滚时才需要,并且在事务提交后可以立即将其丢弃。更新撤消日志也用于一致的读取中,但是只有在不存在为其InnoDB分配了快照的事务( 一致的读取可能需要更新撤消日志中的信息来构建数据库的早期版本)后,才可以将其删除行。

定期提交您的事务,包括仅发出一致读取的事务。否则, InnoDB将无法丢弃更新撤消日志中的数据,并且回滚段可能会变得太大而填满表空间。

回滚段中的撤消日志记录的物理大小通常小于相应的插入或更新的行。您可以使用此信息来计算回滚段所需的空间。

在InnoDB多版本方案中,当您使用SQL语句删除行时,并不会立即将其从数据库中物理删除。InnoDB仅在丢弃为删除而编写的更新撤消日志记录时,才物理删除相应的行及其索引记录。此删除操作称为purge,它非常快,通常花费与执行删除操作的SQL语句相同的时间顺序。

如果您以大约相同的速率在表中以较小的批次插入和删除行,则由于所有“ 死 ”行,清除线程可能开始滞后并且表可能会变得越来越大 ,从而使所有内容都受磁盘约束慢。在这种情况下,请限制新行的操作,并通过调整innodb_max_purge_lag系统变量来向清除线程分配更多资源 。有关更多信息,请参见第14.15节“ InnoDB启动选项和系统变量”。

多版本索引和二级索引

InnoDB多版本并发控制(MVCC)对二级索引的处理方式不同于聚簇索引。聚簇索引中的记录将就地更新,其隐藏的系统列指向撤消日志条目,可以从中重建记录的早期版本。与聚簇索引记录不同,辅助索引记录不包含隐藏的系统列,也不会就地更新。

更新二级索引列时,将对旧的二级索引记录进行删除标记,将新记录插入,并最终清除带有删除标记的记录。当二级索引记录被删除标记或二级索引页被较新的事务更新时,InnoDB在聚集索引中查找数据库记录。在聚集索引中,DB_TRX_ID检查记录的记录,如果在启动读取事务后修改了记录,则从撤消日志中检索记录的正确版本。

如果二级索引记录被标记为删除或二级索引页被更新的事务更新, 则不使用覆盖索引技术。而不是从索引结构中返回值,而是InnoDB在聚集索引中查找记录。

但是,如果启用了 索引条件下推(ICP)优化,并且WHERE只能使用索引中的字段来评估部分条件,则MySQL服务器仍会将WHERE条件的这一部分下推到存储引擎,并使用指数。如果找不到匹配的记录,则避免聚集索引查找。如果找到了匹配的记录,即使在删除标记的记录中,也要在 InnoDB聚簇索引中查找记录。

你可能感兴趣的:(mysql,mysql,mvcc,innodb)