在查看 tikv 分裂代码发现在 raft apply res 中会对 rocksdb 打快照并 reopen,随后更新 region epoch。但是看 分布式事务的 prewrite 和 commit 在 apply 时会对 epoch check,那么在分裂后,路由没有更新的事务实际都会最终提交失败,但是论坛群说分裂无感。
搜了一些资料并没有看到分裂杀事务相关议题,但是有看到 tidb 层面的重试。
所以实际是 tidb 层面的事务重试 cover 了分裂杀事务这个问题,tikv 层实际是没法做到的吗?希望有大佬解答~
1 个赞
- 依赖 TiDB 层重试机制 TiDB 会自动重试因 Region 分裂、epoch 不匹配等原因失败的事务,这是官方推荐的解决方案。你无需在 TiKV 层做额外处理。
- 优化分裂时机与事务冲突
- 业务侧可通过热点分散(如合理设计主键、使用
SHARD_ROW_ID_BITS)减少大 Region 频繁分裂的概率。 - 对延迟敏感的事务,可在业务代码中增加重试逻辑,主动处理
EpochNotMatch错误。 - TiKV 配置调优 调整
region-split-check-diff等参数,减少不必要的 Region 分裂,降低事务冲突的频率。
2 个赞
TiKV 层确实无法做到 “分裂无感” ——Region 分裂的核心是修改 epoch,而 epoch 是 TiKV 层保障数据一致性的 “核心锁”,任何跨分裂的事务在 TiKV 层都会因 epoch 不匹配被拒绝;而 “分裂无感” 是TiDB 层通过重试机制对外暴露的最终效果,并非 TiKV 原生支持。
- TiKV 层:Region 分裂时因 epoch 检查,会拒绝过期路由的事务请求(表现为 “杀事务”),这是保障数据一致性的必然设计,无法做到 “分裂无感”;
- TiDB 层:通过 “重新获取路由 + 重试事务” 的机制,将 TiKV 层的错误屏蔽,对外呈现 “分裂无感” 的效果;
- 分层职责:TiKV 负责存储层一致性,TiDB 负责分布式事务容错,“分裂无感” 是分层设计的结果,而非 TiKV 原生能力。
2 个赞
- 观察日志 :在TiDB日志中搜索
EpochNotMatch、StaleCommand等关键词,可以确认事务是否因Region变动(分裂/合并/迁移)而重试。 - 关注监控 :在Grafana的 TiDB → KV Errors 面板,关注
KV Backoff OPS和KV Retry Duration监控项。突增可能表示Region变动频繁或热点严重。 - 调整配置 :如果业务对延迟敏感,且监控显示重试较多,可以考虑:
- 优化SQL和索引 ,减少大事务和全表扫描,从源头降低单个Region的数据增长和分裂频率。
- 在TiDB配置中适当调整
tidb_retry-limit(乐观事务重试次数),但需注意悲观事务模式下此参数无效。
- TiKV 层: 实际上是“有感”的,它会拒绝过期的请求(杀事务)。
- TiDB 层: 捕获错误,更新路由,重试事务,从而对外表现出“无感”
1 个赞