锁机制用于管理对共享资源的并发访问,而数据库自己做为共享资源的集合,内部须要提供必定的锁机制来保证事务的隔离性。本文探讨的是MySQL(5.7)InnoDB引擎下的锁机制。html
共享锁也称为读锁,容许事务读一行数据。共享锁之间是兼容的,也就是说多个事务能够针对同一行数据加共享锁。mysql
共享锁也称为写锁,容许事务删除或更新一行数据。排他锁之间以及排他锁和共享锁是不兼容的。sql
表锁(table lock)对整个表加锁,影响表的全部记录数据库
行锁(row lock)并发
共享锁app
排他锁性能
由于表锁覆盖了行锁的数据,因此表锁和行锁也会产生冲突,为了方便检测表级锁和行级锁之间的冲突,就引入了意向锁。spa
表级锁兼容矩阵以下:code
Table-level lock type compatibility is summarized in the following matrix.orm
间隙锁(Gap Lock)是锁定索引记录之间的间隙,锁定在第一个以前或最后一个索引记录以后的间隙上。
能够经过如下两种方式显式关闭Gap Lock
Record Lock + Gap Lock 的结合
在InnoDB的默认的可重复读(REPEATABLE-READ)隔离级别下,存在如下的加锁规则:
Online DDL 修改表结构
Online DDL and pt-online-schema-change for some alter operations applied on a table contains 1,078,880 rows
隔离级别 | 脏 读 | 不可重复读 | 幻 读 |
---|---|---|---|
未提交读(Read uncommitted) | 可能 | 可能 | 可能 |
已提交读(Read committed) | 不可能 | 可能 | 可能 |
可重复读(Repeatable read) | 不可能 | 不可能 | 可能 |
可串行化(Serializable ) | 不可能 | 不可能 | 不可能 |
丢失更新分为两个层面
脏读指的是读取到其余事务未提交的数据,在读已提交及以上的隔离级别下就避免该问题。
不可重复读指的是同一事务下两次读取同一行的数据不一致。InnoDB使用的MVCC机制来实现的。
幻读指的是同一个事务下两次查询,返回的记录数不一致。InnoDB使用的MVCC机制和Next-Key Lock来实现的。
当发生锁定时,能够查下information_schema 库的相关表来查看事务的锁定状况来快速定位问题。
查看当前锁状况
SELECT
w.requesting_trx_id,
t1.trx_state,
t1.trx_query,
t1.trx_started,
t1.trx_wait_started,
w.requested_lock_id,
l1.lock_mode,
l1.lock_type,
l1.lock_table,
l1.lock_index,
l1.lock_data,
w.blocking_trx_id,
t2.trx_state,
w.blocking_lock_id,
l2.lock_mode,
l2.lock_type,
l2.lock_table,
l2.lock_index,
l2.lock_data
FROM
INNODB_LOCK_WAITS AS w
LEFT JOIN INNODB_TRX t1 ON w.requesting_trx_id = t1.trx_id
LEFT JOIN INNODB_TRX t2 ON w.blocking_trx_id = t2.trx_id
LEFT JOIN INNODB_LOCKS l1 ON w.requested_lock_id = l1.lock_id
LEFT JOIN INNODB_LOCKS l2 ON w.blocking_lock_id = l2.lock_id
WHERE
t1.trx_state = 'LOCK WAIT'
LIMIT 1;
复制代码