前言:mysql運維內參中有提到如何快速刪除大表。看到書中案列說drop大表的時候導致mysql例項夯住了,但是本人暫時還沒有碰到過這種情況,也可能是生產中沒有這麼大的表,或者機器效能還不錯的原因吧,但是該項技能還是需要掌握一下,以備不時之需。
一、理論基礎
mysql在刪除表的時候大致做了以下工作:
buffer pool頁面清除過程
刪除ibd磁碟檔案的過程
之所以刪除大表會導致例項夯住的原因是如果buffer pool很大,或者是在buffer pool有很多需要清除的頁面,那麼遍歷掃瞄需要占用的時間就會比較久,導致其他事物在用到相應buffer pool例項時就會被阻塞。
這裡摘抄一下運維內參對於mysql drop table的過程。
通過buf_pool_mutex_enter(buf_pool)函式持有buffer pool mutex
通過buf_flush_list_mutex_enter(buf_pool)函式持有buffer pool中的flush list mutex。
開始掃瞄flush list
如果髒頁屬於drop table,則直接從flush list列表中移除。
如果占用cpu和mutex時間過長,則呼叫buf_flush_try_yield函式釋放cpu資源、flush list mutex和buffer pool mutex,並呼叫ps_thread_yield()函式強制進行context switch。
重新持有buffer pool mutex
重新持有flush list mutex
釋放持有flush list mutex
釋放持有buffer pool mutex
二、實戰操作
1、假設我現在有一張大表,物理檔案大小達到200g,那麼在drop table的過程中,刪除ibd檔案可能會比較久,那麼我們可以在刪除ibd檔案之前先對ibd檔案建立乙個硬連線來加速刪除,減少對資料庫造成的影響。
mysql> select * from t1;
error 2006 (hy000): mysql server has gone away
no connection. trying to reconnect...
connection id: 3
current database: xucl
| id |
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
| 6 |
| 7 |
| 8 |
8 rows in set (0.00 sec)
2、建立硬連線
[root@localhost xucl]# ll
總用量 220
-rw-r----- 1 mysql mysql 61 3月 23 08:21 db.opt
-rw-r----- 1 mysql mysql 8556 3月 23 08:21 t1.frm
-rw-r----- 1 mysql mysql 98304 3月 27 03:50 t1.ibd
-rw-r----- 1 mysql mysql 8556 3月 23 08:22 t2.frm
-rw-r----- 1 mysql mysql 98304 3月 23 08:22 t2.ibd
[root@localhost xucl]# ln t1.ibd t1.ibd.hdlk
[root@localhost xucl]# ll
總用量 316
-rw-r----- 1 mysql mysql 61 3月 23 08:21 db.opt
-rw-r----- 1 mysql mysql 8556 3月 23 08:21 t1.frm
-rw-r----- 2 mysql mysql 98304 3月 27 03:50 t1.ibd
-rw-r----- 2 mysql mysql 98304 3月 27 03:50 t1.ibd.hdlk
-rw-r----- 1 mysql mysql 8556 3月 23 08:22 t2.frm
-rw-r----- 1 mysql mysql 98304 3月 23 08:22 t2.ibd
可以看到t1.ibd和t1.ibd.hdlk的inode均為2,我們知道,乙個磁碟上的檔案,可以由多個檔案系統的檔案引用,這多個檔案是完全相同的,都指向同乙個磁碟檔案,當我們刪除任何乙個檔案的時候,都不會影響真實的檔案,只是會將其被引用數目減1,只有當被引用數為1的時候,才會刪除真實的物理檔案,我們可以利用這個特點,讓mysql在drop table的時候不做物理檔案的刪除而是使檔案的引用數目減1。
3、drop table
mysql> drop table t1;
error 2006 (hy000): mysql server has gone away
no connection. trying to reconnect...
connection id: 4
current database: xucl
query ok, 0 rows affected (0.00 sec)
[root@localhost xucl]# ll
總用量 208
-rw-r----- 1 mysql mysql 61 3月 23 08:21 db.opt
-rw-r----- 1 mysql mysql 98304 3月 27 03:50 t1.ibd.hdlk
-rw-r----- 1 mysql mysql 8556 3月 23 08:22 t2.frm
-rw-r----- 1 mysql mysql 98304 3月 23 08:22 t2.ibd
再看物理檔案的引用數變為1,然後我們可以另外找時間手動刪除物理檔案。
4、刪除物理檔案
[root@localhost xucl]# rm -rf t1.ibd.hdlk
[root@localhost xucl]# ll
總用量 112
-rw-r----- 1 mysql mysql 61 3月 23 08:21 db.opt
-rw-r----- 1 mysql mysql 8556 3月 23 08:22 t2.frm
-rw-r----- 1 mysql mysql 98304 3月 23 08:22 t2.ibd
至此,大表完成刪除。
mysql 刪表引出的問題
將測試環境的表同步到另外乙個資料庫伺服器中,但有些表裡面資料巨大,其實不同步該錶的資料就行,當時沒想太多 幾千萬的資料!1.既然已經把資料同步過來的話,那就直接delete掉就行,多大的事呢?於是 delete from table name where1 1 結果傻眼了,執行了一會兒就卡死了,對卡...
MySQL 刪表或者刪庫沒有響應
看網上教程學習,匯入了別人的sql檔案,但是似乎中間出了點問題,所以想刪庫刪表重新來過。但是無論是無論是刪庫還是刪表都沒有響應。show full processlist 發現很多wating for table metadata lock狀態的程序。kill process id 殺死這些程序後,...
mysql刪庫指令碼 MySQL 多例項刪庫指令碼
db版本 5.5.14 os centos 6.3 在測試環境中,在一台伺服器上建立多個例項,在每個例項中乙個乙個刪庫比較麻煩,因此用下面指令碼,可以直接刪除所有庫,除了系統庫以外 bin bash mysql export servers mysql bin mysql for i in dofo...