ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

全局锁、表锁

2022-01-04 23:34:19  阅读:209  来源: 互联网

标签:语句 事务 MDL lock 读锁 session 全局 表锁


全局锁

全局锁的典型使用场景是,做全库逻辑备份
历史做法:flush table with read lock;确保不会有其他线程对数据库做更新,然后对整个库做备份。

mysql> flush table with read lock;
Query OK, 0 rows affected (0.10 sec)

mysql> select * from t;
+----+------+------+
| id | c    | d    |
+----+------+------+
|  0 |    0 |    0 |
|  5 |    5 |    5 |
| 10 |   10 |   55 |
| 15 |   15 |   15 |
| 20 |   20 |   20 |
| 25 |   25 |   25 |
+----+------+------+
6 rows in set (0.01 sec)

mysql> update d set d = 99 where id = 0;
ERROR 1223 (HY000): Can't execute the query because you have a conflicting read lock

缺陷:

  • 备份期间都不能执行更新,业务基本上就得停摆;
  • 主从同步导致数据不一致

官方自带的逻辑备份工具是 mysqldump,mysqldump 使用参数–single-transaction 的时候,导数据之前就会启动一个事务,来确保拿到一致性视图。而由于 MVCC 的支持,这个过程中数据是可以正常更新的。

能够支持事务隔离的,就可以通过事务隔离的手段来做到,有的引擎不支持(如:MyISAM不支持),需要通过FTWRL来给全局上锁

为什么不用set global readonly=true?

  • readonly 的值会可能会被用来做其他逻辑,如:主备库判断
  • 异常机制差异(客户端发生异常断开,FTWRL会释放全局锁,整个库回到可以正常更新的状态,readonly 不会)

表级锁

表锁

语法:lock tables … read/write
解除:unlock tables

写锁(排他锁):自己能写
读锁(共享锁):都能读,不能写
在这里插入图片描述
对于 InnoDB 这种支持行锁的引擎,一般不使用 lock tables 命令来控制并发,毕竟锁住整个表的影响面还是太大。

MDL(metadata lock)

MDL(MySQL 5.5 版本中引入) 的作用是,保证读写的正确性,MDL 不需要显式使用,在访问一个表的时候会被自动加上。

  • 读锁:对一个表做增删改查操作的时
  • 写锁:当要对表做结构变更操作的时

读锁与读锁止键不互斥,写锁与写锁,读锁与写锁之间互斥,用来保证变更表结构操作的安全性

注意安全性:
在这里插入图片描述
在这里插入图片描述
session A 先启动,这时候会对表 t 加一个 MDL 读锁。
session B 需要的也是 MDL 读锁,因此可以正常执行。
session C 会被 blocked,是因为 session A 的 MDL 读锁还没有释放。session D 也会被 blocked。

导致问题:如果查询语句频繁,且客户端有重试机制会打爆Mysql
结论:事务中的 MDL 锁,在语句执行开始时申请,但是语句结束后并不会马上释放,而会等到整个事务提交后再释放

如何安全地给小表加字段?

  1. information_schema 库的 innodb_trx 表中如果有长事务,暂停 DDL,或者 kill 掉这个长事务。
  2. alter table 语句里面设定等待时间。(如果在这个指定的等待时间里面能够拿到 MDL 写锁最好,拿不到也不要阻塞后面的业务语句,先放弃。之后开发人员或者 DBA 再通过重试命令重复这个过程)思想:防止死锁,加入超时时间机制

MariaDB 已经合并了 AliSQL 的这个功能,所以这两个开源分支目前都支持 DDL NOWAIT/WAIT n 这个语法

ALTER TABLE tbl_name NOWAIT add column ...
ALTER TABLE tbl_name WAIT N add column ... 

MySQL 8.0.1在select语法中给出了NOWAIT特性(官方博客),也就是我们可以在查询时如果需要等待行锁,则立即退出报错。这种特性其实也可以用在MDL锁,这样我们如果在进行DDL语句时,通过NOWAIT检测一下是否有相关元数据锁等待,如果有则立即退出,这样运维人员即可及时判断出能否进行ddl操作,而不至于在执行ddl时,造成大量业务中断。
在这里插入图片描述

标签:语句,事务,MDL,lock,读锁,session,全局,表锁
来源: https://blog.csdn.net/qq_42239520/article/details/122297431

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有