继续回顾笔者的测试环境,如下:
基于昨天讲到的场景2(需要binlog的场景下),且是“暴力”删除binlog文件,昨天的文章链接如下:
今天继续分享场景2(需要binlog的场景)中手动删除binlog文件的方法,但不是“暴力”哦!而是用mysql自身提供的2个语句来更安全的手动删除二进制日志,如下:
- 使用PURGE BINARY LOGS 语句来删除更安全,PURGE的方式会自动更新mysql-bin.index中的条目
- 使用RESET MASTER删除所有的二进制日志文件
PURGE的语法格式如下:
PURGE {MASTER | BINARY} LOGS TO '指定日志文件名' PURGE {MASTER | BINARY} LOGS BEFORE '指定日期'
注意:MASTER和BINARY是同义词,意思是用哪个关键字都行
安全删除,案例1:使用PURGE BINARY LOGS TO删除指定的日志文件名
- 查看binlog文件列表
mysql> show binary logs; +------------------+-----------+-----------+ | Log_name | File_size | Encrypted | +------------------+-----------+-----------+ | mysql-bin.000075 | 15559350 | No | | mysql-bin.000076 | 1975156 | No | | mysql-bin.000077 | 166739 | No | | mysql-bin.000078 | 226151 | No | | mysql-bin.000079 | 563 | No | +------------------+-----------+-----------+ 5 rows in set (0.00 sec)
- 查看当前正在使用的binlog文件
mysql> show master status\G; *************************** 1. row *************************** File: mysql-bin.000079 Position: 874 Binlog_Do_DB: Binlog_Ignore_DB: Executed_Gtid_Set: 9208096f-4731-11ec-a23e-005056210589:1-23:31-585, 92099aae-4731-11ec-a3da-00505629525b:1-1440509 1 row in set (0.00 sec) ERROR: No query specified
- 删除mysql-bin.000075
mysql> PURGE BINARY LOGS TO 'mysql-bin.000075'; Query OK, 0 rows affected (0.22 sec)
- 删除后再次查看,居然还是有mysql-bin.000075,指令是成功的,但好像未生效
mysql> show binary logs; +------------------+-----------+-----------+ | Log_name | File_size | Encrypted | +------------------+-----------+-----------+ | mysql-bin.000075 | 15559350 | No | | mysql-bin.000076 | 1975156 | No | | mysql-bin.000077 | 166739 | No | | mysql-bin.000078 | 226151 | No | | mysql-bin.000079 | 12248 | No |
- 于是笔者尝试重新启动了Mysql服务,再次登录查看,发现之前被删除的mysql-bin.000075还是存在,很奇怪
mysql> show binary logs; +------------------+-----------+-----------+ | Log_name | File_size | Encrypted | +------------------+-----------+-----------+ | mysql-bin.000075 | 15559350 | No | | mysql-bin.000076 | 1975156 | No | | mysql-bin.000077 | 166739 | No | | mysql-bin.000078 | 226151 | No | | mysql-bin.000079 | 12248 | No | | mysql-bin.000080 | 37947 | No | +------------------+-----------+-----------+ 6 rows in set (0.00 sec) mysql>
- 莫非是没有刷新日志?于是笔者刷新日志,但仍然问题依旧
# 刷新日志 mysql> flush logs; Query OK, 0 rows affected (0.04 sec) # 刷新后再次查看,被删除过的mysql-bin.000075还是存在 mysql> show binary logs; +------------------+-----------+-----------+ | Log_name | File_size | Encrypted | +------------------+-----------+-----------+ | mysql-bin.000075 | 15559350 | No | | mysql-bin.000076 | 1975156 | No | | mysql-bin.000077 | 166739 | No | | mysql-bin.000078 | 226151 | No | | mysql-bin.000079 | 12248 | No | | mysql-bin.000080 | 145640 | No | | mysql-bin.000081 | 1980 | No | +------------------+-----------+-----------+ 7 rows in set (0.00 sec) mysql>
最后发现,使用PURGE BINARY LOGS TO删除指定的日志文件mysql-bin.000075不生效,其原因笔者目前也不得而知,并且在数据目录中和索引文件中,都还是存在mysql-bin.000075,也就是说,目前笔者也陷入了大型翻车现场,这个问题笔者后续会继续深究。
安全删除,案例2:使用PURGE BINARY LOGS BEFORE语句删除指定时间之前的binlog文件
- 查看binlog列表
mysql> show binary logs; +------------------+-----------+-----------+ | Log_name | File_size | Encrypted | +------------------+-----------+-----------+ | mysql-bin.000075 | 15559350 | No | | mysql-bin.000076 | 1975156 | No | | mysql-bin.000077 | 166739 | No | | mysql-bin.000078 | 226151 | No | | mysql-bin.000079 | 12248 | No | | mysql-bin.000080 | 145640 | No | | mysql-bin.000081 | 147548 | No | +------------------+-----------+-----------+
- 查看当前正在使用的binlog文件
mysql> show master status\G; *************************** 1. row *************************** File: mysql-bin.000081 Position: 149464 Binlog_Do_DB: Binlog_Ignore_DB: Executed_Gtid_Set: 9208096f-4731-11ec-a23e-005056210589:1-23:31-585, 92099aae-4731-11ec-a3da-00505629525b:1-1441267 1 row in set (0.00 sec) ERROR: No query specified
- 删除2022-05-07 21:10:00时间之前的binlog
mysql> PURGE BINARY LOGS BEFORE '2022-05-07 21:10:00'; Query OK, 0 rows affected, 1 warning (0.65 sec)
- 查看binlog列表,发现生效啦!000075到000080的binlog都删除成功了
mysql> show binary logs; +------------------+-----------+-----------+ | Log_name | File_size | Encrypted | +------------------+-----------+-----------+ | mysql-bin.000081 | 173446 | No | +------------------+-----------+-----------+ 1 row in set (0.00 sec)
- 继续查看binlog索引文件,发现也自动更新了,就只有mysql-bin.000081了
[root@zbx-db01 mysql_data]# cat mysql-bin.index ./mysql-bin.000081
- 查看当前正在使用的binlog
mysql> show master status\G; *************************** 1. row *************************** File: mysql-bin.000081 Position: 175349 Binlog_Do_DB: Binlog_Ignore_DB: Executed_Gtid_Set: 9208096f-4731-11ec-a23e-005056210589:1-23:31-585, 92099aae-4731-11ec-a3da-00505629525b:1-1441339 1 row in set (0.00 sec) ERROR: No query specified
使用RESET MASTER删除所有的二进制日志文件
这个语句在生产的mysql主从环境中请谨慎使用,笔者的是测试环境,由于之前笔者在db01和db02上都删除了binlog,导致主从复制异常,两边的SQL线程都为NO,也就是:
Replica_IO_Running: Yes Replica_SQL_Running: No
造成这种情况的原因是:双向的Source_Log_File都被删了,不在了,所以复制异常
下面笔者回顾一下翻车现场,并把车修好
- 在db01和db02都删除掉所有的二进制日志文件
# 在db01删除所有的二进制日志文件 mysql> RESET MASTER; Query OK, 0 rows affected (4.90 sec) # 发现db01的binlog全都被删除了,而且编号从1开始了 mysql> show binary logs; +------------------+-----------+-----------+ | Log_name | File_size | Encrypted | +------------------+-----------+-----------+ | mysql-bin.000001 | 156 | No | +------------------+-----------+-----------+ 1 row in set (0.00 sec) # 在db02也删除所有的二进制日志文件 ```shell mysql> RESET MASTER; Query OK, 0 rows affected (13.29 sec) # # 发现db02的binlog也全都被删除了,而且编号也是从1开始了 mysql> show binary logs; +------------------+-----------+-----------+ | Log_name | File_size | Encrypted | +------------------+-----------+-----------+ | mysql-bin.000001 | 156 | No | +------------------+-----------+-----------+ 1 row in set (0.01 sec)
- 在db01和db02都查看复制状态,笔者的是互为主从环境,果然不出我所料,两边的双向复制都异常了,IO和SQL线程都为NO了
# db01查看复制状态,两个线程都为NO mysql> show replica status\G; *************************** 1. row *************************** Replica_IO_State: Source_Host: 192.168.11.152 Source_User: syn_b Source_Port: 3306 Connect_Retry: 60 Source_Log_File: mysql-bin.000077 Read_Source_Log_Pos: 666529 Relay_Log_File: zbx-db01-relay-bin.000067 Relay_Log_Pos: 324 Relay_Source_Log_File: mysql-bin.000077 Replica_IO_Running: No Replica_SQL_Running: No # db02查看复制状态,两个线程也都为NO mysql> show replica status\G; *************************** 1. row *************************** Replica_IO_State: Source_Host: 192.168.11.151 Source_User: syn_a Source_Port: 3306 Connect_Retry: 60 Source_Log_File: mysql-bin.000082 Read_Source_Log_Pos: 252 Relay_Log_File: zbx-db02-relay-bin.000117 Relay_Log_Pos: 664893 Relay_Source_Log_File: mysql-bin.000076 Replica_IO_Running: No Replica_SQL_Running: No
- 开始修车,db01是主,db02是从,先修好db02能正常连接到db01进行复制
- 在db02(slave)上操作
# 重置复制 mysql> RESET REPLICA; Query OK, 0 rows affected (0.25 sec) # 启动复制 mysql> start replica; Query OK, 0 rows affected (6.01 sec) # 查看复制状态,发现IO和SQL线程都为YES了,说明已经连接上了DB01 mysql> show replica status\G; *************************** 1. row *************************** Replica_IO_State: Waiting for source to send event Source_Host: 192.168.11.151 Source_User: syn_a Source_Port: 3306 Connect_Retry: 60 Source_Log_File: mysql-bin.000001 Read_Source_Log_Pos: 156 Relay_Log_File: zbx-db02-relay-bin.000003 Relay_Log_Pos: 371 Relay_Source_Log_File: mysql-bin.000001 Replica_IO_Running: Yes Replica_SQL_Running: Yes
- 继续修车,db02是主,db01是从,修好db01能正常连接到db02进行复制
- 在db01(slave)上进行操作
# 重置复制 mysql> reset replica; Query OK, 0 rows affected (0.02 sec) # 启动复制 mysql> start replica; Query OK, 0 rows affected (0.73 sec) # 查看复制状态,发现IO和SQL线程都为YES了,说明已经连接上了DB02 mysql> show replica status\G; *************************** 1. row *************************** Replica_IO_State: Waiting for source to send event Source_Host: 192.168.11.152 Source_User: syn_b Source_Port: 3306 Connect_Retry: 60 Source_Log_File: mysql-bin.000001 Read_Source_Log_Pos: 156 Relay_Log_File: zbx-db01-relay-bin.000003 Relay_Log_Pos: 371 Relay_Source_Log_File: mysql-bin.000001 Replica_IO_Running: Yes Replica_SQL_Running: Yes
大型翻车现场已经成功挽救,那么对reset master和rest replica做个总结:就是生产环境一定要慎用,通常,当从库和主库不一致的时候,才需要用到rest replica,关于这两个语句的作用,再次声明如下:
reset master
- 会删除binlog索引文件中列出的所有binlog文件
- 清空binlog索引文件
- 会创建新的binlog文件
- 清空gtid_purged和gtid_executed系统变量
reset replica
- 清除replica复制时的master binlog位置
- 清空master info和relay log info
- 删除所有的中继日志文件,并创建一个新的中继日志文件(relay log)
写在最后,关于今天的分享就先暂告一段落,但是,之前遇到的问题:使用PURGE BINARY LOGS TO删除指定的日志文件mysql-bin.000075不生效的问题,笔者还会继续深究,到时候继续分享,感谢大家的耐心观看,明天继续分享关于自动删除BinLog的经验,感谢大家的关注。