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存在
  • 最好的方案仍是主從切換來搞

全文完.

相關文章
相關標籤/搜索