锁是数据库区别与文件系统的一个关键特性。
数据库使用锁是为了支持对共享资源进行并发访问,提供数据的完整性和一致性。
对于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,这里就不展开细说了,有兴趣的可以下去自行查找。