如何查看MySQL的表空间

本文探讨了在MySQL中获取表空间真实大小的有效方法。传统方法通过information_schema.TABLES获取的data_length和index_length并非实时更新,而INNODB_SYS_TABLESPACES表能提供实时且准确的数据,包括文件大小和已分配空间,不受innodb_stats_persistent和innodb_stats_on_metadata配置影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

常规方法

通常情况下,我们一般的思路是通过下面的方式获取表空间:

SELECT CONCAT( table_schema, '.', table_name ) table_name, 
    CONCAT( ROUND( data_length / ( 1024 *1024 ) , 2 ) , 'M' ) data_length, 
    CONCAT( ROUND( index_length / ( 1024 *1024 ) , 2 ) , 'M' ) index_length, 
    CONCAT( ROUND( data_free / ( 1024 *1024 ) , 2 ) , 'M' ) free_length, 
    CONCAT( ROUND( ROUND( data_length + index_length + data_free ) / ( 1024 *1024 ) , 2 ) , 'M' ) total_size, 
    CONCAT( ROUND( ROUND( data_free ) / ( 1024 *1024 ) , 2 ) , 'M' ) total_wasted,
             (100*(data_free/(data_length + index_length + data_free))) percent_wasted
FROM information_schema.TABLES
WHERE table_schema = '[NAME_OF_DPA_DATABASE]'
    AND (100*(data_free/(data_length + index_length+data_free))) > [MINIMUM_PERCENT_WASTED]
    AND (data_length + index_length + data_free) > [MINIMUM_FILESIZE_IN_BYTES]
ORDER BY (data_length + index_length + data_free) DESC;

例如:

SELECT CONCAT( table_schema, '.', table_name ) table_name, 
    CONCAT( ROUND( data_length / ( 1024 *1024 ) , 2 ) , 'M' ) data_length, 
    CONCAT( ROUND( index_length / ( 1024 *1024 ) , 2 ) , 'M' ) index_length, 
    CONCAT( ROUND( data_free / ( 1024 *1024 ) , 2 ) , 'M' ) free_length, 
    CONCAT( ROUND( ROUND( data_length + index_length + data_free ) / ( 1024 *1024 ) , 2 ) , 'M' ) total_size, 
    CONCAT( ROUND( ROUND( data_free ) / ( 1024 *1024 ) , 2 ) , 'M' ) total_wasted,
             (100*(data_free/(data_length + index_length + data_free))) percent_wasted
FROM information_schema.TABLES
WHERE table_schema = 'dpa_repo'
    AND (100*(data_free/(data_length + index_length+data_free))) > 75
    AND (data_length + index_length + data_free) > 52428800
ORDER BY (data_length + index_length + data_free) DESC;

可能没有注意到的是

对于上述方法中的data_length 或 index_length的值MySQL并不是实时更新的,而是周期性地维护,通过测试发现当10%的行被改变时,data_length 或 index_length与正在更新的统计数据一致。
而table_rows, data_free 或 update_time却是实时更新的。
那么有没有方法在我们查询information_schema时获取到data_length和 index_length的值呢?
在MySQL 5.7里面如果想获取information_schema精确值,就要disable innodb_stats_persistent 和 enable innodb_stats_on_metadata,这两种方法都有明显的副作用。
disable innodb_stats_persistent意味着每次在MySQL启动时才会刷新统计信息,这中代价非常昂贵并且会在重启之间生成易失性查询计划。
enabling innodb_stats_on_metadata会使每次访问information_schema的时候非常非常慢。

有没有更好的办法

可以查看information.INNODB_SYS_TABLESPACES查看真实的文件大小,不像index_length and data_length,INNODB_SYS_TABLESPACES的值是实时更新的,也不需要额外的配置:

mysql> select * from INFORMATION_SCHEMA.INNODB_SYS_TABLESPACES where name='sbinnodb/sbtest1' G
*************************** 1. row ***************************
        SPACE: 42
         NAME: sbinnodb/sbtest1
         FLAG: 33
  FILE_FORMAT: Barracuda
   ROW_FORMAT: Dynamic
    PAGE_SIZE: 16384
ZIP_PAGE_SIZE: 0
   SPACE_TYPE: Single
FS_BLOCK_SIZE: 4096
    FILE_SIZE: 245937209344
ALLOCATED_SIZE: 245937266688
1 row in set (0.00 sec)

用这个表还有一个更好的事情是:它可以处理MySQL 5.7 新的“Innodb Page Compression”,这不同于file_size(它是在磁盘上的逻辑文件的大小),也不同于allocated_size(它是文件已经分配的空间,可以小很多)

mysql> select * from INFORMATION_SCHEMA.INNODB_SYS_TABLESPACES where name='sbinnodb/testcomp' G
*************************** 1. row ***************************
        SPACE: 48
         NAME: sbinnodb/testcomp
         FLAG: 33
  FILE_FORMAT: Barracuda
   ROW_FORMAT: Dynamic
    PAGE_SIZE: 16384
ZIP_PAGE_SIZE: 0
   SPACE_TYPE: Single
FS_BLOCK_SIZE: 4096
    FILE_SIZE: 285212672
ALLOCATED_SIZE: 113004544
1 row in set (0.00 sec)

结论

查INFORMATION_SCHEMA.INNODB_SYS_TABLESPACES获取INNODB表的真实文件大小。

参考

