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

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

我这边遇到了什么问题?

线上给某个表执行新增索引SQL, 而后整个数据CPU打到100%, 链接数暴增到极限, 最后致使全部访问数据库的应用都奔溃.html

SQL以下:mysql

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

能看到什么?sql

tu1

'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

初步的一些结论

看下来下面的一些结论:ui

  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 使用

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

  • 这里须要找到的是一直在占用该表的会话,而不是正在等待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并无任何的进程输出.code

陷入僵局的...

不过上面给了一些思路, 如今咱们主要是由于有东西占用着 table metadata lock, 致使当前全部的东西都没有执行.orm

show full processlist;htm

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

那么, 看下如今谁占用着锁?

怎么看呢?

select * from information_schema.innodb_trx;

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

那kill 了他们看看.

额, 解决了.

最终结论

某个奇怪的程序开了查询或者奇怪的操做, lock了 table metadata, 以后链接一直都没有被释放, 致使以上各类问题.

如今的问题来了, 到底是哪一个程序或者哪一个代码致使的呢?

抱歉, 我如今也还不知道...

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

最后建议

  • online DDL前,最好确认一下当前数据库有没有相似lock存在
  • 最好的方案仍是主从切换来搞

全文完.

相关文章
相关标签/搜索