高性能mysql
在InnoDB中,会在每行数据后添加两个额外的隐藏的值来实现MVCC,这两个值一个记录这行数据何时被创建,另外一个记录这行数据何时过期(或者被删除)。 在实际操作中,存储的并不是时间,而是系统的版本号,每开启一个新事务,系统的版本号就会递增。 在可重读Repeatable reads事务隔离级别下:
SELECT时,读取创建版本号<=当前事务版本号,删除版本号为空或>当前事务版本号。
INSERT时,保存当前事务版本号为行的创建版本号。
DELETE时,保存当前事务版本号为行的删除版本号。
UPDATE时,插入一条新纪录,保存当前事务版本号为行创建版本号,同时保存当前事务版本号到原来删除的行。
通过MVCC,虽然每行记录都需要额外的存储空间,更多的行检查工作以及一些额外的维护工作,但可以减少锁的使用,大多数读操作都不用加锁,读数据操作很简单,性能很好,并且也能保证只会读取到符合标准的行,也只锁住必要行。
这是来自高性能mysql的一段MVCC的解释,于是我搜索资料发现大部分都是这么讲的,于是我就去官方网站查了一下MVCC的文档,其实它的实现是靠增加的3个字段来实现的。
简而言之,一共三个字段DB_TRX_ID(事务的ID号) ,DB_ROLL_PTR(滚动指针),DB_ROW_ID(行ID)。
- DB_TRX_ID(事务的ID号),用事务的ID来表明指针以实现快照读。对应于系统版本号
- DB_ROLL_PTR(滚动指针),用来指出回滚log记录,就是用来回滚的
- DB_ROW_ID(行ID),每insert一行就会给一个ID号。也就是说的创建时间
由MVCC带来的思考
MVCC实现了事务的隔离性,因为是快照读,别的事务进行添加等操作打上的id号不是早于当前事务的就不会被select。那么快照读的时候幻读的避免也是因为MVCC,事务开启的时候,由事务本身进行的更改操作能被事务本身察觉的原因也是MVCC的原理。那么事务的一些特性就一下子清楚了。