TiDB 解决各种劫难故障堪称驾轻就熟,然而常言道“人祸易躲,人祸难防”,对于各种误操作、bug 写入谬误数据、甚至删库跑路,目前还没什么招。咱们我的项目最后也是为了解决这些“意料之外”的事变。我的项目最后的名字叫 TiDB Flashback,起初又感觉这个名字过于瘠薄,无奈体现我的项目内容的优越性,起初索性改成了“MVCC 时光机”。
——渡渡鸟振兴会战队
在 TiDB Hackathon 2021 赛事中,渡渡鸟振兴会赛队的作品“MVCC 时光机”充分利用 MVCC 个性,增强 MVCC 数据的查问、整顿、复原的能力,进步问题解决的效率,摘得了赛事的“三等奖”。
一个十分 smart 和轻量级的实现,成果很不错,期待尽快公布上线。
——评委冯光普
这个我的项目是给运维同学在某些时候救命的性能。它通过 SQL 很好地解决了运维的操作问题。更赞的是,该我的项目引入了多 Safepoint 机制,也就是能够给 TiDB 集群定期做一些全局 Snapshot,进行疾速轻量级的逻辑备份。
——评委唐刘
对于我的项目
人祸易躲,人祸难防
作为一款分布式数据库,欠缺的高可用和容灾机制能够说是 TiDB 的外围个性。然而在生产中,实践上的劫难复原和实际上要面对的却可能天壤之别。不可预知的硬件故障、自然灾害导致的断网断电诚然可怕,而把生产环境当成测试环境的误操作、有破绽被黑客攻击、业务出 Bug 写坏数据反而可能是更高频的事变。
队员之一 @disking 已经就任于游戏公司,对这种“人为的失误”感触颇深:业务共事写的代码中出了一个 bug,在版本上线后的几个小时内被居心叵测玩家利用取得了许多不正当的收益,这时候就要进行回档操作,让游戏数据回到某个具体的工夫点,须要实现的就是相似“时光机”的性能。手动回档、数据失落造成的损失都会给团队带来很大的麻烦。
当初物理上的故障解决 TiDB 曾经给出了像 BR 工具、两地多核心计划等解决措施,而一句 rm -rf /*,或者“实习生误操作”导致的谬误数据写入带来的危险却更加不可控,这也是 TiDB 缺失的一大块拼图。
Make MVCC Great Again!
因为 TiDB 的事务是基于 MVCC 的,所以一段时间内的旧版本都在,实践上对于上述人祸,都是能够进行手动复原的。然而现有的性能和打算中的性能绝对较弱:
很可能须要排查数据损坏的状况,目前只能指定 ts 去读一个工夫点的数据,要查看某条记录的变动历史太麻烦
RECOVER TABLE 只能复原 DROP/TRUNCATE 这种 DDL 操作,对 DML 没招
GC Safepoint 之前的数据恢复不了,如果想保留长时间的数据,又太费空间了
复原数据要先把数据 dump 进去再从新写入,太慢了
因而充分利用 MVCC 个性,增强 MVCC 数据的查问、整顿、复原的能力,就能进步问题解决的效率。MVCC 不只是能够用来暂时性地处理事务隔离,也齐全能够做为冷备,相比于内部的备份,其长处是能够更省空间,复原数据也更不便更快。
@disking 其实最早在第二届 Hackathon 时就有了这个想法,灵感来源于 Oracle 的 Flashback 性能。过后他就把这个想法放到了研发的探讨群外面却没有失去回应,而过后的他还没有足够的精力来组建本人的战队。尽管不至于说耿耿于怀,然而这么乏味、有用的想法当然要找个机会实现一下,这次的 Hackathon 就是一个实现想法的好机会。
渡渡鸟振兴会就这样开始组建了。
团队用 20 个渡渡鸟的对话状况来进行 demo
对于较量
如何制作一个时光机?
谁把握了过来,谁就把握了将来;谁把握了当初,谁就把握过来。
——乔治·奥威尔《1984》
总的来说就是围绕 TiDB 的 MVCC 机制做了一些(乍)看起来比拟 fancy 的操作,比方查问表记录的 MVCC 历史、篡改 MVCC 记录以及依据 MVCC 记录做到刹时版本回退(Flashback 操作)等。
整个我的项目比拟外围,或者说比拟实用的点还是 GC SavePoint 和 Flashback 性能的组合拳,通过设置定期的快照备份,利用 TiDB MVCC 的机制做到 TiDB 存储外部的“冷备“,在一些关键时刻还是有救命成果的,毕竟只须要一条 SQL 就能够达成整表数据的 Flashback。
整个我的项目分为了三个绝对独立的模块:
1.MVCC Query in SQL -> 操纵过来
参考 _tidb_rowid 的实现,减少 _tidb_mvcc_ts,_tidb_mvcc_op 虚构列。
当查问虚构列时,TiDB 发送给 TiKV 的申请中要带上标记,指明要查问 MVCC 虚构列。
批改 TiKV 的 MVCC 读取逻辑,当须要查问虚构列时,须要扫描所有版本,而不是只扫描最新版本。而后设置每条数据对应的虚构列值。_tidb_mvcc_ts 为事务的 commit_ts,_tidb_mvcc_op 为事务的操作类型,能够是 PUT 或 DELETE。
上面是一次演示,能够看到咱们能够能用各种姿态来查问 MVCC 记录!
甚至还能够去篡改某一次的 MVCC 记录。
2.GC Savepoint -> 掌控当初
增加 gc_savepoint 零碎表,能够通过 SQL 增删改查来进行治理。
GC 进行时,须要将 gc_savepoint 表的数据,与本来的 gc_safepoint 一起寄存到 PD。
批改 GC 逻辑,回收数据时思考 gc_savepoint。因为 GC 有传统 GC 和 compaction GC 两种,工夫关系能够只做一种。在设置 gc_save_point_interval =‘5m’后,在 gc_safe_point 之前,原本会被回收 MVCC 记录每 5 分钟保留一个版本。
3.Subsecond Flashback -> 着眼将来
增加 flashback table tsSQL 语句,用于指定 table 进行数据还原。意义是将表还原至不超过 ts 工夫戳指定的版本。
将工夫范畴写入 table schema 并触发 DDL 操作,DDL 同步实现即可返回操作胜利。
TiDB 申请 TiKV 时,须要将要疏忽的 ts 区间放在申请中发给 TiKV。
批改 MVCC 读取逻辑,要依据指定的区间跳过对应的版本。
当 ts 区间超出了 GC 范畴后,须要被清理。
联合下面的 MVCC 查问,咱们能够看到当初表数据中的“变动渡渡鸟”记录在某个工夫节点前还是“工夫渡渡鸟”,通过 Flashback 操作,咱们胜利让数据变回了已经的模样,把“工夫渡渡鸟”号召了回来。
在理论的劫难复原场景中,如果咱们一不小心谬误地批改了某个表的几条数据,甚至是误删了整个表,都能够通过 Flashback SQL 来将其一键复原到任意 MVCC 记录版本。
将来瞻望
目前的实现仅基于 TableScan 进行了 Demo,还有一些 IndexScan 和点查问的适配工作没有进行;有些 TiDB 的生态工具是越过 SQL 层进行数据查问的,这方面的兼容性也是接下来须要思考的问题。
除此之外,如果可能扩大 Flashback 操作和 MVCC Query 的组合拳,就可能实现更多的性能,比方查看 Flashback 记录、撤销 Flashback 操作、批改 Flashback 记录等等。
对于队员
怎么来到 TiDB 的世界的?
@JmPotato 刚刚完结了本人的学生生涯,当初是一名 PingCAP 的研发工程师,@RinChanNOW 是他的本科室友,也退出到了本次的我的项目之中。他们的另一位室友也在字节跳动分布式系统研发的部门实习。
——一个宿舍的根底软件工程师!
对于很多学生来说,成为一名利用开发者或者算法工程师或者进入 AI 行业都是更加支流的抉择,为什么这么“巧”,他们不谋而合地退出这个行业?
@JmPotato 示意,是他开了这个“头”。2019 年年底,他在听播客的时候偶尔听到了东旭对于分布式数据库的分享,那个时候也不晓得 PingCAP。起初进行相干的学习,在学习 Raft 的过程中接触到了 TiKV、TiDB 这些我的项目,才缓缓理解到原来它们都是 PingCAP 的产品。那时候 PingCAP 刚好在招聘实习生,本人也感觉心驰神往,做了很多相干的筹备就开始面试、进入公司实习直到现在正式退出。
@RinChanNOW 也示意,是 @JmPotato 的这份实习为整个宿舍都关上了一个全新的世界,还记得过后大家一起实现一个简略的 Raft 协定,从那个时候就能感触到分布式系统的微妙,不是被动的内卷,而是一种发自内心的酷爱和向往。
不懂 TiDB,怎么疾速退出 Hackathon 并且开始工作的?
尽管 @RinChanNOW 之前学习过分布式系统的相干常识,然而自身在学习和工作中都没有理论接触 TiDB 的教训。作为一名内部开发者,如何退出到这场对于 TiDB 的 Hackathon 中?这也是很多同学对于 Hackathon 流动望而生畏的重要起因。@RinChanNOW 就齐全没有这样的放心。一方面 TiDB 的文档丰盛,体系化的学习起来并不费劲;另一方面 TiDB 的社区十分沉闷,无论是 AskTUG 还是 TiDB internals 或者说就是 GitHub 上,都能遇到很多气味相投的搭档,他们也都违心帮忙 new TiDBer 疾速融入社区。
@RinChanNOW 也与大家分享了一些具体的学习教训:
除了 TiDB 与 TiKV 的开发环境筹备之外,须要做的一个筹备工作就是理解 TiDB 和 TiKV 的代码构造与它们的数据流,也就是要去大抵理解它们的源码,而这也是最耗时间的一个过程,所以我的代码量并不大,然而却花了很长时间才写完。我依据须要改变的局部,联合 PingCAP 的官网博客,对源码进行了一波学习:
Select 流程:
TiDB 源码浏览系列文章(三)SQL 的毕生
TiDB 源码浏览系列文章(六)Select 语句概览
如何将查问下推到 TiKV 并执行:
TiKV 源码解析系列文章(十四)Coprocessor 概览
TiKV 源码解析系列文章(十六)TiKV Coprocessor Executor 源码解析
Insert 流程:
TiDB 源码浏览系列文章(四)Insert 语句概览
TiDB 源码浏览系列文章(十六)INSERT 语句详解
一条 SQL 语句的具体执行流程:
TiDB 源码浏览系列文章(二十三)Prepare/Execute 申请解决
TiKV MVCC 读写流程:
TiKV 源码解析系列文章(十三)MVCC 数据读取
玩真的:TiDB Hackathon 有什么不同?
队伍中的 @disking 能够算是 Hackathon 的老玩家了,除了这次的 TiDB Hackathon,@JmPotato 和 @RinChanNOW 也都水平或深或浅地参加到了其余相似的编程比赛中,谈及不同赛事体验的差别,他们有着对立的认识:很多编程比赛更多是面向学生的,留一些有着明确指标甚至是标准答案的作业,更像一场测验编程能力的考试,比拼的可能是谁的实现更优雅,成果更佳。而参加 TiDB Hackathon 就是一种齐全不同的体验。TiDB Hackathon 更偏差实操,没有明确的选题,是一场未知的冒险,比起代码实现更重要的是创造力和思考,只有真正在用、真正参加到产品迭代中的开发者能力感触到其中的乐趣。
然而受到疫情的影响,近两年的 TiDB Hackathon 尽管冷落,但还是少了一点氛围。如果有机会,还是期待明年的 Hackathon 可能和各位选手来到同一空间现场交换,来一场真正的 48 小时密集开发。