MySQL:数据库表的空间回收

1. 表数据的存储方式

  表数据既可以存储在共享表空间,也可以时单独的文件。这个行为由参数 innodb_file_per_table 控制:

  设置为 OFF 时,表示表数据存储在共享表空间;

  设置为 ON 时,表示表数据单独存储在一个以.ibd为后缀的文件之中;

  MySQL 5.6.6后默认值为 ON 。

  当使用 drop table 命令时,如果表数据存储在单独的文件中,系统直接会删除这个文件;如果表数据存储在共享表空间,即使删除表也不会回收表空间。

2. 数据删除流程

  当删除一条记录后,这个记录的位置就可以被复用,不过只限于符合条件的数据;

  当整个数据页的记录全部被删除后,这个数据页可以复用到任何位置;

  使用delete 删除记录后,只是把记录或者数据页标记为可复用,并不会改变数据文件的大小;

  一个表经过大量的增删改之后,可能会有许多没有被利用的空间,此时就需要重建表来收缩空间。

3. 重建表

  可以使用 alter table xxx  engine = InnoDB命令重建表;

  MySQL 5.6.6 引入 Online DDL,可以支持重建表时同时进行增删改查操作,大概流程如下:

  1. 建立临时文件,扫描表主键的所有数据页;
  2. 用数据页中表的记录生成B+树,存储到临时文件;
  3. 生成临时文件的过程中,将这个期间对表的所有操作记录在 row log 的日志文件中;
  4. 临时文件生成后,将日志中的操作应用到临时文件;
  5. 临时文件替换原来的表数据文件;

  alter 语句启动时获取到表的DDL写锁,在拷贝数据前退化为读锁,退化读锁后可以继续进行增删改查操作,不释放锁是为了禁止其他线程对该表进行DDL操作;

原文地址:https://www.cnblogs.com/virgosnail/p/10473644.html