https://www.percona.com/blog/2016/01/26/finding_mysql_table_size_on_disk/
https://support.solarwinds.com/Success_Center/Database_Performance_Analyzer_(DPA)/Knowledgebase_Articles/MySQL_repository_table_optimization_for_DPA
https://dev.mysql.com/doc/refman/5.7/en/innodb-persistent-stats.html

<think>嗯,用户想了解如何用SQL语句查看MySQL表空间。首先,我得回忆一下MySQL表空间的相关知识。表空间主要分为系统表空间和独立表空间,可能还有通用表空间之类的。系统表空间存储数据字典、Undo日志等信息,而独立表空间每个表单独一个.ibd文件。用户可能需要查看这些信息,比如表的大小、数据文件的位置等。 接下来,用户需要的是具体的SQL语句。我记得在information_schema数据库中,有几个表可能有用,比如TABLES和FILES。TABLES表里有DATA_LENGTH和INDEX_LENGTH,可以计算表的大小。而FILES表可能有文件的具体路径和大小,但需要权限才能访问。 首先,我应该给出查询单个表大小的语句。比如SELECT语句从TABLES中选取TABLE_NAME, DATA_LENGTH等字段,然后计算总大小。可能还要转换单位,比如用MB显示,这样用户更直观。 然后,可能需要查看所有数据库表空间情况,这时候需要汇总所有表的数据,按数据库分组。SUM函数加上GROUP BY TABLE_SCHEMA应该可以做到。 还有独立表空间文件路径,可以通过SHOW VARIABLES LIKE 'datadir'获取数据目录,然后每个数据库文件夹里会有表的.ibd文件。这个可能需要用语句拼接,或者在操作系统层面查看,但用户可能希望用SQL解决,所以可能需要结合文件系统的信息。 另外,系统表空间的位置通常在datadir下的ibdata1文件,可以通过变量innodb_data_file_path查看配置。可能需要用SHOW VARIABLES来获取这些信息。 还要注意权限问题,因为访问information_schema可能需要一定的权限。另外,不同版本的MySQL可能有差异,比如InnoDB的配置是否使用独立表空间由innodb_file_per_table控制,这个变量可能需要检查。 用户可能还想知道如何优化或管理表空间,比如OPTIMIZE TABLE或者ALTER TABLE重建表,但问题主要是查看,所以这部分可能作为附加信息提到。 需要确保提供的SQL语句正确,比如字段名是否正确,单位转换是否准确。例如,DATA_LENGTH的单位是字节,转换成MB需要除以1024两次。同时,处理四舍五入,使用ROUND函数。 另外,可能需要提醒用户,某些查询如information_schema.FILES可能需要更高的权限,或者在某些托管环境中不可用。这时候可能需要替代方法,比如查看文件系统。 最后,总结一下步骤,分点列出不同的方法,并解释每个方法的作用,让用户能根据需求选择。同时,补充注意事项,比如权限、版本差异等,确保用户在实际操作中不会遇到问题。</think>在 MySQL查看表空间信息,可以通过以下 SQL 语句和系统表实现: --- ### **一、查看单个表空间大小** ```sql SELECT TABLE_NAME AS `表名`, ROUND((DATA_LENGTH + INDEX_LENGTH) / 1024 / 1024, 2) AS `总空间(MB)`, ROUND(DATA_LENGTH / 1024 / 1024, 2) AS `数据空间(MB)`, ROUND(INDEX_LENGTH / 1024 / 1024, 2) AS `索引空间(MB)` FROM information_schema.TABLES WHERE TABLE_SCHEMA = '你的数据库名' AND TABLE_NAME = '你的表名'; ``` --- ### **二、查看整个数据库表空间** ```sql SELECT TABLE_SCHEMA AS `数据库名`, SUM(DATA_LENGTH + INDEX_LENGTH) / 1024 / 1024 AS `总空间(MB)` FROM information_schema.TABLES GROUP BY TABLE_SCHEMA; ``` --- ### **三、查看独立表空间文件路径** ```sql -- 查看数据存储目录 SHOW VARIABLES LIKE 'datadir'; -- 查看独立表空间文件名(需要访问权限) SELECT FILE_NAME, ROUND(TOTAL_EXTENTS * EXTENT_SIZE / 1024 / 1024, 2) AS `文件大小(MB)` FROM information_schema.FILES WHERE FILE_TYPE = 'TABLESPACE' AND FILE_NAME LIKE '%你的表名%'; ``` --- ### **四、查看系统表空间** ```sql -- 查看系统表空间配置 SHOW VARIABLES LIKE 'innodb_data_file_path'; ``` --- ### **五、关键说明** 1. **系统表空间 vs 独立表空间** - `innodb_file_per_table=ON` 时,表使用独立的 `.ibd` 文件 - `innodb_file_per_table=OFF` 时,表数据存储在共享的 `ibdata1` 文件 2. **单位转换** `DATA_LENGTH` 和 `INDEX_LENGTH` 的单位是字节,除以 `1024^2` 转换为 MB 3. **物理文件定位** - 独立表空间文件路径:`${datadir}/数据库名/表名.ibd` - 系统表空间文件路径:`${datadir}/ibdata1` --- ### **六、注意事项** - 需要 `SELECT` 权限访问 `information_schema` - 精确计算表空间建议使用 `innodb` 引擎 - 大表查询可能较慢,建议在非高峰时段操作 通过以上方法,可以全面了解 MySQL 表空间的使用情况。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值