MySQL 锁

2020-10-29  本文已影响0人  3fc28cd0576c

锁的类别

1.表锁(MyISAM)

2.行锁(InnoDB)

S 锁:共享锁,允许事务读取一条数据

X锁:排他锁,允许事务删除或更新一条数据

S锁仅与S锁兼容,X锁与所有锁都不兼容

InnoDB 锁

一致性非锁定读

InnoDB 如果要读取某一行的数据,如果该行正在进行DELETE 或者 UPDATE 操作,不会等待该行锁释放,而是通过undo去读取一个快照,一行数据可能有多个快照,这就是MVCC(多版本并发控制),提高并发。

在 READ CIMMITED 隔离级别下:读取的总是最新版本的快照(造成不可重复读),违法了隔离性

在 REPEATABLE READ 隔离级别下:读取的总是事务开始的数据快照(解决了不可重复读的问题,既可重复读)

一致性锁定读

两种实现方式:

1)SELECT...FOR UPDATE 给读取的行加X锁

2) SELECT...FOR SHARE MODE 给读取的行加S锁

两种方式不影响非一致性读,在事务提交时自动释放

自增长和锁

1)以前用表锁的AUTO-INC Locking 实现,不会等事务提交,只要插入就会释放,存在性能问题

外键与锁

外键会自动加上索引,避免表锁

锁的算法

Record Lock :单个行记录上的锁

Gap Lock:间隙锁,锁定一个范围,但不包括该行记录

Next-Key Lock:Gap Lock + Record Lock,锁定一个范围,并且锁定该记录

InnoDB 采用Next-Key Lock 算法,当查询的索引列有唯一属性时,会降级为Recod Lock ,只锁定该行,不锁定范围

锁带来的问题

1.脏读:读取到未提交的数据(设置为READ COMMITED解决)

2.不可重复读:一次事务中两次读取到的数据不一致,违反了隔离性(设置为 REPEATABLE READ ,采用 Next-Key Lock锁定一段个范围,在这个范围内的插入都是阻塞的。解决)

3.丢失更新:物理不会出现,逻辑出现。

阻塞

阻塞超时,不会回滚数据

死锁

死锁是因为两个事务争抢同一个资源而造成相互等待。

解决死锁:

1):回滚所有事务,性能急剧下降,不可接受

2):超时回滚:也会有性能影响

3):当前数据库普遍采用 wait-for graph (等待图)实现,检测死锁,如果存在就选择undo段最小的事务进行回滚

锁升级(InnoDB 不存在锁升级,根据事务对每个页进行锁管理,采用位图实现,开销小)

上一篇下一篇

猜你喜欢

热点阅读