生產環境常遇磁盤告警,罪魁禍首通常是 ibdata1(共享表空間)與 mysql-bin.*(Binlog)。本文深度解析成因,給出清理與架構遷移方案。
| 文件 | 現象 | 根因 |
|---|---|---|
| ibdata1 > 120G | 共享表空間單文件無限增長 | InnoDB 共享表空間模式:數據、索引、撤銷日誌混存,刪除數據不回縮文件 |
| mysql-bin.* > 80G | Binlog 積壓佔用磁盤 | 未配置過期清理、主從同步延遲導致主庫保留、大事務產生海量 Binlog |
| 模式 | 配置 | 優點 | 缺點 |
|---|---|---|---|
| 共享表空間 | 預設 innodb_file_per_table=0 | 可跨磁盤分散文件、表大小不受單文件限制 | 數據索引混存、刪除不回縮、臨時操作導致文件永久膨脹 |
| 獨立表空間 | innodb_file_per_table=1 | 每表獨立 .ibd 文件、DROP TABLE 瞬間回收空間、ALTER TABLE ... ENGINE=InnoDB 可回縮碎片 | 單表過大(>100G)性能下降、需調大 innodb_open_files |
-- 刪除指定文件之前的 Binlog
PURGE MASTER LOGS TO 'mysql-bin.010';
-- 刪除指定時間之前的 Binlog
PURGE MASTER LOGS BEFORE '2024-01-15 12:00:00';
[mysqld]
expire_logs_days = 30 # 30 天自動清理
max_binlog_size = 1G # 單文件上限,防止單文件過大
原理: 開啟 innodb_file_per_table=1 後,新建表自動使用獨立 .ibd 文件。存量表需「導出→刪除共享文件→導入」重建。
mysqldump -q -uroot -p --add-drop-table --all-databases > /backup/all.sql
systemctl stop mysqld
/etc/my.cnf)
[mysqld]
innodb_file_per_table=1
rm -f /var/lib/mysql/ibdata1 /var/lib/mysql/ib_logfile* /var/lib/mysql/<業務庫目錄>/*
# 保留 mysql/ 系統庫目錄
systemctl start mysqld
mysql -uroot -p < /backup/all.sql
mysql> SHOW VARIABLES LIKE 'innodb_file_per_table';
+-----------------------+-------+
| Variable_name | Value |
+-----------------------+-------+
| innodb_file_per_table | ON |
+-----------------------+-------+
ls -lh /var/lib/mysql/業務庫/*.ibd # 應見每表獨立 .ibd 文件
# 遷移前
-rw-rw---- 1 mysql mysql 120G ibdata1
# 遷移後
-rw-rw---- 1 mysql mysql 10M ibdata1 # 僅存系統元數據
drwx------ 2 mysql mysql 4.0K db_name/
-rw-rw---- 1 mysql mysql 50M db_name/table1.ibd
-rw-rw---- 1 mysql mysql 30M db_name/table2.ibd
...
OPTIMIZE TABLE 或 ALTER TABLE t ENGINE=InnoDBinnodb_file_per_table、innodb_open_files、磁盤使用率完成遷移後,磁盤空間可控、備份恢復更靈活、單表維護無影響,是 InnoDB 架構演進的必經之路。