数据库|Binlog故障处理之drainer周期性罢工

news/2024/5/19 14:50:55 标签: 数据库, Tidb, 故障排查, Drainer

目录

一、背景

二、故障现象

三、分析过程

四、解决方案

五、思考

六、总结


一、背景

最近,用户反馈我们的生产环境TiDB集群的drainer频繁发生故障。故障表现为服务崩溃无法启动,或者数据在运行过程中丢失,给我们的业务带来了很大的困扰。这个集群运行的是离线分析业务,数据量达到20T,使用的是v4版本的drainer,并且有多个drainer同步数据到下游,目标端包括kafka、file、tidb等多种形态。

两天前,我们刚刚解决过一次这样的故障,但是现在又出现了同样的问题。因此,我们需要进行一次根本原因排查,以解决这个问题。

二、故障现象

接业务端反馈,某下游kafka几个小时没收到 TiDB 数据了,但是 pump 和 drainer 节点状态都显示正常,同样在几天前也收到类似的反馈,当时是因为 binlog 发生未知异常导致 TiDB server 停止写入,需要通过以下 API 验证 binlog 状态:

curl http://{tidb-server ip}:{status_port}/info/all

该 API 会返回所有 TiDB server 的元信息,其中就包括每个实例 binlog 的写入状态(binlog_status字段),如果 TiDB server设置了ignore-error,那么在 binlog 故障时通常是 skipping,正常情况下是 on。

经确认7个 TiDB server 的 binlog_status 均为 skipping状态,和此前是一样的问题。

处理方法比较简单,重启 TiDB server 即可,但是避免后续重复出现需要搞清楚原因后再重启。

三、分析过程

数据不同步了相信大家都会第一时间怀疑是 drainer 的问题, 最常见的原因就是大事务导致 drainer 崩溃panic,但是登录到 drainer 所在的机器上分析日志,并没有发现异常现象,日志显示 savepoint 正常写入,checkpoint 正常推进,实例状态up,说明并不是 drainer的问题。

根据 binlog skip 状态,转头去分析 TiDB server监控,在 TiDB->Server->Skip Binlog Count面板可以看到被跳过的 binlog 数量:

从监控看到,在8月18号下午6点左右 Skip Count 突然从高位掉到0,正是因为上一次重启 TiDB server 修复了故障。往后到21号早上左右,Skip Count 又开始出现,那么就要重点分析这个时间点的日志。

进一步分析监控,发现 Skip Count 上升趋势和 Critical Error 相吻合,说明在21号早上07:06左右开始出现大量的 binlog 写入异常,接下来根据这个时间点去排查 pump 的日志。

根据精确的时间点,很快就在 pump 日志中定位到了panic的位置,在panic之后日志发现了一个非常有用的信息:

日志显示,binlog 确实停止写入了,同时指出停止写入的原因是磁盘空间不够,这里有个关键信息StopWriteAtAvailableSpace,也就是说 pump 所在的磁盘可用空间小于这个参数时就会停止写入。我们用edit-config看一下 pump 的配置参数:

pump:
gc: 2
heartbeat-interval: 2
security:
ssl-ca: ""
ssl-cert: ""
ssl-key: ""
storage:
stop-write-at-available-space: 1gib

发现日志和配置参数可以对应上,确实是磁盘不够了。反手就是一个df -h看看什么情况:

意外的是,上图显示 pump 的数据盘只用了1%,还有大把的空间没被使用,貌似和日志报错原因不符。

到这里我忽略了一个重要的时间因素,就是介入排查的时候离 pump 故障已经过去了3天(从前面第一章监控图可以看到),而 pump gc时间设置的是2天,那么意味着在排查的时候 pump 之前记录的binlog 已经被 gc 掉了,至于这些 binlog 有没有被 drainer正常消费还不得而知。好在 Grafana 监控里面有一个面板记录了 pump storage 的变化情况,路径是:Binlog->pump->Storage Size。

从上面这个曲线联想最近两次的故障,貌似问题一下子清楚了:18号下午6点左右重启 TiDB Server 恢复 binlog 写入,pump 可用空间开始变少,到21号早上7点左右几乎被使用完毕,触发StopWriteAtAvailableSpace异常,binlog 停止写入变成 skipping状态,但与此同时 pump gc 还在工作,且没有新的 binlog 进来,两天后存量数据被 gc 完毕在23号早上7点左右恢复到空盘水平,持续到现在。

半途接手的集群,各种背景信息也不是很了解,经常奇奇怪怪问题一查就是查半天,这就是oncall人的日常。。

四、解决方案

通过与用户的沟通,我们了解到无法增加磁盘空间,因此我们面临两条选择:开源或节流。

