暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

需要binlog的场景下,“暴力”干掉历史binlog文件,尽情释放磁盘空间

TtrOpsStack 2022-05-06
659

场景2:需要binlog的场景

基于昨天讲到的场景1是不需要binlog的场景,文章链接如下:

  • https://mp.weixin.qq.com/s?__biz=MzUzMTkyODc4NQ==&mid=2247483861&idx=1&sn=d597a9dd1d7fb19776fbc3f34998db62&chksm=faba426bcdcdcb7d55bed58b9b7ee384c3903795033488737611032021f6e03ddb306790b131&token=156993506&lang=zh_CN#rd

今天接着讲场景2:需要binlog的场景

关于场景2,简而言之就是需要启用或者已经是启用了binlog的场景,如生产环境中的MySQL主从环境。当日积月累,binlog撑爆磁盘空间的时候,又该如何正确的、安全的进行删除较旧的Binlog文件从而释放空间?笔者分享自身的经验,如有不足之处,还望广大IT圈的盆友指出,我们共同学习、成长。

当binlog文件即将要撑爆磁盘的时候,该如何正确、安全的删除历史的binlog?有2种办法,分别为:

  1. 利用mysql自身的机制自动删除,也就是通过设置相关参数,让binlog保留多少天,当达到期限就会自动删除
  2. 手动删除,那么手动删除,又分以下几种情况:
  • 找到binlog所在的目录,“暴力”直接删除binlog文件,也就是通过rm命令干它,但注意,一定要同时在mysql-bin.index索引文件中删除对应的条目
  • mysql提供的PURGE BINARY LOGS 语句来删除更安全,PURGE的方式会自动更新mysql-bin.index中的条目
  • RESET MASTER删除所有的二进制日志文件

因笔者每天时间有限,为了保持文章的高质量,今晚就只对“暴力”直接删除binlog文件的方案进行分析,关于另外2个删除办法,我们明天继续谈谈!

1. 笔者的环境如下图

两台服务器组成的互为主从环境,双向复制,非常简单。意思就是:

  • db01是master,它的slave是db02
  • db02是master,它的slave是db01

互为主从的环境,需要注意,两边都是需要开启binlog记录,笔者环境中使用了keepalived做高可用,当前VIP被db01进行接管,上层应用连接的是VIP,架构很简单,并没有去做双主可以支持并发写数据的事情,因为这涉及到很多问题需要解决,比如数据的一致性等问题,关于双主如何支持并发写,以后笔者会分享这块的经验,目前笔者的环境只使用一个主库提供服务,另外一个是作为BACKUP。

2. 大部分生产环境的mysql架构

一般生产环境架构要么是:

  • 一主、一从,主和从都存在单点
  • 如果应用的特点是读多写少,那么可以是一主多从,做读写分离的架构,但主只有1台,存在单点
  • 既然主有单点故障的风险,那就部署双主多从,甚至是多主多从的架构

3. “暴力“删除之前需要做的相关检查

1. 检查复制状态

  • db01
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.000072
          Read_Source_Log_Pos: 22831562
               Relay_Log_File: zbx-db01-relay-bin.000046
                Relay_Log_Pos: 364
        Relay_Source_Log_File: mysql-bin.000072
           Replica_IO_Running: Yes
          Replica_SQL_Running: Yes
...

  • db02
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.000071
          Read_Source_Log_Pos: 22806499
               Relay_Log_File: zbx-db02-relay-bin.000102
                Relay_Log_Pos: 18710090
        Relay_Source_Log_File: mysql-bin.000071
           Replica_IO_Running: Yes
          Replica_SQL_Running: Yes
...

两台的IO和SQL线程均为YES,说明都正常

2. 查看binlog列表

  • db01
