mysql-锁

作者: IT雪山 | 来源:发表于2021-03-31 16:31 被阅读0次

    一 什么是锁

    锁机制用于管理对公共资源的并发访问。

    1.1 优点

    数据是一种供多用户共享的资源,保证数据并发访问的一致性,有效性

    1.2 缺点

    加锁是消耗资源的,锁的各种操作,包括获得锁、检测锁是否已解除、释放锁等 ,都会增加系统的开销。

    1.3 两段锁

    数据库遵循的是两段锁协议,将事务分成两个阶段,加锁阶段和解锁阶段(所以叫两段锁)

    • 加锁阶段:在该阶段可以进行加锁操作。在对任何数据进行读操作之前要申请并获得S锁(共享锁,其它事务可以继续加共享锁,但不能加排它锁),在进行写操作之前要申请并获得X锁(排它锁,其它事务不能再获得任何锁)。加锁不成功,则事务进入等待状态,直到加锁成功才继续执行。
    • 解锁阶段:当事务释放了一个封锁以后,事务进入解锁阶段,在该阶段只能进行解锁操作不能再进行加锁操作。


      截屏2021-04-01 10.45.38.png

      这种方式虽然无法避免死锁,但是两段锁协议可以保证事务的并发调度是串行化(串行化很重要,尤其是在数据恢复和备份的时候)的。

    1.4 隔离级别

    在数据库操作中,为了有效保证并发读取数据的正确性,提出的事务隔离级别。我们的数据库锁,也是为了构建这些隔离级别存在的。


    截屏2021-04-01 10.51.42.png
    • 未提交读(Read Uncommitted):允许脏读,也就是可能读取到其他会话中未提交事务修改的数据
    • 提交读(Read Committed):只能读取到已经提交的数据。Oracle等多数数据库默认都是该级别 (不重复读)
    • 可重复读(Repeated Read):可重复读。在同一个事务内的查询都是事务开始时刻一致的,InnoDB默认级别。在SQL标准中,该隔离级别消除了不可重复读,但是还存在幻象读
    • 串行读(Serializable):完全串行化的读,每次读都需要获得表级共享锁,读写相互都会阻塞

    查看事务的隔离级别(注意:polardb用的是READ-COMMITTED)
    select @@global.transaction_isolation;
    select @@global.tx_isolation;

    二 锁分类

    2.1表锁

    2.1.1 特点

    由MySQL SQL layer层实现,表锁是对整张表加锁,开销小,加锁快,无死锁,锁粒度大,发送锁冲突概率极高,并发性极低(myisam引擎是表锁,并发读没有问题,并发插入性能会差一些)

    2.1.2 分类

    1 表锁
    2 元数据锁(meta data lock, MDL)
    在 MySQL 5.5 版本中引入了 MDL,当对一个表做增删改查操作的时候,加 MDL 读锁;当要对表做结
    构变更操作的时候,加 MDL 写锁。

    1、session1: 
    begin;--开启事务 
    select * from mylock;--加MDL读锁 
    2、session2: 
    alter table mylock add f int; -- 修改阻塞 
    3、session1:commit; --提交事务 或者 rollback 释放读锁 
    4、session2:Query OK, 0 rows affected (38.67 sec) --修改完成 Records: 0 Duplicates: 0 Warnings: 0
    

    MySQL 实现的表级锁定的争用状态变量


    截屏2021-03-31 15.43.56.png
    • table_locks_immediate:产生表级锁定的次数(包括意向锁 ,可能很大,一般不看这个);
    • table_locks_waited:出现表级锁定争用而发生等待的次数;、

    show open tables:
    查看哪个表被锁住 in_use

    2.2页锁

    加锁时间和锁粒度介于表锁和行锁之间,会出现死锁,并发处理能力一般

    2.3行锁

    2.3.1 分类

    InnoDB存储引擎实现, 行锁很重要本章重点研究行锁
    InnoDB的行级锁,按照锁定范围来说,分为三种:
    记录锁(Record Locks):锁定索引中一条记录。 主键指定 where id=3
    间隙锁(Gap Locks): 锁定记录前、记录中、记录后的行 RR隔离级 (可重复读)-- MySQL默认隔离级
    Next-Key 锁: 记录锁 + 间隙锁

    按照功能来说,分为两种:
    共享读锁(S):允许一个事务去读一行,阻止其他事务获得相同数据集的排他锁。
    排他写锁(X):允许获得排他写锁的事务更新数据,阻止其他事务取得相同数据集的共享读锁(不是读)和排他写锁。

    2.3.2 示例

    对表执行新增、修改、删除,或者select ...for update时,会触发数据库的锁机制
    InnoDB行锁是通过给索引上的索引项加锁来实现的,因此InnoDB这种行锁实现特点意味着:只有通过
    索引条件检索的数据,InnoDB才使用行级锁,否则,InnoDB将使用表锁!
    where 索引 行锁 否则 表锁

    相关文章

      网友评论

        本文标题:mysql-锁

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