admin管理员组

文章数量:1530048

一、序言

腾讯云数据库TDSQL是腾讯自研的分布式数据库产品,同时支持分布式实例和集中式实例在国内有众多的部署及使用案例。

binlog是MySQL时间点恢复的基石,如果只有全量/增量备份但是没有对应的binlog备份此时就只能恢复到全量/增量备份的一致性快照时间点。想要恢复到其它指定的时间点就必须要有全量/增量备份之后对应的binlog备份。

TDSQL分为MySQL和PostgreSQL两种版本,本篇文章以MySQL版本为基础分享binlog的备份和自动清理逻辑同时本文从模拟binlog备份异常开始通过TDSQL的日志内容展现相关的技术细节。

本文范例版本信息:

        TDSQL:  10.3.17.3.0

备份介质:

        Hadoop

【本文内容同样适用于其它版本TDSQL,仅在细节方面有微小的差异】

二、问题描述

实例管理员收到告警信息binlog备份异常,登录赤兔查看实例的【日志磁盘使用率】达到了156%超过告警阈值需要进行处理(此处仅以第一个set的问题处理过程为例,另外一个set参照此方法);

三、概念及原理

1. 处理问题之前我们先回忆一下binlog的备份清理策略以及相关概念。

  • 首先每个set会有一个逻辑主的概念,逻辑主即某个set(一组主从架构的实例)中充当备份节点的某个从MySQL实例;set首次启动后会选择一个从库充当逻辑主的角色;
  • 当逻辑主的MySQL进程出现故障 / mysqlagent进程异常或者此从库延迟过大时TDSQL会自动选择另外一台合格的从库充当逻辑主的角色;
  • binlog的备份会在逻辑主的节点进行。相应数据库端口的mysqlagent进程(二进制文件名称为mysqlreport)检测到本实例为逻辑主后会拉起binlog的备份进程;
  • 备份以流的方式实时进行同时使用lz4格式进行压缩。

以下以4001端口为例,截图分别为mysqlagent和对应binlog的备份进程:

 2. 了解了备份逻辑后,那么binlog又是在什么情况下进行清理的呢?具体清理逻辑如下:

  • 首先此处的binlog清理指的是DB服务器上存放的binlog文件的清理非HDFS存储的备份binlog文件;
  • 创建实例时均会指定日志目录的大小,当DB服务器上对应实例binlog目录大小超过指定日志目录大小的50%并且进行了备份的情况下就会启动binlog清理线程删除binlog文件;
  • 当清理线程检测到binlog目录大小重新小于等于指定日志目录大小的50%时会停止清理动作进入sleep状态;
  • 每次清理从编号最小的binlog文件开始,直到不符合清理逻辑后结束;
  • 清理线程在日志中的关键字为removebinlog.cpp每20秒唤醒一次(有些版本可能会40秒唤醒一次);

以下为正常清理binlog时的截图:

3. 回到之前的binlog日志磁盘使用率达到156%的告警问题。首先我们需要查看mysqlagent的日志根据removebinlog关键字进行过滤。

# 登录逻辑主服务器执行,以下以4001端口为例
vi /data/tdsql_run/4001/mysqlagent/log/sys_report_4001.log.2021-04-22.0

 通过以上的日志发现binlog.000760还没有进行备份或者没有备份完毕所以不能进行删除,这也验证了TDSQL会保证在有备份的情况下才有可能触发binlog清理的流程。查看备份记录也可以看到最后一个binlog备份文件只到binlog.000759 :

# 登录逻辑主服务器执行,以下以4001端口为例
tailf /data1/tdengine/log/4001/dblogs/bin/binlog.coldbackbinlog

四、解决方法

1. 通过以上日志发现binlog没有进行备份是无法清理binlog的原因。那么在什么情况下会出现binlog没有进行正常备份呢?常见的几种场景如下:

  • mysqlagent进程没有启动binlog备份进程(之前已经检查过是正常启动的,本范例非此原因);
  • binlog生成的速度远大于备份的速度(经检查binlog文件并没有生成的特别频繁);
  • 逻辑主服务器的hadoop客户端连接服务器异常(使用如下命令检查发现确实有异常);

 2. 出现上述异常的原因较多,此处不做过多分析。修复如上问题最简单的方案就是从同一集群的其它正常DB服务器拷贝hadoop目录到本机即可(hadoop环境变量如不正常的话同时需要更新/etc/profile文件中的HADOOP部分,此处略):

