當innodb_file_per_table設置爲OFF,那麼全部數據將被存儲在ibdata文件。若是刪除一些數據和刪除一些表則沒有回收未使用的磁盤空間,除了導出表而後再導入的方法來回收表空間大小,除此以外沒有任何其餘的方法。
當innodb_file_per_table設置爲ON時,每一個表中存儲的數據和索引在它本身的表空間文件。可是,共享表空間的ibdata1仍然在增加,爲何呢?由於ibdata1中依然有:html
(1)data dictionary aka metadata of InnoDB tablesmysql
(2)change buffersql
(3)doublewrite buffer服務器
(4)undo logsapp
更爲詳細的介紹請各位童鞋閱讀此文章
http://www.mysqlperformanceblog.com/2013/08/20/why-is-the-ibdata1-file-continuously-growing-in-mysql/工具
當你刪除表中一些記錄時,他們只是在磁盤上標記爲刪除,但空間會由之後能夠重複使用,當插入/更新多個行,但它永遠不會被回收。
可是,若是設置innodb_file_per_table爲ON,即便用獨立表空間,那麼能夠經過在該表運行OPTIMIZE TABLE回收空間。 OPTIMIZE TABLE將建立一個新的相同的空表。而後,它會經過行數據複製一行從舊錶到新的表。在這個過程當中一個新的。 ibd表空間將被建立和空間將被回收。性能
具體的咱們來看一個例子:優化
mysql> select count(*) from salaries; +----------+ | count(*) | +----------+ | 2844047 | +----------+ 1 row in set (0.00 sec) mysql>
[root@localhost ~]# ls -lh /data/mysql/employees/salaries.ibd -rw-rw---- 1 mysql mysql 140M Mar 26 22:12 /data/mysql/employees/salaries.ibd [root@localhost ~]#
mysql> delete from salaries limit 2000000; Query OK, 2000000 rows affected (37.50 sec) mysql> select count(*) from salaries; +----------+ | count(*) | +----------+ | 844047 | +----------+ 1 row in set (0.13 sec) mysql>
[root@localhost ~]# ls -lh /data/mysql/employees/salaries.ibd -rw-rw---- 1 mysql mysql 140M Mar 26 23:56 /data/mysql/employees/salaries.ibd [root@localhost ~]#
能夠看見雖然刪除200w記錄後,可是ibd文件並無減少,仍是140M。spa
mysql> optimize table salaries; +--------------------+----------+----------+-------------------------------------------------------------------+ | Table | Op | Msg_type | Msg_text | +--------------------+----------+----------+-------------------------------------------------------------------+ | employees.salaries | optimize | note | Table does not support optimize, doing recreate + analyze instead | | employees.salaries | optimize | status | OK | +--------------------+----------+----------+-------------------------------------------------------------------+ 2 rows in set (7.89 sec) mysql>
[root@localhost ~]# ls -lh /data/mysql/employees/salaries.ibd -rw-rw---- 1 mysql mysql 48M Mar 27 00:01 /data/mysql/employees/salaries.ibd [root@localhost ~]#
在OPTIMIZE 優化表後,能夠回收空間。正如你看到的,salaries.ibd文件的大小減少從140M減少到48M。
我想在這裏提一提,在這個過程當中該表將被鎖定(Table locked for just Writes),當操做比較大的表時,這會影響性能,數據沒法寫入。因此,若是不想要鎖定表,咱們能夠使用Percona的pt-online-schema-change。它能夠改變表的存儲引擎而且不會鎖表。能夠使用ALTER TABLE ENGINE=INNODB,這將從新建立表並回收空間。code
mysql> select count(*) from salaries; +----------+ | count(*) | +----------+ | 2844047 | +----------+ 1 row in set (0.00 sec) mysql> delete from salaries limit 2000000; Query OK, 2000000 rows affected (21.88 sec) mysql> \! ls -lh /data/mysql/employees/salaries.ibd -rw-rw---- 1 mysql mysql 140M Mar 27 00:21 /data/mysql/employees/salaries.ibd
接下來使用pt-online-schema-change回收空間:
[root@localhost ~]# pt-online-schema-change --alter "ENGINE=InnoDB" D=employees,t=salaries --execute Operation, tries, wait: copy_rows, 10, 0.25 create_triggers, 10, 1 drop_triggers, 10, 1 swap_tables, 10, 1 update_foreign_keys, 10, 1 Altering `employees`.`salaries`... Creating new table... Created new table employees._salaries_new OK. Altering new table... Altered `employees`.`_salaries_new` OK. 2014-03-27T00:24:29 Creating triggers... 2014-03-27T00:24:29 Created triggers OK. 2014-03-27T00:24:29 Copying approximately 843830 rows... 2014-03-27T00:24:41 Copied rows OK. 2014-03-27T00:24:41 Swapping tables... 2014-03-27T00:24:41 Swapped original and new tables OK. 2014-03-27T00:24:41 Dropping old table... 2014-03-27T00:24:41 Dropped old table `employees`.`_salaries_old` OK. 2014-03-27T00:24:41 Dropping triggers... 2014-03-27T00:24:41 Dropped triggers OK. Successfully altered `employees`.`salaries`. [root@localhost ~]# ls -lh /data/mysql/employees/salaries.ibd -rw-rw---- 1 mysql mysql 48M Mar 27 00:24 /data/mysql/employees/salaries.ibd [root@localhost ~]#
能夠看見已經成功釋放空間。從140M縮小到48M
使用該工具須要注意:
請確保有足夠的空間運行pt-online-schema-change,由於它會建立一個包含原始表的大小大體相同的臨時表。在主的操做會應用到從服務器!(假如你是主從環境)
參考資料:
http://www.mysqlperformanceblog.com/2013/09/25/how-to-reclaim-space-in-innodb-when-innodb_file_per_table-is-on/
http://www.percona.com/doc/percona-toolkit/2.1/pt-online-schema-change.html