正确、安全的手动删除历史binlog,尽情释放磁盘空间。

本文涉及的产品
RDS Agent(兼容OpenClaw),2核4GB
RDS MySQL DuckDB 分析主实例,基础系列 4核8GB
RDS DuckDB + QuickBI 企业套餐,8核32GB + QuickBI 专业版
简介: 正确、安全的手动删除历史binlog,尽情释放磁盘空间。

继续回顾笔者的测试环境,如下:

基于昨天讲到的场景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删除指定的日志文件名

  1. 查看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)
  1. 查看当前正在使用的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
  1. 删除mysql-bin.000075
mysql> PURGE BINARY LOGS TO 'mysql-bin.000075';
Query OK, 0 rows affected (0.22 sec)
  1. 删除后再次查看,居然还是有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        |
  1. 于是笔者尝试重新启动了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>
  1. 莫非是没有刷新日志?于是笔者刷新日志,但仍然问题依旧
# 刷新日志
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文件

  1. 查看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        |
+------------------+-----------+-----------+
  1. 查看当前正在使用的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
  1. 删除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)
  1. 查看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)
  1. 继续查看binlog索引文件,发现也自动更新了,就只有mysql-bin.000081了
[root@zbx-db01 mysql_data]# cat mysql-bin.index 
./mysql-bin.000081
  1. 查看当前正在使用的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都被删了,不在了,所以复制异常

下面笔者回顾一下翻车现场,并把车修好

  1. 在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)
  1. 在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
  1. 开始修车,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
  1. 继续修车,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的经验,感谢大家的关注。

相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。   相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情: https://www.aliyun.com/product/rds/mysql 
相关文章
|
SQL 安全 关系型数据库
需要binlog的场景下,“暴力”干掉历史binlog文件,尽情释放磁盘空间
需要binlog的场景下,“暴力”干掉历史binlog文件,尽情释放磁盘空间
271 0
|
8月前
|
SQL 运维 关系型数据库
深入探讨MySQL的二进制日志(binlog)选项
总结而言,对MySQL binlogs深度理解并妥善配置对数据库运维管理至关重要;它不仅关系到系统性能优化也是实现高可靠性架构设计必须考虑因素之一。通过精心规划与周密部署可以使得该机能充分发挥作用而避免潜在风险带来影响。
254 6
|
9月前
|
存储 SQL 关系型数据库
MySQL中binlog、redolog与undolog的不同之处解析
每个都扮演回答回溯与错误修正机构角色: BinLog像历史记载员详细记载每件大大小小事件; RedoLog则像紧急救援队伍遇见突發情況追踪最后活动轨迹尽力补救; UndoLog就类似时间机器可倒带历史让一切归位原始样貌同时兼具平行宇宙观察能让多人同时看见各自期望看见历程而互不干扰.
522 9
|
存储 SQL 关系型数据库
mysql 的ReLog和BinLog区别
MySQL中的重做日志和二进制日志是确保数据库稳定性和可靠性的关键组件。重做日志主要用于事务的持久性和原子性,通过记录数据页的物理修改信息来恢复未提交的事务;而二进制日志记录SQL语句的逻辑变化,支持数据复制、恢复和审计。两者在写入时机、存储方式及配置参数等方面存在显著差异。
338 6
|
10月前
|
存储 SQL 关系型数据库
MySQL的Redo Log与Binlog机制对照分析
通过合理的配置和细致的管理,这两种日志机制相互配合,能够有效地提升MySQL数据库的可靠性和稳定性。
330 10
|
12月前
|
SQL 监控 关系型数据库
MySQL日志分析:binlog、redolog、undolog三大日志的深度探讨。
数据库管理其实和写小说一样,需要规划,需要修订,也需要有能力回滚。理解这些日志的作用与优化,就像把握写作工具的使用与运用,为我们的数据库保驾护航。
793 23
|
canal 消息中间件 关系型数据库
Canal作为一款高效、可靠的数据同步工具,凭借其基于MySQL binlog的增量同步机制,在数据同步领域展现了强大的应用价值
【9月更文挑战第1天】Canal作为一款高效、可靠的数据同步工具,凭借其基于MySQL binlog的增量同步机制,在数据同步领域展现了强大的应用价值
2273 4
|
SQL 关系型数据库 MySQL
【揭秘】MySQL binlog日志与GTID:如何让数据库备份恢复变得轻松简单?
【8月更文挑战第22天】MySQL的binlog日志记录数据变更,用于恢复、复制和点恢复;GTID为每笔事务分配唯一ID,简化复制和恢复流程。开启binlog和GTID后,可通过`mysqldump`进行逻辑备份,包含binlog位置信息,或用`xtrabackup`做物理备份。恢复时,使用`mysql`命令执行备份文件,或通过`innobackupex`恢复物理备份。GTID模式下的主从复制配置更简便。
1955 2
|
SQL 关系型数据库 MySQL
【MySQL】根据binlog日志获取回滚sql的一个开发思路
【MySQL】根据binlog日志获取回滚sql的一个开发思路