MySQL 5.7 information_schema.tables中DATA_FREE值异常

问题现象

在RDS MySQL 5.7版本的实例中 ,执行如下SQL语句查询DATA_FREE值时,发现DATA_FREE的较大值集中在information_schema库下的部分表,这些表的DATA_FREE值相同且与实际的磁盘碎片空间不符。

SELECT TABLE_SCHEMA, TABLE_NAME, DATA_FREE FROM INFORMATION_SCHEMA.TABLES ORDER BY DATA_FREE DESC LIMIT 10; 

查询结果:

+--------------------+-----------------+-----------+
| TABLE_SCHEMA       | TABLE_NAME      | DATA_FREE |
+--------------------+-----------------+-----------+
| information_schema | COLUMNS         |   8388608 |
| information_schema | EVENTS          |   8388608 |
| information_schema | OPTIMIZER_TRACE |   8388608 |
| information_schema | PARAMETERS      |   8388608 |
| information_schema | PARTITIONS      |   8388608 |
| information_schema | PLUGINS         |   8388608 |
| information_schema | PROCESSLIST     |   8388608 |
| information_schema | ROUTINES        |   8388608 |
| information_schema | TRIGGERS        |   8388608 |
| information_schema | VIEWS           |   8388608 |
+--------------------+-----------------+-----------+

可能原因

MySQL 5.7版本存在缺陷:

information_schema中的部分表(如COLUMNS、EVENTS等)存储引擎为InnoDB,类型为临时表,其表空间均为innodb_temporary(该空间与文件ibtmp1相对应)。

在使用上述SQL语句查询这些临时表的磁盘碎片空间时,INFORMATION_SCHEMA.TABLES中的DATA_FREE均读取的是文件ibtmp1的磁盘碎片空间值(该值包含了该文件中所有表的磁盘碎片空间),而并非每个表自身的磁盘碎片空间值。

说明

可执行如下SQL语句查询ibtmp1的DATA_FREE值:

SELECT TABLESPACE_NAME, FILE_NAME, ENGINE, DATA_FREE FROM INFORMATION_SCHEMA.FILES WHERE TABLESPACE_NAME='innodb_temporary';

查询结果:

+------------------+-----------+--------+-----------+
| TABLESPACE_NAME  | FILE_NAME | ENGINE | DATA_FREE |
+------------------+-----------+--------+-----------+
| innodb_temporary | ./ibtmp1  | InnoDB |   8388608 |
+------------------+-----------+--------+-----------+

可以看到,问题现象中所述的DATA_FREE异常值和ibtmp1的DATA_FREE相同。

解决方案

存储引擎为InnoDB的临时表的磁盘碎片空间查询不准确是由MySQL 5.7版本的缺陷导致的,目前暂无解决方案。您可以忽略该问题。如果您不希望遇到此问题,建议升级到MySQL 8.0版本,升级方法请参见升级数据库版本

如果您希望释放ibtmp1文件所占用的磁盘碎片空间,可以重启实例,重启后ibtmp1文件所占用的磁盘空间会自动恢复至初始值(由innodb_temp_data_file_path参数定义)。