InnoDB 的行锁定与 MVCC 非阻塞读取相同吗?

Mat*_*tty 4 mysql innodb

MVCC Non-Blocking Reads 是 InnoDB 行锁定的正式名称吗?我在InnoDB 和 NDB的比较表中遇到过这个词汇;我不确定它们是相同的东西还是完全不同的东西。

Bil*_*win 5

MVCC 非阻塞读取在某种程度上是没有锁定。MVCC 使一个或多个读取器能够获得对数据的可重复读取访问,即使写入器正在更新相同的行。在这种情况下不需要锁定。

例如,如果我更改某行,InnoDB 会立即创建该行旧版本的副本。您读取该数据的并发事务可以继续读取副本。只要您的交易持续,该旧版本就会保留在数据库中。

如果您开始一个新事务,您将看到该行最近提交的版本,而旧版本最终会被垃圾回收,从而回收一些空间。

锁定用于当多个作者试图更新相同的行时。一次只有一个作者可以更新一行,第一个更新行的人会锁定它,直到他们提交更改。其他作家必须等到第一个作家提交。但至少对于行级锁定,它们只有在更新同一行时才会发生争用。

学习更多关于 InnoDB 并发和锁定的好资源是高性能 MySQL,第 3 版。


来自@AlexYakunin 的评论:

任意数量的并发线程都可以在同一行上获取共享锁。但是排他锁要求不存在任何类型的锁——一次只有一个线程可以获得排他锁。

UPDATE 总是请求排他锁,这是更常见的情况。共享锁用于 InnoDB 中一些更奇特的情况:

  • 我更新了一个具有父表外键的子行。我在子行上得到一个 X 锁,在父行上得到一个 S 锁。基本上,当我更新依赖于父行的行时,没有人可以更新父行。

  • SELECT ... LOCK IN SHARE MODE在阅读时明确使用来阻止对某些行的更新。这通常不是必需的。

  • SELECT在事务隔离级别为SERIALIZABLE(这并不常见)时执行任何操作。

  • 我发出导致重复键错误的 INSERT,我的线程请求行上的共享锁。

有关更多详细信息和示例,请参阅http://dev.mysql.com/doc/refman/5.6/en/innodb-locks-set.html