mysql> show binary logs;
+------------------+-----------+-----------+
| Log_name         | File_size | Encrypted |
+------------------+-----------+-----------+
| mysql-bin.000054 |   3403136 | No        |
| mysql-bin.000055 |   4405820 | No        |
| mysql-bin.000056 |  23387993 | No        |
| mysql-bin.000057 |   7747401 | No        |
| mysql-bin.000058 |  20376333 | No        |
| mysql-bin.000059 |   1421676 | No        |
| mysql-bin.000060 |  11762442 | No        |
| mysql-bin.000061 |    106139 | No        |
| mysql-bin.000062 |  29829686 | No        |
| mysql-bin.000063 |       275 | No        |
| mysql-bin.000064 |  44495957 | No        |
| mysql-bin.000065 |  23984155 | No        |
| mysql-bin.000066 |   3381900 | No        |
| mysql-bin.000067 |  79700058 | No        |
| mysql-bin.000068 |  46420313 | No        |
| mysql-bin.000069 |  18793760 | No        |
| mysql-bin.000070 |   3059876 | No        |
| mysql-bin.000071 |  23207777 | No        |
| mysql-bin.000072 |    502239 | No        |
+------------------+-----------+-----------+
19 rows in set (43.05 sec)

mysql>
 

  • db02
mysql> show binary logs;
+------------------+-----------+-----------+
| Log_name         | File_size | Encrypted |
+------------------+-----------+-----------+
| mysql-bin.000055 |   2758206 | No        |
| mysql-bin.000056 |    332959 | No        |
| mysql-bin.000057 |    171809 | No        |
| mysql-bin.000058 |  27972976 | No        |
| mysql-bin.000059 |   5465998 | No        |
| mysql-bin.000060 |   2171749 | No        |
| mysql-bin.000061 |  33699992 | No        |
| mysql-bin.000062 |    104275 | No        |
| mysql-bin.000063 |  29770161 | No        |
| mysql-bin.000064 |       259 | No        |
| mysql-bin.000065 |  44606908 | No        |
| mysql-bin.000066 |  23973022 | No        |
| mysql-bin.000067 |   3362504 | No        |
| mysql-bin.000068 |  79785449 | No        |
| mysql-bin.000069 |  46437843 | No        |
| mysql-bin.000070 |  18810455 | No        |
| mysql-bin.000071 |   3050696 | No        |
| mysql-bin.000072 |  23235692 | No        |
| mysql-bin.000073 |    513397 | No        |
+------------------+-----------+-----------+
19 rows in set (11.81 sec)

mysql>
 

3. 查看当前正在使用的binlog

  • db01
mysql> show master status\G;
*************************** 1. row ***************************
             File: mysql-bin.000072
         Position: 1232726
     Binlog_Do_DB: 
 Binlog_Ignore_DB: 
Executed_Gtid_Set: 9208096f-4731-11ec-a23e-005056210589:1-23:31-585,
92099aae-4731-11ec-a3da-00505629525b:1-1406317
1 row in set (0.00 sec)

ERROR: 
No query specified

mysql>
 

  • db02
mysql> show master status\G;
*************************** 1. row ***************************
             File: mysql-bin.000073
         Position: 2065293
     Binlog_Do_DB: 
 Binlog_Ignore_DB: 
Executed_Gtid_Set: 9208096f-4731-11ec-a23e-005056210589:1-585,
92099aae-4731-11ec-a3da-00505629525b:1-1407638
1 row in set (0.00 sec)

ERROR: 
No query specified

mysql>
 

注意:db01当前使用的是mysql-bin.000072,db02当前使用的是mysql-bin.000073,正在使用的binlog文件是绝对不能手动去删除,不然会引发不可预料的问题。

4. ”暴力“手动直接删除

  • 笔者只在db01上操作,db02是一样的操作,笔者就不重复撰写。

注意,之前查看到db01正在使用的binlog文件是mysql-bin.000072,所以,除了当前正在使用的mysql-bin.000072外,其他的可以全部删除,我说的是可以,当然要删除哪些你自己看着办呗!

  1. 先搜索出要删除的binlog文件,文件比较多时可以用find命令,并排除不需要删除的binlog文件
[root@zbx-db01 mysql_data]# cd /data/mysql_data
[root@zbx-db01 mysql_data]# find ./ -type f -name "mysql-bin.*" ! -name "mysql-bin.index" ! -name "mysql-bin.000072"
./mysql-bin.000070
./mysql-bin.000065
./mysql-bin.000060
./mysql-bin.000071
./mysql-bin.000055
./mysql-bin.000059
./mysql-bin.000057
./mysql-bin.000068
./mysql-bin.000061
./mysql-bin.000058
./mysql-bin.000067
./mysql-bin.000064
./mysql-bin.000069
./mysql-bin.000056
./mysql-bin.000054
./mysql-bin.000062
./mysql-bin.000063
./mysql-bin.000066
[root@zbx-db01 mysql_data]# 

