本文约 3,040 字,预计阅读 8 分钟。文中命令与配置均经过实测,可直接参考执行。
引言
当你的网站还能打开,但发文章时报”无法写入数据库”、发表评论失败、上传图片卡住,或者后台出现 Disk full、No space left on device、数据表是只读的 之类提示,八成是数据库所在磁盘空间爆满了。还有一种更隐蔽的情况:MySQL 运行到一半开始拒绝写入,前台看着正常,实际上所有新数据都进不去。空间爆满不是数据库本身坏了,而是”仓库塞满了,新货放不进去”。它常常发生在博客写了三五年、评论和修订版本堆积如山、或者插件生成了大量日志表之后。好消息是,这类问题不用重装,只要按顺序排查占用、清理垃圾、必要时扩容,就能让网站重新写入。
故障原因分析
- wp_posts 和 wp_postmeta 被垃圾数据撑大。文章修订版本(revision)、自动草稿(auto-draft)、回收站里的文章都会长期占据空间,加上 WooCommerce 等插件往 wp_postmeta 写入大量数据,几张表很快就能长到几个 G。
- wp_options 的 autoload 数据膨胀。很多插件把临时数据、缓存、日志直接塞进 wp_options 并设为自动加载,日积月累让这张小表变成巨无霸,既占空间又拖慢网站。
- 评论表被垃圾评论淹没。没开反垃圾的站点,wp_comments 和 wp_commentmeta 会被成千上万条垃圾评论占满。
- 插件自建日志表或备份文件堆积。备份插件、日志插件、SEO 插件会生成自己的数据表和大量临时文件,删了插件表却留了下来。
- 磁盘本身配额小或被别的文件占满。有些主机给的空间很小,网站图片、缓存、日志文件先把磁盘占满,数据库自然写不进;MySQL 的 binlog、慢查询日志、ibdata 也可能持续增长。
分步解决方案
第一步:先确认是不是磁盘满
登录服务器或主机面板,查看磁盘使用率。宝塔面板在首页就能看到磁盘占用;命令行可用:
df -h
du -sh /www/wwwroot /var/lib/mysql /var/log
如果 df -h 显示根分区或数据分区 Use% 接近 100%,就从最大的目录开始清理。也别忘了检查 MySQL 的数据目录,ibdata1、binlog 文件过大同样会吃光空间。
第二步:找出数据库里的大表
在 phpMyAdmin 里选中数据库,点”结构”标签,右侧会显示每张表的数据大小和索引大小,按占用排序,重点看 wp_posts、wp_postmeta、wp_options、wp_comments、wp_commentmeta 这几张。也可以用 SQL 查询各表占用:
SELECT table_name AS 表名,
ROUND((data_length + index_length) / 1024 / 1024, 2) AS 占用MB,
table_rows AS 行数
FROM information_schema.TABLES
WHERE table_schema = '你的数据库名'
ORDER BY (data_length + index_length) DESC;
把 你的数据库名 换成实际库名,就能一眼看出谁在吃空间。
第三步:清理可安全删除的垃圾数据
动手前请完整备份数据库。以下 SQL 用于清理常见的垃圾数据,表前缀 wp_ 请按实际替换。
删除文章修订版本:
DELETE FROM wp_posts WHERE post_type = 'revision';
DELETE FROM wp_postmeta WHERE post_id NOT IN (SELECT ID FROM wp_posts);
删除自动草稿和回收站中间态:
DELETE FROM wp_posts WHERE post_status = 'auto-draft';
DELETE FROM wp_posts WHERE post_status = 'trash';
删除垃圾评论(示例:把所有未通过审核的垃圾评论删掉):
DELETE FROM wp_comments WHERE comment_approved = 'spam';
DELETE FROM wp_commentmeta WHERE comment_id NOT IN (SELECT comment_ID FROM wp_comments);
清理后回收空间,对相关表执行优化:
OPTIMIZE TABLE wp_posts;
OPTIMIZE TABLE wp_postmeta;
OPTIMIZE TABLE wp_options;
注意:OPTIMIZE 在 InnoDB 上会重建表,操作期间该表短暂锁定,建议在低峰期执行。
第四步:检查并清理 wp_options 的膨胀数据
按数据大小排序看看哪些选项占地方:
SELECT option_name,
LENGTH(option_value) AS 长度,
autoload
FROM wp_options
ORDER BY LENGTH(option_value) DESC
LIMIT 30;
重点排查那些名字带 _transient_(临时缓存)、_cache、日志类前缀的记录,以及已经卸载插件残留的选项。删除前务必确认它不属于 WordPress 核心或正在使用的插件,不确定的不要删。选错的后果可能是主题设置丢失。
第五步:清理文件和扩容
如果清理数据表后空间仍紧张,去网站目录删掉缓存、旧备份、日志文件,清空 MySQL 的 binlog 和慢查询日志(在面板里操作,别手动 rm 正在使用的文件)。若网站确实在增长,最根本的办法是给磁盘扩容或升级主机套餐,并在 MySQL 配置里限制 binlog 保留天数、设置日志轮转。
第六步:验证
清理后重启一次 MySQL,再在后台新发一篇草稿、提交一条测试评论,确认能正常写入,同时再次 df -h 确认空间有余量。
常见踩坑点
- 不备份就批量删数据。DELETE 一旦执行很难撤销,先导出再动手。
- 误删 _transient_ 之外的选项。wp_options 里核心选项删错会导致站点地址丢失,只删明确无用的。
- 只删数据不做 OPTIMIZE。InnoDB 不会立刻把空间还给磁盘,优化表才会真正释放。
- 忽略 MySQL 自身的 binlog 和 ibdata。数据库表的空间清出来了,磁盘却还是满的,往往是这些系统文件没处理。
- 把 binlog 当垃圾直接 rm。会导致 MySQL 起不来,要用 PURGE BINARY LOGS 或面板工具。
- 长期不设自动清理。修订版本和垃圾评论会再次堆积,建议装插件或建定时任务定期清理。
总结
数据库空间爆满导致网站无法写入,本质是磁盘或数据表被垃圾数据塞满,只要按”查磁盘→找大表→清垃圾→优化表→必要时扩容”的顺序处理,就能恢复写入。对 WordPress 站长来说,wp_posts、wp_postmeta、wp_options、wp_comments 是最容易被撑大的四张表,定期清理修订版本、自动草稿和垃圾评论,配合 OPTIMIZE,可以长期保持数据库轻装运行。记住,清理数据库空间之前一定要先备份,再重要的数据也经不起一次误删。
