如果您的 Drupal 网站突然变慢、显示错误,甚至无法访问,而服务器显示磁盘空间已满,那么您正面临一个常见的挑战。本文将深入探讨 Drupal 7 网站磁盘空间爆满的诊断过程,并提供一套从紧急清理到长期优化的彻底解决方案。
1) 问题初现:Drush 命令失败与 "No space left on device"
一切始于一个看似简单的缓存清理命令:drush cc all。然而,Drush 却报错:
Drush command terminated abnormally due to an unrecoverable error. PDOException: SQLSTATE[HY000]: General error: 3 Error writing file '/tmp/MYfd=295' (OS errno 28 - No space left on device)
这个错误信息清晰地指出:服务器磁盘空间不足。MySQL 无法在 /tmp 目录创建临时文件,导致数据库查询失败,进而使 Drupal 无法正常运行和清除缓存。
通过 df -h 命令确认,根分区 /dev/vda2 已达 100% 使用率,可用空间为 0。这是所有问题的根源。
2) 阶段一:紧急止血——快速释放磁盘空间
当磁盘空间 100% 满时,系统将变得极其不稳定,甚至可能崩溃。当务之急是立即释放空间。
1. 检查备份目录 /var/backups:
这是最常见的占用大空间的目录之一。运行 ls -lh /var/backups 可以看到大量备份文件,例如:
7.6G drupal7_backup_2025-02-23.tar.gz4.7G database-backup20240725ws.sql4.3G database-backup.sql3.9G wishiny_01bc20220813.sql
这些巨大的备份文件总计占据了数十 GB 的空间。
解决方案:
- 谨慎删除不再需要的旧备份。 优先删除日期最老或最大的文件。
示例命令:
cd /var/backups/ rm database-backup20240725ws.sql rm drupal7_backup_2025-02-23.tar.gz # 如果已确认有其他副本或不再需要- 每次删除后,立即运行
df -h检查磁盘空间是否释放。目标是将/dev/vda2的使用率降到 90% 以下。
2. 定位快速增长的活动文件:
如果仅仅删除旧备份不足以解决问题,或者磁盘空间又迅速被填满,那么很可能是有活跃进程正在生成大量新文件。
诊断命令: 查找过去 60 分钟内,大小超过 10MB 的文件:
sudo find / -type f -size +10M -mmin -60 -print0 | xargs -0 du -h | sort -rh
诊断结果(示例):
输出清晰指向 MySQL 数据库文件的异常膨胀:
51G /var/lib/mysql/chogory_db/cache_form.ibd: 惊人的 51GB!Drupal 的表单缓存表不应如此巨大。1.9G /var/lib/mysql/drupal7/semaphore.ibd: Drupal 信号量表,过大表明并发或锁释放问题。1.2G /var/lib/mysql/chogory_db/watchdog.ibd: Drupal 日志表,显示日志记录过于频繁且无清理。485M /var/lib/mysql/drupal7/watchdog.ibd: 另一个 Drupal 站点的日志表。785M /var/lib/mysql/undo_002和385M /var/lib/mysql/undo_001: InnoDB 的 undo 日志,大量事务操作或长事务的产物。58M /var/log/mysql/mysql-slow.log: MySQL 慢查询日志,表明存在大量耗时查询。111M /var/log/btmp: 失败登录日志,可能预示暴力破解攻击。- 大量
32M /var/lib/mysql/#innodb_redo/#ib_redoXXXXX_tmp文件: InnoDB redo 日志,指示大量写入活动。
解决方案:针对性清空数据库文件和日志:
警告:直接 TRUNCATE TABLE 会永久删除数据,但在处理缓存和日志表时通常是安全的,因为它们可以重新生成或不影响核心功能。操作前请确保理解风险。
清空异常膨胀的 Drupal 数据库缓存表:SQL
通过 MySQL 客户端执行命令:
`mysql -u root -p
-- 针对 chogory_db 数据库
USE chogory_db; TRUNCATE TABLE cache_form; -- 51GB 的罪魁祸首,优先清理
TRUNCATE TABLE watchdog; -- 巨型日志表
TRUNCATE TABLE cache_views;
TRUNCATE TABLE cache_menu;
TRUNCATE TABLE cache_field;
TRUNCATE TABLE cache;
TRUNCATE TABLE cache_advagg_aggregates;-- 针对 drupal7 数据库
USE drupal7;
TRUNCATE TABLE semaphore; -- 解决并发锁问题
TRUNCATE TABLE watchdog;
TRUNCATE TABLE advagg_aggregates;
TRUNCATE TABLE advagg_aggregates_versions;
TRUNCATE TABLE cache_update;`执行后,再次运行
df -h检查空间释放情况。清空大型日志文件:
MySQL 慢查询日志:
sudo truncate -s 0 /var/log/mysql/mysql-slow.log失败登录日志:
sudo truncate -s 0 /var/log/btmp
这些操作可安全地清空文件内容而不删除文件本身,防止服务中断。
3) 阶段二:根本解决——网站性能优化与预防
仅仅清理是治标不治本。为了防止磁盘空间再次爆满,并从根本上提升网站性能,需要进行系统性的优化。
1. 内存配置优化:解决 Swap 缺失与 MySQL 内存瓶颈
您的 top 输出显示服务器负载高,没有 Swap 空间,且 MySQL (mysqld) 进程占用了 137.5% CPU 和 44.5% 内存(约 2.6GB),是主要瓶颈。
配置 Swap 空间 (紧急且关键!)Bash
没有 Swap 会导致内存耗尽时系统崩溃。
sudo fallocate -l 4G /swapfile # 创建 4GB Swap 文件 sudo chmod 600 /swapfile sudo mkswap /swapfile sudo swapon /swapfile echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab # 开机自动挂载优化 MySQL 配置 (my.cnf)
修改 /etc/mysql/my.cnf 或类似路径下的配置文件。
innodb_buffer_pool_size: 最重要的参数。对于 5.9GB 内存的服务器,如果 MySQL 是主要应用,可以设置为物理内存的 50%-70%。例如,innodb_buffer_pool_size = 3G。max_connections: 根据实际并发需求调整,避免过高浪费内存。tmp_table_size和max_heap_table_size: 针对复杂查询和临时表,适当增加以防止写入磁盘。expire_logs_days: 如果使用二进制日志 (log_bin),设置自动清理旧日志,例如expire_logs_days = 7。query_cache_type = 0/query_cache_size = 0: 对于活跃的 Drupal 网站,通常建议禁用查询缓存,因为它可能在高并发下降低性能。
修改后,重启 MySQL 服务:
sudo systemctl restart mysql
2. PHP-FPM 进程优化
多个 PHP-FPM 进程共同占用了大量 CPU 和内存。
调整 PHP-FPM 池配置 (
www.conf或相关池文件)pm.max_children: 最大的子进程数。根据每个 PHP-FPM 进程的内存占用(约 80-100MB)和服务器总内存,合理设置。例如,对于 5.9GB 内存,可以尝试设置为 15-20。pm = dynamic: 平衡内存占用和响应速度,按需动态创建进程。- 统一 PHP 版本: 您的服务器同时运行 PHP 7.0 和 7.4。建议统一到最新版本(PHP 7.4)以简化管理和优化资源。
修改后,重启 PHP-FPM 服务:
sudo systemctl restart php7.4-fpm
3. Drupal 自身优化
- 缓存配置:
- 在 Drupal 后台的 性能页面 (
/admin/config/development/performance) 启用所有内置缓存:匿名用户页面缓存、区块缓存,并设置合理的缓存生命周期。 - 使用 Memcached 作为缓存后端: 确保 Drupal 的
settings.php配置正确,将缓存数据存储在 Memcached 中,而不是数据库,这能显著减轻数据库负担。 - 定期运行
drush cc all清理 Drupal 缓存。
- 在 Drupal 后台的 性能页面 (
- 日志管理:
- 启用 Syslog 模块: 将 Drupal 的
watchdog日志从数据库重定向到系统日志文件,这是解决watchdog表膨胀的最佳实践。 - 配置 Logrotate:确保所有系统日志(包括 MySQL 日志、Web 服务器日志和 Syslog)都配置了日志轮转,防止它们无限增长。
- 启用 Syslog 模块: 将 Drupal 的
- 禁用不必要模块和优化 Views: 审查 Drupal 模块列表,禁用未使用的模块。优化 Views 查询,并为高流量的 Views 启用缓存。
- PHP OPcache: 确保 PHP 已经安装并启用了 OPcache 扩展。这是 PHP 性能的关键。
- 图片优化和 CDN: 对网站图片进行压缩优化,并考虑使用 CDN 来分发静态文件,减轻服务器压力。
4) 阶段三:持续监控与预防
- 安装 Fail2ban: 针对
btmp日志中大量失败登录尝试,安装 Fail2ban 自动封禁恶意 IP,提高服务器安全性并减少日志增长。 - 监控工具: 配置专业的服务器监控工具(如 Zabbix、Prometheus 等)或简单的 Cron 脚本,实时监控磁盘空间、CPU、内存和 MySQL 状态,并在达到阈值时发出警报。
- 定期维护: 制定定期清理日志、检查备份和优化数据库的计划。
通过这一套组合拳,您不仅能解决当前的磁盘空间爆满问题,更能显著提升 Drupal 网站的性能和稳定性,避免未来再次陷入同样的困境。
Back to top
评论