文章目录
锁
lock 与 latch
- latch
- 轻量级锁,要求遂定时间非常短
- 分为mutex(互斥量),rwlock(读写锁)
- 目的是保证并发线程操作临界资源的正确性,通常没有死锁检测机制
- lock
- 对象是事务,用于锁定数据库中的对象
- 具有死锁机制
- 比较
innodb中的锁
锁的类型
-
共享锁 S :允许事务读取一行数据
-
排他锁 X :允许事务删除或更新一行数据
-
兼容性
-
意向锁
-
特性
- InnoDB存储引擎支持意向锁设计比较简练,其意向锁即为表级别的锁
- 由于InnoDB支持的是行级别的锁,因此意向锁其实不会阻塞除全表扫以外的任何请求
-
目的
- 为了在一个事务中揭示下一行将被请求的锁类型
- 为了支持在不同粒度锁定上进行加锁操作
-
意向共享锁 IS :事务想要获取一张表中的某几行的共享锁
-
意向排他锁 IX :事务想要获取一张表中的某几行的排他锁
-
-
兼容性
一致性非锁定读
- 概念
- 指通过多版本控制的方式读取点给钱执行时间数据库中行数据
- 如果读取的行正在del或update操作,读出操作会去读取行的快照数据而不需要等待行上的锁的释放
- 每个事务隔离级别下读出方式不尽相同,即使都是一致性非锁定读,对快照数据的定义也不尽相同
- 优点
- 极大提高了数据库的并发性
一致性锁定读
- 某些情况下,用户需要显示对数据库读取操作进行加锁以保证数据逻辑的一致性
- innodb对select语句支持的两种一致性锁定读操作
- select … for update (X)
- select … lock in share mode (S)
- 两条语句必须在一个事务中,当事务提交,锁也就释放
自增长与锁
-
AUTO-INC Locking
- 概念: 对每个含有自增值表存在一个自增长计时器,进行插入操作时 select MAX(auto_inc_col) from t for update 依据这个计数器加一赋予自增长列
- 采用一种特殊的表锁机制,为了提高插入性能,锁不是在一个事务完成后才释放,而是在完成对自增长值插入的sql后立即释放
- 问题:
- 对于有自增长值的列的并发插入性能较差,事务必须等待前一个插入的完成
- 对于insert … select的大数据量插入会影响插入性能,因为另一个事务中的插入会被阻塞
-
轻量级互斥量自增实现机制
-
引入innodb_autoinc_lock_mode控制自增长模式
-
自增插入类型
-
-
注意
- innodb下自增长值的列必须是索引, 同时必须是索引的第一个列
外键与锁
- 对于外键如果没有显式增加索引,会自动添加索引,这样可以避免表锁
- 外键插入或更新时需要select父表,select父表操作时使用select … lock in share mode一致性锁定读,来保证数据一致性
锁算法
行锁的三种算法
- Record Lock 单个行记录上的锁
- 总是锁定索引记录,如果建表时没有设置任何索引,将使用隐式的主键进行索引
- Gop Lock 间隙锁,锁定一个范围,但不包含记录本身
- Next-Key Lock Gop Lock + Record Lock,锁定一个范围,并锁定记录本身
- 结合 Gop Lock + Record Lock的锁定算法, 为了解决Phantom Problem(幻像问题)
- 当查询的索引含有唯一属性时,innodb会对next-key lcok进行优化,降级为Record Lock, 提高应用并发性
解决 Phantom Problem
- 概念
- Phantom Problem指在同以事务下,连续执行两次同样的sql语句可能导致不同的结果,第二次的sql语句可能返回之前不存在的行
- 解决
- 在repeatable read下,innodb采用Next-Key Locking机制来避免
锁问题
脏读
- 脏数据: 指未提交的数据
- 脏读: 在不同事务下,当前事务可以读取到另一个事务未提交的数据
不可重复读
- 不可重复读: 在一个事务中多次读取同一数据集合,在这个事务还没有结束时,另一个事务也访问同一数据集合,并做一些DML操作,因此第一个事务两次读取数据之间,由于第二个事务的修改,导致两次读取数据不同
- 通过Next-Key Locking机制来避免,将不可重复读定义为Phantom Problem
丢失更新
- 丢失更新: 一个事务的更新操作被另一个事务的更新操作覆盖,导致数据不一致
- 在当前数据库任何隔离级别下,都不会导致数据库理论意义上的丢失更新问题
- 生产应用中可能发生逻辑意义上的丢失更新问题
阻塞
- 因为不同锁的兼容性关系,在有些时刻一个事务中的锁需要等待另一个事务中的锁释放他所占的资源
死锁
概念
- 死锁是指两个或以上的事务在执行过程中,因争夺资源而造成的一种相互等待的现象
- 解决死锁方式
- 任何等待进行回滚
- 超时控制
- wait-for graph(等待图) innodb采用的方式