锁是数据库区别与文件系统的一个关键特性。

数据库使用锁是为了支持对共享资源进行并发访问,提供数据的完整性和一致性。

对于MyISAM引擎,其锁是表锁设计。

InnoDB存储引擎锁的实现和Oracle数据库非常类似,提供一致性的非锁定读、行级锁支持。行级锁没有相关额外的开销,并可以同时得到并发性和一致性。

lock和latch

lock和latch是两个比较容易混淆的概念,在数据库中两者都可以称为“锁”,但两者的含义截然不同。

latch一般被称为闩锁(轻量级锁),因为其要求锁定的时间必须非常短,若持续时间长,则性能会非常差。在InnoDB引擎中,latch又可以分为mutex(互斥量)和rwlock(读写锁)。其目的是用来保证并发线程操作临界资源的正确性,并且通常没有死锁检测的机制。

lock的对象是事务,用来锁定的是数据库中的对象,入表、页、行。并且一般lock对象仅在事务commit获rollback后进行释放。此外,lock是有死锁机制的。

lock和latch的比较

lock

latch

对象

事务

线程

保护

数据库内容

内存数据结构

持续时间

整个事务

临界资源

模式

行锁、表锁、意向锁

读写锁,互斥量

死锁

通过waits-for graph、time out 等机制进行死锁检测

无死锁检测与处理机制。仅通过应用程序加锁的顺序保证无死锁发生

存在于

Lock Manager的哈希表中

每个数据结构的对象中

InnoDB存储引擎中的锁

锁的类型

InnoDB中有两种标准的行级锁:

  • 共享锁(S Lock),允许事务读一行数据。
  • 排他锁(X Lock),允许事务删除获更新一行数据。

S和X锁都是行锁,兼容是指对同一记录锁的兼容性情况。另外,InnoDB引擎支持多粒度锁定,所以InnoDB支持一种额外的锁方式,意向锁(I Lock)。意向锁是讲锁定的对象分为多个层次,意向锁意味着事务希望在更细粒度上进行加锁。

两种意向锁:

意向共享锁(IS Lock):事务想要获得一张表的某几行的共享锁。

意向排他锁(IX Lock):事务想要获得一张表中某几行的排他锁。

一致性非锁定读

如果读取的行正在执行DELETE或UPDATE操作,这时读取操作不会因此去等待行上锁的释放。相反的InnoDB回去读取行的一个快照数据。快照数据是指该行的之前版本的数据,是通过undo段来完成的,undo用来事务中数据的回滚,因为快照数据本身没有额外的开销。快照数据是不需要上锁的,因为没有事务需要对历史数据进行修改操作。

非锁定读机制极大的提高了数据库的并发性,是InnoDB引擎的默认设置,即读取不会占用和等待表上的锁。

一行记录可能有不止一个快照数据,一般称这中技术位行多版本技术,由此带来的并发控制称为多版本并发控制MVCC)。

要注意的是,不同的事物隔离级别,快照的定义不同:READ COMMITTED和REPEATABLE READ下,InnoDB存储引擎使用非锁定的一致性读。在READ COMMITTED下,快照数据是读取被锁行的最新一份快照数据;在REPEATABLE READ下,快照数据总是读取事物开始时的行数据版本

一致性锁定读

在某些情况下,用户需要显示的对数据库读操作进行加锁以保证数据逻辑的一致性。InnoDB存储引擎对于select语句支持两种一致性的锁定读操作:

  • SELECT...FOR UPDATE
  • SELECT...LOCK IN SHARE MODE

SELECT...FOR UPDATE对读取的行记录加一个X锁,其他事务不能对已锁定的行加上任何锁。SELECT...LOCK IN SHARE MODE对读取的行加一个S锁,其他事物可以想被锁定的行加S锁,但是如果加X锁,会被阻塞。

需要注意的是,以上两种锁定方式必须在一个事务中,当事务提交了,锁也就释放了,因此在使用上述两句select锁定语句时,务必加上BEGIN,START TRANSACTION 或者 SETAUTOCOMMIT = 0。

自增长与锁

在InnoDB存储引擎中,对每个含有自增长值的表都有一个自增长计数器(auto-increment counter)。当对含有自增长的计数器的表进行插入操作时,这个计数器会被初始化。

插入操作会依据这个自增长的计数器加1赋予自增长列。这个实现方式称作AUTO-INC Locking。这种锁其实是采用一种特殊的表锁机制,为了提高插入性能,锁不是在一个事务完成后才释放,而是在完成自增长值插入的SQL语句后就立即释放

在5.1.22版本后,InnoDB提供了一个参数innodb_autoinc_lock_mode来控制自增长的模式,默认为1。0则为5.1.22之前的方式,即通过表锁的方式。还有2,这里就不展开细说了,有兴趣的可以下去自行查找。