# Index, or not index? That is not a question ## 背景 在真实的业务场景中,数据库索引的选择往往是困扰很多开发/DBA的难题之一。索引可以用于辅助查询,同时更多的索引也有助于面对未来可能的需求变更,很多数据库事故都是由于一些非热点SQL突然流量增加却缺失关键索引引起的。但构建过多的索引会给在线业务带来更大的写延迟,其中的 trade off 比较难把控。 学术界也提出过一些 idea 来解决这个问题,如 self-driven database 的一大优化场景就是预测未来的 workload 以自动构建 index。但这种实现一旦预测错误,对业务是雪崩式的影响,落地非常困难。 ## 方案 我们想引进一种新的索引机制,这里简称 Async Index,它并不直接在在线业务的时候写入,而是基于 TiCDC 异步地同步到 TiKV。而在读取时根据 Index 的 watermark 和事务的 start_ts 比较,决定是否需要等待。 Sync Index 和 Async Index 可以根据 workload 动态转换,分别应对 read heavy 和 write heavy 的业务场景。如果一个字段有潜在的索引需求,可以先把索引建上,我们的 detector 发现索引使用频率很低以后,就会将其转为 Async Index,从而减少在线写入的事务的影响。反之,如果 Async Index 被一些热点 SQL 命中,我们也可以自动将其转换为 Sync Index,减少读等待。针对一些特殊的读取不频繁的场景(导入数据或者作为备库),所有的索引都是 Async Index,写入只需要1PC写主表就行。 这种方案仅适用于没有 constraint 的 Non unique index,但可以覆盖大部分的场景。 ## 实现细节 在这个过程中,我们需要 hack 三个主要方面: 1. Write Path 上,Async Index 不可见,需要被忽略。 2. 一个独立的 agent,订阅 TiCDC 的数据(需要打开 old-data 开关),并向 TiKV 灌数据。 3. Read Path 上,需要根据 watermark 做等待。 4. Sync/Async Index 的动态转换需要 hack DDL 的状态机。具体来说,Async Index 转化为 Sync Index 的过程等价于一个已经完成了 99% 的 CREATE INDEX,所以找到一个合适的点 hack 进去,让它等到 100% 即可。 ## Future Story * 可以利用 placement rule,将 async index 物理隔离,进一步减少对在线业务的影响。 * TBD
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up