简介

InnoDB在MySQL 5.5版本代替MyISAM成为默认的存储引擎,这也是Oracle收购Sun之后发布的首个版本。InnoDB采用MVCC(多版本并发控制)来支持高并发,并且实现了四个标准的隔离级别,默认级别是REPEAABLE READ(可重复读),并且通过间隙锁(next-key locking)策略防止幻读的出现。InnoDB表是基于聚簇索引建立的,对于主键查询有很高的性能。这篇博客重点记录一下MVCC和聚簇索引。

MVCC

MVCC(多版本并发控制)可以认为是行级锁的一个变种,但是它在很多情况下避免了加锁操作,因此开销更低。
InnoDB的MVCC,是通过在每行记录后面保存两个隐藏的列来实现的。这两个列保存了行的创建时间和删除时间,但存储的并不是实际的时间值,而是系统版本号。版本号随着事务的操作逐渐递增,通过将当前版本号与版本号比较来判断操作是否合法。具体的操作如下。

SELECT

InnoDB会根据以下两个条件检查每行记录:

  1. InnoDB只查找版本号早于当前事务版本的数据行(这就保证了此行数据要么是事务开始之前已经存在的,要么是事务自身插入或者修改过的)。
  2. 行的删除要么未定义,要么大于当前版本号(意味着有一个并发事务把这条数据删除了)。这可以确保事务读取到的行,在事务开始之前未被删除。

只有符合上述两个条件的记录,才能返回作为查询结果。

INSERT

InnoDB为新插入的每一行数据保存当前系统版本号作为行版本号。

DELETE

InnoDB为删除的每一行数据保存当前系统版本号作为行删除标识。

UPDATE

注意此时的UPDATE命令实际上是执行了“DELETE + INSERT”。将旧行的删除版本号设置为当前版本号,并将新行INSERT同时设置创建版本号为当前版本号。

另外从网上一篇博客上看到,由于旧数据并不真正的删除,所以必须对这些数据进行清理,innodb会开启一个后台线程执行清理工作,具体的规则是将删除版本号小于当前系统版本的行删除,这个过程叫做purge。

聚簇索引


在《数据库原理》里面,对聚簇索引的解释是:聚簇索引的顺序就是数据的物理存储顺序。而在InnoDB中的聚簇索引实际上在同一个结构中保存了B-Tree索引和数据行。
在聚簇索引中,数据行和相邻的键值紧凑的存储在一起,因为无法同时把数据行存在两个不同的地方,所以一个表只能有一个聚簇索引。表中行的物理顺序和索引中行的物理顺序是相同的,在创建任何非聚簇索引之前创建聚簇索引,这是因为聚簇索引改变了表中行的物理顺序,数据行按照一定的顺序排列,并且自动维护这个顺序。
聚簇索引默认是主键,如果表中没有定义主键,InnoDB 会选择一个唯一且非空的索引代替。一般来说使用int型自增变量作为主键方便排序并且默认会在索引树的末尾增加主键值,对索引树的结构影响最小

以上只是聚簇索引的一些基本知识,具体实现鸽一篇博客。

怎样选择存储引擎

MySQL有很多种类的引擎。在大部分情况下,InnoDB都是正确的选择,支持行级锁、事务、事务安全等。但是如果是查询占了服务的大多数时间时可以考虑MyISAM,像是日志等。不过相比于选择存储引擎,我们更应该考虑避免在服务中混合使用存储引擎。如果混合使用了支持事务和不支持事务的表,在正常提交时不会有什么问题,但如果该事务需要回滚,非事务的表的操作变更就无法撤销,这会导致数据库数据处于不一致状态。

Last modification:March 28th, 2020 at 03:19 pm
如果觉得我的文章对你有用,请随意赞赏