mysql快速刪表 MySQL 如何快速刪除大表

2021-10-17 13:48:10 字數 3151 閱讀 7128

前言: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...