1.背景
某个项目为了实现通过Canal
将MySql
自动同步至Redis
的目的,开启了MySql
的log-bin
模式(binary-log,二进制日志)。开启方式很简单,这里只是给出初步介绍:
//关闭MySql服务
//vi /etc/my.cnf
[mysqld]
...
log-bin=mysql-bin
...
//开启MySql服务
开启了二进制日志后,我们确实实现了Redis的自动同步。但是后来发现服务器磁盘空间暴减,通过分析发现是MySql
产生了大量二进制文件,如下:
[root@localhost mysql]# ls -1
ibdata1
ib_logfile0
ib_logfile1
ib_logfile0
mysql-bin.000001
mysql-bin.000002
mysql-bin.000003
mysql-bin.000004
...
mysql-bin.index
...
我分配给MySql
的磁盘空间只有20G
,经常会一两天就产生MySql
磁盘爆满导致MySql
服务不可用的问题。
然后我就开始了悲催的MySql
日志清理之旅。
2.第一种策略:手动清理
刚开始都是通过手动进行清理。
通常这么做:
#将指定时间之前的日志清理
purge binary logs before '2018-02-01 12:00:00';
#将指定日志文件之前的日志清除
purge binary logs to 'mysql-bin.000003';
这么做一直都能达到清理的目的,就是过几天就需要清理一次,很是繁琐。
但是因为工期紧,任务重,我也没花时间了解别的方式,直到有一天…
有一天,开启了MySql
的主从模式,然后照例通过purge
进行日志清理。
刚开始也是没有问题的,然后,有一次执行了purge
之后就没有然后了:MySql
直接被玩坏了…
后来分析,应该是我们清理日志的时刻,正巧与主从复制冲突了,然后就出错了。
冲突的原因我没有深究,但是大概有可能如下:
- 恰巧试图清除正在被从服务器读取的日志,清除失败
- 恰巧清除了从服务器想要读取的日志,清除成功,但是从服务器不能再复制
最后,经过一番研究,通过flush logs + restart
解决了问题。
3.第二种策略:自动清理
考虑到purge
的不稳定性以及天天清理日志的烦恼,后来采取了自动清理策略。实现方法如下:
一次性的(不推荐:因为服务重启,配置失效):
SQL > set global expire_logs_days = 3;
一劳永逸(就是改配置,推荐):
//关闭MySql服务
//vi /etc/my.cnf
[mysqld]
...
#开启binary log
log-bin=mysql-bin
#日志超过3天自动过期
expire_logs_days = 3
...
//开启MySql服务