锁的算法
Record Lock:单个行记录上的锁
- 通过主键索引,锁定单行
- read committed隔离级别下采用。
Geo Lock:间隙锁,锁定一个范围但不包含本身
- 可以防止多个多个事务将记录插入到同一个范围内(Phantom Problem)
- 对于唯一键值对的锁定,GeoLock会降级为Record Lock。
Next-Key Lock:Geo Lock+Record Lock,锁定一个范围并锁定记录本身
- 在同一事务下,连续执行两次sql语句可能导致不同的结果。第二次的sql可能会返回之前不存在的行
- 例如,假设表里有id为1,2,5三条记录,对于select * from table where id >2 for update语句,Next-Key Lock锁定的不止是5这一行,而是[2,+∞]。
- repeatable read隔离级别采用
数据问题
Dirty Read(脏读问题)
- 一个事务中读到了另一个事务中未提交的数据,违反了数据库隔离性,隔离级别read uncommitted。
Phantom Problem(幻读问题)
- 在同一事务下,连续执行两次sql语句可能导致不同的结果。第二次的sql可能会返回之前不存在的行。
- repeatable read隔离级别下,Innodb采用Next-Key Lock对查询区域进行枷锁解决幻读问题。
不可重复读
- 一个事务中读到了另一个事务中未提交的数据,违反了数据库一致性。
- 一般情况下,读到的都是已提交的数据,很多厂商默认隔离级别就是read committed。
- MYSQL官方文档将不可重复读定义为Phantom Problem(幻读),通过Next-Key Lock来解决幻读问题。
- Next-Key Lock不仅锁住了扫描到的索引,同时锁住了索引的覆盖范围。
丢失更新
- T1事务提交的更新操作被T2事务的更新覆盖掉。
- 物理丢失更新不会出现,因为T2事务的操作会被T1阻塞。
- 逻辑丢失可能会出现:所有操作添加X排他锁,数据库串行化。
阻塞
- T2事务需要等待T1事务释放资源后再进行资源占有。
死锁
- 两个或以上的事务因争夺资源造成的互相等待现象。
-
解决方案:
- 超时回滚:当超时的事务所占权重较大或事务更新了较多行,undolog较大时回滚所用时间较长。
-
wait-for graph(等待图) 死锁检测方式:
- 等待图存储了锁的信息链表和事务等待链表,通过深度优先搜索进行递归排查。
- 查到后选择undolog较小的事务进行回滚。
锁升级
- 如果数据库设计者认为锁是一种稀缺资源,则会出现1000个行锁升级为页锁,页锁升级为表锁现象。
- Innodb没有锁升级。因为每个事务都是对页进行管理,且采用的是位图存储的方式。锁开销较小。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。