如何在不轉儲所有數據庫的情況下縮小 innodb 文件 ibdata1?
InnoDB 將所有表儲存在一個大文件
ibdata1
中。刪除大表後,無論表有多大,文件都會保持其大小。如何縮小該文件而不必轉儲並重新導入整個數據庫(總共有數百 GB)?
我認為原因是你仍然能夠回滾丟棄。就我而言,我不需要。
這是我多年來作為 MySQL DBA 和 DBA StackExchange 處理過的最具爭議的話題之一。
說得委婉一點,根本沒有其他方法可以縮小 ibdata1。禁用innodb_file_per_table後,每次在 InnoDB 表上執行時
OPTIMIZE TABLE
,ibdata1 都會快速增長。使用 DDL 而非 DML 刪除DROP TABLE
且DROP DATABASE
無法回滾的數據。我相信Oracle和MSSQL可以回滾DDL。MySQL 無法做到這一點。ibdata1 中有幾類資訊
- 表數據
- 表索引
- 表元數據
- MVCC 控制數據
- 雙寫入緩衝區(後台寫入以防止依賴作業系統記憶體)
- 插入緩衝區(管理對非唯一二級索引的更改)
使用
innodb_file_per_table=1
將允許您使用在 ibdata1 外部創建的表數據和表索引來創建新表。ALTER TABLE ... ENGINE=InnoDB;
您可以使用or提取仍在 ibdata1 中的任何表,OPTIMIZE TABLE
但這會在 ibdata1 中留下巨大的未使用空間。儘管如此,您必須清理 InnoDB 基礎架構。我已經寫了關於如何以及為什麼這樣做的 StackExchange 文章:
May 21, 2012
: MySQL 數據庫相對於轉儲文件有多大?Apr 01, 2012
: innodb_file_per_table 可取嗎?Mar 25, 2012
:為什麼 InnoDB 將所有數據庫儲存在一個文件中?Feb 04, 2011
: MySQL InnoDB - innodb_file_per_table 缺點?Oct 29, 2010
: Howto: 清理 mysql InnoDB 儲存引擎?好消息
您只需要轉儲數據,再重新載入一次,並且永遠不會再次訪問此問題。之後執行
OPTIMIZE TABLE
確實會縮小.ibd
任何 InnoDB 表的表空間文件。
如果您未在 my.cnf 預設文件中使用以下設置,則 InnoDB 僅將所有 InnoDB 表儲存在 ibdata1 中:
innodb_file_per_table = 1
DROP TABLE(和 DROP DATABASE)不能回滾。
這不是你不能縮小 ibdata1 的原因。
這是一個簡短的解釋,但 ibdata1 除了您的表數據之外還包含 InnoDB 內部。據我了解,要縮小它需要對其進行碎片整理,這不是受支持的操作。