为了解决这个问题,我们决定采取缩短pump gc时间的措施,将其缩短至1天。然而,缩短gc时间也存在风险,如果drainer故障超过1天,将会丢失数据。

最终,我们在24号下午6点左右同时调整了gc时间和TiDB server重启,这使得binlog同步恢复正常。

经过几天的观察,我们发现pump的磁盘使用率稳定在一半左右,评估不会再出现类似问题,因此我们可以安心休息,不必再担心出现之前的故障。

幸运的是,下游的kafka对丢数据不敏感,可以随时从当前时间重新同步,这为我们节省了很多时间和精力,否则我们可能会面临更大的挑战。

五、思考

必须说,为了恢复binlog不得不重启TiDB server真的让人感到非常不舒服。在生产环境中,重启并不是一件轻易就能执行的操作。幸运的是,后来我发现还有一个API可以用于恢复binlog。下次再遇到类似的问题,我会尝试使用这个API来解决。

curl http://{tidb-server ip}:{status_port}/binlog/recover

文档隐蔽工作做的太好了,这些走后门的方法不知道 TiDB 还隐藏了多少。

再就是在文档上看到的 binlog 主从故障恢复方法,真是瑟瑟发抖,谁用谁996。↓↓↓

根据我的使用经验,设置ignore-error后,发生critical error的可能性非常高。binlog同步似乎非常脆弱,稍有不合适就会停止工作。每次都需要进行全备份、恢复和重启TiDB server,这对于动辄几十T的集群来说绝对是灾难。不仅耗费时间,而且这么大数据量出错的概率也很高,想想都让人感到恐惧。

六、总结

从这个案例中我总结到,在参数设置上要留有一些buffer,给后续出问题时有缓冲时间来处理。比如在本案中可以把stop-write-at-available-space设大一点,在出现磁盘空间不足时可以快速把值调小,这样 binlog 还能恢复继续同步,也能留出时间去做磁盘扩容,或者制定其他方案。

另外,我们需要注意pump gc的影响。pump gc不会考虑drainer是否正常消费。因此,在设置gc时,我们需要为drainer故障处理预留一些时间。

最后,我们应该加强对监控指标的研究,以便在排查问题时能够少走弯路。

作者 :何傲 | 高级后端开发工程师

版权声明:本文由神州数码云基地团队整理撰写,若转载请注明出处。

公众号搜索神州数码云基地,后台回复数据库,加入数据库技术交流群。


http://www.niftyadmin.cn/n/5166310.html

相关文章

Salesforce使用的数据库是什么

Salesforce使用了多种不同的数据库技术来支持其云端CRM(客户关系管理)服务。其中最显著的数据库技术是它自己的多租户数据库系统,称为"Salesforce数据库"或"Force.com数据库"。以下是关于Salesforce数据库的一些关键特点…

【CSDN 每日一练 ★☆☆】【字符串】最后一个单词的长度

【CSDN 每日一练 ★☆☆】【字符串】最后一个单词的长度 字符串 题目 给你一个字符串 s,由若干单词组成,单词之间用空格隔开。返回字符串中最后一个单词的长度。如果不存在最后一个单词,请返回 0 。 单词 是指仅由字母组成、不包含任何空…

使用 docker 不加sudo

sudo usermod -aG docker your_usernameReplace “your_username” with the actual username of the user. 如果添加用户到 “docker” 组不起作用,这可能意味着您的Docker套接字文件(/var/run/docker.sock)的权限设置不正确。您可以尝试手…

浙大计算机学院2024届推免直博生名单

名单: 分析: 浙大计算机学院共录取推免直博生158人,其中计算机科学与技术专业73人,人工智能专业7人,软件工程专业21人,网络空间安全专业19人,电子信息专业31人,设计专业7人 欢迎关…

mongodb数据同步到hive

背景 用户需求: 需要将 mongodb 的数据同步到 hive 表,共 2 亿条数据,总数据量约 30G 查阅一些博客后,大致同步方法有以下几种 手动离线 对于比较小的数据,可以先通过 mongoexport 将数据导出到本地 json 文件,再将…

2722. 根据 ID 合并两个数组

现给定两个数组 arr1 和 arr2 ,返回一个新的数组 joinedArray 。两个输入数组中的每个对象都包含一个 id 字段。joinedArray 是一个通过 id 将 arr1 和 arr2 连接而成的数组。joinedArray 的长度应为唯一值 id 的长度。返回的数组应按 id 升序 排序。 如果一个 id …

GitHub上的开源工业软件

github上看到一个中国人做的流体力学开源介绍,太牛了! https://github.com/clatterrr/FluidSimulationTutorialsUnity 先分析一下工业仿真软件赛道 工业仿真软件的赛道和产品主要功能如下: 1. 工艺仿真赛道: - 工厂布局优化&am…