MySQL Online DDL导致全局锁表案例分析

我这边遇到了什么问题?

线上给某个表执行新增索引SQL, 然后整个数据CPU打到100%, 连接数暴增到极限, 最后导致所有访问数据库的应用都奔溃.

SQL如下:

ALTER TABLE `book`
ADD INDEX `idx_sub_title` (`sub_title` ASC);

能看到什么?

'10063293', 'root', '10.0.0.1:35252', 'novel', 'Query', '50', 'Waiting for table metadata lock', 'ALTER TABLE `lemon_novel`.`book` \nADD INDEX `idx_sub_title` (`sub_title` ASC)'

'10094494', 'root', '172.16.2.112:42808', 'novel', 'Query', '31', 'Waiting for table metadata lock', 'SELECT \n            book_trend.book_id AS book_id,

很奇怪, 这两边都在等"Waiting for table metadata lock"

反手查一下"Waiting for table metadata lock"是什么

  1. MySQL出现Waiting for table metadata lock的原因以及解决方法

  2. mysql: Waiting for table metadata lock

  3. How do I find which transaction is causing a “Waiting for table metadata lock” state?

  4. MySQL:8.11.4 Metadata Locking

  5. MySQL:14.13.1 Online DDL Operations

初步的一些结论

看下来下面的一些结论:

  1. MySQL 5.6以后的版本,支持在线DDL,新增index/删除index之类的可以直接InPlace操作,不需要rebuild整张表,理论上效果是很快的,详细资料见Online DDL Operations

  2. DDL add index 操作会lock table metadata,此操作是导致我们服务不可用的原因

  3. 有怀疑过lock tabel matadata和MySQL autocommit有关,但是实践下来两者看起来没有关联。

后来在阿里云上面还看到过他们特定写过类似的答疑.

  1. 解决MDL锁导致无法操作数据库的问题

  2. RDS for MySQL Online DDL 使用

阿里云建议主要是这样操作.

  • 这里需要找到的是一直在占用该表的会话,而不是正在等待MDL锁解除的会话,注意区分。可以根据State列的状态和Info列的命令内容来进行分析判断。

  • 您也可以用如下命令查询长时间未完成的事务,如果导致阻塞的语句的用户与当前用户不同,请使用导致阻塞的语句的用户登录来终止会话。

select concat('kill ',i.trx_mysql_thread_id,';') from information_schema.innodb_trx i,
(select
id, time
from
information_schema.processlist
where
time = (select
max(time)
from
information_schema.processlist
where
state = 'Waiting for table metadata lock'
and substring(info, 1, 5) in ('alter' , 'optim', 'repai', 'lock ', 'drop ', 'creat'))) p
where timestampdiff(second, i.trx_started, now()) > p.time
and i.trx_mysql_thread_id not in (connection_id(),p.id);

然而在我的场景, 上面的SQL并没有任何的进程输出.

陷入僵局的...

不过上面给了一些思路, 现在我们主要是因为有东西占用着 table metadata lock, 导致当前所有的东西都没有执行.

show full processlist;

看一眼没什么卵用, 处理那两个奇怪的wait lock, 其他的都挺正常的.

那么, 看下现在谁占用着锁?

怎么看呢?

select * from information_schema.innodb_trx;

神奇了, 真有两个东西在占用锁.

那kill 了他们看看.

额, 解决了.

最终结论

某个奇怪的程序开了查询或者奇怪的操作, lock了 table metadata, 之后连接一直都没有被释放, 导致以上各种问题.

现在的问题来了, 究竟是哪个程序或者哪个代码导致的呢?

抱歉, 我现在也还不知道...

理论上可以查, 但是上次去查的时候发现数据库显示的host对应机器的端口早就没东西了, 死无对证ing.

最后建议

  • online DDL前,最好确认一下当前数据库有没有类似lock存在

  • 最好的方案还是主从切换来搞

全文完.

