MySQL 回收表碎片實踐教程

前言:

在 MySQL 數據庫中咧七,隨著數據的增刪改操作递宅,表空間可能會出現碎片化,這不僅會占用額外的存儲空間锉屈,還可能降低表的掃描效率荤傲,特別是一些大表,在進行數據清理后會產生大量的碎片部念。本篇文章我們一起來學習下如何進行碎片回收以及相關注意點弃酌。

查看表碎片大小

一般 MySQL 數據庫都是開啟 innodb_file_per_table 參數的氨菇,這代表每個表使用獨立的表空間,即每個表的數據及索引存儲在一個獨立的 表名.ibd 文件里妓湘,如果某個表有大量碎片查蓉,ibd 文件占用磁盤空間會非常大,碎片回收掉后 ibd 文件也會顯著減小榜贴。

首先我們要確定哪些表需要進行回收碎片操作豌研,MySQL 系統(tǒng)表 information.TABLES 中的 DATA_FREE 字段顯示的是可用的空閑空間量(單位:字節(jié)),它可以幫助你估計碎片的程度唬党,如果 DATA_FREE 很大鹃共,那么這個表的碎片量一般也比較大。

image.png

如果某個表比較大或者變動特別頻繁驶拱,你可以看下這個表的 DATA_FREE 大小霜浴,看是否需要回收碎片,也可以從系統(tǒng)表中篩選出碎片量大于 100M 的表或者碎片率達到多少的表蓝纲,這類表一般是需要進行碎片回收的阴孟。下面幾條查詢 SQL 可能對你有所幫助:

# 查看某個表的詳細信息(包含碎片大小)
select 
table_schema as '數據庫',
TABLE_NAME as '表名',
sys.FORMAT_BYTES(data_length) as '數據容量',
sys.FORMAT_BYTES(index_length) as '索引容量',
sys.FORMAT_BYTES(data_length+index_length) as '總容量' ,
sys.FORMAT_BYTES(DATA_FREE) as '碎片大小'
from information_schema.tables where TABLE_SCHEMA = 'db_name' and TABLE_NAME = 'tb_name';

# 按碎片大小排序
SELECT t.TABLE_SCHEMA,
       t.TABLE_NAME,
       t.DATA_FREE,
       sys.FORMAT_BYTES(DATA_LENGTH+INDEX_LENGTH) as '總容量' ,
       sys.FORMAT_BYTES(DATA_FREE) as '碎片大小'
FROM information_schema.tables t
WHERE
    t.table_schema NOT IN (
        'mysql',
        'information_schema',
        'performance_schema',
        'sys'
    )
AND t.table_type = 'BASE TABLE' ORDER BY `DATA_FREE` DESC LIMIT 20

# 查看碎片率大于0.3的表
select 
table_schema as '數據庫',
TABLE_NAME as '表名',
sys.FORMAT_BYTES(DATA_LENGTH+INDEX_LENGTH) as '總容量' ,
sys.FORMAT_BYTES(DATA_FREE) as '碎片大小',
(DATA_FREE / (data_length + index_length)) AS '碎片率'
FROM information_schema.tables t
WHERE
    t.table_schema NOT IN (
        'mysql',
        'information_schema',
        'performance_schema',
        'sys'
    ) AND t.table_type = 'BASE TABLE' and (DATA_FREE / (data_length + index_length)) > 0.3

以上三條 SQL 基本能覆蓋日常所需場景税迷,想要回收表碎片的話永丝,可以按照不同場景執(zhí)行相關 SQL 來查找,比如是想回收碎片比較多的表還是碎片率比較大的表箭养。找到需要回收碎片的表后慕嚷,下一步就是評估進行正式回收碎片操作了。

回收表碎片

對于 InnoDB 存儲引擎的表毕泌,可以用 optimize table table_name; 或者 alter table table_name engine = innodb; 兩種方式進行回收喝检。

OPTIMIZE TABLE 對于 InnoDB 表來說,實際上會執(zhí)行一個重建表的操作懈词,這與 ALTER TABLE ... FORCE 類似蛇耀。這個過程會重新組織表的數據和索引,更新索引統(tǒng)計信息坎弯,并釋放聚簇索引中未使用的空間纺涤。它可以在一定程度上減少表占用的空間,并提高訪問表時的 IO 效率抠忘。OPTIMIZE TABLE 對于常規(guī)的和分區(qū)的 InnoDB 表使用 online DDL 撩炊,這減少了并發(fā)的 DML 操作的停機時間。OPTIMIZE TABLE 僅在操作的準備階段和提交階段短暫地獲取獨占的表鎖崎脉,在準備階段拧咳,元數據會被更新并且創(chuàng)建一個中間表,在提交階段囚灼,將提交表元數據更改骆膝。

