MySQL Online DDL導致全域性鎖表案例分析
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"是什麼
MySQL出現Waiting for table metadata lock的原因以及解決方法
mysql: Waiting for table metadata lock
How do I find which transaction is causing a “Waiting for table metadata lock” state?
MySQL:8.11.4 Metadata Locking
MySQL:14.13.1 Online DDL Operations
初步的一些結論
看下來下面的一些結論:
MySQL 5.6以後的版本,支援線上DDL,新增index/刪除index之類的可以直接InPlace操作,不需要rebuild整張表,理論上效果是很快的,詳細資料見Online DDL Operations
DDL add index 操作會lock table metadata,此操作是導致我們服務不可用的原因
有懷疑過lock tabel matadata和MySQL autocommit有關,但是實踐下來兩者看起來沒有關聯。
後來在阿里雲上面還看到過他們特定寫過類似的答疑.
解決MDL鎖導致無法操作資料庫的問題
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存在
最好的方案還是主從切換來搞
全文