我想知道一个MySQL表在磁盘上占用多少空间,但这似乎微不足道。不应该在INFORMATION_SCHEMA.TABLES中提供此信息吗?没那么简单!这个看似简单的问题在MySQL中其实很复杂。MySQL支持多种存储引擎(其中一些根本不在磁盘上存储数据),以及不同的数据存储格式。例如,InnoDB存储引擎为MySQL5.7提供了三种“基本”格式,包括row_formats和两种可压缩类型。为了简化:我们如何找到存储在其自己的表空间中的InnoDB表在磁盘上的表大小(提供innodb_file_per_table=1)。在我们得到答案之前,这是一个通过sysbench运行的预先获得的图表(批量数据插入表):该图表显示了由从INFORMATION_SCHEMA.TABLES获得的data_length和index_length定义的表大小。随着数据的增长,您可以预期该表会突飞猛进地增长(有时增长10GB或更多)。该图与磁盘上数据变化的方式不匹配,它逐渐增长(如预期):-rw-r-----1mysqlmysql220293234688Jan2517:03sbtest1.ibd-rw-r-----1mysqlmysql220310011904Jan2517:03sbtest1.ibd-rw-r-----1mysqlmysql222499438592Jan2517:07sbtest1.ibd从这个实验我们可以看出,MySQL并没有真正实时维护data_length和index_length的值,而是周期性地刷新它们——并且不定期刷新。在图表的后半部分,一些数据刷新变得更加规律。这与图表的第一部分不同,在该部分中,统计信息似乎在每次10%的行更改时更新。table_rows、data_free或update_time,它们也是实时更新的。为了让information_schema在MySQL5.7中获得更准确的实时信息,需要做两件事:禁用innodb_stats_persistent启用innodb_stats_on_metadata这两者都会带来严重的成本。禁用持久统计意味着每次服务器启动时InnoDB都必须刷新统计信息,这很昂贵并且会在重新启动之间产生不稳定的查询计划。有没有更好的办法?原来是有的。可以通过INNODB_SYS_TABLESPACES查看表空间信息表,查看实际文件大小。与index_length和data_length不同,INNODB_SYS_TABLESPACES是实时更新的,无需特殊配置:mysql>select*fromINFORMATION_SCHEMA.INNODB_SYS_TABLESPACESwherename='sbinnodb/sbtest1'\G*****************************1.row******************************空间:42NAME:sbinnodb/sbtest1FLAG:33FILE_FORMAT:BarracudaROW_FORMAT:DynamicPAGE_SIZE:16384ZIP_PAGE_SIZE:0SPACE_TYPE:SingleFS_BLOCK_SIZE:4096FILE_SIZE:245937209344ALLOCATED_SIZE:2459372666881rowinset(0.00sec)使用此表的好处是它还处理新功能“InnoPage_whichDB”的逻辑文件sizeondisk)和allocated_file文件分配的空间之间的差异可以显着减小)。最后,让我们看看不同的InnoDB压缩方法如何影响information_schema中提供的信息。mysql>选择*fromINFORMATION_SCHEMA.INNODB_SYS_TABLESPACESwherename='sbinnodb/testcomp'G******************************1.row***************************SPACE:48NAME:sbinnodb/testcompFLAG:33FILE_FORMAT:BarracudaROW_FORMAT:DynamicPAGE_SIZE:16384ZIP_PAGE_SIZE:0SPACE_TYPE:SingleFS_BLOCK_SIZE:4096FILE_SIZE:285212672ALLOCATED_SIZE.0inset4010row如果(4010row)正在使用旧版InnoDB压缩(InnoDB表压缩),您将看到data_length和index_length中显示的压缩数据大小作为结果。例如,avg_row_length会比您预期的低很多。如果你在MySQL5.7中使用新的InnoDB压缩(InnoDBPageCompression),你会看到文件大小对应的值,而不是information_schema中显示的分配大小。结论回答“这张表在磁盘上占用多少空间?”这个微不足道的问题。在MySQL中真的不是一个简单的问题——明显的数据,可以得到错误的答案。有关InnoDB表的实际文件大小值,请参阅INFORMATION_SCHEMA.INNODB_SYS_TABLESPACES。
