mysql清除磁盤碎片

任務背景

接到金山雲報警短信,說某數據庫的容量已經達到了90%的水位線,於是登陸控制檯查看詳細情況。

在控制檯首先發現,每一天的磁盤容量的確有所波動,那麼就證明開發人員寫的“資源回收”模塊是在正常運行的,如圖:
mysql清除磁盤碎片

那麼就說明沒有什麼數據是可以刪的,既然刪不掉多餘的數據又不想多掏錢擴磁盤容量,只能從“磁盤碎片”下手了。而InnoDB引擎清理磁盤碎片的命令就是OPTIMIZE

具體操作

首先我先查詢一下所有的“磁盤碎片情況”,使用語句如下:

    select CONCAT(TABLE_SCHEMA,'.',TABLE_NAME) as 數據表名,concat(truncate(sum(DATA_LENGTH+DATA_FREE+INDEX_LENGTH)/1024/1024,2),' MB') as total_size, concat(truncate(sum(DATA_LENGTH)/1024/1024,2),' MB') as data_size,concat(truncate(sum(DATA_FREE)/1024/1024,2),' MB') as data_free, concat(truncate(sum(INDEX_LENGTH)/1024/1024,2),'MB') as index_size from information_schema.tables group by TABLE_NAME order by data_length desc; 

或者使用select table_schema, table_name, data_free, engine from information_schema.tables where table_schema not in ('information_schema', 'mysql') and data_free > 0;也可以,這個是查詢data_free大於0的所有表。

然後看到我這個叫history_device_flow_day的表裏情況如下:
mysql清除磁盤碎片

表裏的data_free就是磁盤碎片的量,比如我現在要幹掉history_device_flow_day裏所有的磁盤碎片,是975MB,於是先查詢一下這個history_device_flow_day的存儲引擎,使用語句如下:

    show table status from jsonlinef***ds where name='history_device_flow_day';

上面語句裏的jsonlinef***ds是對應的數據庫,看到的效果如下:
mysql清除磁盤碎片

存儲引擎是InnoDB,那麼就可以啓動清除碎片的語句了:OPTIMIZE TABLE 數據表表名;,因爲OPTIMIZE TABLE只對MyISAMBDBInnoDB表起作用。

再執行了OPTIMIZE TABLE history_device_flow_day;之後,大約9分鐘,就會看到“OK”的字樣:
mysql清除磁盤碎片

估計有的朋友會問,那上面不是明明寫了“Table does not support optimize, doing recreate + analyze instead”嗎?這個其實無妨,實際上磁盤碎片已經被清除掉了。我們可以再用一次查詢磁盤碎片的命令看一下,如圖:
mysql清除磁盤碎片

的確釋放了900多M。

或者使用ALTER TABLE 表名 ENGINE = Innodb;(只是InnoDB的表可以這麼做)來達到清理磁盤碎片的目的,這個命令表面上看什麼也不做,實際上是重新整理碎片了。當執行優化操作時,實際執行的是一個空的ALTER命令,但是這個命令也會起到優化的作用,它會重建整個表,刪掉未使用的空白空間。

補充

爲什麼會產生磁盤碎片?那是因爲某一個表如果經常插入數據和刪除數據,必然會產生很多未使用的空白空間,這些空白空間就是不連續的碎片,這樣久而久之,這個表就會佔用很大空間,但實際上表裏面的記錄數卻很少,這樣不但會浪費空間,並且查詢速度也更慢。

注意!OPTIMIZE操作會暫時鎖住表,而且數據量越大,耗費的時間也越長,它畢竟不是簡單查詢操作。所以把OPTIMIZE命令放在程序中是不妥當的,不管設置的命中率多低,當訪問量增大的時候,整體命中率也會上升,這樣肯定會對程序的運行效率造成很大影響。比較好的方式就是做個shell,定期檢查mysql中 information_schema.TABLES字段,查看DATA_FREE字段,大於0的話,就表示有碎片,然後啓動腳本。

參考資料

http://pengbotao.cn/mysql-suipian-youhua.html
http://irfen.me/mysql-data-fragmentation-appear-and-optimization/

最後的最後,如果您覺得本文對您升職加薪有幫助,那麼請不吝贊助之手,刷一下下面的二維碼,贊助本人繼續寫更多的博文!
mysql清除磁盤碎片

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