维护mysql 对表空间的回收策略是只拓展,不回收。对表执行delete之后,表空间是不回收的,空闲的空间可以被insert 继续使用,通常执行truncate,重新逻辑导出,再导入或者执行optimize table 三种都可以重新使用未使用的表空间。
本文介绍一下optimize table OPTIMIZE TABLE可以重新利用未使用的空间,并整理数据文件的碎片。
1 演示回收空间
删除之前:
[root@rac1 test]# ll tab.ibd
-rw-rw---- 1 mysql mysql 150994944 10-16 22:15 tab.ibd
对表进行删除操作:
root@rac1 : test 21:12:00> optimize table tab;
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0
删除之后:
[root@rac1 test]# ll tab.ibd
-rw-rw---- 1 mysql mysql 98304 10-16 22:15 tab.ibd
显然 ibd文件经过optimize之后 明显的减小了。
2 使用范围
OPTIMIZE TABLE只对MyISAM, BDB和InnoDB表起作用。
对于MyISAM表,OPTIMIZE TABLE按如下方式操作:
1.如果表已经删除或分解了行,则修复表。
2.如果未对索引页进行分类,则进行分类。
3.如果表的统计数据没有更新(并且通过对索引进行分类不能实现修复),则进行更新。
对于BDB表,OPTIMIZE TABLE目前被映射到ANALYZE TABLE上。
对于InnoDB表,OPTIMIZE TABLE被映射到ALTER TABLE上,这会重建表。重建操作能更新索引统计数据并释放成簇索引中的未使用的空间。
3 对于 M-S,M-M 架构的数据库
如果不想把optimize table 写入从数据库,可以执行
OPTIMIZE NO_WRITE_TO_BINLOG TABLE
这样命令就不会写入binglog 并且不被从库执行。
4 遇到的问题
如果在使用optimize的时候遇到如下错误:
root@rac1 : test 22:10:22> optimize table tab;
+----------+----------+----------+-------------------------------------------------------------------+
| Table | Op | Msg_type | Msg_text |
+----------+----------+----------+-------------------------------------------------------------------+
| test.tab | optimize | note | Table does not support optimize, doing recreate + analyze instead |
| test.tab | optimize | status | OK |
+----------+----------+----------+-------------------------------------------------------------------+
2 rows in set (29.88 sec)
使用--skip-new或--safe-mode选项可以启动mysqld。通过启动mysqld,您可以使OPTIMIZE TABLE对其它表类型起作用。
注意,在OPTIMIZE TABLE运行过程中,MySQL会锁定表。