Innodb MVCC工做原理

《MySQL》高性能的说法:html

为什么须要MVCC
mysql

        对于事务型的存储引擎实现,仅仅依赖锁是不够的,还须要MVCC(Multiversion Concurrency Control )的帮助,能够简单的将MVCC理解成为一个row lock的一个变种,只是在必要的时候加行锁。
sql

InnoDB的MVCC实现方式数据库

        每一个事物存储引擎的MVCC实现方式是不同的,InnoDB的MVCC简单来说是经过给表添加两列隐藏列。
数据结构

        一列(建立列)存储行的insert(若是行不存在)时间或者update(若是行已存在)时间,一列存储行的删除时间,固然,这里的时间并不是咱们所说的时分秒,而是系统版本号(system version number),列存储的SVN是事物开始时刻的SVN,每开始一个新的事物,SVN号递增。
并发

MVCC只有在隔离级别是READ COMMITED(Oracle默认)和REPEATABLE READ(MySQL默认)两个隔离级别下工做。性能

如今讨论在REPEATABLE READ下的MVCC实现:this

SELECTspa

        a. Innodb查找SVN小于等于当前事物的SVN的行,若是是小于,说明行以前就已经存在,若是是等于,说明这行是事物自己修改过的.线程

        b.行的删除时间列要么为空(说明该行未被删除)要么删除时间列的SVN大于当前事物的SVN(表示行是在事物开始以后被删除的).

只有记录知足以上两条,才会被select语句返回!


Insert

        插入以后以当前事物的SVN号更新建立列

Delete

        删除以后,用当前SVN更新删除列

Update

        更新建立列为当前SVN,同时更新删除列为update以前的建立列的SVN值

这样设计的优势是大部分的读操做都不用加锁了,使数据库操做简单,性能好,不足之处是增长了存储开销,须要额外的维护工做

查阅5.5的官方文档,关于MVCC的介绍是这样的:

InnoDB的MVCC是经过保存旧版本的修改信息来实现事物的并发控制和回滚。这些信息以一种数据结构的形式保存在表空间中,这种数据结构就是“rollback segment”回滚段能够提供两项功能:回滚,一致性读。

与MVCC相关的元素

DB_TRX_ID:占6字节,用来标识最近一次修改(insert|update)行的事物的标识符,至于delete操做,在innodb看来也不过是一次update操做,更新行中的一个特殊位将行表示为deleted。并不是真正删除。

DB_ROLL_PTR:占用7个字节,滚动指针指向回滚段中的对应回滚日志记录,如何update一行,那么改行旧的信息就会被保存到指针所指向的回滚段中。

DB_ROW_ID:该值随行数的增多而增长,若是是cluster index,会包含这列,其余索引则不会有这列。

对于回滚段的管理:

        Insert Logs:当事物被提交时,所保存的insert 回滚记录就能够被删除

        Update Logs:这个日志不单单在rollback时须要,在一致性读也须要,因此不能随便删除,只有当数据库所使用的快照中不涉及该日志记录,对应的回滚日志才能够删除。


回滚段的管理指导:

常常将一些事务提交,包括哪些只发出一致性读的事务,不然InnoDB没法删除回滚段中的 undo update logs,这将致使回滚段增加过快直到填满表空间。

在InnoDB中,发出Delete语句以后,改行并不会马上被物理的从数据库中删除,只有当对应的行update undo logs被删除以后,才会被物理的删除(purge)purge操做很快,时间等于delete所用时间。

有个问题:在频繁的进行小规模的插入和删除操做,purge线程将会滞后。由于没法删除这些被标记为deleted的行,这会致使表愈来愈大,致使磁盘瓶颈,性能降低。

解决办法:限制新行的操做,分配更多的资源给purge线程。涉及参数innodb_max_purge_lag

当purge_lags表示有多少通过delete或者update操做被标记为deleted的行,没有被purge,若是该值超过了innodb_max_purge_lag值,则delete和insert,update操做将会被挂起。


The InnoDB transaction system maintains a list of transactions that have index records delete-marked by UPDATEor DELETE operations. The length of this list represents the purge_lag value. When purge_lag exceedsinnodb_max_purge_lag, each INSERTUPDATE, and DELETE operation is delayed by ((purge_lag/innodb_max_purge_lag)×10)–5 milliseconds. The delay is computed in the beginning of a purge batch, every ten seconds. The operations are not delayed if purge cannot run because of an old consistent readview that could see the rows to be purged.

root@localhost>show engine innodb status\G
------------
TRANSACTIONS
------------
Trx id counter 9652
Purge done for trx's n:o < 7965 undo n:o < 0 state: running but idle
History list length 17
LIST OF TRANSACTIONS FOR EACH SESSION:
---TRANSACTION 0, not started
MySQL thread id 13, OS thread handle 0x8effdb70, query id 361 localhost root init
show engine innodb status
相关文章
相关标签/搜索