# 需要切到tdsql帐号执行以下命令
[root@db1 ~]#  su - tdsql
[tdsql@db1 ~]$ cd /data/home/tdsql
[tdsql@db1 ~]$ mv hadoop hadoop.old
[tdsql@db1 ~]$ scp -r anotherDBIP:/data/home/tdsql/hadoop ./

3. hadoop目录拷贝到本机后执行hdfs dfs -ls / 命令可以看到/tdsqlbackup备份目录即表示hadoop客户端配置正常;

4. 再次查看binlog.coldbackbinlog发现binlog.000760已经进行了备份同时后续的binlog也在持续备份中;

# 登录逻辑主服务器执行,以下以4001端口为例
tailf /data1/tdengine/log/4001/dblogs/bin/binlog.coldbackbinlog

5. 过一段时间再次查看mysqlagent日志文件会发现binlog的目录大小(130489163776字节)已经小于创建实例时指定的日志大小(日志中的log_disk:250000MB)的一半(250000/2*1024*1024=131,072,000,000),此时日志显示【don‘t need purge】表示无需再进行日志清理工作;

# 登录逻辑主服务器查看mysqlagent日志,以下以4001端口为例
vi /data/tdsql_run/4001/mysqlagent/log/sys_report_4001.log.2021-04-22.0

# 查看逻辑主的binlog目录的大小,单位为字节
du -b /data1/tdengine/log/4001/dblogs/bin

 6. 过一段时间再次查看实例的日志磁盘使用率已经降低为62%,binlog文件已经进行了正确清理;

五、进一步思考

1. 我们之前说过binlog备份正常的情况下超过50%的阈值时会进行自动清理,上面的截图为什么显示日志磁盘使用率为62%且一直没有降低到50%以内呢?

首先我们需要知道日志磁盘使用率的计算方法:

  • 日志磁盘使用率的计算逻辑为binlog的父目录的空间占用除以创建实例时指定的日志大小的比值,不仅包含binlog的空间大小还包含其它日志文件的大小例如mysqld.err;
  • 下图可以看到bin目录大约占用121.5GB已经控制在实例日志指定大小的50%以内(250GB/2=125GB);同时还有一个大约30GB的mysqld.err文件占用实例日志指定大小的12%(30GB/250GB=0.12);再加上relay的文件内容占用3.5GB(1.4%左右);
  • 总体的日志磁盘使用率计算为:121.5GB/250GB+30GB/250GB+3.5GB/250GB=62% ;

通过以上分析就会发现其实是其它日志也占用了空间导致的日志磁盘使用率超过50%,和binlog的清除逻辑并没有关系;

2. 本文中的mysqlagent日志文件记录的内容很详细,为什么我看到的mysqlagent日志文件只有ERROR的信息呢?

  • 默认情况下mysqlagent的配置文件中log_level值为0即会打印所有的日志信息;
  • 如果无法看到详细日志时可以检查一下mysqlagent的配置文件里的log_level是否被修改为了其它值;
  • 此参数的变更需要重启mysqlagent进程才会生效;
  • 配置文件路径: /data/tdsql_run/4001/mysqlagent/conf/mysqlagent_4001.xml

六. 总结

1. binlog备份是时间点恢复的基本要求,TDSQL会从binlog是否进行备份以及binlog的空间占用等多个维度来进行binlog文件的清理工作(即正确备份并同时超过实例创建时指定日志空间大小的50%;如果此节点同时为多源同步的producter上报节点还会考虑是否已经解析数据到kafka - 此部分内容不在本文展开);

2. TDSQL也考虑了不同角色的binlog清理逻辑,例如主库如何进行清理,从库如何进行清理等。以上只对逻辑主的binlog清理方法进行了说明,主库的binlog以及非逻辑主从库的binlog清理希望大家可以通过日志自行分析;

3. 赤兔界面上显示的日志磁盘使用率计算方法并不只是binlog的大小除以实例创建时指定日志空间的大小,还包括了mysqld.err日志大小和relay log等日志的大小甚至非日志文件只要存放在对应端口的dblogs目录下都会计算进去。这样的计算方法才能更真实的反映整体日志目录所占用的空间大小。

本文标签: 腾讯算法备份数据库TDSQL