MySQL 磁盘空间被占满导致服务宕机是 VPS 运维中极常见的故障。很多朋友在主机选社区反馈,明明数据量不大,磁盘却红了。这通常是 binlog 没清理、表空间碎片堆积或者自动备份没做周期删除。别急着扩容,用 AI Agent 辅助排查能快速定位这些“隐形杀手”,恢复宝贵的存储空间。

MySQL 磁盘占用异常与 AI Agent 辅助排查
遇到磁盘报警,先别急着重启 MySQL,否则可能导致数据文件损坏。这时候利用 AI Agent(如 Claude Code 或本地部署的 Ollama 模型)辅助分析服务器状态,能比手动逐个目录排查更高效。我们可以把系统命令的输出结果丢给 AI Agent,让它快速判断是哪个目录出了问题。
快速定位大目录与文件
登录服务器,先看根目录和 MySQL 数据目录的占用情况。
du -sh /*
du -sh /var/lib/mysql/*
把输出结果复制给 AI Agent,提示词可以是:“分析以下目录占用,找出可能导致 MySQL 磁盘占满的异常文件或目录,并给出清理建议。” AI 通常能迅速识别出 `binlog.0000xx` 文件过大、`ibtmp1` 临时表空间爆满或者 `backup` 目录未清理。
清理 MySQL Binlog 日志
Binlog(二进制日志)是导致磁盘占满的头号嫌疑人。它记录了数据库的所有修改操作,主要用于主从复制和数据恢复。如果没设置自动过期,它会一直写,直到把磁盘塞满。
检查 Binlog 开启状态与保留天数
进入 MySQL 命令行查看当前配置。
mysql -u root -p
sql
— 查看 binlog 是否开启及日志保留天数
SHOW VARIABLES LIKE 'log_bin';
SHOW VARIABLES LIKE 'expire_logs_days';
如果 `expire_logs_days` 为 0,表示永不过期。这就是磁盘被吃掉的元凶。
手动清理与自动配置
应急清理:如果磁盘已经 95% 以上,必须立刻手动清理。
sql
— 删除 7 天前的 binlog(PURGE 命令)
PURGE BINARY LOGS BEFORE DATE(NOW()) – INTERVAL 7 DAY;
— 或者重置 master(慎用!会删除所有 binlog,导致从库无法同步)
RESET MASTER;
永久配置:修改 `my.cnf`(通常在 `/etc/my.cnf` 或 `/etc/mysql/my.cnf`),防止未来再次爆满。
ini
[mysqld]
log_bin=mysql-bin
expire_logs_days=7
max_binlog_size=100M
修改后重启 MySQL 服务:`systemctl restart mysqld`。
优化 InnoDB 表空间与碎片整理
如果 binlog 清理了,空间还是没释放,大概率是 InnoDB 的表空间碎片或者临时表空间在作祟。
识别碎片化严重的表
在 MySQL 中执行以下 SQL,找出那些“虚胖”的表。
sql
SELECT
table_name,
data_free / 1024 / 1024 AS data_free_mb
FROM
information_schema.tables
WHERE
table_schema NOT IN ('mysql', 'information_schema', 'performance_schema')
AND data_free > 0
ORDER BY
data_free DESC;
`data_free` 列显示的就是碎片化空间。如果这个值很大,说明表里删除了大量数据,但空间没还给操作系统。
执行表空间回收
对于碎片化严重的表,执行 `OPTIMIZE TABLE`。注意:此操作会锁表,生产环境请在低峰期进行。
sql
— 回收表空间,重建表
OPTIMIZE TABLE your_table_name;
另外,检查 `ibtmp1` 文件大小。这是 InnoDB 的临时表空间文件,重启 MySQL 服务后通常会自动清理并重置。如果它异常巨大,建议在业务低峰期重启 MySQL。
AI Agent 自动化巡检脚本实战
手动敲命令排查一次还行,天天搞谁受得了。我们可以利用 AI Agent 编写一个 Shell 脚本,配合 crontab 定时巡检。
使用 Claude Code 编写 Shell 脚本
你可以直接向 AI Agent(如 Claude Code)提问:“写一个 Shell 脚本,检查 MySQL 磁盘占用,如果超过 80%,则输出警告并检查 binlog 数量和 ibtmp1 大小,发送邮件通知管理员。”
AI 生成的脚本逻辑通常包含以下核心步骤:
1. 获取磁盘使用率:`df -h /var/lib/mysql | awk 'NR==2 {print $5}' | sed 's/%//'`。
2. 判断阈值,如果大于 80,继续执行。
3. 统计 binlog 数量:`ls -lh /var/lib/mysql/mysql-bin.* | wc -l`。
4. 检查 `ibtmp1` 大小。
5. 格式化输出日志或调用邮件接口。
部署定时任务
把脚本保存为 `/root/check_mysql_disk.sh`,赋予权限。
chmod +x /root/check_mysql_disk.sh
加入 crontab,每天早上 10 点检查一次。
crontab -e
0 10 * * * /bin/bash /root/check_mysql_disk.sh >> /var/log/mysql_disk_check.log 2>&1
这样,AI 帮你写的“哨兵”就会每天盯着磁盘,一旦异常立刻报警。
老鸟叮嘱
1.别直接删 binlog 文件:在 Linux 层面直接 `rm -rf` 删除 binlog 文件,MySQL 的索引文件不知道物理文件没了,会导致错误甚至数据丢失。务必进 MySQL 用 `PURGE` 命令或者配置 `expire_logs_days`。
2.生产环境慎用 OPTIMIZE:`OPTIMIZE TABLE` 会重建表,期间会锁表,如果是大表(几十 GB),可能导致长时间服务不可用。建议使用 `pt-online-schema-change` 这样的工具在线改表。
3.备份文件也是大户:很多人的磁盘是被 `mysqldump` 的备份文件撑爆的。备份脚本里一定要加一句 `find /backup -name "*.sql" -mtime +7 -delete`,只保留最近 7 天的备份。
4.AI 给的命令先看懂再执行:AI Agent 生成的脚本虽然快,但可能会根据你的描述产生歧义。特别是涉及 `rm -rf` 或 `DROP` 的命令,务必在测试环境跑一遍,或者人工审查代码逻辑。
FAQ
Q1: 删除 binlog 会导致数据丢失吗?
A: 只要你的全量备份和 binlog 截止点能匹配,删除旧的 binlog 是安全的。通常只保留最近几天的 binlog 用于即时恢复,更早的数据依赖全量备份。
Q2: AI Agent 能直接连接数据库清理吗?
A: 理论上可以通过 API 或插件连接,但强烈不建议。让 AI 拥有数据库的写权限风险极高,建议只让 AI 生成脚本或分析日志,由运维人员审核后执行。
Q3: 为什么执行了 DELETE 删除数据,磁盘空间没变小?
A: InnoDB 删除数据只是标记为“可复用”,空间并没有还给操作系统。需要执行 `OPTIMIZE TABLE` 或者等待新数据填入这些空隙。如果大量删除导致表碎片化,必须优化表空间。
Q4: ibdata1 文件越来越大能删吗?
A:绝对不能直接删。`ibdata1` 是系统表空间文件,删了数据库就崩了。在 MySQL 5.6+ 版本中,建议开启 `innodb_file_per_table`,让每个表独立存储,这样 `OPTIMIZE TABLE` 才能有效释放空间,`ibdata1` 也就不会无限增长了。
通过结合 AI Agent 的分析能力和基础运维命令,解决 MySQL 磁盘占用问题其实并不难。关键在于建立自动化的监控机制,防患于未然,而不是等到磁盘爆满才去救火。
转载请注明出处:https://www.zhujixuan.com/jishujiaocheng/10173.html 商家投稿邮箱:zhujixuanblog@qq.com
