• Mysql 45讲学习笔记(六)全局锁


    一.全局锁:整个数据库实例加锁

    Mysql提供了一个加全局读锁的方法 命令是

    Flush tables with read lock(FTWRL) 

    当你需要让整个库出于只读状态,可以使用这个命令,其他线程的语句会被阻塞

    数据更新语句(数据的增删改查),

    数据定义语句(包括建表,修改表结构等)

    更新类事务的提交语句

    全局锁的典型使用场景--做全库逻辑备份

    也就是把整库每个表都select出来存成文本 备份过程中整个库处于只读状态,但是让整个库只读很危险

    • 主库备份,备份期间不能执行更新,业务基本停摆
    • 从库备份,备份期间从库不能执行主库同步过来的binlog,会导致主从延迟
    • 不加锁的话,备份系统备份的得到的库不是一个逻辑时间点,这个视图是逻辑不一致的。

    官方自带的逻辑备份工具是mysqldump

    当mysqldump,使用参数-single-transaction的时候,导数据之前都会启动一个事务,来确保拿到一致性视图

    由于MVCC这个数据时可以正常更新的。

    表级锁 MySql 里面表级别的锁有两种:

    • 一种是表锁,
    • 一种是元数据锁(meta data lock,MDL

    表锁的语法是 lock tables ...read/write。与FTWRL类似。可以用 unlock tables 主动释放锁。也可以在客户端断开的时候自动释放。

    需要注意 lock tables语法除了会限制别的线程读写外 也限定本线程接下来的操作对象

    • 举例子,如果在某个线程A执行 lock tables t1 t2 write 这个语句,则其他线程写t1,读写t2的语句都会被阻塞
    • 同时,线程A 在执行unlock tables之前也只能执行读t1,读写t2的操作。连写t1都不允许,自然也不能访问其他表。

    在还没有出现更细粒度的锁的时,表锁是最常用的处理并发的方式。

    二.表级锁是MDL(metadata lock)

    • MDL不需要显式使用,在访问一个表的时候会被自动加上
    • MDL的作用是,保证读写的正确性
    • 如果一个查询正在遍历一个表中的数据,而执行期另一个线程对这个表结构做变更,删了一列,那么查询线程拿到的结果跟表结构对不上,肯定不行。
    • 因此,在MySQL5.5版本引入MDL,当一个表在做增删改查操作的时候,加上MDL读锁,当要对表 做结构变更操作的时候,加上MDL写锁

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

    给一个小表加字段,导致整个库挂了

    • 事务中的MDL锁。在语句执行开始时申请,但是语句结束后也不会马上释放,而是会等整个事务提交后再释放。
    • 首先我们要解决长事务,事务不提交,就会一直占着MDL锁。在MySQL的information_schema库的innoDB_trx表中,你可以查到当前执行中的事务、
    • 你要做DDL变更的表刚好有长事务在执行,要考虑先暂停DDL或者kill掉长事务

    特殊场景

    如果你要变更的表是一个热点表,虽然数据量不大,但是上面的请求很频繁,而你不得不加个字段,你该怎么做

    • 在alert table语句设定等待时间,如果这个指定的等待时间能够拿到MDL写锁最好,拿不到也不要阻塞后面的业务语句,先放弃,之后开发人员或者DBA通过重试命令重复这个过程。










     

  • 相关阅读:
    关于深度学习一些疑惑的总结
    想要拿到手软的大厂offer必须要刷5遍这份5000页Java 最全技术栈手册
    SteamVR 2.x 关闭SteamVR弹窗提醒(16)
    水仙花数_pyhon实现
    [题] 差分矩阵 #差分
    POI知识【Java程序操作Excel】
    安装驱动提示错误“文件的哈希值不在指定的目录文件中”的解决方法
    数据库编程sqlite3库安装及使用
    数学王国找寻另一半:求一个整数的真因子总和,算法优化解决方案超时问题
    安卓手机如何使用第三方主题,制作专属自己喜好的主题
  • 原文地址:https://blog.csdn.net/weixin_42369687/article/details/125417497