维护指南:架构、调度、MVCC、动态配置与运维信号)
TiKV 事务与存储层src/storage维护指南架构、调度、MVCC、动态配置与运维信号【免费下载链接】tikvDistributed transactional key-value database, originally created to complement TiDB项目地址: https://gitcode.com/GitHub_Trending/ti/tikv本文以 TiKV 仓库的 storage 维护指南 为核心骨架系统讲解src/storage这一事务与存储层的职责边界、分层架构、请求执行链路、生命周期、数据模型契约、关键不变量、可观测信号以及变更管理方法。读完本文你将掌握 TiKV 存储层的代码地图与必读顺序、StorageAPI 与TxnScheduler的协作原理、storage 相关配置参数含动态下发机制的完整语义以及排查回调丢失、latch 卡死、MVCC 跨 CF 漂移、动态配置未生效等典型故障的入手点。目的与范围src/storage 是什么src/storage是 TiKV 的事务与存储层也是仓库中最重要的维护面之一。从 模块文档 可以看到它承担了把高层事务命令降低为对持久存储的底层raw key-value交互这一核心职责。它拥有并维护StorageAPI面向 RPC 层的顶层事务/存储入口事务命令调度命令准入、latch 串行化、任务追踪与 worker 交接MVCC多版本并发控制读取、扫描、冲突检测与写入侧变更处理raw KV 操作raw 键值 API 及其可选的 MVCC 封装latches 与锁等待调度器侧冲突串行化、存储侧锁等待契约流控flow control写压力管理存储相关动态配置在线配置的解析、校验与运行时副作用下发。从架构归属看src/storage向下通过Engine抽象见 engine_traits与持久化引擎交互向上被 src/server/service/kv.rs 这一主要调用方承接写路径经 raftkv 桥接 进入 raftstore。架构视图分层视图自顶向下src/storage分为五层顶层StorageAPImod.rs命令调度器txn/scheduler.rsMVCC 读写逻辑mvcc/raw KV 逻辑raw/锁等待与流控lock_manager/ 与 txn/flow_controller/。请求执行视图一次请求的典型执行链路为RPC 边界调用Storage主要调用方是 src/server/service/kv.rs调度器scheduler准入命令获取 latch、登记任务、按优先级与资源组策略排队MVCC/raw 执行发生在快照snapshot与引擎engine之上回调callback最终完成并返回 RPC 或更高层。从 txn/scheduler.rs 的模块注释可以印证每个 store 有一个TxnScheduler运行在单线程事件循环中命令执行被委托给 worker 线程池scheduler 只保证命令级别对重叠行的串行访问事务级语义由客户端库实现的事务协议保证。进程生命周期与启动时序Storage在服务器启动时构造且必须满足依赖顺序引擎engines、读池read pools、并发管理器concurrency manager、配额限流器quota limiter以及相关运行时辅助组件先就绪之后才构建Storage。启动后运行时配置管理器runtime config managers通过 config_manager.rs 更新存储侧行为。关闭阶段必须保持回调与 worker 的所有权安全直到所有强引用消失。代码层面有几个具体的运行时锚点storage 构造Storage::from_enginemod.rs接收 engine、config、read_pool 等构建整个协调层Storage 结构体 持有engine、schedTxnScheduler、read_pool、concurrency_manager、quota_limiter、resource_manager、resource_tag_factory等成员并通过refs: ArcAtomicUsize做引用计数——线程池与 worker 只有在引用归零后才停止见Clone/Drop实现mod.rs。scheduler 执行位于 txn/scheduler.rs。动态配置副作用位于 config_manager.rs 的dispatch方法。数据模型与元数据契约src/storage依赖若干严格的数据与元数据契约MVCC 数据模型横跨 default、lock、write 三个列族CF。lock CF 记录未提交的锁write CF 记录已提交写入的版本指针与提交时间戳default CF 保存实际数据或短值SHORT_VALUE_MAX_LEN见 mvcc/mod.rs。调度器任务元数据与 latch 所有权TaskContext持有lock、cb回调、prProcessResult以及一个owned: AtomicBool用于保证回调与结果只能被一个线程安全取走scheduler.rs。锁等待元数据与 tokenLockDigest、DiagnosticContext、KeyLockWaitInfo与WaitTimeout定义在 lock_manager/mod.rs超时在 protobuf 中编码为 i640 表示默认超时负值表示不等待。raw KV 编码与 API 版本raw 层按 API 版本选择存储实现RawStore是V1/V1Ttl/V2三个变体的枚举raw/store.rs分别对应ApiV1、ApiV1Ttl、ApiV2的KvFormat。资源控制元数据调度过程中消费资源组resource group与任务元数据TaskMetadata、ResourceTagFactory。高风险契约维护时最需要小心的契约包括MVCC 跨 default/lock/write CF 的关系一致性ProcessResult与回调完成语义ProcessResult定义在 txn/mod.rs包含Res、MultiRes、PrewriteResult、MvccKey、Locks、TxnStatus、NextCommand、Failed、PessimisticLockRes、SecondaryLocksStatus、RawCompareAndSwapRes等变体是调度执行结果回传的唯一通道TxnStatusCache与 max-ts 相关假设容量默认40_000 * 128见 config.rsraw KV 的 API 版本与 TTL 规则定义在 config.rs 的api_version/enable_ttl校验中。代码地图Start Here 与必读顺序文档给出的从这开始清单均以仓库根目录为起点src/storage/mod.rssrc/storage/txn/scheduler.rssrc/storage/txn/mod.rssrc/storage/txn/commands/mod.rssrc/storage/mvcc/mod.rssrc/storage/txn/store.rssrc/storage/raw/store.rssrc/storage/config.rssrc/storage/config_manager.rs推荐的必读文件顺序为src/storage/mod.rssrc/storage/config.rssrc/storage/txn/mod.rssrc/storage/txn/scheduler.rssrc/storage/txn/commands/mod.rssrc/storage/mvcc/mod.rssrc/storage/mvcc/reader/reader.rssrc/storage/txn/store.rssrc/storage/lock_manager/mod.rssrc/storage/config_manager.rs内部结构详解顶层 APIStoragemod.rs 定义了Storage与大量公开操作。从Storage的成员可以看到它的协调者角色它把 schedulerTxnScheduler、read pool、concurrency manager、quota limiter、resource control 组装在一起对外提供事务与 raw APImax_key_size等配置字段直接参与命令参数校验。模块内还细分了txn事务命令 → MVCC 抽象、mvccMVCC 实现、kv持久化存储抽象三个层次mod.rs 模块注释。调度器与命令执行txn/scheduler.rs 拥有命令准入、latches、任务追踪与 worker 交接。任务槽位数为1 124096见 scheduler.rs。txn/commands/ 定义具体事务命令prewrite、commit、acquire_pessimistic_lock、gc、cleanup、flashback 等见 txn/mod.rs 的 actions 导出。txn/task.rs、txn/sched_pool.rs 与 txn/tracker.rs 支撑执行。关于调度池的细节sched_pool.rs仅为自定义资源组customized resource groups选择优先级队列仅后台控制仍使用 vanilla 队列并在池内对匹配的长运行任务进行节流。调度池会从非只读 scheduler 命令中累计 MVCC 读流——包括前台写命令执行过程中执行的读——并在 ticker 与 worker 关闭时的 flush 中把 region 级ReadStats上报给 raftstore reporterlocal_read_stats/report_read_stats。需要留意此路径上关键范围key ranges与 bucket 增量不可用。MVCCmvcc/mod.rs 定义 MVCC 错误与公共面。错误类型覆盖KeyIsLocked、Committed、WriteConflict、Deadlock、TxnLockNotFound、PessimisticLockRolledBack等mvcc/mod.rs这些是事务冲突与恢复逻辑的判定基础。mvcc/reader/ 拥有读侧scanner、point getter、冲突检测。mvcc/txn.rs 拥有写侧 MVCC 变更处理MvccTxn、GcInfo、MAX_TXN_WRITE_SIZE。Raw KVraw/ 实现 raw 键值 API 及其可选的 MVCC 封装。RawStore::new按ApiVersion分发到 V1 / V1Ttl / V2 三种内部实现raw/store.rsV1 直接基于 snapshotV1Ttl 额外套一层RawEncodeSnapshot处理 TTL 过期V2 再叠加RawMvccSnapshot。scan 操作带MAX_TIME_SLICE 2ms与MAX_BATCH_SIZE 1024的时间片/批量限制raw/store.rs。等待与流控lock_manager/ 定义存储侧锁等待契约与本地等待队列辅助LockDigest、DiagnosticContext、KeyLockWaitInfo、WaitTimeout以及 lock_wait_context / lock_waiting_queue。活跃的 waiter-manager 工作者、死锁检测器deadlock detector与锁管理器 RPC 服务位于 src/server/lock_manager/。txn/flow_controller/ 控制写压力行为。Max-ts 动态配置config.rs 的MaxTsConfig::validate使用max_drift与cache_sync_interval的有效整毫秒值进行比较要求max_drift严格大于cache_sync_interval否则启动报错config.rs。config_manager.rs 的dispatch把max_ts.max_drift精确地以ReadableDuration下发到ConcurrencyManager::set_max_ts_drift_allowanceconfig_manager.rs。ConcurrencyManager有意用整毫秒存储该容差因为 TSO 物理时间戳以毫秒为单位。例如一个合法的配置值15s1us其有效强制执行容差为15000ms这是领域边界domain boundary而非在线配置截断。这一行为由单元测试test_validate_max_ts_config_uses_effective_milliseconds锁定config.rs。存储配置全景参数、默认值与校验规则storage 相关配置在 src/storage/config.rs 中定义模板注释在 etc/config-template.toml 中可查。以下是关键字段、默认值及其校验逻辑。顶层配置[storage]段对应字段字段默认值说明与校验data_dir./数据目录不可在线修改engineraft-kvraft-kv/partitioned-raft-kvRaftKv2。校验时会检查kv与tablet子目录是否同时存在两者同时存在直接报错若数据目录与 engine 类型不符则以已存在的数据目录为准自动回退config.rsgc_ratio_threshold1.1已由GcConfig.ratio_threshold取代仅保留向后兼容max_key_size8 * 10248KB命令 key 大小上限scheduler_concurrency1024 * 512调度器 latch 并发度上限2 * 1024 * 1024超限会被钳制并告警v4.0 起 latch 已优化不建议设过大scheduler_worker_pool_sizeCPU≥16 时 8否则clamp(1, 4)必须大于 0 且不超过max(4, cpu 配额)否则校验失败scheduler_pending_write_threshold100MB依据 Littles law 的写入积压阈值按 100MB/s 写速、约 100ms 处理时延估计reserve_space5GB磁盘满时保留的压缩空间reserve_raft_space1GBraft 日志保留空间enable_async_apply_prewritefalse异步 apply prewrite 开关api_version1只能为 1 或 2API V2 强制开启 TTLenable_ttlfalseAPI V2 下必须为truebackground_error_recovery_window1h后台错误恢复窗口设为 0 可禁用遇到此类错误立即 panicttl_check_poll_interval12h全量 SST 的 TTL 检查间隔txn_status_cache_capacity40_000 * 1285.12MTxnStatusCache 容量上限128 槽位memory_quota256MB待执行与执行中 storage 命令kv_get/kv_prewrite/kv_commit 等的内存配额校验时若小于 pending-write 阈值会自动抬升flow_control见下流控子模块block_cache见下共享 block cache 子模块io_rate_limit见下IO 限速子模块max_ts见下max-ts 偏差控制子模块memory_quota的 256MB 默认值背后有工程依据config.rs单条命令内存约等于 1KB KV 对 约 448 字节 Command 约 6184 字节执行 future256MB 约可支撑 3.5 万个并发执行命令或 18.2 万个排队命令单节点默认配置下 TPCC prepare--threads 500实测内存约 50MB。[storage.flow-control]字段默认值说明enabletrue启用后禁用 kvdb 与 raftdb 的 write stallmemtable 除外改为在 scheduler 层限流raftstore 与 apply 不再被阻塞soft-pending-compaction-bytes-limit192GB达到后开始以ServerIsBusy拒绝部分写请求hard-pending-compaction-bytes-limit1024GB达到后拒绝全部写请求memtables-threshold5kvdb 不可变 memtable 数达到该值开始流控l0-files-threshold20kvdb L0 SST 文件数达到该值开始流控模板注释见 etc/config-template.toml流控配置支持动态修改write_into_metrics会把阈值同步到CONFIG_FLOW_CONTROL_GAUGE指标config.rs。[storage.block-cache]capacity共享块缓存大小。raft-kv 默认约为系统可用内存的 45%partitioned-raft-kv 约为 30%见 config-template.toml单机多实例部署必须显式配置以避免 OOM。缓存总是共享shared字段已废弃。其他参数num-shard-bits 6容量过小时adjust_shard_bits会自动下调、strict-capacity-limit false、high-pri-pool-ratio 0.8、low-pri-pool-ratio 0.2、memory-allocator nodumpjemalloc nodump用于避免缓存内存被 dump。[storage.io-rate-limit]字段默认值说明max-bytes-per-sec0MB每秒最大 IO 字节数0 表示不限速建议设为磁盘厂商标称的最优 IO 带宽modewrite-only目前仅支持write-only模式其他模式校验报错strictfalse关闭时高优先级 IO 只计数不限速多租户场景应开启各*_priority见代码前/后台 IO 优先级前台读写、flush 为 Highcompaction 为 Low其余见 config.rs校验规则config.rsIOType::Other优先级会被强制为 High该类型可能包含关键 IOgc_priority会被强制与前台写优先级一致避免优先级反转。[storage.max-ts]字段默认值说明max-drift60s允许 max_ts 偏离 PD TSO 的最大值cache-sync-interval15s从 PD 刷新 max_ts 上限的间隔不可在线修改action-on-invalid-updatepanic收到非法 max_ts 更新时的动作合法值由ActionOnInvalidMaxTs定义校验要求max_drift的有效毫秒值必须大于cache_sync_interval的有效毫秒值config.rs两者以有效整毫秒对齐运行时 TSO 的毫秒精度。动态配置下发config_manager.rs运行时变更由 config_manager.rs 的StorageConfigManger::dispatch处理它把配置修改分发到具体运行时对象这也是改配置必须同步改副作用这一维护原则的落点block_cache.capacity→ConfigurableDb::set_shared_block_cache_capacity并写CONFIG_ROCKSDB_CF_GAUGEttl_check_poll_interval→ 调度TtlCheckerTask::UpdatePollIntervalflow_control→ 先FlowController::update_config再按enable开关批量设置各 CF 的disable_write_stall并调用FlowController::enablescheduler_worker_pool_size→TxnScheduler::scale_pool_sizememory_quota→TxnScheduler::set_memory_quota_capacityio_rate_limit→ 更新IoRateLimiter的速率与各IoType优先级max_ts.action_on_invalid_update→ConcurrencyManager::set_action_on_invalid_max_ts_updatemax_ts.max_drift→ConcurrencyManager::set_max_ts_drift_allowance。关键不变量Critical Invariants维护src/storage时必须始终维持以下不变量命令回调必须恰好完成一次且携带正确的错误/结果语义对应ProcessResult与回调契约latch 所有权必须串行化冲突命令且不使调度器死锁MVCC 读写必须维持 lock、write、default CF 之间的关系region 边界、快照上下文、flashback/max-ts 安全必须持续生效max-ts 关系校验必须与运行时 TSO 强制执行使用相同的整毫秒精度内存配额与 pending-write 阈值必须保持运维上有效。可观测性与运维信号开始故障排查时建议从以下位置入手src/storage/metrics.rssrc/storage/txn/scheduler.rssrc/storage/lock_manager/src/storage/config_manager.rs可观测信号包括scheduler 延迟、latch 等待与 pending-write 信号SCHED_HISTOGRAM_VEC_STATIC等热路径指标scheduler.rsMVCC 冲突、读与 GC 相关指标流控与内存配额行为CONFIG_FLOW_CONTROL_GAUGE暴露阈值配额限流器负责执行锁等待与死锁诊断DiagnosticContext携带 key、资源组 tag 与 tracker用于聚合同一语句产生的锁等待详情lock_manager/mod.rsPD 读流报告包含前台写命令执行的读当 PD 读字节数与 read-pool 工作量不匹配时检查 txn/sched_pool.rs 的读流累计与上报逻辑。TopSQL / 资源计量的逻辑 IO 归属细节当resource-metering.enable-network-io-collection启用时资源计量/TopSQL 记录逻辑 IO当resource-metering.enable-detailed-io-collection也启用时逻辑读与逻辑写被独立选取前台 SQL 请求的 RocksDB PerfContext 增量被记录为rocksdb_block_read_count。该字段向下游read_iops维度提供相对归因并不是设备级 IOPS 测量值。存储命令边界在 metrics.rs 中拥有对该归因的所属权适用于只读命令与写命令的读阶段。特别地事务写与raw_compare_and_swap必须保留Storage的 PerfContext因为 CAS 在决定是否写入前要先读取旧值恢复的悲观锁pessimistic-lock批次可能包含来自多个请求的工作TopSQL 有意使用合成命令的第一个上下文作为整个批次的代表包括逻辑写与单次 detailed-I/O PerfContext 观测因此混合 tag 批次的归因是近似值以避免在锁唤醒路径上做逐项工作不要把 raftstore apply/store 写 worker 的活动归因到请求上这些路径使用只写 PerfContext 指标且可能批量处理多个请求的工作。变更管理指导任何对StorageAPI、回调语义、MVCC 契约或动态配置副作用的改动都应在同一 patch 内同步更新本维护指南存储语义或错误映射变化时应审计 server 与 raftstore 桥接层如果修改配置值却没有同步更新 config_manager.rs 的副作用该改动通常是不完整的。变更影响矩阵变更类型需要检查的范围公开StorageAPI 或回调变更mod.rs、txn/scheduler.rs以及 src/server 中面向 RPC 的调用方调度器、latch 或任务流变更txn/scheduler.rs、txn/task.rs、txn/sched_pool.rs 与指标MVCC 读写或冲突变更mvcc/、txn/store.rs 与事务命令raw KV 变更raw/、API 版本处理与 coprocessor_v2 存储适配器锁等待或流控变更lock_manager/、txn/flow_controller/以及 src/server 中的运行时工作者动态配置变更config.rs、config_manager.rs 与运行时副作用消费方审查清单提交涉及存储层的改动前请逐项确认是否影响StorageAPI 行为或回调契约是否触及 txn/scheduler.rs、latches 或锁等待队列是否修改 MVCC 冲突检测、锁解析或 commit-ts 规则是否改变与插件 coprocessor 或外部 API 共享的 raw KV 行为是否改变必须同时适用于raftkv与raftkv2桥接层的快照或写入假设src/server/raftkv/mod.rs 与 src/server/raftkv2动态配置是否需要 config-manager 副作用是否改变资源控制集成、流控或配额限流器行为测试与可观测性MVCC、事务命令、latches、锁等待、raw MVCC 与调度器辅助逻辑拥有大量内联单元测试例如 config.rs 的 validate 测试 覆盖 engine 类型回退、max-ts 毫秒精度比较与 shard bits 调整集成测试多归属 components/test_storage调度器、MVCC、读池与流控的热路径指标遍布各模块。常见故障模式回调从未调用或调用两次破坏ProcessResult完成语义会导致请求悬挂或结果重复latch 释放 bug造成命令卡死或乱序MVCC 跨 CF 写/读漂移lock/write/default 关系被破坏从底层错误中提取 region 错误不正确影响上层重试与错误上报动态配置只更新了内存中的 config 值、未应用到运行时对象典型的 config_manager 副作用缺失锁等待唤醒逻辑导致饥饿或漏唤醒影响悲观事务的并发与延迟。阅读地图与配套文档建议按 1 → 10 的顺序阅读代码地图中的必读文件见上文代码地图一节配套文档包括repo-overview.mdsrc/server.mdcomponents/raftstore.mdPERFORMANCE_CRITICAL_PATH.md术语表MVCCmulti-version concurrency control基于 default/lock/write CF 的多版本并发控制Latch调度器侧用于冲突命令串行化的原语ProcessResult调度执行结果通过回调返回Flow control压力管理逻辑用于减缓或门控写密集活动。相关组件src/server/service/kv.rsStorage的主要调用方src/server/raftkv/mod.rs把写请求桥接进 raftstoresrc/server/lock_manager/围绕存储侧等待队列契约的活跃锁管理器工作者与死锁检测服务components/resource_control 与 components/resource_metering直接与调度和计量集成。【免费下载链接】tikvDistributed transactional key-value database, originally created to complement TiDB项目地址: https://gitcode.com/GitHub_Trending/ti/tikv创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考