【Docker】MySQL binlog日志过大问题解决
中秋节前做了一次客户的回访,回访的过程中提到了以前其中一个项目的一些问题。本着“要为客户服务到底的原则”答应在节后帮他处理这个事情。
客户看到的现象是服务器中磁盘空间在短时间内会被占满(大概几天几十GB就没有了),一开始他们还以为是被攻击了。但客户的网络环境之前我这边也参与了评审,不应该会出现轻易被攻击的情况。通过几张截图没有头绪,直接连上去看看究竟是什么个情况。
现象
客户这边的机器是一台Windows Server2019虚拟机,如下图:
12GB内存,4核心其实作为服务器还真的不太够格,但业务量不算大的情况下能够给到这样的配置也是可以了。
再看上面这张图,虽然磁盘有接近90GB但是占用情况是这个样子的,如下图:
进入C盘看了一下,发现除Docker相关文件外全部加起来也不过只有24.4GB而已,如下图:
也就是说Docker一个就占了接近60G的内容(想想都可怕)。
排查既然这样先进去docker文件夹中逐个看看文件夹大小,最后发现mysql5文件夹就是占用60GB的主要“元凶”。如下图:
接着继续往下排查,发现在某一时段开始mysql-bin文件开始大量占用磁盘空间。距了解这时间段就是客户系统开始通过RESTful接口大量与另一系统交互的时间起始,如下图:
从上图可以看出几乎每个binlog文件都占用了差不多1GB内容,“炸”是理所当然的了。
后面与客户深入了解后得知,该项目也采用了阿里的Canal数据同步工具对数据库的某些特定表进行数据同步到Redis。众所周知,Canal需要MySQL开启binlog功能来模拟“备机”从而实现数据同步。而此时,项目需要公开RESTful接口给第三方做大量的写数据库的操作,这将产生大量日志写入就是上面看到的情况了。
既然问题已经定位到了,那怎么解决呢?
首先不要考虑改变代码结构哪怕是同步机制(不是自己的东西不要动,动就死了),优先考虑如何清理掉多余的binlog文件。
还好容器是使用Docker(不要问我为什么Windows Server服务器还用Docker,我也不知道啊...),数据文件没有丢失的情况下只需重新执行docker run就能够恢复mysql。如下图:
docker run -m 1G \
-p <ref_port>:3306 \
--network <private_network_name> \
--ip 172.20.0.3 \
-v C:\docker\mysql5\data:/var/lib/mysql \
-v C:\docker\mysql5\config\mysql:/etc/mysql \
-e MYSQL_ROOT_PASSWORD=<root_init_password> \
--name mysql5 \
-d --restart=always <mysql_images>:5.6
由于需要删除binlog文件不能直接在挂载目录上面删除(不要问我为什么知道),这时只能通过docker exec进入容器内部进行binlog文件的删除,如下图:
使用purge master logs before......语句即可将一个时间段之前的所有binlog删除(以上图为例,这里是删除2022年6月2日前的所有binlog文件),效果如下图所示:
但是这样还不够binlog还是会增长的,难道是要写一个定时器定期删除吗?
肯定不是啦,首先我们要考虑使用这个binlog的原因是什么。
说白了,其实就是将数据实时同步从代码中解耦出来,也就是说不存在需要数据还原这种情况。
这样一来就好办了,针对这个binlog的问题,MySQL本来就有一套规则能够处理这件事情的,如下图:
通过设定max_binlog_size在他超大的时候强制分文件,最最最重要的还是expire_logs_days的参数是用于规定这个binlog文件能够留存多少时间。这里只需要保留2天就可以了,这样就不需要自己写脚本清理啦。
版权声明
本文仅代表作者观点,不代表博信信息网立场。