MySQL Online DDL导致全局锁表案例分析的更多相关文章

  1. mysql查询更新时的锁表机制分析

    为了给高并发情况下的mysql进行更好的优化,有必要了解一下mysql查询更新时的锁表机制. 一.概述 MySQL有三种锁的级别:页级.表级.行级.MyISAM和MEMORY存储引擎采用的是表级锁(t ...

  2. mysql查询更新时的锁表机制分析(只介绍了MYISAM)

    为了给高并发情况下的mysql进行更好的优化,有必要了解一下mysql查询更新时的锁表机制. 一.概述 MySQL有三种锁的级别:页级.表级.行级.MyISAM和MEMORY存储引擎采用的是表级锁(t ...

  3. 【MySQL 读书笔记】全局锁 | 表锁 | 行锁

    全局锁 全局锁是针对数据库实例的直接加锁,MySQL 提供了一个加全局锁的方法, Flush tables with read lock 可以使用锁将整个表的增删改操作都锁上其中包括 ddl 语句,只 ...

  4. MySQL的中的全局锁、表级锁、行锁

    MySQL的中的全局锁.表级锁.行锁 学习极客时间-林晓彬老师-MySQL实战45讲 学习整理 全局锁 对整个数据库实例加锁.通过使用Flush tables with read lock (FTWR ...

  5. mysql死锁-查询锁表进程-分析锁表原因【转】

    查询锁表进程: 1.查询是否锁表 show OPEN TABLES where In_use > 0;   2.查询进程     show processlist   查询到相对应的进程===然 ...

  6. MySQL5.7之在线DDL不会锁表

    MySQL5.7在线修改varchar字段不在锁表,测试过程如下: mysql> select version(); +------------+ | version() | +-------- ...

  7. MySQL中select * for update锁表的范围

    MySQL中select * for update锁表的问题 由于InnoDB预设是Row-Level Lock,所以只有「明确」的指定主键,MySQL才会执行Row lock (只锁住被选取的资料例 ...

  8. MySQL中select * for update锁表的问题

    MySQL中select * for update锁表的问题 由于InnoDB预设是Row-Level Lock,所以只有「明确」的指定主键,MySQL才会执行Row lock (只锁住被选取的资料例 ...

  9. mysql中kill掉所有锁表的进程

    --mysql中kill掉所有锁表的进程 --------------------------------2014/05/20 在数据库的管理中,我们经常会碰到锁表的问题,看一下进程列表. mysql ...

随机推荐

  1. idea 控制台允许输入

    打开idea配置文件添加 -Deditable.java.test.console=true

  2. 【新手可看懂】ubuntu配置appium环境

    1.node安装: 在node官网:https://nodejs.org/en/download/ 下载对应的安装包(这里建议下载最新的版本)下载好后放在liunx指定路径下 我这里放到opt这个文件 ...

  3. oracle in和exists区别

    in和exists http://oraclemine.com/sql-exists-vs-in/ https://www.techonthenet.com/oracle/exists.php htt ...

  4. Linux常用时间函数

    time()函数: NAME time - get time in seconds SYNOPSIS #include <time.h> time_t time(time_t *tloc) ...

  5. MySQL数据库开发规范-EC

    最近一段时间一边在线上抓取SQL来优化,一边在整理这个开发规范,尽量减少新的问题SQL进入生产库.今天也是对公司的开发做了一次培训,PPT就不放上来了,里面有十来个生产SQL的案例.因为规范大部分还是 ...

  6. LOJ#3104「TJOI2019」甲苯先生的字符串

    题目描述 一天小甲苯得到了一条神的指示,他要把神的指示写下来,但是又不能泄露天机,所以他要用一种方法把神的指示记下来. 神的指示是一个字符串,记为字符串 \(s_1\),\(s_1\) 仅包含小写字母 ...

  7. lomback插件在日志管理方面的应用

    由于现在使用日志可以省去在解决bug时候的很多麻烦, lomback为我们提供了很方便的打印日志的管理 @RunWith(SpringRunner.class) @SpringBootTest @Sl ...

  8. test20190805 夏令营NOIP训练20

    100+0+0=100,由于第二题写挂rank 1就没了 山 xyz现在站在一个斜坡面前 这个斜坡上依次排布这n座山峰,xyz打算爬上其中的一座 因为xyz体力不好,所以他只能爬上最矮的一座山 又因为 ...

  9. *.Net框架 - IGrouping类 & Lookup类

    Dictionary<TKey, TValue>只为每个键支持一个值.新类Lookup<TKey, TElement>是.NET 3.5中新增的,它类似于Dictionary& ...

  10. css cursor效果图

    效果图: <!DOCTYPE html> <html lang="zh-cmn-Hans"> <head> <meta charset=& ...