首页 / 资讯中心 / 文章详情

数据库磁盘占用排查指南:MySQL/PostgreSQL/SQL Server/Oracle命令与避坑

数据库磁盘占用排查指南:MySQL/PostgreSQL/SQL Server/Oracle命令与避坑 ★ FEATURED ARTICLE
先聊结论查看数据库占用磁盘空间不是一条命令能解决的事。因为数据库文件不只是数据和索引还有日志、临时文件、回滚段操作系统上看到的“目录大小”和数据库内部统计的“表大小”往往对不上。这篇文章把主流数据库里常用的几种查看方法、对应的命令和 SQL、以及我踩过的几个坑都整理了一遍覆盖 MySQL、PostgreSQL、SQL Server、Oracle适合运维、DBA、后端开发随时翻出来用。文章不会只丢命令还会解释为什么查出来的数字有偏差以及在磁盘告警时怎么判断、怎么安全清理避免出现“统计显示 200MB、实际文件 600MB”这类让人误判的情况。阅读时间大约十分钟干货居多。1. 查看磁盘占用前先分清三个层面1.1 文件系统看到的占用和数据库统计的占用我最早做数据库运维时也犯过一个错误新人发来一张磁盘告警截图我直接登录服务器执行df -h看到数据目录所在分区快满就手动去删文件结果删完发现空间没降多少再一查才知道删掉的只是从库的归档文件主库那块几 GB 的 binlog 还躺在那里瞬间头皮发麻。所以要先建立概念磁盘占用有“文件层”和“数据库层”两套视角。文件层由操作系统管理du、ls、df看到的是实际文件块占用数据库层是数据字典和统计表中的逻辑大小比如 MySQL 的information_schema.tables、PostgreSQL 的pg_database_size。两者不是一回事差距可能很大。为什么会有差距我归纳出三个原因数据库统计信息是异步刷新的不一定和磁盘实时一致。InnoDB 表有独立表空间、共享表空间、undo、redo 等统计 SQL 通常只统计逻辑页不含历史数据版本和碎片。文件预分配和稀疏文件会让ls看到的“长度”和实际磁盘占用不一致。换句话说想要一次准确结论必须“两层对拍”先用系统命令看文件再用数据库查询看统计最后以实际文件大小作为仲裁参考。1.2 排查的整体顺序我自己现在遇到磁盘告警一定按照固定顺序来不乱翻目录因为乱翻很容易漏掉关键对象。整体顺序是先看磁盘分区df -h确认是哪个分区告警使用率多少inode 有没有耗尽。再定位数据库数据目录和日志目录用du找出占用大的子目录。然后进数据库查询库大小、表大小、索引大小列出 TOP 20。最后核对所有日志文件binlog、WAL、错误日志、慢查询日志、临时表空间。确认占用的真实对象后再决定是清理日志、归档备份、还是重建表回收空间。这个顺序把“操作系统视角”和“数据库视角”串起来了基本不会漏掉最大占用者。很多新人一上来就执行大 SQL 查表大小结果数据库统计信息异常查出来最大表才几 GB可磁盘已经满了最后发现是 binlog 没清理这就是没有先看日志目录导致的问题。1.3 需要关心的“隐藏大户”除了数据表和索引下面这些对象经常悄无声息地把磁盘撑满属于排查时必须留意的“隐藏大户”binlog / WAL / redo logMySQL 的 binlog、PostgreSQL 的 pg_wal、SQL Server 的事务日志、Oracle 的 redo log都可能因为备份策略、归档配置或长事务而膨胀。临时表空间MySQL 的ibtmp1PostgreSQL 的base/pgsql_tmpSQL Server 的 tempdb大排序或大事务会瞬间放大它们。数据库备份文件很多人把备份直接放在数据库数据盘备份积压会导致磁盘告警但数据库内部统计完全看不到。错误日志和慢查询日志开启后如果不做轮转大小可以涨到几十 GB。回滚段/undo长事务或大事务产生的历史版本在事务结束前不会释放占用的空间会影响文件大小。这些对象有的能通过数据库命令查看有的只能靠文件系统命令查看所以绝对不能只看其中一种。2. 先从操作系统层面对文件分布做到心里有数2.1 确定数据目录和日志目录操作系统层面的第一步是定位数据库相关文件到底放在哪里。很多人只知道默认路径比如 MySQL 是/var/lib/mysqlPostgreSQL 是/var/lib/postgresql/版本/main但实际生产环境经常是自定义的数据盘盲目去默认目录查会一无所获。我常用的做法是让数据库自己告诉你路径。MySQL 中执行SHOW VARIABLES LIKE datadir; SHOW VARIABLES LIKE log_bin_basename; SHOW VARIABLES LIKE innodb_log_group_home_dir; SHOW VARIABLES LIKE tmpdir;PostgreSQL 中执行SHOW data_directory; SHOW log_directory; SHOW archive_command;如果连不上数据库就从配置文件和进程启动参数里找。比如看ps -ef | grep mysqld启动参数里往往带有--datadir/data/mysqlPostgreSQL 可以看postgresql.conf中的data_directory和log_directory。拿到路径后再用lsof -p 数据库进程PID | awk {print $NF} | sort | uniq -c这类方式可以列出进程正在打开的所有文件路径很多你意想不到的日志、socket、临时文件都能暴露出来。实际操作时我喜欢先ps -ef拿到 PID再lsof -p PID看文件描述符效率比满盘翻目录高很多。2.2 用 du 快速定位大目录定位到目录后直接用du统计每个子目录的大小这是最快、最稳的方法。对比ls -lhdu更准因为它统计的是磁盘块的实际占用不是文件的逻辑长度而且不会把稀疏文件空洞也当内存占用。我的常用命令是du -xh --max-depth2 /var/lib/mysql | sort -rh | head -30参数解释一下-x不要跨文件系统避免把挂载点外的目录也算进来。-h人类可读格式显示 K/M/G。--max-depth2最多显示两层目录避免子目录展开太多刷屏。sort -rh | head -30按大小逆序排列显示前 30 个一眼看到最大目录。如果想看某一层的总和可以配合awkdu -sh /var/lib/mysql/*/ | sort -rh | head -20在生产环境执行du时要小心如果数据库正在大量写入du会读取整个目录树产生额外磁盘 IO。低峰期使用问题不大但不要在高并发时段频繁执行du -sh全目录尤其数据库数据文件特别多时。我见过有人在大促前反复du -sh /var/lib/mysql结果磁盘 IO 被打高这就是操作时机没选好。2.3 检查被删除但仍然被进程占用的文件这是一个常见的诡异场景明明用rm删掉了几个大日志文件df -h显示可用空间没有变。原因通常是数据库进程还持有已删除文件的文件句柄文件虽然看不到了但磁盘空间不会释放直到进程关掉句柄。排查命令lsof L1L1表示列出 link count 为 0 但仍被打开的文件。更常规的写法是lsof | grep deleted我们曾经在 MySQL 环境遇到过一次binlog 手动清理后df空间还是满的执行lsof发现 mysqld 进程依然持有十几个已删除的旧 binlog 句柄每个 1GB 左右。当时没有直接 kill 进程而是先确认维护窗口再重启实例空间才真正释放。这种问题并不只出现在 MySQLPostgreSQL、Redis 也一样。避免方式是日志轮转时不要简单rm而应该使用logrotate的copytruncate或者清理后确认进程已经不再持有旧文件再决定是否重启。3. 数据库内部统计信息从库到表逐一排查3.1 MySQLinformation_schema 和 sys schema操作系统层看完后下一步进数据库里看逻辑占用。MySQL 最常用的是information_schema.tables里面有每个表的data_length数据页总长和index_length索引页总长这两个值加起来可以近似认为是表占用的逻辑空间。按库统计的经典 SQLSELECT table_schema AS db_name, ROUND(SUM(data_length index_length) / 1024 / 1024, 2) AS size_mb, ROUND(SUM(data_length) / 1024 / 1024, 2) AS data_mb, ROUND(SUM(index_length) / 1024 / 1024, 2) AS index_mb, COUNT(*) AS table_count FROM information_schema.tables GROUP BY table_schema ORDER BY size_mb DESC;按表统计和排序的 SQLSELECT table_schema AS db_name, table_name, ROUND((data_length index_length) / 1024 / 1024, 2) AS size_mb, ROUND(data_length / 1024 / 1024, 2) AS data_mb, ROUND(index_length / 1024 / 1024, 2) AS index_mb FROM information_schema.tables WHERE table_schema NOT IN (mysql, information_schema, performance_schema, sys) ORDER BY size_mb DESC LIMIT 30;如果 MySQL 版本是 5.7 并启用了 sys schema可以更省事直接查SELECT * FROM sys.schema_table_statistics_with_buffer ORDER BY total_allocated DESC LIMIT 20;这个视图会把表的行数、数据大小、索引大小、缓冲区中占用的内存都列出来运维排查很方便。但这里必须强调information_schema.tables里的data_length并不是 ibd 文件真实大小。它只是统计页数乘以页大小的估算值BLOB/TEXT 字段溢出页、碎片、尚未清理的 undo 历史都不包含所以和文件实际占用会有差距。要对表做准确判断还是要结合第 4 节的.ibd文件大小。为了让统计信息尽量准确在低峰期可以执行ANALYZE TABLE table_name;不需要对所有表都做只针对查询出来的大表和变化频繁的表因为ANALYZE本身也会产生一些 IO。3.2 PostgreSQL大小即所得但要注意 TOAST 和膨胀PostgreSQL 提供了一组专门的函数查起来比 MySQL 方便不少逻辑语义也清楚。比如查单个数据库大小SELECT pg_size_pretty(pg_database_size(your_database));查所有数据库大小SELECT datname AS db_name, pg_size_pretty(pg_database_size(datname)) AS db_size FROM pg_database ORDER BY pg_database_size(datname) DESC;查某个 schema 下所有表的大小包括索引和 TOASTSELECT schemaname, relname AS table_name, pg_size_pretty(pg_total_relation_size(relid)) AS total_size FROM pg_stat_user_tables ORDER BY pg_total_relation_size(relid) DESC LIMIT 20;这里要注意pg_total_relation_size和pg_relation_size的区别pg_relation_size(relid)只算表主体数据大小。pg_total_relation_size(relid)还包含该表的索引、TOAST 表和 TOAST 索引。所以查“哪个表最占空间”应该用pg_total_relation_size查“表数据本身多大”才用pg_relation_size。另外还可以单独看索引大小SELECT indexrelname AS index_name, pg_size_pretty(pg_relation_size(relid)) AS index_size FROM pg_stat_user_indexes ORDER BY pg_relation_size(relid) DESC LIMIT 20;PostgreSQL 有个特点更新和删除不会立刻物理释放空间而是留下 dead tuple需要日后由 VACUUM 回收。所以即使查出来表逻辑行数很少实际文件也可能很大。此时需要关注膨胀率当表膨胀明显时单纯VACUUM不能把文件变小要使用VACUUM FULL或在线重建工具而且VACUUM FULL会锁表务必在维护窗口执行。3.3 SQL Server 与 Oracle 的一页速查SQL Server 里最简单的办法是使用系统存储过程EXEC sp_spaceused;加上表名可以查看单表空间但只包含行数据、索引、未使用空间等。更全面的数据可以从sys.dm_db_partition_stats或sys.dm_db_file_space_usage取。实际排错时我习惯用这条 DMV 查库内表大小排行SELECT s.name AS schema_name, t.name AS table_name, SUM(ps.reserved_page_count) * 8 / 1024 AS reserved_mb, SUM(CASE WHEN ps.index_id IN (0,1) THEN ps.in_row_data_page_count ELSE 0 END) * 8 / 1024 AS data_mb, SUM(CASE WHEN ps.index_id 1 THEN ps.in_row_data_page_count ELSE 0 END) * 8 / 1024 AS index_mb FROM sys.tables t JOIN sys.schemas s ON t.schema_id s.schema_id JOIN sys.dm_db_partition_stats ps ON t.object_id ps.object_id GROUP BY s.name, t.name ORDER BY reserved_mb DESC;注意reserved_page_count * 8 / 1024是把页数转换成 MB因为 SQL Server 一个页是 8KB。Oracle 则主要查数据字典视图SELECT segment_name, owner, segment_type, ROUND(bytes / 1024 / 1024, 2) AS size_mb FROM dba_segments WHERE owner NOT IN (SYS,SYSTEM) ORDER BY bytes DESC FETCH FIRST 20 ROWS ONLY;如果想查数据文件总大小可以从dba_data_files获取SELECT tablespace_name, ROUND(SUM(bytes)/1024/1024/1024, 2) AS size_gb FROM dba_data_files GROUP BY tablespace_name ORDER BY size_gb DESC;Oracle 中dba_segments统计的是段分配的 extents不是实际“已使用”的大小所以表删了很多数据之后段不一定收缩查询出来的大小可能偏大需要重建或使用在线收缩功能。4. 数据文件、索引文件还是日志继续细分4.1 统计信息不可靠时直接看 ibd 文件很多时候数据库统计信息只是“参考值”真正做清理决策时要看物理文件大小。MySQL 开启独立表空间后每个 InnoDB 表对应一个.ibd文件路径一般在数据目录下的库名子目录里。可以先用下面的命令确认是否开启独立表空间SHOW VARIABLES LIKE innodb_file_per_table;如果结果是ON那么每个表都有独立文件。此时在 shell 里直接找出占用最大的表文件find /var/lib/mysql -name *.ibd -printf %s %p\n | sort -nr | head -20 | awk {printf %.2f MB\t%s\n, $1/1024/1024, $2}把%s字节数转成 MB排序前 20 个非常直观。我遇到过一个案例某个订单表用information_schema.tables查出来只有 800MB但对应的.ibd文件已经膨胀到 3.2GB。原因是表频繁更新产生大量碎片加上存在多个 BLOB 字段统计页数和实际分配页面差很多。如果只按统计信息判断会严重低估磁盘占用清理方案也完全不一样。所以我的判断原则是以.ibd文件大小作为“物理真实值”以数据库统计作为“逻辑参考值”两者差距超过 20% 就需要考虑表碎片和膨胀问题。4.2 索引、BLOB、TOAST 带来的额外空间表大小不仅包括行数据索引、大字段、TOAST 表都会占用空间而且经常是表空间膨胀的元凶。MySQL 里information_schema.tables.index_length字段就可以反映索引占用的总大小。我们可以单独查索引占用比例SELECT table_schema, table_name, ROUND(index_length / 1024 / 1024, 2) AS index_mb, ROUND((index_length / NULLIF(data_length index_length, 0)) * 100, 1) AS index_pct FROM information_schema.tables WHERE table_schema NOT IN (mysql,information_schema,performance_schema,sys) ORDER BY index_length DESC LIMIT 20;如果某个表的索引占比超过 50%说明索引冗余可能比较严重可以考虑删除低效索引或重建索引来回收空间。但删索引前要和业务确认不能只看空间就动手。PostgreSQL 的 TOAST 比较容易忽略。TOAST 表负责存储超出单页容量的长字段数据即使主表不大TOAST 也可能很大。查看方式SELECT relname AS toast_table_name, pg_size_pretty(pg_total_relation_size(relid)) AS total_size FROM pg_class WHERE oid IN ( SELECT reltoastrelid FROM pg_class WHERE reltoastrelid ! 0 ) ORDER BY pg_total_relation_size(relid) DESC LIMIT 20;TOAST 表膨胀通常是因为大量更新长字段需要 VACUUM FULL 回收空间同样要注意锁表时间。4.3 binlog、WAL、事务日志和临时文件日志类文件是磁盘占用的重灾区任何人排查磁盘占用时都不能跳过。先说 MySQL 的 binlog它记录所有变更操作在主从复制、时间点恢复时都很有用但如果不定期清理会一直膨胀。查看 binlog 当前状态SHOW MASTER STATUS;查看二进制日志列表SHOW BINARY LOGS;清理策略上一般设置自动过期时间即可MySQL 8.0 推荐用binlog_expire_logs_secondsSET GLOBAL binlog_expire_logs_seconds 604800;表示保留 7 天过期后自动清理。如果空间告警等不及自动清理可以手动清理但务必先确认所有下游已经消费完对应的 binlog否则会造成复制中断PURGE BINARY LOGS BEFORE NOW() - INTERVAL 2 DAY;PostgreSQL 对应的日志是 WAL目录通常在pg_wal下。WAL 文件可以自动回收或删除但膨胀的时候要看两点一是max_wal_size设置是否过大二是是否存在长时间未checkpoint的情况长事务会阻止 WAL 被回收。快速查看 WAL 目录大小du -sh /var/lib/postgresql/版本/main/pg_wal不要手动随机删除pg_wal下的文件那会造成数据损坏。正确做法是执行CHECKPOINT;后再观察必要时调整max_wal_size和检查长事务而不是直接删文件。SQL Server 的事务日志.ldf也是膨胀高发区。如果事务日志长时间不收缩文件会很大。查看日志文件大小DBCC SQLPERF(LOGSPACE);收缩事务日志有很多坑不建议平时主动收缩只有在确认日志备份正常且空间告警才考虑DBCC SHRINKFILE (N数据库_log, 目标大小MB);收缩前一定要确认数据库的恢复模式和日志备份策略否则日志链断裂会导致无法做时间点恢复。临时文件也很容易遗漏。MySQL 的ibtmp1是全局临时表空间默认路径在 datadir 下大小受到长查询、排序、大事务影响du -h /var/lib/mysql/ibtmp1如果它不断增长且无法释放通常是有大查询或长事务在运行可以在业务低峰重启实例来重置但临时表空间本身不会被主动压缩需要配合内存参数调整比如tmp_table_size、max_heap_table_size。PostgreSQL 的临时文件在 base 目录下的pgsql_tmp子目录如果看到 pgsql_tmp 里有很多大文件说明有排序、哈希连接或索引构建把结果倒到了磁盘需要优化 SQL 或增加 work_mem。5. 一套完整的排查与清理流程5.1 磁盘告警时的六步走真实业务里的磁盘告警往往很紧急没有时间一条一条翻文档。我把日常处理浓缩成六步基本能应对绝大多数场景执行df -h和df -i先确认是空间满还是 inode 耗尽。从数据库系统变量或配置文件中确认 datadir、logdir、backup dir。执行du -xh --max-depth2 datadir | sort -rh | head -30找出文件层最大占用。进数据库执行库大小、表大小排行 SQL找出逻辑层占用。单独检查 binlog/WAL/错误日志/慢日志/临时表空间因为配置文件不在 datadir 下也可能很大。根据对象类型决定处理方式日志该轮转轮转数据该重建重建备份该清理清理不要盲目删文件。这个流程看起来很基础但能有效避免“只看数据库表大小”或“只看目录文件”的单视角局限。尤其是第 5 步许多人会忽略日志路径不在 datadir 下的情况结果找半天找不到大文件。5.2 一键排查脚本模板为了提高效率我把这个流程写成了简单的 bash mysql 组合脚本适合 Linux 上的 MySQL 环境。脚本的逻辑很简单先打印磁盘和目录占用再查询库表和索引排行。落到具体机器上时需要根据实际数据目录、数据库登录方式调整。#!/bin/bash # 数据库磁盘占用排查脚本请在低峰期运行 DATA_DIR/var/lib/mysql MYSQL_CMDmysql -uroot -p echo 磁盘分区使用情况 df -h echo 数据目录 Top 20 子目录 du -xh --max-depth1 $DATA_DIR 2/dev/null | sort -rh | head -20 echo 大 ibd 文件 Top 20 find $DATA_DIR -name *.ibd -printf %s %p\n | sort -nr | head -20 | awk {printf %.2f MB\t%s\n, $1/1024/1024, $2} echo 库大小排行 $MYSQL_CMD -e SELECT table_schema AS db_name, ROUND(SUM(data_length index_length) / 1024 / 1024, 2) AS size_mb FROM information_schema.tables GROUP BY table_schema ORDER BY size_mb DESC; echo 表大小排行 Top 20 $MYSQL_CMD -e SELECT table_schema, table_name, ROUND((data_length index_length) / 1024 / 1024, 2) AS size_mb FROM information_schema.tables WHERE table_schema NOT IN (mysql,information_schema,performance_schema,sys) ORDER BY size_mb DESC LIMIT 20; 脚本里的 MySQL 账号建议使用只读权限的专用账号避免把 root 口令直接写在脚本里。另外du和find在超大目录下可能耗时较长建议配合timeout使用避免脚本长时间占用 IO。需要的话还可以把输出重定向到文件再分析。5.3 长期监控建议把空间趋势做出来临时排查只能解决当下告警更成熟的做法是周期性采集空间快照数据都存到一张统计表里之后用趋势图观察增长。我在实践中会写一个定时任务每周执行一次以下逻辑记录每个 MySQL 库的总大小插入db_size_history表。记录每个数据库的数据目录总大小连同 binlog 目录大小一起记录。保留近 8 周的数据用来对比每周增长量。这样当磁盘使用率达到 70% 时就能提前看出哪些库、哪些日志在快速膨胀而不是等到 90% 才手忙脚乱。监控告警的阈值我的经验是数据盘 70% 做观察80% 做提醒90% 做紧急处理配置项里把 binlog 过期时间、慢日志轮转周期都提前处理好。6. 常见排查问题与避坑经验6.1 统计信息不准数值和文件大小严重不符看起来是同一张表information_schema.tables显示 500MBdu看.ibd文件却有 1.2GB。这种差异在 MySQL 中很常见原因包括统计信息没有及时刷新、BLOB/TEXT 数据溢出、大量碎片、多版本未清理的 undo 数据。处理方式是先在低峰期执行ANALYZE TABLE刷新统计再看差异是否缩小如果差异仍然很大基本可以判断是物理碎片问题考虑OPTIMIZE TABLE。但OPTIMIZE会重建表产生额外的临时空间耗时取决于表大小必须预留足够磁盘余量否则可能因为空间不足中途失败。我的经验是磁盘使用率超过 80% 时不要直接OPTIMIZE先清理日志和临时文件腾出空间再操作。6.2 删了很多数据但磁盘空间没有下降这个问题最容易让人心态崩溃。原因通常是 InnoDB 删除数据只标记删除页面空间没有立刻释放给操作系统而是留在表空间内复用。只有当表重建或收缩时物理文件才会变小。所以正确做法是如果业务表是按时间分区的直接DROP PARTITION这种方式比DELETE高效得多也会立即释放空间如果没有分区且确实需要收缩表文件可以在低峰期执行OPTIMIZE TABLE或使用在线 DDL 工具。另外还要注意如果大事务一直未提交其对应的 undo 日志会持续占用空间必须先找到并处理长事务否则表空间很难收缩。查询长时间运行事务的命令MySQL 中可以直接看information_schema.innodb_trxSELECT trx_id, trx_started, trx_state, trx_rows_modified FROM information_schema.innodb_trx ORDER BY trx_started;发现长时间未提交的事务后和业务确认是否能终止连接否则再多的空间清理手段都不顶用。6.3 临时表空间不断膨胀查不到具体表临时表空间膨胀在 PostgreSQL 和 MySQL 上都可能发生。MySQL 的ibtmp1只增不减运行大 GROUP BY、ORDER BY、连接排序时会把中间结果写到临时表空间。SQL Server 的 tempdb 也一样大排序和大哈希聚合都可能塞满 tempdb。排查思路不是直接去“删临时文件”而是去优化 SQL。我通常会抓当时正在执行的慢查询观察是否有高频的大排序再看long_running_queries和innodb_trx。找到问题查询后针对性优化 join、加索引、减少排序集或者调整tmp_table_size、max_heap_table_size、work_mem让临时结果尽量在内存中完成。临时表空间本身不用太担心自动收缩大多会在重启数据库实例时重置但如果生产库不能随意重启就要早点处理源头查询。6.4 磁盘没满却写不进文件inode 耗尽判断是否 inode 耗尽只要执行df -i即可。如果显示 inode 使用率 100%即使df -h显示还有空间数据库也写不进新文件错误日志里会频繁出现磁盘空间不足的提示。inode 耗尽常见于小文件特别多的场景比如慢查询日志按小时重复生成、临时文件没有清理、数据目录下有海量归档。排查时可以按目录统计文件数量for d in /var/lib/mysql/*/; do echo $d: $(find $d -type f | wc -l); done找到文件数量异常的子目录后删除过期日志或无用的临时文件通常就能缓解。另外别忽略lsof | grep deleted被删除但未释放的句柄一样会占用 inode。如果遇到 inode 占用异常但找不到大文件优先检查这类情况。6.5 生产环境清理的三个安全习惯在最后总结几个安全习惯我吃过亏所以每次都反复确认清理任何日志文件之前先确认备份和复制状态。binlog 清理要确保下游已消费日志备份要确保完整否则数据恢复时会断开。不要在生产高峰期执行OPTIMIZE TABLE、VACUUM FULL、DBCC SHRINKFILE这类重操作它们都会锁表或产生额外 IO。放在维护窗口提前评估耗时和临时空间。手动删除文件前先用du确认目标文件确实是可清理对象不要只看扩展名。比如ibtmp1、ib_logfile*虽然看着像日志但直接删掉会导致实例无法启动。排查数据库磁盘占用这件事方法本身并不稀缺难的是建立一套能从操作系统、数据库统计、日志文件三个角度交叉验证的判断体系。我自己的经验是平时做好定期快照和趋势记录真正遇到告警时反而不是最慌的时刻。最后再分享一个小技巧把第 5 节的脚本放到定时任务里每周自动记录一份空间报告哪怕只看一眼哪个库增长最快也能提前拦住大部分磁盘故障。
阅读完成 · 觉得有帮助?
咨询建站