MySQL表空间释放

我们在需要释放MySQL磁盘空间的时候第一反应是删除或者归档一些历史数据,但是这样的做法不一定是绝对正确的,因为有时候删除数据也不一定会及时释放磁盘空间。


在项目中使用神策因为是私有化部署所以极度’珍惜‘磁盘空间,数据量的确太大了。那时候神策的工程师告诉我们可以删除一些不要的数据,但是磁盘空间无法及时归还而是标记删除后面优先使用这部分删除的空间。


带着上面的一些问题我逐步巩固了一些知识

MySQL的物理存储文件

myisam

  • .frm
    表相关元素信息都存放frm文件,包括表的一些结构的定义信息,共有特性
  • .myd
    myisam专用,用于存储myisam表数据
  • .myi
    myisam专用,用于存储myisam表的索引相关信息

InnoDB

.ibd 和 ibddate1 是二选一的,通过innodb_file_per_table来控制,ON表示独立文件存储不和系统表空间公用。5.6开始这个参数是默认打开的

  • .frm 同上
  • .ibd 独占表空间文件
  • ibdata1 默认表空间文件

删除数据

  1. innodb_file_per_table为ON时我们drop table时就会删除相应的.idb文件,而为OFF时就只会标记删除实际空间没释放。

  2. 在删除table中的一部分数据时,并不会释放磁盘的空间出来。delete命令不能回收表空间,只能标记出来删除的数据位置为可复用,数据进来后填补这些’空洞’。

回收表空间

既然delete不能释放表空间,那我们该怎么办呢?

  1. 我们可以新建立一张表结构一样的 B 表
  2. 把A表的数据导入B表
  3. 然后删除A表,B表重命名A表

可以使用alter table name engine=InnoDB完成上述操作

在5.6版本前这个过程不能在线完成。在5.6版本后对这个流程做了优化,可以在线进行

  1. 建立一个临时文件,扫描A表主键的所有数据页
  2. 用A的数据页生成B+树,存储到临时文件
  3. 生成临时文件过程中,记录实时更改的记录
  4. 临时文件生成后,将记录的更改日志文件同步过去。
  5. 用临时文件替换表A的数据文件

题外话

这边在扩充2个优化表的函数命令

  • analyze table t
    重新统计索引信息,不会修改数据
  • optimize table t
    等于 alter table name engine=InnoDB + analyze
  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!

请我喝杯咖啡吧~