• 5、MySql 全局锁、表锁、行锁


    5、MySql全局锁、表锁、行锁

    全局锁

    全局锁就是对整个数据库实例加锁。MySQL 提供了一个加全局读锁的方法,命令是 Flush tables with read lock (FTWRL)。当你需要让整个库处于只读状态的时候,可以使用这个命令,之后其他线程的以下语句会被阻塞:数据更新语句(数据的增删改)、数据定义语句(包括建表、修改表结构等)和更新类事务的提交语句。全局锁的典型使用场景是,做全库逻辑备份。

    表级锁

    MySQL 里面表级别的锁有两种:一种是表锁,一种是元数据锁(meta data lock,MDL)。

    表锁:表锁的语法是 lock tables … read/write。与 FTWRL 类似,可以用 unlock tables 主动释放锁,也可以在客户端断开的时候自动释放。需要注意,lock tables 语法除了会限制别的线程的读写外,也限定了本线程接下来的操作对象。

    **MDL(metadata lock):**MDL 不需要显式使用,在访问一个表的时候会被自动加上。MDL 的作用是,保证读写的正确性。如果一个查询正在遍历一个表中的数据,而执行期间另一个线程对这个表结构做变更,删了一列,那么查询线程拿到的结果跟表结构对不上,肯定是不行的。

    行锁

    MySQL 的行锁是在引擎层由各个引擎自己实现的。但并不是所有的引擎都支持行锁,比如 MyISAM 引擎就不支持行锁。不支持行锁意味着并发控制只能使用表锁,对于这种引擎的表,同一张表上任何时刻只能有一个更新在执行,这就会影响到业务并发度。InnoDB 是支持行锁的,这也是 MyISAM 被 InnoDB 替代的重要原因之一。

    在 InnoDB 事务中,行锁是在需要的时候才加上的,但并不是不需要了就立刻释放,而是要等到事务结束时才释放。这个就是两阶段锁协议。

    如果事务中需要锁多个行,要把最可能造成锁冲突、最可能影响并发度的锁尽量往后放。

    死锁和死锁检测

    当并发系统中不同线程出现循环资源依赖,涉及的线程都在等待别的线程释放资源时,就会导致这几个线程都进入无限等待的状态,称为死锁。

    当出现死锁以后,有两种策略:

    **一种策略是,**直接进入等待,直到超时。这个超时时间可以通过参数 innodb_lock_wait_timeout 来设置。

    另一种策略是,发起死锁检测,发现死锁后,主动回滚死锁链条中的某一个事务,让其他事务得以继续执行。将参数 innodb_deadlock_detect 设置为 on,表示开启这个逻辑。

    备注

    读锁之间不互斥,因此你可以有多个线程同时对一张表增删改查。读写锁之间、写锁之间是互斥的,用来保证变更表结构操作的安全性。因此,如果有两个线程要同时给一个表加字段,其中一个要等另一个执行完才能开始执行。

    全局锁主要用在逻辑备份过程中。对于全部是 InnoDB 引擎的库,建议使用–single-transaction 参数,对应用会更友好。

    MDL 会直到事务提交才释放,在做表结构变更的时候,要小心不要导致锁住线上查询和更新。

  • 相关阅读:
    php安装ldap扩展模块
    如何设计一份问卷?
    Java杨辉三角
    编写虚拟UART驱动程序-框架
    el-date-picker 日期时间选择器 限时时间范围 精确到时分秒
    看文章-做笔记
    关于C++11静态成员变量的类内初始化
    Maxwell 一款简单易上手的实时抓取Mysql数据的软件
    PTA题目 两个数的简单计算器
    优优嗨聚集团:旅游经济繁荣,助力当地外卖市场崛起
  • 原文地址:https://blog.csdn.net/NanyouqiaoMu_/article/details/126183310