292024.03

包拯断案 | 集群备份为什么多次失败@还故障一个真相

2024.03.29

问:作为DBA运维的你是否遇到过这些烦恼



1)数据库集群在夜间全量备份时,会出现多次报错?
2)而且一般在备份的准备阶段就退出了,根本没法完成数据备份工作?


心中有章,遇事不慌
作为DBA的你,遇到问题无从下手,除了在问题面前徘徊,还能如何选择?如果你一次或多次遇到该问题还是无法解决,又很懊恼,该如何排忧呢?关注公众号,关注《包拯断案》专栏,让小编为你排忧解难~




#包拯秘籍#

秘籍不能少,一整套故障排错及应对策略送给你,让你像包拯一样断案如神:
#首先
遇到此类问题后,我们要做到心中有章(章程),遇事不慌。一定要冷静,仔细了解故障现象(与研发/用户仔细沟通其反馈的问题,了解故障现象、操作流程、数据库架构等信息)

#其次
我们要根据故障现象进行初步分析。心中要想:是什么情况导致夜间数据库集群全量备份多次报错?例如:是配置参数还是功能组件的问题?

#然后
针对上述思考,我们需要逐步验证并排除,确定问题排查方向。

#接着
确定了问题方向,进行具体分析。通过现象得出部分结论,通过部分结论继续排查并论证。


#最后
针对问题有了具体分析后,再进行线下复现,最终梳理故障报告。


真刀实战,我们能赢


说了这么多理论,想必实战更让你心动。那我们就拿一个真实项目案例进行分析---某国有大型银行项目现场,运维人员在夜间进行数据库集群全量备份时,多次遭遇备份报错,该如何快速分析处理:

1、故障发生场景
夜间在项目现场兢兢业业进行项目运维的你,正在为某个数据库集群进行全量数据备份,却在备份的准备阶段,系统就退出了,根本没法完成备份工作。经过多次备份尝试仍然行不通,对现场情况和原因不太清楚。

1.png



2、故障排查

通过管控报错定位到备份任务日志,看到备份失败的原因均是因为undo log 清理导致undo log 的space_id变化,从而导致xtrabackup备份失败。


2.png


查看备份节点数据目录,发现在其目录下均存在undo_1_trunc.log文件。两个集群从库情况基本一致,也都存在undo_1_trunc.log文件。




3.jpg4.jpg


undo_1_trunc.log文件是undo表空间truncate 时创建、用于记录truncate操作的临时日志文件,truncate操作完成后自动删除,但undo_1_trunc.log文件一直存在,说明truncate操作一直在进行中,且文件日期比较早,说明truncate操作夯住的时间比较长。


查阅官方bug信息https://bugs.mysql.com/bug.php?id=104573 ,发现有类似的从库undo表空间长时间处于清理状态,该问题是由参数 super_read_only =ON 触发的。


3、故障处理

为了减少触发bug引起的备份失败,需要调整两个参数:innodb_max_undo_log_sizeinnodb_purge_rseg_truncate_frequency。


innodb_max_undo_log_size

01这个参数主要用于定义undo表空间的阈值大小。如果undo表空间超过此阈值,则在innodb_undo_log_truncate=ON时,将其标记为truncation。标记为truncation的undo表空间将被置为inactive,不会被新的事务所使用,现有事务允许完成。purge线程清空、释放那些不再需要的回滚段,当undo表空间的所有回滚段释放后,undo表空间会执行一个truncate 操作,undo表空间截断为初始化大小值(16MB)。truncate完成后,undo表空间重新激活,可以分配新的事物。

采取措施:将innodb_max_undo_log_size由2147483648(2G)调整为4294967296(4G),减少标记为truncation的可能性。


innodb_purge_rseg_truncate_frequency

02这个参数是根据调用purge的次数,定义释放回退段的频率。在回滚段被释放之前,undo表空间不能被truncate。通常情况下,清除系统每调用(默认)128次purge,就释放一次回滚段。加大该值会减低purge线程释放回滚段的频率。

采取措施:将innodb_purge_rseg_truncate_frequency由16调整为128(默认值),降低释放回滚段的频率,从而降低truncate的频率。




本期复盘总结


1、在InnoDB 存储引擎中,undo 在完成事务回滚和 MVCC 之后,就可以 purge 掉了,purge后文件大小虽然不会变,但可以被重新分配使用。

2、在 innodb_max_undo_log_size 设置较大情况下,在undo log 大小达到阈值前被 purge 掉,这样空间就能重用,很难达到阈值,就不会触发 undo log truncate,也就不会触发数据备份失败这个 bug了 。