最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
如何从多服务器中查找占用空间最大的表_跨实例空间容量分析
时间:2026-07-13 09:42:57 编辑:袖梨 来源:一聚教程网
查MySQL表大小不能只依赖information_schema.tables,因其data_length和index_length是估算值;真实磁盘占用需结合innodb_file_per_table配置,通过扫描.ibd文件(或ibdata1)并排除日志、临时文件等干扰项来准确获取。
查 MySQL 表大小不能只看 information_schema.tables
因为 information_schema.tables 里 data_length 和 index_length 是估算值,尤其在 innodb 表启用 innodb_file_per_table=off 时,所有表共用 ibdata1,这些字段会显示为 0 或严重失真。真实磁盘占用得看物理文件大小。
- 优先用
SELECT table_schema, table_name, round((data_length + index_length) / 1024 / 1024, 2) AS mb FROM information_schema.tables WHERE table_schema NOT IN ('mysql','information_schema','performance_schema','sys') ORDER BY mb DESC LIMIT 10;快速筛查——但仅当innodb_file_per_table=ON且未用压缩/页压缩时结果才可信 - 跨实例比对前,先确认各实例的
innodb_file_per_table值:SHOW VARIABLES LIKE 'innodb_file_per_table';,值为OFF的实例必须跳过该 SQL,改用文件系统层分析 - 如果表启用了
ROW_FORMAT=COMPRESSED或KEY_BLOCK_SIZE,data_length会反映压缩后大小,但磁盘上实际占用可能更小(取决于文件系统块对齐),此时 SQL 结果反而比物理大小还小
Linux 下批量获取 MySQL 数据目录中表文件大小
直接扫 /var/lib/mysql/*/ 下的 .ibd 文件最可靠,尤其适合 innodb_file_per_table=ON 场景。注意区分表名和数据库名嵌套路径,别漏掉分区表产生的子目录。
- 进主数据目录执行:
find /var/lib/mysql -name "*.ibd" -type f -printf "%s %pn" | sort -nr | head -20 | awk '{print $1/1024/1024 " MBt" $2}' - 分区表的
.ibd文件可能在/var/lib/mysql/dbname/tablename#P#p0.ibd这类路径下,上面命令能覆盖;但若用mysqld --datadir指定了非默认路径,得先用mysql -e "SELECT @@datadir;"确认真实路径 - 遇到权限拒绝,别直接加
sudo find——MySQL 进程用户(如mysql)可能限制了文件可见性,应切换到该用户执行:sudo -u mysql find ...
跨服务器汇总时别忽略 ibdata1 和 ib_logfile* 的干扰
当某台 MySQL 实例 innodb_file_per_table=OFF,所有表数据都挤在 ibdata1 里,这时单看 .ibd 文件会完全漏掉真实主力占用。而 ib_logfile* 虽然属于日志,但常被误当成“可删”大文件参与容量统计,导致误判。
- 检查
ibdata1大小:ls -lh /var/lib/mysql/ibdata1;若远大于所有.ibd总和,说明该实例必须单独处理:无法按表粒度定位,只能整体优化或迁移 -
ib_logfile0和ib_logfile1大小由innodb_log_file_size决定,是固定循环写入的日志,不随表增长——跨实例比容量时应排除它们,否则高并发实例会因日志大而“虚假上榜” - 临时表空间
ibtmp1可能暴涨(尤其大量排序/JOIN),但它会在 MySQL 重启后清空,不属于持久表容量,也建议过滤
Python 脚本一键拉取多实例表大小并排序
手动 ssh 登每台机器太慢,用 Python + paramiko 批量执行 find 命令再合并排序最省事。关键是把不同实例的路径、用户、过滤逻辑封装进配置,避免硬编码。
- 核心命令保持简洁:
find {datadir} -name "*.ibd" -type f -printf "%s %pn" 2>/dev/null | head -5000(加head防止超大实例卡死) - 脚本里对每行输出做
os.path.basename()提取表名,用os.path.dirname()截出库名,再正则清洗掉分区后缀(如#P#p0),才能按逻辑表归并 - 注意时区与 SSH 连接超时:某些旧版 MySQL 服务器时间不准,
paramiko默认 timeout 是 10 秒,遇到慢盘 I/O 容易中断,建议设成timeout=60
真正麻烦的不是查大小,而是查完发现:同一张表在 A 实例占 50GB,在 B 实例只有 2GB——这时候得立刻去看 pt-table-checksum 或 binlog 位点,大概率是主从延迟、删表没同步、或者某边开了 innodb_stats_persistent=OFF 导致统计信息失效。这些细节不核对,光排大小顺序没意义。
相关文章
- 王者荣耀世界零氪玩家如何生存 07-28
- 快手极速版怎么绑定手机号 07-28
- 明日方舟和轻松小熊联动活动内容一览 07-28
- 逆战未来黎明之光 逆战未来黎明之光玩法机制与新手入门指南 07-28
- 植物大战僵尸融合版毁灭土豆地雷介绍 07-28
- 逆战未来飓风之龙 逆战未来飓风之龙武器获取方法详解 07-28