MySQL 锁

作者: 3fc28cd0576c | 来源:发表于2020-10-29 09:49 被阅读0次

    锁的类别

    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 不存在锁升级,根据事务对每个页进行锁管理,采用位图实现,开销小)

    相关文章

      网友评论

          本文标题:MySQL 锁

          本文链接:https://www.haomeiwen.com/subject/qzqcvktx.html