InnoDB 預設將所有表數據、索引、撤銷日誌、雙寫緩衝等存放在共享表空間 ibdata1 中。隨著業務增長,ibdata1 可能達到數百 GB 甚至 TB,且**永不自動縮小**。本文詳細講解如何安全擴容表空間,以及徹底瘦身的標準流程。
前提:MySQL 5.7/8.0,innodb_file_per_table=ON(單表獨立 .ibd),但共享表空間仍存放系統數據。
service mysqld stopmy.cnf,在 innodb_data_file_path 追加新文件:# 原配置 innodb_data_file_path=ibdata1:10G;ibdata2:10G:autoextend # 擴容後(新增 ibdata3) innodb_data_file_path=ibdata1:10G;ibdata2:10G;ibdata3:10G:autoextend
關鍵細節:若最後一個文件已設 autoextend 且實際大小超過配置值,**必須精確填寫實際大小**(單位 MB,且為 1MB 倍數),否則啟動報錯。
# 例:ibdata2 實際 15360MB innodb_data_file_path=ibdata1:10G;ibdata2:15360M;ibdata3:10G:autoextend
ls -lh /data/mysql/ibdata*原理:InnoDB 不支援縮減共享表空間文件,必須通過 mysqldump 導出邏輯備份,刪除舊文件,重新初始化實例,再導入。
mysqldump -uroot -p --single-transaction --routines --triggers --events \ --hex-blob --default-character-set=utf8mb4 --quick \ --no-autocommit --extended-insert \ --databases db1 db2 > /backup/full_$(date +%F).sql
service mysqld stop rm -f /var/lib/mysql/ibdata1 /var/lib/mysql/ib_logfile* /var/lib/mysql/mysql-bin.index # 保留 mysql、sys、performance_schema 等系統庫目錄
service mysqld start # 生成全新 ibdata1 (12MB)、ib_logfile0/1、新隨機 root 密碼(5.7+)
mysql -uroot -p < /backup/full_2024-01-15.sql
執行 SHOW ENGINE INNODB STATUS\G 觀察 TRANSACTION 與 History list length。
ACTIVE 1256288 sec 顯示事務運行 14 天。InnoDB 必須保留該事務啟動時的所有舊版本(Undo Log),導致 ibdata1 瘋狂增長。maxLifetime、監控長事務殺掉。DELETE/UPDATE 百萬行產生海量 Undo。pt-archiver 歸檔。History list length 持續增長。innodb_max_purge_lag、升級 MySQL 5.7+(獨立 Purge 線程)。innochecksum(Mark Callaghan 版):統計頁類型分布,快速定位 Undo 佔比。./innochecksum /var/lib/mysql/ibdata1innodb_ruby(Jeremy Cole):更詳細的空間分布可視化。innodb_space -f ibdata1 space-summary | grep UNDO_LOG | wc -l| 參數 | 作用 | 建議值 |
|---|---|---|
innodb_undo_tablespaces | 獨立 Undo 表空間(可單獨截斷) | >= 2 |
innodb_undo_log_truncate | 允許自動截斷 Undo 表空間 | ON |
innodb_max_undo_log_size | 觸發截斷閾值 | 1G |
innodb_undo_directory | Undo 表空間存放目錄(可掛載獨立磁碟) | /data/undo |
innodb_doublewrite_file | 雙寫緩衝獨立文件 | /data/doublewrite.buf |