linux 清理mongodb磁盘占满

74 阅读4分钟

一、适用场景

本教程适用于 Linux 系统 MongoDB 因数据量过大导致磁盘占满的应急恢复,核心目标:

  1. 解除 MongoDB 运行锁,恢复服务正常启动;
  1. 清理冗余数据,释放磁盘空间;
  1. 避免强制删除导致的数据损坏或服务异常。

二、前置风险提示(重要!)

  1. 数据备份优先:以下操作涉及直接删除数据集文件,若数据重要,建议先通过磁盘挂载、文件拷贝等方式备份 /db/data/ 目录下的核心数据(如无额外磁盘空间,可跳过备份但需承担数据丢失风险);
  1. 锁文件删除需谨慎:mongod.lock 是 MongoDB 崩溃或异常关闭时生成的锁文件,正常运行时删除可能导致数据不一致,需确保 MongoDB 已完全停止;
  1. 数据集删除后果:直接删除 T036*、T040* 等数据文件会永久删除对应集合 / 数据库,仅适用于非核心数据或可重建的数据。

三、应急恢复步骤

1. 确认 MongoDB 服务状态并停止

# 查看 MongoDB 进程(确认是否运行)
ps -ef | grep mongod
# 若正在运行,强制停止服务(避免删除文件时冲突)
kill -9 $(ps -ef | grep mongod | grep -v grep | awk '{print $2}')

2. 删除数据库锁文件

# 进入 MongoDB 数据存储目录(根据实际路径调整)
cd /db/data/
# 删除锁文件(仅当服务已停止时执行)
rm -rf mongod.lock
  • 说明:锁文件用于防止多进程同时访问数据目录,磁盘占满可能导致 MongoDB 异常退出,锁文件未自动清理,需手动删除。

3. 清理大体积数据集,释放磁盘空间

# 方法1:查看数据目录下各文件/目录大小(找到占用最大的数据集)
du -sh /db/data/* | sort -rh
# 方法2:删除指定数据集文件(示例:删除 T036* 和 T040* 开头的所有文件/目录)
rm -rf /db/data/T036*
rm -rf /db/data/T040*
# 方法3:若需清空全部非核心数据(谨慎使用!)
# rm -rf /db/data/*  # 此命令会删除所有数据,仅适用于测试环境或可重建数据
  • 优化建议:通过 du -sh 确认最大占用文件后,针对性删除,避免误删核心数据集(如 admin.、local. 等系统库文件)。

4. 重启 MongoDB 服务

# 启动命令(指定数据目录、日志路径、端口、绑定IP,后台运行)
/usr/local/mongodb/bin/mongod --dbpath=/db/data/ --logpath=/usr/local/mongodb/log --logappend --port 27017 --bind_ip 192.168.0.1,127.0.0.1 --fork
  • 核心参数说明:
    • --dbpath=/db/data/:指定数据存储目录(需与实际路径一致);
    • --logpath=/usr/local/mongodb/log:日志输出路径(确保目录存在且有写入权限);
    • --logappend:日志追加模式(避免覆盖历史日志);
    • --port 27017:默认 MongoDB 端口;
    • --bind_ip:允许访问的 IP(多个 IP 用逗号分隔);
    • --fork:后台运行(守护进程模式)。

5. 验证服务恢复成功

# 方法1:查看 MongoDB 进程是否启动
ps -ef | grep mongod
# 方法2:通过 mongo 客户端连接测试
/usr/local/mongodb/bin/mongo 192.168.0.1:27017
# 连接成功后,查看数据库列表(确认核心数据存在)
show dbs;

四、进阶优化:避免磁盘再次占满

1. 配置数据保留策略(自动清理过期数据)

通过 MongoDB 内置的 TTL 索引,自动删除过期数据(适用于日志、临时数据等):

// 连接 MongoDB 后,执行以下命令(以 logs 集合为例,保留7天数据)
use 数据库名;
// 创建 TTL 索引,expireAt 为过期时间字段(需是 Date 类型)
db.logs.createIndex({ "expireAt": 1 }, { expireAfterSeconds: 60*60*24*7 });

2. 定期备份与清理脚本(自动化运维)

创建定时任务,定期备份核心数据并清理冗余数据:

# 1. 创建清理脚本(/usr/local/mongodb/clean_mongodb.sh)
vim /usr/local/mongodb/clean_mongodb.sh
# 2. 脚本内容(示例:每周日凌晨3点清理30天前的日志数据)
#!/bin/bash
/usr/local/mongodb/bin/mongo 192.168.0.1:27017 <<EOF
use 数据库名;
// 删除 logs 集合中30天前的数据
db.logs.deleteMany({ "createTime": { $lt: new Date(Date.now() - 30*24*60*60*1000) } });
EOF
# 3. 给脚本添加执行权限
chmod +x /usr/local/mongodb/clean_mongodb.sh
# 4. 添加到 crontab 定时任务(每周日3点执行)
crontab -e
# 添加以下内容:
0 3 * * 0 /usr/local/mongodb/clean_mongodb.sh

3. 监控磁盘空间(提前预警)

配置磁盘空间监控,当使用率超过 80% 时触发预警(避免完全占满):

# 编写监控脚本(/usr/local/mongodb/monitor_disk.sh)
#!/bin/bash
# 监控 /db 分区(MongoDB 数据目录所在分区)
disk_usage=$(df -h /db | grep / | awk '{print $5}' | sed 's/%//g')
if [ $disk_usage -ge 80 ]; then
  # 发送邮件预警(需安装 mailutils)或写入日志
  echo "MongoDB 磁盘使用率已达 $disk_usage%,请及时清理数据" | mail -s "磁盘预警" admin@example.com
fi
# 添加到 crontab(每小时执行一次)
crontab -e
0 * * * * /usr/local/mongodb/monitor_disk.sh

五、常见问题排查

1. 重启后提示「数据文件损坏」

  • 原因:强制删除数据文件或未正常停止服务导致数据不一致;
  • 解决:执行修复命令 usr/local/mongodb/bin/mongod --dbpath=/db/data/ --repair,修复完成后再重启服务。

2. 启动后端口占用

  • 原因:之前的 MongoDB 进程未完全停止;
  • 解决:kill -9 (lsof -i:27017 | grep LISTEN | awk '{print 2}'),强制释放端口后重启。

3. 日志提示「无写入权限」

  • 原因:/usr/local/mongodb/log 目录权限不足;
  • 解决:chmod 777 -R /usr/local/mongodb/log(或给 MongoDB 运行用户授权)。

六、核心注意事项

  1. 生产环境不建议直接删除数据文件:优先通过 db.collection.deleteMany() 命令删除数据(避免文件级删除导致的碎片和损坏);
  1. 磁盘扩容优先于数据删除:若数据均为核心数据,建议先扩容磁盘(如挂载新硬盘),再进行数据迁移,避免数据丢失;
  1. 定期备份:无论是否清理数据,核心数据库需定期备份(可使用 mongodump 工具),防止意外情况导致数据丢失。