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

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS MySQL,高可用系列 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的经验,感谢大家的关注。

相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
SQL 安全 关系型数据库
需要binlog的场景下,“暴力”干掉历史binlog文件,尽情释放磁盘空间
需要binlog的场景下,“暴力”干掉历史binlog文件,尽情释放磁盘空间
110 0
|
20天前
|
存储 SQL 关系型数据库
mysql 的ReLog和BinLog区别
MySQL中的重做日志和二进制日志是确保数据库稳定性和可靠性的关键组件。重做日志主要用于事务的持久性和原子性,通过记录数据页的物理修改信息来恢复未提交的事务;而二进制日志记录SQL语句的逻辑变化,支持数据复制、恢复和审计。两者在写入时机、存储方式及配置参数等方面存在显著差异。
|
3月前
|
canal 消息中间件 关系型数据库
Canal作为一款高效、可靠的数据同步工具,凭借其基于MySQL binlog的增量同步机制,在数据同步领域展现了强大的应用价值
【9月更文挑战第1天】Canal作为一款高效、可靠的数据同步工具,凭借其基于MySQL binlog的增量同步机制,在数据同步领域展现了强大的应用价值
840 4
|
4月前
|
SQL 关系型数据库 MySQL
【揭秘】MySQL binlog日志与GTID:如何让数据库备份恢复变得轻松简单?
【8月更文挑战第22天】MySQL的binlog日志记录数据变更,用于恢复、复制和点恢复;GTID为每笔事务分配唯一ID,简化复制和恢复流程。开启binlog和GTID后,可通过`mysqldump`进行逻辑备份,包含binlog位置信息,或用`xtrabackup`做物理备份。恢复时,使用`mysql`命令执行备份文件,或通过`innobackupex`恢复物理备份。GTID模式下的主从复制配置更简便。
555 2
|
3天前
|
SQL 关系型数据库 MySQL
数据库灾难应对:MySQL误删除数据的救赎之道,技巧get起来!之binlog
《数据库灾难应对:MySQL误删除数据的救赎之道,技巧get起来!之binlog》介绍了如何利用MySQL的二进制日志(Binlog)恢复误删除的数据。主要内容包括: 1. **启用二进制日志**:在`my.cnf`中配置`log-bin`并重启MySQL服务。 2. **查看二进制日志文件**:使用`SHOW VARIABLES LIKE 'log_%';`和`SHOW MASTER STATUS;`命令获取当前日志文件及位置。 3. **创建数据备份**:确保在恢复前已有备份,以防意外。 4. **导出二进制日志为SQL语句**:使用`mysqlbinlog`
22 2
|
4月前
|
SQL 关系型数据库 MySQL
【MySQL】根据binlog日志获取回滚sql的一个开发思路
【MySQL】根据binlog日志获取回滚sql的一个开发思路
|
19天前
|
SQL 存储 缓存
MySQL进阶突击系列(02)一条更新SQL执行过程 | 讲透undoLog、redoLog、binLog日志三宝
本文详细介绍了MySQL中update SQL执行过程涉及的undoLog、redoLog和binLog三种日志的作用及其工作原理,包括它们如何确保数据的一致性和完整性,以及在事务提交过程中各自的角色。同时,文章还探讨了这些日志在故障恢复中的重要性,强调了合理配置相关参数对于提高系统稳定性的必要性。
|
1月前
|
关系型数据库 MySQL 数据库
【赵渝强老师】MySQL的binlog日志文件
MySQL的binlog日志记录了所有对数据库的更改操作(不包括SELECT和SHOW),主要用于主从复制和数据恢复。binlog有三种模式,可通过设置binlog_format参数选择。示例展示了如何启用binlog、设置格式、查看日志文件及记录的信息。
122 6
|
1月前
|
存储 SQL 关系型数据库
mysql 的ReLog和BinLog区别
MySQL中的重做日志(Redo Log)和二进制日志(Binary Log)是两种重要的日志系统。重做日志主要用于保证事务的持久性和原子性,通过记录数据页的物理修改信息来恢复未提交的事务更改。二进制日志则记录了数据库的所有逻辑变化操作,用于数据的复制、恢复和审计。两者在写入时机、存储方式、配置参数和使用范围上有所不同,共同确保了数据库的稳定性和可靠性。
|
3月前
|
消息中间件 canal 关系型数据库
Maxwell:binlog 解析器,轻松同步 MySQL 数据
Maxwell:binlog 解析器,轻松同步 MySQL 数据
397 11