TiDB HTAP 上手指南丨添加 TiFlash 副本的工作原理
TiFlash 是 TiDB HTAP 形态的关键组件,它是 TiKV 的列存扩展,在提供了良好的隔离性的同时,也兼顾了强一致性。列存副本通过 Raft Learner 协议异步复制,但是在读取的时候通过 Raft 校对索引配合 MVCC 的方式获得 Snapshot Isolation 的一致性隔离级别。这个架构很好地解决了 HTAP 场景的隔离性以及列存同步的问题。
使用 TiFlash 前,需要给表添加 TiFlash 副本。不少用户反馈添加 TiFlash 副本的时候出现问题。TiFlash 副本始终处于不可用状态官方文档总结了一些简单的问题排查。
【TiDB HTAP 上手指南丨添加 TiFlash 副本的工作原理】这篇文章将介绍目前版本(目前所有 release 的 4.x, 5.x 版本)下给 TiDB 中的表添加 TiFlash 副本的工作原理,主要供 DBA 同学们排查相关的问题时,可以从中参考先从哪些方面收集信息及尝试解决。
基本概念
在 PD 的视角里,TiFlash 实例与 TiKV 实例类似,都是一个 store,只是 TiFlash 的 store 会带有 “key=engine, value=https://www.it610.com/article/TiFlash” 的一个 label。添加 TiFlash 副本后,PD 把 region 调度到 TiFlash,并让其中的 region 一直只以 learner 的形式存在,依赖的是 Placement Rules 功能。
TiFlash 实例中包含有一个修改版本的 TiKV 代码,主要负责与 TiKV 协同处理 Raft 层的操作,其输出日志与 TiKV 基本一致。TiUP 部署时,其日志会输出到 tiflash_tikv.log。
TiFlash 实例会定期启动一个子进程来处理与 TiFlash 副本添加、删除相关的操作。如果在进程列表中偶尔看到一个名为 tiflash_cluster_manager 的不常驻进程(在官网中称为 “pd buddy”),属于正常情况。其日志会输出到 tiflash_cluster_manager.log。
文章图片
TiFlash 内部组件架构图
添加 TiFlash 副本各阶段集群中组件的工作
文章图片
添加 TiFlash 副本的时序图
执行副本数修改 DDL
在 TiDB 中执行 alter tableset tiflash replica
时,这条语句作为 DDL 语句执行。
从 progress 0.0 到 1.0 的同步过程中
TiDB 提供 http 接口,其他组件可以通过此接口查询哪些表存在 TiFlash 副本:curl http://:/tiflash/replica
。
TiFlash 有定期任务,负责:
- 从 TiDB 的 tiflash/replica 接口拉取哪些表/分区有 TiFlash 副本。对于未 available 的表,如果表在 PD 上没有相应的 Placement Rules,该任务会负责设立相应的 rule,key range 为 [ t__r, t__ )。
- 对于未 available 的表,该任务会从 PD 拉取 key range 对应的 region_id,以及在线的所有 TiFlash store 中有多少已经同步的 region_id。
- 以 TiFlash store 中去重后的 region_id 个数 PD 中 region_id 个数,通过给 tiflash/replica 接口发 POST 请求的方式更新同步进度 progress。
- 如果 PD 中存在 placement-rules 但 tiflash/replica 中不存在相应的 table_id,说明该表/分区已经被 DROP 而且已经过了 GC 时间,会到 PD 中移除相应的 rule。
PD 的行为:接收到 placement-rules 后,PD 会:
- 先对 Region 进行切分,确保 Region 的边界不会跨越 表数据 及 索引(因为 TiFlash 只同步表数据部分)
- 对 Region 的 Leader 下发 AddLearner 到 TiFlash store 的调度
- TiKV 中 Region 的 Leader 接受并执行 PD 的 AddLearner 命令
- Region Leader 以 Snapshot 形式把 Region 数据发送到 TiFlash 的 Region peer
TiDB 对已经有 TiFlash 副本的分区表进行 Add partition 时,会在生成 partition 后(但对用户不可见)block 并等待。直到 TiFlash 上报该 partition 对应的 partition_id 已经 available 后,DDL 才执行完成。(详细内容可参考 TiDB 相关 PR)
对于 TiFlash 而言,给分区表添加一个 partition 与添加一个普通表是类似的操作,可以参考上文的流程。不同的是在此情况下,会额外在 PD 添加 accelerate-schedule 的操作,提升分区表 key range 相关 Region 的调度优先级,以期望在集群繁忙的情况下,缩短分区表的 available 速度,减少 DDL block 的时间。
为什么需要 block 分区表的 Add partition 操作:
- 假如不 block Add partition 的 DDL 操作,在用户执行查询语句时(比如 count(*) ),如果查询选择了从 TiFlash 读,但是新 partition 上的 region 还没有建立起 TiFlash 副本,此时会导致用户的查询因为少数的 region 而失败。表现出来为用户在执行 Add partition 时,查询该表不稳定,容易失败。
- 为了避免造成查询的不稳定,block 分区表的 Add partition 操作,待新建分区的 Region 建立完 TiFlash 副本 ready 后才允许读到该分区。
alter tableset tiflash replica
时卡住通常来说,这句 DDL 操作仅修改 TiDB 中的元信息,执行时不会阻塞太久。如果出现执行此语句卡住的问题,可以看是否有其他 DDL 操作 block 了该语句的执行(比如在同一个表上是否存在 add index 操作)。更多地可以参考其他 TiDB 中 DDL 卡住的经验 [FAQ] DDL 卡住排查经验 - TiDB 常见 FAQ。
副本数修改成功,但是 progress 一直为零,或者 progress 有进展,但是很 “慢”
- 先根据 TiFlash 副本始终处于不可用状态确认下基本的问题
- 上述排查无误的情况下,先检查 tiflash_cluster_manager.log 的日志。看是否与 TiDB 或 PD 连接出现异常,如果有异常,先确认是相关组件的 API 查询超时(curl http://:10080/tiflash/replica,见TiDB 与 TiFlash 同步接口)还是网络连通性有问题。
- 再确认出现问题的表是否有创建 placement-rule (tiflash_cluster_manager.log 日志中关键字 “Set placement rule … table--r”),上报给 TiDB 的进度信息(id, region_count, flash_region_count)。确认 PD 上是否能够查询到相应表的 rule (参考Placement Rules 使用文档 )。
- 确认同步进度 “慢” 的具体表现。出问题的表,其 flash_region_count 是否很长时间”没有变化”,还是只是 “变化得慢” (比如几分钟还是会涨几个 region)。
- 如果是 “没有变化”,需要排查整个工作链路上什么环节出现问题。
可以检查 tikv、tiflash-proxy 日志中的 warn/error 信息,确认是否存在网络隔离之类的错误。
- 如果是 “变化得慢”,可以排查 TiFlash 当前的负载、PD 的调度。
PD 相关的调度参数调整见:PD 调度参数。
对已经有 TiFlash 副本的分区表进行 Add partition 过程中卡住
根据 PR 中的 comment,如果是因为 TiFlash 没有建立起副本而 block 住,会打印 “[ddl] partition replica check failed” 的日志。接下来的排查方向,大概是当时的是否有较多 Region 在建立 TiFlash 副本、TiFlash apply snapshot 的压力、PD 调度优先级是否有生效等。
附录: 一些过程中辅助排查的 API:
TiDB 中查询 TiFlash 副本、进度等
select * from information_schema.tiflash_replica
查看最近 执行 pending 的 DDL 任务
admin show ddl jobs
TiDB 中获取 TiFlash 副本消息的 API 接口(与 TiFlash 交互的主要接口)
curl http://:/tiflash/replica
TiDB 中查询表的 Region 信息
SHOW TABLEREGIONS;
查询单个 TiFlash 节点上 table_id 对应的 Region 信息
echo "DBGInvoke dump_all_region(,true)" | curl "http://:/?query=" --data-binary @-
PD 中查询 Region 的信息
tiup ctl pd -u http://:region
PD 中查询 Placement-rules 信息
tiup ctl pd -u http://:config placement-rules show
推荐阅读
- docker资源小结
- TiDB Cloud 上线亚马逊云科技 Marketplace,为全球用户提供云端一栈式实时 HTAP 数据库体验
- 极简实现 TiDB 冷热数据分层存储 | He3 团队访谈
- 关于TDB数据脱敏的一些想法
- 2022年1月国产数据库排行榜(TiDB霸榜两年势头不减,openGauss与OceanBase分数大涨)
- “爆到天际线” - TiDB 2021 Hackathon 决赛不负责任点评
- 有关 TiDB 升级的二三事——教你如何快乐升级
- 美团李凯揭秘数据库发展三大趋势 | TiDB Hackathon 评委访谈
- 新一代状态管理工具,Pinia.js 上手指南
- Matplotlib进行数据可视化的快速上手指南