Docker部署的MariaDB二进制日志文件过大致磁盘耗尽的问题排查与解决
Docker部署的MariaDB二进制日志文件过大致磁盘耗尽的问题排查与解决
嘿,我看到你被Docker里MariaDB的binlog文件占满磁盘的问题困扰了,先梳理下你提供的排查信息:
首先是你执行的查看binlog文件的命令和结果:
ls -lh /root/docker/yml/nextcloud/db/binlog.*
输出:
-rw-rw---- 1 999 999 960M Aug 25 22:55 /root/docker/yml/nextcloud/db/binlog.000043 -rw-rw---- 1 999 999 5.5M Aug 25 23:52 /root/docker/yml/nextcloud/db/binlog.000044 -rw-rw---- 1 999 999 156M Aug 26 23:40 /root/docker/yml/nextcloud/db/binlog.000045 -rw-rw---- 1 999 999 260M Aug 28 15:10 /root/docker/yml/nextcloud/db/binlog.000046 -rw-rw---- 1 999 999 548M Sep 1 00:03 /root/docker/yml/nextcloud/db/binlog.000047 -rw-rw---- 1 999 999 593M Sep 4 11:28 /root/docker/yml/nextcloud/db/binlog.000048 -rw-rw---- 1 999 999 13M Sep 4 13:21 /root/docker/yml/nextcloud/db/binlog.000049 -rw-rw---- 1 999 999 529M Sep 9 22:20 /root/docker/yml/nextcloud/db/binlog.000050 -rw-rw---- 1 999 999 128 Sep 4 13:26 /root/docker/yml/nextcloud/db/binlog.index
再看你的Docker Compose里DB服务的配置:
services: db: image: mariadb:10.6 container_name: nextcloudDB restart: always command: --transaction-isolation=READ-COMMITTED --log-bin=binlog --binlog-format=ROW --expire_logs_days=2 volumes: - ./db:/var/lib/mysql environment: - MYSQL_ROOT_PASSWORD=d`X'1B7Ss/=E;JxROOT - MYSQL_PASSWORD=d`X'3B7SD/dE;Jx - MYSQL_DATABASE=nextcloud - MYSQL_USER=nextcloud logging: driver: "json-file" options: max-size: "50m" max-file: "10" # 你备注的挂载说明:special add ./ in ./db for backup
问题分析
你已经在启动命令里加了--expire_logs_days=2,理论上超过2天的binlog应该自动被清理,但从文件时间来看,8月25号的日志还存在,说明自动清理没生效——大概率是容器时间和宿主机时间不同步导致的,或者配置没正确加载。
解决步骤
1. 手动清理旧日志,紧急释放磁盘空间
先进入MariaDB容器,手动清理掉过期的binlog:
# 进入容器的mysql命令行,输入root密码(对应环境变量里的MYSQL_ROOT_PASSWORD) docker exec -it nextcloudDB mysql -uroot -p
在mysql交互界面执行:
# 清理2天前的所有binlog PURGE BINARY LOGS BEFORE DATE_SUB(NOW(), INTERVAL 2 DAY); # 或者如果你想保留最新的几个,比如只保留到binlog.000050,就执行: # PURGE BINARY LOGS TO 'binlog.000050';
执行完后输入exit退出mysql即可。
2. 同步容器与宿主机时间
这是自动清理失效的最常见原因:
# 查看容器内的时间 docker exec nextcloudDB date # 查看宿主机时间 date
如果两个时间不一致,修改Docker Compose的volumes部分,挂载宿主机的时间文件来同步:
volumes: - ./db:/var/lib/mysql - /etc/localtime:/etc/localtime:ro # 新增这一行,同步宿主机时间
然后重启容器:
docker-compose down && docker-compose up -d
3. 验证自动清理配置是否生效
再次进入mysql命令行,检查配置:
SHOW VARIABLES LIKE 'expire_logs_days';
如果返回的值是2,说明配置生效了;如果不是,检查启动命令里的--expire_logs_days=2有没有拼写错误(注意是下划线,不是连字符),也可以临时在mysql里设置:
SET GLOBAL expire_logs_days = 2;
不过这个临时设置重启容器会失效,所以还是要确保Docker Compose的command参数正确。
4. 后续预防建议
- 如果你不需要主从复制或者基于binlog的备份,可以直接关闭binlog:把command里的
--log-bin=binlog --binlog-format=ROW去掉,这样就不会生成binlog了,彻底解决占用问题。 - 定期检查磁盘使用情况,或者设置监控告警,避免再次出现磁盘耗尽的情况。
备注:内容来源于stack exchange,提问作者dr.ipkins




