{
    "componentChunkName": "component---src-templates-blog-blog-detail-tsx",
    "path": "/blog/improve-tidb-performance-by-adding-index",
    "result": {"pageContext":{"blog":{"id":"Blogs_349","title":"TiDB Hackathon 2021 — 去掉中间商赚差价，TiDB 添加索引性能提升 10 倍！丨黑马警长团队采访 ","tags":["TiDB Hackathon 2021"],"category":{"name":"社区动态"},"summary":"本篇文章将介绍 TiDB Hackathon 2021 黑马警长团队赛前幕后的精彩故事。","body":"在刚刚结束的 TiDB Hackathon 2021 赛事中，首次参赛的“黑马警长”团队， 获得了内核组“三等奖”的成绩。海量数据场景下，TiDB 添加索引速度慢这个问题一直困扰着很多用户，“黑马警长”的参赛项目将添加索引的速度提升了 10 倍以上，是这次内核赛道中绝对的黑马项目。\n\n![三等奖 黑马警长.mp4](https://img1.www.pingcap.com/prod/_e2efceaef5.mp4)\n\n\n<center>黑马警长战队 Demo Show</center>\n\n在本篇文章中，我们将为大家简单介绍这个项目的实现原理和队员们此次比赛的趣闻。欢迎对 TiDB DDL 模块/TiDB-Lightning 有兴趣的同学，联系黑马警长的队员们：\n> 胡海峰(@pingcap.com) github : knull-cn  \n> 李淳竹(@pingcap.com) github : lichunzhu  \n> 曹闯(2546768090@qq.com) github : xcziii\n\n\n我一看到这个项目，就非常的开心，因为这个项目是在我们产品 roadmap 上面的，想不到大家在 TiDB Hackathon 实现了。在 TiDB 里面，add index 是一个比较慢的操作，尤其是在数据量大的情况下面，这个速度极大的影响了用户的体验。我们现在有不少 SaaS 用户，他们的业务变化太快，DDL 是一个非常高频的操作，其中就有不少 add index，所以如果我们 add index 速度越快，就越能提升用户的业务敏捷性，我非常期待这个项目后续的落地。\n\n<p align=\"right\">—— 评委唐刘</p>\n\n## 项目缘起\n\n这个项目的想法源自黑马警长团队成员胡海峰在金融机构的一次 POC 经历。在该 POC 项目中，TiDB  在 online-DDL 添加索引这个环节表现不佳。  \n\n于是，在 POC 结束之后，胡海峰的 Leader 帅鹏找到他，提了这个加速的想法：使用 TiDB-Lightning，一款高速导入数据到 TiDB 集群的工具来添加索引。于是，海峰先找内部 Lightning 研发同事 Gaolei 简单论证了可行性。在聊天过程当中，听说淳竹和龙恒也有类似想法。于是海峰就联系了淳竹，一番探讨之后就和淳竹以及另一位成员曹闯组队报名了。\n\n## 去掉“中间商赚差价”\n\n简单说说这个想法的实现原理。目前 TiDB 添加索引的方式是这样的：TiDB DDL 模块会根据整个表的行数据产生一组索引数据并保存到 TiKV。在线添加 DDL 时，很容易因为表行数据的改变而引发写入冲突。为了避免这个问题，TiDB 会划分数据块，每次取部分数据事务写入 TiKV，TiKV 经过事务层处理后最终保存到 RocksDB。这就导致了添加索引速度很慢的情况。\n\n![01.webp](https://img1.www.pingcap.com/prod/01_a93a53684b.webp)\n\n黑马警长小组的方案是，在准备好多次取表数据本地构造索引数据完成排序后，通过一次性 import 的方式注入到 TiKV 的 RocksDB，使索引数据跳过了事务层，直接走了存储层，**成功避免了事务层耗时，添加索引的时间就大大降低，等于直接把“中间商”去掉**。\n\n![02.webp](https://img1.www.pingcap.com/prod/02_20b353d4ad.webp)\n\n**在整个项目的推进中，黑马警长遇到的最大困难是 “数据正确性” 论证**。作为数据库，数据正确性是最重要的（想象下如果正确性都保证不了，谁敢用你？），之前的添加索引，是通过事务机制来保证索引与数据的一致性。但是，本地编排数据一次性导入到 TiKV 能否保证该一致性呢？  \n\n在仔细查阅源码与资料并请教相关研发后，黑马警长小组最终在理论上证明了该方法的正确性，他们采用两个方式来完成论证：\n\n### 理论论证\n\n在 [TiDB Online DDL 解析](https://pingcap.com/zh/blog/tidb-source-code-reading-17)一文中提到了在线加索引的实现与其中间五个状态，使用 Lightning 添加索引的流程和当前实现基本一致。区别仅在回填数据的处理上，本项目通过以下方式保证一致性：  \n\na. 所有 range 均使用在 write reorg 开始时获取的统一的 tso 读取数据。该阶段往后添加的索引已是写入/删除可见，即 TiDB 插入/删除新的行数据时会一并添加/清理索引数据。  \n\nb. 写入 TiKV 时 Lightning 也将以读取时的统一 tso 写入 KV 数据。当 TiDB 存在增量写入数据可能引发索引改变时，利用 TiKV 的 MVCC 机制可以保证内嵌的 Lightning 可以保证写入的 KV 数据 tso 更小，可以被更新的更新/删除事件覆盖掉。从 TiDB 的视角看，虽然多写入了部分数据，但错写的数据是不可见的，从而保证了索引数据的正确性。\n\n### 测试论证\n\n理论上虽然正确，但需要更多测试保证该论证是正确的。于是，在正确性测试阶段，在不断更新 a 列数据的同时也使用 Hackathon 项目的 TiDB 在线添加索引。添加索引完成后，进行 admin check 确认没有索引不一致问题，进一步证明了理论的正确性。\n\n**项目最终测试结果性能获得了约 10 倍—— 20 倍的提升，而且后续引入并行导入后性能还可以有进一步提升**。  \n\n**最后借这个机会特别感谢以下小伙伴**：  \n\n**胡海峰**：这里特别下我的 Leader @Shuaipeng Yu ，是他提供了 idea，否则就没有这个项目。同时要感谢 @Chunzhu Li 兄，合作愉快！  \n\n**李淳竹**：这里要感谢 @Heng Long 提出了这个 idea，以及要感谢 @Yujie Xia 与 @Lei Gao 对方案正确性和具体实施都给出了非常多的重要意见。没有大家的支持项目落地实施将更加困难。\n当然，同时也要感谢各位产研大佬的无私帮忙，包括：Wenjun Huang\\ Cong Wang\\  Lei Zhao \\ Lei Gao\\ Yujie Xia。\n\n**Q：队名由来有什么故事？**\n\n队名是临时想的，有一次家里小孩在看黑猫警长，我就想着直接叫黑马警长怎么样。黑马也具有突出重围的寓意，最后我们就定下了这个名字。\n\n**Q：是第一次参加 Hackathon 吗？Why Hackathon？**\n\n其实我们去年就想参加，但当时没有特别好的想法，今年有了这个项目的想法后，第一反应就是这个东西似乎有可行性，又不是特别麻烦，觉得可以搞。万一能获奖，还有钱拿。\n所以我觉得反过来说，其实要参加 Hackathon ，一个好的 idea 真的很重要（这里再次感谢下帅鹏与龙恒）\n\n**Q：项目遗憾的地方？**\n\n因为时间关系我们没有在比赛中实现出并行导入，不过我们花了更多时间完善了性能和集群影响的测试 。\n\n**Q：对项目未来有什么展望与期待？**\n\n目前这个项目已经在走合并入 TiDB 仓库的流程，期待以后该方法能成为默认加索引方式，今后广大 DBA 都能飞速地添加索引。\n\n> 延展阅读：点击查看更多 [TiDB Hackathon 2021 优秀项目分享](https://pingcap.com/zh/blog/?tag=TiDB%20Hackathon%202021)","date":"2022-02-17","author":"PingCAP","fillInMethod":"writeDirectly","customUrl":"improve-tidb-performance-by-adding-index","file":null,"relatedBlogs":[]}}},
    "staticQueryHashes": ["1327623483","1820662718","3081853212","3430003955","3649515864","4265596160","63159454"]}