TiDB binlog故障处理之drainer周期性罢工
背景
前段时间用户反馈某生产环境 TiDB 集群 drainer 频繁发生故障,要么服务崩溃无法启动,要么数据跑着跑着就丢失了,很是折磨人。该集群跑的是离线分析业务,数据量20T ,v4版本,有多个 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: 1 gib
发现日志和配置参数可以对应上,确实是磁盘不够了。反手就是一个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 对丢数据不敏感,可以接受随时从当前时间重新同步,省了好多事,要不然得崩溃。
吐槽时间
不得不说要重启 TiDB server 才能恢复 binlog 真的太难受了,生产环境不是想重启就能重启的,好在后面发现了还有个 API 能恢复 binlog,下次碰到了试一下。
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 的影响,它不会管 drainer 有没有正常消费,gc 设置上也要给 drainer 故障处理留出一些时间。
最后,没事多研究下监控指标,在排查问题时能少走很多弯路。
不好意思,标题让 drainer 背锅了。
作者介绍:hey-hoho,来自神州数码钛合金战队,是一支致力于为企业提供分布式数据库TiDB整体解决方案的专业技术团队。团队成员拥有丰富的数据库从业背景,全部拥有TiDB高级资格证书,并活跃于TiDB开源社区,是官方认证合作伙伴。目前已为10+客户提供了专业的TiDB交付服务,涵盖金融、证券、物流、电力、政府、零售等重点行业。
TiDB binlog故障处理之drainer周期性罢工的更多相关文章
- TiDB 在摩拜单车的深度实践及应用
一.业务场景 摩拜单车 2017 年开始将 TiDB 尝试应用到实际业务当中,根据业务的不断发展,TiDB 版本快速迭代,我们将 TiDB 在摩拜单车的使用场景逐渐分为了三个等级: P0 级核心业务: ...
- TiDB上百T数据拆分实践
背景 提高TiDB可用性,需要把多点已有上百T TiDB集群拆分出2套 挑战 1.现有需要拆分的12套TiDB集群的版本多(4.0.9.5.1.1.5.1.2都有),每个版本拆分方法存在不一样 2.其 ...
- TIDB学习资料
TiDB 源码阅读系列文章(一)序 TiDB 源码阅读系列文章(二)初识 TiDB 源码 TiDB 源码阅读系列文章(三)SQL 的一生 TiDB 源码阅读系列文章(四)Insert 语句概览 TiD ...
- Pulsar 联合 TiDB 推出大数据场景数据应用分析解决方案
方案概述 大数据时代,各类应用对消息解决方案的要求不仅仅是数据的流动,而是要在持续增长的服务和应用中传输海量数据,进行智能的处理和分析,帮助业务做出更加精准的决策. Pulsar 与 TiDB 联合解 ...
- xtra+binlog增量备份脚本
目录 一.备份原理 innobackupex原理 binlog原理 特点 备份策略 二.环境准备 开启binlog 创建授权用户 安装innobackupex 三.添加脚本 全量备份 增量备份 bin ...
- TiDB在科捷物流神州金库核心系统的应用与实践
导读:在经过了近半年的测试验证和迁移准备之后,神州金库3.0核心系统 WMS 正式从 MySQL 迁移到了分布式 HTAP 数据库 TiDB,上线后不久即经历了第一次双11的考验,TiDB的性能和稳定 ...
- 高可用 | Xenon:后 MHA 时代的选择
原创:知数堂 | MySQL 高可用的选择 在 MySQL(5.5 及以下)传统复制的时代,MHA(Master High Availability)在 MySQL 高可用应用中非常成熟.在 MySQ ...
- MySQL备份管理
MySQL备份管理 目录 MySQL备份管理 一.MySQL备份管理 1.1.1 MySQL备份管理介绍 1.1.2 基于mysqldump的备份恢复 1.1.3 基于xtrabackup软件的物理备 ...
- Centos7配置TiDB集群
一:各模块属性 模块名称 状态 建议实例数 功能 负载均衡组件 TiDB 无状态 2 接收SQL请求,处理SQL相关逻辑,并通过PB找到存储数据的TiKV地址 LVS.HAProxy.F5 PB 集群 ...
- TiDB 深度实践之旅--真实“踩坑”经历
美团点评 TiDB 深度实践之旅(9000 字长文 / 真实“踩坑”经历) 4 PingCAP · 154 天前 · 3956 次点击 这是一个创建于 154 天前的主题,其中的信息可能已经有所发 ...
随机推荐
- 2021-7-11 Vue的自定义指令简单实例
获取焦点简单实例,用Vue.directive(ps:指令)定义,命名不要是关键字,用v-加自定义指令名称调用,而内部用钩子函数inserted来实现 <!DOCTYPE html> &l ...
- markdown之mermaid
官方文档 01 简单的流程图 TD或TB:top to bottom,从上到下的流程图 LR:从左到右 其它:RL,BT flowchart LR; A([节点A的圆矩框]) --> |AB之间 ...
- Linux 内核设备驱动程序的IO寄存器访问 (上)
Linux 内核提供了一套可缓存的设备 IO 寄存器访问机制,即 regmap.regmap 机制支持以统一的接口,访问多种不同类型的设备 IO 寄存器,如内存映射的设备 IO 寄存器,和需要通过 I ...
- C++笔记(自用)
<Effective C++> 条款11 在operator=中处理"自我赋值" 自我赋值 证同测试: if(this==&rhs)return*this; 影 ...
- CCF 202012-5星际旅行(20~100分)
前置知识 线段树:通过懒惰标记,可实现区间处理,和区间询问皆为\(O(logn)\)时间复杂度的数据结构,是一种二叉树.因此对于一个节点\(st\),其左儿子节点为\(st*2\),右节点为\(st* ...
- CodeForces 1311E Construct the Binary Tree
题意 给定\(n\)和\(d\),构造一颗\(n\)个节点的二叉树(以\(1\)为根),所有节点到\(1\)的距离和为\(d\),不行输出\(NO\),否则输出\(YES\)和\(2\)-\(n\)的 ...
- 接口未配置在app.json文件中
微信小程序发布 提示 接口未配置在app.json文件中 狗血 昨天更新 就在app.json中添加 解决问题 "requiredPrivateInfos":[ "ge ...
- 《Python魔法大冒险》005 魔法挑战:自我介绍机器人
魔法师和小鱼坐在图书馆的一扇窗户旁,窗外的星空闪烁着神秘的光芒.魔法师轻轻地拍了拍小鱼的肩膀. 魔法师: 小鱼,你已经学会了编写简单的魔法程序,现在我要教你如何创造一个有自己思想的机器人,让它能够和我 ...
- centos7离线安装docker和docker-compose
1.找一台可联网的centos7主机 在这台可以联网的机器上把离线包都下载好. 2.下载docker rpm安装包和相关依赖 ## 安装yum-utils包,添加docker yum源 sudo yu ...
- nginx ServerName匹配规则
1.同一个主机配置不同端口,访问不同资源 worker_processes 1; events { worker_connections 1024; } http { include mime.typ ...