06 | 全局锁和表锁 :给表加个字段怎么有这么多阻碍?(待评论)

MySQL 的锁:全局锁、表级锁和行锁

全局锁(FTWRL :Flush tables with read lock )

整库实例加锁。整库只读态,其他线程被阻塞:数据更新语句(数据的增删改)、数据定义语句(包括建表、修改表结构等)和更新类事务的提交语句。

典型使用场景:做全库逻辑备份。整库只读危险

(1)主库备份,业务停;

(2)从库备份,不能执行主库同步binlog,主从延迟。

(3)备份不加锁:用户账户余额表和课程表

备份期间,用户购买,先备份账户余额表 (u_account),购买,再备份用户课程表 (u_course);

备份结果:“余额没扣,多了课”。

图 1 业务和备份状态图

官方自带备份工具 mysqldump。用–single-transaction时(只适用于所有的表使用事务引擎的库),导数据之前启动事务,确保拿到一致性视图(可重复读隔离级别)。 MVCC 支持,过程可以正常更新。

为什么还需要 FTWRL 呢?一致性读是好,前提引擎要支持这个隔离级别。 MyISAM 不支持事务引擎,备份过程中更新,只能取到最新数据,破坏了一致性。这时需 FTWRL 命令。

既然要全库只读,为什么不使用 set global readonly=true 的方式呢

(1)readonly 值被用来做其他逻辑,如判断主/备库,修改 global 影响大.

(1)异常处理有差异。FTWR异常,自动释放,readonly 异常,一直readonly 状态,不可写状态。

业务更新不只增删改数据(DML),还可能加字段等修改表结构的操作(DDL)全局锁会锁。

二、表级锁

表级锁:(1)表锁,(2)元数据锁(meta data lock,MDL)。

1、lock tables … read/write。 FTWRL 类似, unlock tables 主动释放锁,断开时自动释放。限制别的线程读写,也限定本线操作对象。

线程 A  lock tables t1 read, t2 write; 其他线程写 t1、读写 t2 被阻塞。 unlock tables 之前,只能读 t1、读写 t2 。

 InnoDB 支持行锁,不使用 lock tables 命令,锁表影响大。

2、MDLmetadata lock)不需显式使用,访问表时自动加上。保证读写正确性。查询时,表结构变,查询结果跟表结构对不上。

增删改查时,加 MDL 读锁(读锁之间不互斥);表做结构变更,加 MDL 写锁(保证变更表结构安全)事务提交才释放,结构变更时,不要导致锁住线上查询和更新。

MDL 锁是系统默认加,但却是你不能忽略的一个机制。给小表加字段,导致整个库挂了。

给表加字段,修改字段,加索引,需要扫描全表。小表操作不慎也会出问题


session A 先加 MDL 读锁。session B 也MDL 读锁。(读锁不冲突,隔离级别原因)

session C 写锁被 blocked,A 读锁没释放。之后新请求被C 阻塞。表完全不可读写

重试机制,再起session请求,爆满,内存升高

ps:没有begin的话,select执行完成,MDL自动释放

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

解决长事务,事务不提交,占着 MDL 锁。information_schema库 innodb_trx 表中,查到当前执行中长事务。要做 DDL 变更,kill 掉长事务。

热点表加个字段

kill 未必管用,新请求来。alter table 设定等待时间拿到 MDL 写锁最好拿不到不要阻塞后面,通过重试命令重复这个过程。

MariaDB 已经合并了 AliSQL 的这个功能,都支持 DDL NOWAIT/WAIT n 这个语法。

ALTER TABLE  tbl_name NOWAIT add column ...

ALTER TABLE  tbl_name WAIT N add column ...

小结

(1)全局锁:逻辑备份。InnoDB 引擎库,用–single-transaction更好。

(2)表锁:不支持行锁时用。程序里有 lock tables 追查,可能情况:

    1)用 MyISAM 不支持事务的引擎,换引擎;

    2)引擎升级了,代码没升级。lock tables 和 unlock tables 改成 begin 和 commit,问题解决

MDL事务提交才释放,表结构变更时,不锁住线上查询和更新。

问题:

备库上执行备份,用–single-transaction方法,主库上小表做 DDL(),加一列。从备库上会看到什么现象呢?关键语句:

DDL: CREATE TABLE/VIEW/INDEX/SYN/CLUSTER;隐性提交,不能rollback 

Q1:SET SESSION  TRANSACTION ISOLATION LEVEL REPEATABLE READ;确保 RR(可重复读)隔离级别,再设置一次

Q2:START  TRANSACTION  WITH CONSISTENT SNAPSHOT;启动事务用,确保执行完,得一致性视图

Q3:SAVE POINT sp; 设置保存点  /* 时刻 1 */

Q4:show create  table `t1`;  拿到表结构  /* 时刻 2 */

Q5:SELECT * FROM  `t1`;  导数据  /* 时刻 3 */

Q6:ROLLBACK TO  SAVEPOINT sp;  /* 时刻 4 */ 回滚到 SAVEPOINT,释放 t1 的 MDL

1. 拿到表结构Q4 之前到达,没有影响,备份的是 DDL 后

2. “时刻 2”到达,表结构改过,Q5 执行的时候,报 Table definition has changed, please retry transaction,mysql dump 终止

3. “时刻 2”和“时刻 3”之间到达,mysql dump 占着 t1 的 MDL 读锁,binlog 被阻塞,现象:主从延迟,直到 Q6 执行完成。

4. “时刻 4”开始,mysql dump 释放了 MDL 读锁,现象:没有影响,备份拿到的是 DDL 前的表结构。

评论1

mysql 5.6不是支持online ddl了吗?增加字段,实际上不阻塞读写

DDL过程:

1. 拿MDL写锁

2. 降级成MDL读锁

3. 真正做DDL

4. 升级成MDL写锁

5. 释放MDL锁

1、2、4、5如果没有锁冲突,执行时间非常短。第3步占DDL大部分时间,期间表正常读写,称“online ”.文中例子,第一步就堵住

评论2

FTWRL 前有读写 ,要等待完执行。执行时要刷脏页数据到磁盘,保持一致性 

MDL 并发时维护一致性,有事务时,不可对元数据写,server层实现。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,937评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,503评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,712评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,668评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,677评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,601评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,975评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,637评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,881评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,621评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,710评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,387评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,971评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,947评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,189评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,805评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,449评论 2 342

推荐阅读更多精彩内容

  • 数据库锁设计的初衷是处理并发问题。作为多用户共享的资源,当出现并发访问的时候,数据库需要合理地控制资源的访问规则。...
    花神子阅读 568评论 2 1
  • 一、锁的分类:根据加锁的范围,MySQL里面的锁大致可以分成全局锁、表级锁和行锁三类。 二、全局锁: 1、所谓的全...
    墨殇染泪阅读 415评论 0 2
  • 数据库锁设计的初衷是处理并发问题。作为多用户共享的资源,当出现并发访问的时候,数据库需要合理地控制资源的访问规则。...
    yywfy的昵称阅读 542评论 0 0
  • 全局锁 对整个数据库实例加锁 使用场景:做全库逻辑备份时,为了保证备份期间的库在同一个逻辑时间点,即一致性视图(类...
    Java大宝宝阅读 851评论 0 1
  • 代码CR文档文件bug任务进度
    便便君阅读 275评论 0 0