1.1 解释:
该方法可以删除列于索引文件中的所有二进制日志,把二进制日志索引文件重新设置为空,并创建一个以.000001为后缀新的二进制日志文件。 该语法一般只用在主从环境下初次建立复制时。 在主从复制进行过程中,该语句是无效的。 主从环境下的配置步骤:
a. 启动master和slave,开启replication(即复制)
b. 在master上运行一些测试的语句,看数据是否能够复制到 slave上面
c. 当复制运行正常的话,就在从上stop slave 然后执行 reset slave,去掉不需要的数据
d. 在master上面执行reset master 清除测试产生的数据 查看删除前日志
[root@localhost mysql]# ls -al
-rw-r----- 1 mysql mysql 202 8月 9 08:09 master-bin.000022
-rw-r----- 1 mysql mysql 202 8月 9 08:09 master-bin.000023
-rw-r----- 1 mysql mysql 202 8月 9 08:09 master-bin.000024
-rw-r----- 1 mysql mysql 202 8月 9 08:09 master-bin.000025
-rw-r----- 1 mysql mysql 202 8月 9 08:09 master-bin.000026
-rw-r----- 1 mysql mysql 202 8月 9 08:09 master-bin.000027
-rw-r----- 1 mysql mysql 202 8月 9 08:09 master-bin.000028
-rw-r----- 1 mysql mysql 202 8月 9 08:09 master-bin.000029
-rw-r----- 1 mysql mysql 202 8月 9 08:09 master-bin.000030
-rw-r----- 1 mysql mysql 202 8月 9 08:09 master-bin.000031
-rw-r----- 1 mysql mysql 202 8月 9 08:09 master-bin.000032
-rw-r----- 1 mysql mysql 154 8月 9 08:09 master-bin.000033
-rw-r----- 1 mysql mysql 240 8月 9 08:09 master-bin.index
1.2 用RESET MASTER命令进行删除
mysql> reset master;
Query OK, 0 rows affected (0.00 sec)
查看删除后的日志
[root@localhost mysql]# ls -al master-bin.*
-rw-r----- 1 mysql mysql 154 8月 9 08:15 master-bin.000001
-rw-r----- 1 mysql mysql 20 8月 9 08:15 master-bin.index
1.语法: PURGE { BINARY | MASTER } LOGS { TO 'log_name' | BEFORE datetime_expr } 用于删除列于在指定的日志或日期之前的日志索引中的所有二进制日志。这些日志也会从记录在日志索引文件中的清单中被删除,这样被给定的日志成为第一个。
1.1 实例:
1.mysql> PURGE BINARY LOGS TO 'mysql-bin.000002';
2.mysql> PURGE BINARY LOGS BEFORE '2017-12-15 11:53:59';
3.mysql> PURGE MASTER LOGS BEFORE DATE_SUB(CURRENT_DATE, INTERVAL 60 DAY);
Query OK, 0 rows affected, 1 warning (0.28 sec)
4.mysql> PURGE MASTER LOGS BEFORE DATE_SUB( NOW( ), INTERVAL 60 DAY);
Query OK, 0 rows affected, 1 warning (0.00 sec)
分别表示:
1.删除mysql-bin.000002之前的日志(不包括mysql-bin.000002)
2.删除2014-04-28 23:59:59时间点之前的日志
3,4.清除60天前binlog日志
注意事项: 在删除binlog日志同时,也会清理mysql-bin.index的文件记录,清理完后命令中指定的日志文件成为第一个。 主从架构下,如果复制正在进行中,执行该命令是安全的,例如slave正在读取我们要删除的log,该语句将什么也不会做,并返回一个错误;如果复制是停止的,我们删除了一个slave还未读取的日志,则复制重新建立连接时将会失败。 建议操作步骤:
a 在每个从属服务器上,使用SHOW SLAVE STATUS来检查它正在读取哪个日志。
b 使用SHOW MASTER LOGS获得主服务器上的一系列日志。
c 在所有的从属服务器中判定最早的日志。这个是目标日志。如果所有的从属服务器是最新的,这是清单上的最后一个日志。
d 备份您将要删除的所有日志。(这个步骤是自选的,但是建议采用。)
e 清理除目标日志之外的所有日志。
手动删除binlog日志文件 删除mysql-bin.000003 日志
删除前
[root@localhost mysql]# ls -al master-bin.*
-rw-r----- 1 mysql mysql 202 8月 9 08:20 master-bin.000001
-rw-r----- 1 mysql mysql 202 8月 9 08:20 master-bin.000002
-rw-r----- 1 mysql mysql 202 8月 9 08:20 master-bin.000003
-rw-r----- 1 mysql mysql 154 8月 9 08:20 master-bin.000004
-rw-r----- 1 mysql mysql 80 8月 9 08:20 master-bin.index
[root@localhost mysql]# cat master-bin.index
./master-bin.000001
./master-bin.000002
./master-bin.000003
./master-bin.000004
删除后:
[root@localhost mysql]# rm -rf master-bin.000004
[root@localhost mysql]# rm -rf master-bin.000003
[root@localhost mysql]# rm -rf master-bin.000002
[root@localhost mysql]# vim master-bin.index
[root@localhost mysql]# cat master-bin.index
./master-bin.000001
mysql> show variables like 'expire_logs_days';
+------------------+-------+
| Variable_name | Value |
+------------------+-------+
| expire_logs_days | 7 |
+------------------+-------+
1 row in set (0.00 sec)
1.临时修改过期时间
mysql> set global expire_logs_days = 60;
Query OK, 0 rows affected (0.00 sec)
mysql> show variables like 'expire_logs_days';
+------------------+-------+
| Variable_name | Value |
+------------------+-------+
| expire_logs_days | 60 |
+------------------+-------+
1 row in set (0.01 sec)
2.
修改/etc/my.cnf 增加参数
expire_logs_days=60
重启mysql 服务生效
刷新日志查看,日志被清楚
3.刷新日志查看,日志被清楚
mysql> flush logs;
Query OK, 0 rows affected (0.00 sec)
mysql> show master logs;
+-------------------+-----------+
| Log_name | File_size |
+-------------------+-----------+
| master-bin.000001 | 202 |
| master-bin.000002 | 154 |
+-------------------+-----------+
2 rows in set (0.00 sec)
注意事项 在双机复制环境下,应确保过期天数不应小于从机追赶主机binlog日志的时间。 触发过期删除的条件 每次进行 LOG flush的时候会自动删除过期的日志。 触发log flush的条件为:
1. 重启mysql;
2. BINLOG文件大小达到参数max_binlog_size限制;
3. 手工执行命令。
1、我们一般情况采取第三、第四种方式
2、每次执行命令不需重启即可清楚超期日志
MySQL 清除 binlog 和 relay log 方法说明 -- cnDBA.cn_中国DBA社区
MySQL binlog 自动清理脚本 -- cnDBA.cn_中国DBA社区
在主从复制环境下,MySQL通过binlog和relay log进行主从数据的同步,binlog由主库产生,从库通过复制io线程拉取binlog,写入到relay log中,sql线程读取relay log中的事务信息,并进行应用。
relay log通常不需要人工清理,因为从库的复制线程在应用完relay log中的事务后,会自动把relay log删除。每次复制的IO线程重启,都会生成一个新的relay log,每个relay log文件的大小由参数max_relay_log_size控制,该参数默认为0,即表示其大小和binlog文件大小一致,通常也为1G。
当然在从库上也可以执行命令来清除relay log文件,比如:reset slave 和 reset slave all。这两个命令会将relay log文件全部删除,并且生成新的索引从1开始的relay log文件。
mysql>STOP SLAVE;
mysql>reset slave
mysql>STOP SLAVE;
自动清廉脚本:
# vim /data/scripts/delete_mysql_binlog.sh
#!/bin/bash
#=======================================================================================
# 用于删除 MySQL Master 端已经同步完的 binlog【需在 Master 端运行】,以减少磁盘空间
# 每天凌晨 1:00 分运行一次
#
# 注:需在 Slave 端添加允许 Master 端访问的帐号【帐号:allen,密码:123456】
# 运行于 MySQL Master 端【目前只用于一主一从的同步模式,对于多从的情况暂时未考虑】
#=======================================================================================
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin
## Slave端连接信息
SLAVE_ADDR="XXX.XXX.XXX.XXX"
SLAVE_USER="allen"
SLAVE_PWD="123456"
LOGFILE="/data/logs/db_sync_info.log"
PINGFILE="/tmp/mysqlping.log"
## MySQL状态信息查看命令
SQLCMD="show slave status"
#=======================================================================================
## 检查MySQL是否已经运行
if [[ `ps aux | grep mysql[d] | wc -l` -eq 0 ]]; then
echo The MySQL is not running at: `date +%F" "%H-%M-%S` >> ${LOGFILE}
exit 1
fi
## 测试Slave端的连通性
nohup mysqladmin -h${SLAVE_ADDR} -u${SLAVE_USER} -p${SLAVE_PWD} ping > ${PINGFILE}
retval=$(grep "^error" ${PINGFILE})
rm -f ${PINGFILE}
if [[ "${retval}X" != "X" ]]; then
echo The MySQL Slave can not be connected at: $(date +%F" "%H-%M-%S) >> ${LOGFILE}
exit 1
fi
## 检查是否合法的Slave
MASTER_ADDR=`mysql -h${SLAVE_ADDR} -u${SLAVE_USER} -p${SLAVE_PWD} -e "${SQLCMD}/G;" | awk '$1=="Master_Host:" {print $2}'`
LOCAL_ADDR=`/sbin/ifconfig eth1 | awk -F ':' '/inet addr/{print $2}' | sed 's/[a-zA-Z ]//g'`
if [[ "${MASTER_ADDR}" != "${LOCAL_ADDR}" ]]; then
echo The MySQL Slave is not lawful at: `date +%F" "%H-%M-%S` >> ${LOGFILE}
exit 1
fi
## 获得Slave端信息,以此来确定是否处于正常同步的情况
IO_STATUS=`mysql -h${SLAVE_ADDR} -u${SLAVE_USER} -p${SLAVE_PWD} -e "${SQLCMD}/G;" | awk '$1=="Slave_IO_Running:" {print $2}'`
SQL_STATUS=`mysql -h${SLAVE_ADDR} -u${SLAVE_USER} -p${SLAVE_PWD} -e "${SQLCMD}/G;" | awk '$1=="Slave_SQL_Running:" {print $2}'`
if [[ "${IO_STATUS}" != "Yes" || "${SQL_STATUS}" != "Yes" ]]; then
echo The MySQL Replication is not synchronous at: `date +%F" "%H-%M-%S` >> ${LOGFILE}
exit 1
fi
## 再做一次判断,以保证数据同步绝对正常【创建测试数据】
mysql -uroot -e "create database if not exists mytestdb;"
sleep 3
retval=`mysql -h${SLAVE_ADDR} -u${SLAVE_USER} -p${SLAVE_PWD} -e "show databases;" | grep mytestdb`
mysql -uroot -e "drop database if exists mytestdb;"
if [[ "${retval}X" = "X" ]]; then
echo The MySQL Replication is not synchronous at: `date +%F" "%H-%M-%S` >> ${LOGFILE}
exit 1
fi
## 在已经同步的情况,还需要判断当前同步的binlog,以此来确定哪些已经是过期的binlog
SLAVE_BINLOG1=`mysql -h${SLAVE_ADDR} -u${SLAVE_USER} -p${SLAVE_PWD} -e "${SQLCMD}/G;" | awk '$1=="Master_Log_File:" {print $2}'`
SLAVE_BINLOG2=`mysql -h${SLAVE_ADDR} -u${SLAVE_USER} -p${SLAVE_PWD} -e "${SQLCMD}/G;" | awk '$1=="Relay_Master_Log_File:" {print $2}'`
## 获得Master端,当前的binlog文件以及binlog路径
MASTER_BINLOG=`mysql -uroot -e "show master status;" | grep -v '^+' | tail -1 | awk '{print $1}'`
## 主从端已经同步到相同的binlog
if [[ "${SLAVE_BINLOG1}" = "${SLAVE_BINLOG2}" && "${SLAVE_BINLOG1}" = "${MASTER_BINLOG}" ]]; then
CURR_BINLOG="${MASTER_BINLOG}"
## 主从端已经同步,但从端的binlog还没有追赶到主端最新的binlog
elif [[ "${SLAVE_BINLOG1}" = "${SLAVE_BINLOG2}" && "${SLAVE_BINLOG1}" != "${MASTER_BINLOG}" ]]; then
CURR_BINLOG="${SLAVE_BINLOG1}"
## 主从端已经同步,主从端的binlog一致,但relaylog还不一致
elif [[ "${SLAVE_BINLOG1}" != "${SLAVE_BINLOG2}" && "${SLAVE_BINLOG1}" = "${MASTER_BINLOG}" ]]; then
CURR_BINLOG="${SLAVE_BINLOG2}"
else
echo Has noknown error at:`date +%F" "%H-%M-%S` >> ${LOGFILE}
exit 1
fi
mysql -uroot -e "purge binary logs to '${CURR_BINLOG}';"
if [[ $? -eq 0 ]]; then
echo Clear MySQL binlog is ok at: `date +%F" "%H-%M-%S` >> ${LOGFILE}
fi
# crontab -e
00 01 * * * /data/scripts/delete_mysql_binlog.sh >/dev/null 2>&1