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

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS PostgreSQL,集群系列 2核4GB
简介: 正确、安全的手动删除历史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的经验,感谢大家的关注。

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
SQL 安全 关系型数据库
需要binlog的场景下,“暴力”干掉历史binlog文件,尽情释放磁盘空间
需要binlog的场景下,“暴力”干掉历史binlog文件,尽情释放磁盘空间
103 0
|
1月前
|
canal 消息中间件 关系型数据库
Canal作为一款高效、可靠的数据同步工具,凭借其基于MySQL binlog的增量同步机制,在数据同步领域展现了强大的应用价值
【9月更文挑战第1天】Canal作为一款高效、可靠的数据同步工具,凭借其基于MySQL binlog的增量同步机制,在数据同步领域展现了强大的应用价值
375 4
|
2月前
|
SQL 关系型数据库 MySQL
【揭秘】MySQL binlog日志与GTID:如何让数据库备份恢复变得轻松简单?
【8月更文挑战第22天】MySQL的binlog日志记录数据变更,用于恢复、复制和点恢复;GTID为每笔事务分配唯一ID,简化复制和恢复流程。开启binlog和GTID后,可通过`mysqldump`进行逻辑备份,包含binlog位置信息,或用`xtrabackup`做物理备份。恢复时,使用`mysql`命令执行备份文件,或通过`innobackupex`恢复物理备份。GTID模式下的主从复制配置更简便。
248 2
|
2月前
|
SQL 关系型数据库 MySQL
【MySQL】根据binlog日志获取回滚sql的一个开发思路
【MySQL】根据binlog日志获取回滚sql的一个开发思路
|
27天前
|
消息中间件 canal 关系型数据库
Maxwell:binlog 解析器,轻松同步 MySQL 数据
Maxwell:binlog 解析器,轻松同步 MySQL 数据
162 11
|
2月前
|
关系型数据库 MySQL Shell
MySQL回滚脚本: 误操作delete binlog回滚shell脚本
MySQL回滚脚本: 误操作delete binlog回滚shell脚本
|
2月前
|
关系型数据库 MySQL 数据库
MySQL回滚工具:binlog 闪回工具 MyFlash工具
MySQL回滚工具:binlog 闪回工具 MyFlash工具
|
2月前
|
监控 关系型数据库 MySQL
MySQL如何快速获取binlog的开始时间和结束时间
【8月更文挑战第17天】在MySQL中快速获取binlog的开始与结束时间可通过多种途径:1) 使用`mysqlbinlog`结合`head`和`tail`命令查看单个或多个binlog文件的时间范围;2) 查询`information_schema.binlog_events`表获取近似的开始与结束时间戳;3) 利用第三方工具如Percona Toolkit的`pt-mysql-summary`获取binlog信息。选择适当方法前应考虑操作环境及数据安全性。
261 2
|
2月前
|
数据采集 关系型数据库 MySQL
大数据-业务数据采集-FlinkCDC The MySQL server is not configured to use a ROW binlog_format
大数据-业务数据采集-FlinkCDC The MySQL server is not configured to use a ROW binlog_format
36 1
|
3月前
|
关系型数据库 MySQL Java