ALTER TABLE ... ENGINE = InnoDB 命令實際上是將表的存儲引擎重新設置為 InnoDB 祭衩。在這個過程中,MySQL 會對表進行重建阅签,會回收掉未使用的空間掐暮。在 5.6 及以后的版本中,這個操作會使用 Online DDL 政钟,減少對并發(fā) DML 操作的影響路克。它通過創(chuàng)建一個臨時文件,掃描表的數據頁养交,并將操作記錄在日志文件中精算,最后將臨時文件替換原表的數據文件。此方法只適用于 InnoDB 引擎表碎连。

總的來說灰羽,兩者都可以用于整理 InnoDB 表的碎片,但是 OPTIMIZE TABLE 更側重于專門的碎片整理和空間回收鱼辙,還可以用于其他存儲引擎谦趣。而 ALTER TABLE ... ENGINE=InnoDB 主要是更改存儲引擎屬性時附帶的一些空間優(yōu)化。在實際使用中座每,可以根據具體情況選擇合適的方式來回收 InnoDB 表的空間。

需要注意的一點是摘悴,盡管二者操作都是 Online DDL 峭梳,但回收操作還是盡量在業(yè)務低峰期執(zhí)行,特別是大表蹂喻,回收操作還是需要一段時間的葱椭。除此之外,要確保有足夠的磁盤空間進行回收操作口四,因為執(zhí)行期間會生成臨時文件孵运,進一步占用磁盤空間,執(zhí)行完成后才會刪除臨時文件蔓彩。例如你要對一個 200G 的表進行回收操作治笨,預估能回收掉 50G 碎片,則要確保磁盤空間至少剩余 150G赤嚼,一般建議剩余空間在表大小以上。如果你的磁盤剩余空間不足則無法完成回收操作。

總結:

本篇文章介紹了如何查看 InnoDB 表的碎片以及如何進行回收昔头。生產環(huán)境中洛口,建議定期巡檢 MySQL 系統(tǒng)中的表碎片,并在業(yè)務低峰期執(zhí)行回收操作蹂空「┟龋回收表碎片是一種良好的數據庫維護實踐果录,可以提高數據庫查詢性能,同時也可以提高存儲效率和管理簡便性咐熙。

?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末弱恒,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子糖声,更是在濱河造成了極大的恐慌斤彼,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,126評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蘸泻,死亡現場離奇詭異琉苇,居然都是意外死亡,警方通過查閱死者的電腦和手機悦施,發(fā)現死者居然都...
    沈念sama閱讀 88,254評論 2 382
  • 文/潘曉璐 我一進店門并扇,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人抡诞,你說我怎么就攤上這事穷蛹。” “怎么了昼汗?”我有些...
    開封第一講書人閱讀 152,445評論 0 341
  • 文/不壞的土叔 我叫張陵肴熏,是天一觀的道長。 經常有香客問我顷窒,道長蛙吏,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,185評論 1 278
  • 正文 為了忘掉前任鞋吉,我火速辦了婚禮鸦做,結果婚禮上,老公的妹妹穿的比我還像新娘谓着。我一直安慰自己泼诱,他們只是感情好,可當我...
    茶點故事閱讀 64,178評論 5 371
  • 文/花漫 我一把揭開白布赊锚。 她就那樣靜靜地躺著治筒,像睡著了一般。 火紅的嫁衣襯著肌膚如雪舷蒲。 梳的紋絲不亂的頭發(fā)上矢炼,一...
    開封第一講書人閱讀 48,970評論 1 284
  • 那天,我揣著相機與錄音阿纤,去河邊找鬼句灌。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的胰锌。 我是一名探鬼主播骗绕,決...
    沈念sama閱讀 38,276評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼资昧!你這毒婦竟也來了酬土?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 36,927評論 0 259
  • 序言:老撾萬榮一對情侶失蹤格带,失蹤者是張志新(化名)和其女友劉穎撤缴,沒想到半個月后,有當地人在樹林里發(fā)現了一具尸體叽唱,經...
    沈念sama閱讀 43,400評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡屈呕,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 35,883評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現自己被綠了棺亭。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片虎眨。...
    茶點故事閱讀 37,997評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖镶摘,靈堂內的尸體忽然破棺而出嗽桩,到底是詐尸還是另有隱情,我是刑警寧澤凄敢,帶...
    沈念sama閱讀 33,646評論 4 322
  • 正文 年R本政府宣布碌冶,位于F島的核電站,受9級特大地震影響涝缝,放射性物質發(fā)生泄漏种樱。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,213評論 3 307
  • 文/蒙蒙 一俊卤、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧害幅,春花似錦消恍、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,204評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至邑遏,卻和暖如春佣赖,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背记盒。 一陣腳步聲響...
    開封第一講書人閱讀 31,423評論 1 260
  • 我被黑心中介騙來泰國打工憎蛤, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 45,423評論 2 352
  • 正文 我出身青樓俩檬,卻偏偏與公主長得像萎胰,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子棚辽,可洞房花燭夜當晚...
    茶點故事閱讀 42,722評論 2 345

推薦閱讀更多精彩內容