写点什么

血泪教训 TiKV 多副本丢失 unsafe-recover 恢复记录

  • 2022 年 7 月 11 日
  • 本文字数:2164 字

    阅读完需:约 7 分钟

作者: realcp1018 原文来源:https://tidb.net/blog/9163546d


【是否原创】是


【首发渠道】TiDB 社区


一、问题背景


某集群替换 5 台机器中的 3 台后,由于 store 空间使用率已超过阈值,旧节点上的 region 和 leader 有一部分 (约 2000*9 个左右) 未能完全迁移到其他节点 (通过 grafana 可观察到),导致旧节点的 tikv 一直处于 pending offline 状态。为尽快清理旧机器,某天早上失智直接 force scale-in 强制缩容了所有 3 台旧机器上的 tikv 实例。


强制缩容一段时间后,业务报某些查询出现“Region is unavailable ”9005 编号的报错。查看 tidb 日志找到一个具体的问题 region,发现其 leader 处于被强制缩容的 store 上,并且 3 副本中 2 副本已丢失,导致 leader 无法选举。


推测集群中目前存在一些 2 副本丢失或 3 副本全部丢失的 region,需要执行多副本丢失恢复流程。


二、恢复准备


查看官方提供的《多副本丢失处理方案.pdf》文档,需要先找出 3 副本丢失的全部 region ID(因为重建 region 时会用到)。直接使用文档中提供的下述 pdctl –jq 语句发现查询多副本丢失的 region 会返回为空,因此需要使用其他方式统计出 3 副本丢失的 region ID 列表。


pd-ctl -u http://{pd_ip}:2379 region --jq=".regions[] | {id: .id, peer_stores:[.peers[].store_id] | select(length < 2)}"


2.1. 通过 pdctl 获取到所有旧机器上的 store ID 列表。


pdctl -u {pd_ip}:2379 store --jq=".stores[]|{id: .store.id, address: .store.address, status: .store.state_name, region: .status.region_count, leader: .status.leader_count}" | grep Offline // 找出位于旧机器上的所有store_id,jq功能需要yum -y install jq开启


2.2. 通过查询 /pd/api/v1/regions 接口,过滤出所有 3 peer 全部位于上述 store ID 列表中的 region,此类 region3 副本已丢失。


下述为查询的简易脚本,替换其中的解释性代码为实际值:


findEmptyRehion.py (999 字节)


2.3. 将 2 中的 region 列表存于 emptyRegions.txt 文件中 (见上述代码)


三、恢复流程


按文档流程执行如下:


3.1. 关闭 pd 调度


// 记录当前调度参数,pd-ctl 中执⾏ config show // 关闭调度 scheduler pause balance-leader-scheduler scheduler pause balance-region-scheduler scheduler pause balance-hot-region-scheduler config set replica-schedule-limit 0 // 查看调度是否完成 operator show


使用下述命令关闭 pd 调度更为稳妥 (记下原值方便之后恢复):


config set leader-schedule-limit 0 //4 config set region-schedule-limit 0 //4 config set replica-schedule-limit 0 //8 config set merge-schedule-limit 0 //8 config set hot-region-schedule-limit 0 //4


3.2. 拷贝与集群版本相同的 tikv-ctl 到所有正常 tikv 节点


scp .tiup/components/ctl/v4.0.8/tikv-ctl <新机器>:/home/tidb/


3.3. 停止所有 tikv 节点


tiup cluster stop {cluster-name} -R tikv


3.4. 在所有正常的 tikv 节点执行下述 remove-fail-stores 指令


./tikv-ctl --db /path/to/tikv-data/db unsafe-recover remove-fail-stores -s <2.1步骤中得到的store-id列表,逗号分割> --all-regions // 单机多store时针对每个store执行一次 // 实测速度较快,单store 1TB左右的目录可以在2s内返回


3.5 恢复空洞 region(3 副本丢失的 region)


任意找一个正常的 store:


for region_id incat emptyRegions.txtdo ./tikv-ctl --db /path/to/tikv-data/db recreate-region -p {pd_ip}:2379 -r $region_id done // 谨慎起见先echo下生成的命令语句 // 实测恢复速度约为1.5s一个新region,可据此估算全部耗时


3.6 启动 tikv 并恢复 scheduler


tiup cluster start {cluster-name} -R tikv


scheduler resume balance-leader-scheduler scheduler resume balance-region-scheduler scheduler resume balance-hot-region-scheduler config set replica-schedule-limit 2048 // 通过修改limit禁用pd调度的改回原值即可


四、后期检查


// 若存在数据索引不⼀致情况,重建索引,下述admin指令返回错误时即需要重建 // 重建时先创建替代索引,之后重建旧索引,最后删除替代索引 // RawKV 集群不需要执⾏该步骤 ADMIN CHECK TABLE tbl_name [, tbl_name] ...;


五、事故回放


默认 tidb 为 3 副本架构,实际部署中基本不会修改,因此当一次性替换或下架超过 2 台机器时,需要考虑多数副本丢失的问题。


一般来说替换过后需要等待新实例状态变为 tombstone 才可以缩容,但本例中由于磁盘使用率高导致旧机器中剩余一些 region 未能迁移到新节点,实例状态保持为 pending offline。此时应当考虑放大磁盘空间阈值或扩容来确保剩余的 region 被调度走。


本次事故中出现多副本丢失的 region 个数有 7005 个,其中 5715 个为 2 副本丢失,1290 个为 3 副本丢失,这 1290 个 region 的数据已经永久丢失只能通过其他方式补回。


本次事务中多副本丢失的 region 可以通过查询 information_schema.TIKV_REGION_STATUS 来获取其所属的表,幸运的是这个系统表所属的 region 未出问题,据此查到本次多副本丢失的 region 涉及 3 个业务表,可以缩小故障范围方便之后的校验和数据补全,还可以查看 region 存放数据还是索引以便评估损失的数据记录数。


最后,感谢 @这道题我不会 以及他的 5 个小伙伴的鼎力支持。😭


发布于: 刚刚阅读数: 3
用户头像

TiDB 社区官网:https://tidb.net/ 2021.12.15 加入

TiDB 社区干货传送门是由 TiDB 社区中布道师组委会自发组织的 TiDB 社区优质内容对外宣布的栏目,旨在加深 TiDBer 之间的交流和学习。一起构建有爱、互助、共创共建的 TiDB 社区 https://tidb.net/

评论

发布
暂无评论
血泪教训 TiKV多副本丢失unsafe-recover恢复记录_故障排查/诊断_TiDB 社区干货传送门_InfoQ写作社区