讓天下沒有難用的資料庫 » Drop table 出現的問題
由於應用下線,需要把資料庫中相關應用的表刪除,庫中有一千多張表,事先已經將所有的表rename到test庫中,drop table的腳步也已經準備好,所以接下來的工作本以為是很輕鬆的事情,但是在執行指令碼的過程中,發現刪除表的速度感覺有點慢,檢視主機的負載也在挺高的,報警訊息中thread running過高也出現了,發現大多數執行緒的狀態是Opening Tables,但還是勉強的忍受了過去,事後想想為什麼刪除表也會這麼的慢?
在drop table的時候有幾件事情需要去做:
對目標表加上write lock,然後在將資料檔案,資料字典檔案從儲存引擎中刪除,看似簡單的兩個工作,但為什麼會這麼長?下面的程式碼中展示了刪除過程中的工作,在刪除的過程中lock_open mutex會一直用於防止任何query來訪問主表;同時在刪除表資料檔案,資料字典檔案的時候由於檔案系統的原因(ext3)導致大量的隨機i/o,同樣會使得刪除變慢。
VOID(pthread_mutex_lock(&LOCK_open));
error= mysql_rm_table_part2(thd, tables, if_exists, drop_temporary, 0, 0);
pthread_mutex_unlock(&LOCK_open);
同時在刪除表的過程中,由於innodb_file_per_table=1引數的開啟,每個表有一個數據檔案,而不是共享一個表空間,在drop table的時候,innodb必須檢查LRU連結串列,把該連結串列上屬於該表的page清除,如果該資料庫的buffer pool設定的很大,花費在LRU
同時innodb在開啟每一張表的時候,還需要重新計算每張表的統計資訊,如果有上千張的表,當採用innodb_file_per_table方式管理表的時候,這時候對磁碟i/o,cpu的要求也是很高的,這也是為什麼mysql沒有像oracle一樣需要手動去收集表的的統計資訊,而這個操作是序列的,不能夠並行處理。
綜上所述,drop table的速度受制於檔案系統,lock,cache,LRU等諸多因素;上面一個很重要的因素是innodb_file_per_table=1
參考: