緩慢的Drop Table

 (原文:http://www.mysqlperformanceblog.com/2009/06/16/slow-drop-table/)

 

衆所周知,EXT3並不是效率最高的文件系統,例如文件刪除就是其隱痛並且會造成大量的隨機I/O。而且,有時會嚴重影響到MySQL的性能。

 

當我們運行DROP TABLE命令時,會依序發生以下步驟:
    1. 給表加寫鎖,以使它不能被其他線程訪問。
    2. 存儲引擎(MyISAM,InnoDB...)刪除數據文件
    3. MySQL刪除定義文件(.frm)。

 

但這些並不是全部,期間還有一個步驟:
    1. VOID(pthread_mutex_lock(&LOCK_open));
    2. error= mysql_rm_table_part2(thd, tables, if_exists, drop_temporary, 0, 0);
    3. pthread_mutex_unlock(&LOCK_open);

 

刪除表的代碼被LOCK_open這個互斥鎖包裹。這個鎖在MySQL的代碼中多次被使用到——主要是打開和關閉表的時候。這表明,當LOCK_open被佔用,所有需要訪問表的查詢都將不能被執行。

 

在此,EXT3文件系統上緩慢的文件刪除便開始產生影響。刪除10GB的MySQL表要花費幾秒鐘,鎖持續被佔用,以至於全部的查詢都被掛起。
+-----+------+-----------+----+---------+------+----------------+-----------------------------------------------
| Id  | User | Host      | db | Command | Time | State          | Info
+-----+------+-----------+----+---------+------+----------------+-----------------------------------------------
| 1   | root | localhost |test| Query   | 7    | NULL           | drop table large_table
| 329 | root | localhost |test| Query   | 7    | Opening tables | select sql_no_cache * from other_table limit 1  
+-----+------+-----------+----+---------+------+----------------+-----------------------------------------------

 

我曾嘗試過其他方法,試圖讓MySQL刪除小一些的文件以降低影響,例如:
    * TRUNCATE TABLE large_table; ALTER TABLE large_table ENGINE=…; DROP TABLE large_table;
    * TRUNCATE TABLE large_table; OPTIMIZE TABLE large_table; DROP TABLE large_table;

 

然而不幸的是,任何管理的指令如ALTER TABLE 或 OPTIMIZE TABLE在刪除舊錶的時候都要使用LOCK_open鎖:
    | 3   | root | localhost | test | Query | 7 | rename result table | ALTER TABLE large_table ENGINE=MyISAM
    | 679 | root | localhost | test | Query | 6 | Opening tables      | select * from other_table limit 1 

 

唯一替換的方法是改變文件系統,例如將文件系統改爲刪除文件更有效的XFS。

EXT3
      mysql> drop table large_table;
      Query OK, 0 rows affected (7.44 sec)

XFS
      mysql> drop table large_table;
      Query OK, 0 rows affected (0.29 sec)

 

更好的解決方法是在MySQL內部模擬刪除表,其實將文件保留並在不使用LOCK_open鎖的情況下物理刪除。然而,實際情況並沒這麼簡單,因爲刪除的指令是由存儲引擎執行的,而並非是MySQL。

 

以上並非一般情況,但有些時候會引起問題。(例如刪除舊的不用的表)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章