Raw kv 基本无技术支持
以下是 AI 分析:
社区问题分析
问题链接: TiDB 社区论坛 - 无 SQL 请求,API v1 + txn KV 是否需要部署 TiDB 进行 GC
提问者环境: TiDB v8.5.6,只使用 TiKV Go Client 的 Txn 请求,TiKV 配置为 API v1,无 SQL 请求。
问题 1:API v1 的 txn KV 是否必须采用 MVCC 存储?
是的,必须采用 MVCC 存储。
API v1 和 API v2 在 txn 模式下都使用 MVCC 实现,这是 TiKV 事务机制的基础。两者的区别在于 raw 模式:
| 特性 |
API v1 |
API v2 |
| Txn KV |
MVCC(多版本) |
MVCC(多版本) |
| Raw KV |
无 MVCC(单版本) |
有 MVCC(RawMvccSnapshot) |
| Key 编码 |
直接存储,无前缀 |
带 key prefix(r=raw, x=txn) |
| TTL 支持 |
独立 API(V1Ttl) |
内置支持 |
源码证据(components/api_version/src/api_v1.rs):API v1 的 raw 模式直接存储用户 key,无版本信息;txn 模式则使用与 TiDB 事务相同的 MVCC 引擎。
问题 2:API v1 + txn KV 是否必须部署 TiDB 来推进 GC?
理论上需要,但不一定必须部署 TiDB。 下面详细解释:
GC 的运作机制
- GC safe point 由 TiDB 计算:TiDB 的 GC leader 根据
tidb_gc_life_time(默认 10m)计算出一个安全时间戳
- GC safe point 存储在 PD:TiDB 将 safe point 写入 PD,TiKV 通过 PD client 从 PD 获取
源码证据(src/server/gc_worker/gc_worker.rs:75-83):
pub trait GcSafePointProvider: Send + 'static {
fn get_safe_point(&self) -> Result<TimeStamp>;
}
impl<T: PdClient + 'static> GcSafePointProvider for Arc<T> {
fn get_safe_point(&self) -> Result<TimeStamp> {
block_on(self.get_gc_safe_point()) // 从 PD 获取
}
}
TiKV 的 GcManager 每 10 秒轮询 PD 获取 safe point(gc_manager.rs:25)。
不部署 TiDB 的后果
如果没有 TiDB(或其他组件)推进 GC safe point,MVCC 的历史版本会无限堆积,导致:
- 存储空间持续膨胀 — 每次 update/delete 都会留下旧版本
- 读取性能下降 — 多版本扫描开销增大
- 最终可能导致磁盘满
替代方案
- 可以通过 pd-ctl 或 PD HTTP API 手动设置 GC safe point,但需要自行编写调度逻辑
- 目前官方文档对此场景的描述不够清晰,这是一个文档改进点
结论:API v1 + txn KV 的 MVCC 数据确实需要 GC,但推进 safe point 的组件不一定是 TiDB,TiDB 只是默认的实现者。
问题 3:API v1 + RawKV 是否不必须部署 TiDB?
基本正确,但有细微差别。
- API v1 RawKV 无 MVCC:每个 key 只有一个版本,写入即覆盖,不需要 GC 清理历史版本
- API v1Ttl(启用 TTL):虽然也有过期数据清理需求,但通过 RocksDB compaction filter 实现,不依赖 TiDB 的 GC safe point
源码证据(src/storage/raw/store.rs):
pub enum RawStore<S: Snapshot> {
V1(RawStoreInner<S, ApiV1>), // 无 MVCC
V1Ttl(RawStoreInner<...ApiV1Ttl>), // TTL 通过 compaction filter 清理
V2(RawStoreInner<RawEncodeSnapshot<RawMvccSnapshot<S>, ApiV2>, ApiV2>), // 有 MVCC
}
结论:API v1 + RawKV 不需要部署 TiDB 来推进 GC。
问题 4:API v1 + TxnKV 是否可以部署 TiKV-CDC?API v2 + TxnKV 呢?
TiKV-CDC 目前不支持 TxnKV 模式(无论 API v1 还是 v2)。
源码证据(components/cdc/src/service.rs:43-46):
pub fn validate_kv_api(kv_api: ChangeDataRequestKvApi, api_version: ApiVersion) -> bool {
kv_api == ChangeDataRequestKvApi::TiDb
|| (kv_api == ChangeDataRequestKvApi::RawKv && api_version == ApiVersion::V2)
}
源码证据(components/cdc/src/endpoint.rs:843-844):
if !validate_kv_api(kv_api, api_version) {
error!("cdc RawKv is supported by api-version 2 only. TxnKv is not supported now.");
}
TiKV-CDC 的支持矩阵:
| KV API 模式 |
API v1 |
API v2 |
| TiDb(TiDB 内部事务数据) |
支持 |
支持 |
| RawKv(纯 KV 数据变更捕获) |
不支持 |
支持(v6.6.0 GA) |
| TxnKv(Go Client 事务数据) |
不支持 |
不支持 |
注意:TiDb 模式和 TxnKv 模式不同。TiDb 模式捕获的是 TiDB SQL 写入的表数据(有 TiDB 行格式编码),而 TxnKv 模式是指通过 TiKV Go Client 直接写入的事务 KV 数据。TiKV-CDC 只支持 TiDb 和 RawKv 两种模式。
总结与建议
| 组合 |
是否需要 TiDB 做 GC |
TiKV-CDC 支持 |
说明 |
| API v1 + RawKV |
不需要 |
RawKv 不支持 |
RawKV 无 MVCC,无需 GC |
| API v1 + TxnKV |
需要 GC 机制 |
TxnKv 不支持 |
需要推进 safe point,但不一定要 TiDB |
| API v2 + RawKV |
需要 |
支持 |
API v2 RawKV 有 MVCC |
| API v2 + TxnKV |
需要 GC 机制 |
TxnKv 不支持 |
同上,需要推进 safe point |
建议:
- 如果只使用 txn KV 且无 TiDB,需要自行实现 GC safe point 推进逻辑(通过 PD API)
- 如果需要 CDC 能力,建议评估是否可以将业务数据编码为 RawKV 格式使用 API v2 + TiKV-CDC
- 该社区帖子的用户讨论中,几位回复者(wbslxw、TiDBer_sheldon、Royce1220、独善其身)都确认了 GC 是必需的