注意:要排除掉db01正在使用的binlog文件mysql-bin.000072,还要排除掉binlog索引文件mysql-bin.index,可别误删了哦!

  1. 开始删除
find ./ -type f -name "mysql-bin.*" ! -name "mysql-bin.index" ! -name "mysql-bin.000072" | xargs rm -rf

  1. 删除之后,搜索看看,就剩俩了
[root@zbx-db01 mysql_data]# find ./ -type f -name "mysql-bin.*"
./mysql-bin.index
./mysql-bin.000072

  1. 接着很重要的一步,手动清理掉mysql-bin.index中已删除的条目,笔者删除后,用cat查看
[root@zbx-db01 mysql_data]# cat mysql-bin.index 
./mysql-bin.000072

关于mysql-bin.index的作用,其作用是加快查找binlog文件的速度。

  1. 接着登录数据库查看binlog信息,发现已删除的还在,但File_size都为0了
mysql> show binary logs;
+------------------+-----------+-----------+
| Log_name         | File_size | Encrypted |
+------------------+-----------+-----------+
| mysql-bin.000054 |         0 | No        |
| mysql-bin.000055 |         0 | No        |
| mysql-bin.000056 |         0 | No        |
| mysql-bin.000057 |         0 | No        |
| mysql-bin.000058 |         0 | No        |
| mysql-bin.000059 |         0 | No        |
| mysql-bin.000060 |         0 | No        |
| mysql-bin.000061 |         0 | No        |
| mysql-bin.000062 |         0 | No        |
| mysql-bin.000063 |         0 | No        |
| mysql-bin.000064 |         0 | No        |
| mysql-bin.000065 |         0 | No        |
| mysql-bin.000066 |         0 | No        |
| mysql-bin.000067 |         0 | No        |
| mysql-bin.000068 |         0 | No        |
| mysql-bin.000069 |         0 | No        |
| mysql-bin.000070 |         0 | No        |
| mysql-bin.000071 |         0 | No        |
| mysql-bin.000072 |   3645040 | No        |
+------------------+-----------+-----------+
19 rows in set (0.07 sec)

  1. 刷新日志,以及再次查看
# 刷新logs
mysql> flush logs;
Query OK, 0 rows affected (1.62 sec)

#
 刷新后查看,发现又自动生成了一个新的mysql-bin.000073
mysql> show binary logs;
+------------------+-----------+-----------+
| Log_name         | File_size | Encrypted |
+------------------+-----------+-----------+
| mysql-bin.000072 |   3659564 | No        |
| mysql-bin.000073 |      1973 | No        |
+------------------+-----------+-----------+
2 rows in set (0.00 sec)

mysql>
 

#
 且当前使用的就是最新的binlog文件,
mysql> show master status\G;
*************************** 1. row ***************************
             File: mysql-bin.000073
         Position: 108261
     Binlog_Do_DB: 
 Binlog_Ignore_DB: 
Executed_Gtid_Set: 9208096f-4731-11ec-a23e-005056210589:1-23:31-585,
92099aae-4731-11ec-a3da-00505629525b:1-1410247
1 row in set (0.00 sec)

ERROR: 
No query specified

mysql>


#
 查看binlog索引文件mysql-bin.index
[root@zbx-db01 mysql_data]# cat mysql-bin.index 
./mysql-bin.000072
./mysql-bin.000073 

flush logs命令的作用就是刷新binlog日志,刷新后会自动生成新的binary log文件,且文件的序号加1。其实,当mysql服务停掉后,再拉起,也会自动生成一个新的binlog日志文件。


写在最后,因笔者每天时间有限,为了保持文章的高质量,今晚就只对“暴力”直接删除binlog文件的方案进行分析,关于另外2个删除办法,我们明天继续谈谈!今晚就此搁笔,感谢大家的耐心观看。


文章转载自TtrOpsStack,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论