![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
以下是纯英文格式的流程图,以及对应的中文详细解释:
---
### **流程图(纯英文)**
```plaintext
+----------------+ +----------------+ +----------------+
| TiDB | | PD | | TiKV |
+----------------+ +----------------+ +----------------+
| 1. Parse SQL | | | | |
| (Internal) | | | | |
+----------------+ +----------------+ +----------------+
| | |
| 2. Logical Plan | |
| (Metadata Binding) | |
| | |
+----------------+ +----------------+ +----------------+
| 3. Physical |←(Stats Metadata)→| Manage Stats | | Store Stats |
| Optimization| | Metadata | | Data |
+----------------+ +----------------+ +----------------+
| | |
| 4. Build Executors | |
| (Split Key Ranges) | |
| | |
+----------------+ +----------------+ +----------------+
| 5. GetRegion |←(Key Range) →| Provide Region | | |
| Metadata | | Info (Leader) | | |
+----------------+ +----------------+ +----------------+
| | |
| 6. Send Cop Requests | |
| (To TiKV Leaders) | |
| | |
+----------------+ +----------------+ +----------------+
| 7. Process | | |←(Read/Write) →| Execute |
| Cop Data | | | | Coprocessor |
+----------------+ +----------------+ +----------------+
| | |
| 8. Aggregate Results | |
| | |
+----------------+ +----------------+ +----------------+
| 9. Start Txn |←(GetTS) →| Assign TSO | | |
| (MVCC) | | (StartTS) | | |
+----------------+ +----------------+ +----------------+
| | |
| 10. Prewrite Phase | |
| (Lock Data) | |
| | |
+----------------+ +----------------+ +----------------+
| 11. Commit |←(GetTS) →| Assign TSO |←(Commit) →| Update MVCC |
| Txn | (CommitTS) | (CommitTS) | | |
+----------------+ +----------------+ +----------------+
| | |
| 12. Handle Errors | |
| (Retry on Region Error) | |
| | |
+----------------+ +----------------+ +----------------+
| 13. Update |←(Heartbeat) →| Trigger Region |←(Split/Migrate)→| Maintain |
| Cache | | Operations | | Raft |
+----------------+ +----------------+ +----------------+
```
---
### **中文详细解释**
#### **1. SQL 解析(TiDB 内部)**
- **操作**:将 SQL 文本解析为抽象语法树(AST),进行词法分析(Lexer)和语法分析(Parser)。
- **关键点**:生成结构化 AST(如 `ast.SelectStmt`),无外部组件交互。
#### **2. 逻辑优化(TiDB 内部)**
- **操作**:绑定元数据(表、列、权限校验),展开通配符(`SELECT *`),隐式类型转换。
- **关键点**:依赖 `INFORMATION_SCHEMA` 或缓存校验元数据合法性。
#### **3. 物理优化(TiDB ↔ PD 隐式交互)**
- **操作**:基于统计信息生成最优执行计划(RBO/CBO)。
- **PD 角色**:管理统计信息元数据版本,TiDB 从 TiKV 拉取实际统计数据。
#### **4. 执行器构建(TiDB 内部)**
- **操作**:将物理计划转换为执行器(如 `TableReader`、`IndexLookUp`)。
- **关键点**:按键值范围拆分任务(如 `[startKey, endKey]`)。
#### **5. 获取 Region 元数据(TiDB ↔ PD)**
- **操作**:向 PD 发送 `GetRegion` 请求,查询键值范围对应的 Region Leader 地址。
- **PD 角色**:返回 Region ID、Leader 地址、键值边界。
#### **6. 发送协处理器请求(TiDB → TiKV)**
- **操作**:执行器向 TiKV Leader 发送键值扫描或计算请求(如 `Coprocessor`)。
- **TiKV 角色**:执行过滤、聚合等下推计算,返回结果。
#### **7. 处理数据(TiDB 内部)**
- **操作**:聚合来自多个 TiKV 节点的结果,组装为最终数据集。
#### **8. 事务启动(TiDB ↔ PD)**
- **操作**:向 PD 请求 `startTS`(事务开始时间戳)。
- **PD 角色**:分配全局唯一且递增的时间戳,用于 MVCC 快照。
#### **9. Prewrite 阶段(TiDB → TiKV)**
- **操作**:向涉及的所有 TiKV Region Leader 写入带锁的预提交数据。
- **冲突处理**:若锁冲突,触发回滚或重试。
#### **10. 提交事务(TiDB ↔ PD ↔ TiKV)**
- **操作**:
1. 向 PD 请求 `commitTS`(提交时间戳)。
2. 向 TiKV 发送提交请求,异步清理锁。
- **PD 角色**:确保 `commitTS` 全局顺序一致性。
#### **11. 异常处理(TiDB ↔ PD)**
- **场景**:Region Leader 切换、网络分区等。
- **操作**:TiDB 重新查询 PD 获取最新 Region 信息,并重试请求。
#### **12. 集群调度(PD ↔ TiKV)**
- **操作**:PD 监控负载,触发 Region 分裂、迁移或副本重平衡。
- **TiDB 响应**:通过心跳或错误更新 Region 路由缓存。
---
### **关键交互总结**
| **阶段** | **TiDB 操作** | **PD 角色** | **TiKV 角色** |
|------------------------|---------------------------------------|------------------------------------------|------------------------------------------|
| **解析与优化** | 生成执行计划,拆分键值范围 | 管理统计元数据 | 存储统计数据 |
| **执行阶段** | 发送协处理器请求,聚合结果 | 提供 Region 路由信息 | 执行计算下推,返回数据 |
| **事务提交** | 协调 2PC 流程,处理锁冲突 | 分配 TSO 时间戳 | 写入 MVCC 数据,维护锁状态 |
| **集群调度** | 更新 Region 缓存,重试失败请求 | 触发 Region 分裂、迁移 | 维护 Raft 副本,响应调度指令 |
---
### **完整流程示例**
#### **场景:执行 `SELECT * FROM t WHERE id = 1`**
1. **TiDB**:解析 SQL,优化生成 `PointGet` 计划。
2. **PD**:查询 `id=1` 的 Region Leader 地址。
3. **TiKV**:返回对应键值数据,TiDB 组装结果。
4. **事务提交(写操作)**:
- **Prewrite**:TiDB → TiKV(锁定数据)。
- **Commit**:TiDB → PD(获取 `commitTS`)→ TiKV(提交数据)。
---
通过上述流程,TiDB 实现了分布式 SQL 的高效执行,PD 负责全局协调,TiKV 提供强一致的存储与计算下推能力。
下面是一个 **完整的 TiKV RawKV 模式下的系统架构与流程图(文本版)**,包含 **PD、TSO、TiKV、Region 管理、Raft、调度器等所有核心组件与流程**。
特别补充了 TSO 的位置和作用,即使在没有事务的场景中。
---
## 📄 TiKV RawKV 模式整体流程图(含 TSO)- 文本格式
```
+---------------------+ +----------------------+
| Client API | | pd-server (PD) |
| (RawKV: put/get) | | |
+----------+----------+ +----------+-----------+
| |
| | 1. 启动时加载 cluster 信息、Region 元信息
| | 2. 启动 TSO 模块(默认启用)
| |
| |<-----------------------------+
| | |
| | 3. TSO 定时生成(用于调度) |
| +----------------------------->+
| | 4. 提供 TSO 给调度、lease、region 合并
| |
| | 5. 接收 TiKV 心跳/调度上报
| |
| +-----------------------------+
| |
v |
+---------------------+ |
| gRPC or HTTP | <---------------------------------------------+
| API 调用 |
+---------------------+
|
v
+-----------------------------+
| TiKV Store |
| |
| 1. 请求解析 |
| 2. 定位对应 Region |
| 3. 通过 raft 提交写入 |
| (无事务,直接 apply) |
| 4. 返回执行结果 |
+-------------+---------------+
|
| +------------------------+
| 发送 raft 日志 | Other TiKV Nodes |
+--------------------------->| (同一个 Region) |
+------------------------+
|
v
+-----------------------+
| Raft Consensus |
| Region 日志同步 |
+-----------------------+
+-----------------------------+
| Region + RocksDB Engine |
| - 存储 key-value 数据 |
| - 不带 MVCC 元信息 |
+-----------------------------+
调度 & 维护流程:
-----------------------------
[PD 调度器流程]
1. 定时评估 Region 热点、空间等
2. 生成调度 operator(迁移、合并、打散)
3. 为操作生成 TSO 时间戳(调度 TTL)
4. 下发给 TiKV -> 控制迁移/分裂
5. TSO 确保多次调度不冲突
[Region heartbeat 流程]
1. TiKV 定时向 PD 上报 region 心跳
2. 包含 store 状态、region epoch 等
3. PD 判断是否需要重新调度
```
---
## 🔎 模块说明(带 TSO 补充)
### 💾 TiKV Store
| 模块 | 作用 |
| --------- | ---------------------- |
| RawKV 引擎 | 直接读写 RocksDB,无需版本号 |
| Raft 引擎 | 保证每个 Region 数据一致性 |
| Region 管理 | 存储多个 Region,数据按 key 分片 |
---
### 🧠 PD Server
| 模块 | 是否使用 TSO | 说明 |
| -------------- | -------- | --------------------------------- |
| Region 管理 | ✅ | 判断 Region 合并、分裂是否需要时间窗口 |
| 调度器(scheduler) | ✅ | 为每个调度 operator 分配 TTL,用 TSO 生成时间戳 |
| Leader lease | ✅ | PD 多节点共识需要 TSO 参与保证 leader 时效 |
| Metrics 采集 | ✅ | 监控指标(如操作延迟)时间参考 |
| etcd | ✅ | PD 使用 etcd 实现一致性状态机,其租约机制也依赖系统时间 |
---
## 🧭 TSO 在 RawKV 下的职责总结
| 职责 | 是否仍在 RawKV 使用 | 原因 |
| ------------------- | ------------- | -------------------- |
| 数据版本控制 | ❌ 不使用 | RawKV 无 MVCC |
| PD 调度 TTL | ✅ 使用 | 调度 TTL、operator 生命周期 |
| Region 调度安全 | ✅ 使用 | 避免过期调度干扰 |
| leader lease | ✅ 使用 | 避免 PD 脑裂 |
| Region heartbeat 检测 | ✅ 使用 | 心跳超时判断逻辑 |
---
## 📌 文件导出
是否需要我将该图以 `.txt` 文件形式导出给你?
如需补充 **事务模式 TiKV 流程图** 或 **图像格式**,也可以立即生成。
是否需要 `.txt` 下载文件?
你这段 PD 日志中出现了:
```
[WARN] [tso.go:334] ["clock offset"] [...] [jet-lag=XXXms] ...
```
说明 **PD 检测到当前节点系统时间跳动异常**(时钟偏移),具体字段如下:
| 字段 | 含义 |
| ------------------------------- | ------------------------ |
| `jet-lag=160.368435ms` | 当前系统时间比预期多快/多慢了 `160ms` |
| `prev-physical` | 上次 TSO 的物理时间戳 |
| `now` | 当前系统物理时间戳 |
| `update-physical-interval=50ms` | 正常情况下 PD 每 50ms 同步一次物理时钟 |
---
## ⚠️ 问题本质:系统时钟发生了非线性跳动
这是 PD 的 TSO 模块 `tso.go` 检测到 **系统时间回拨或快进**。
---
## 🔍 产生原因
1. **NTP 时间同步异常**(最常见):
* `ntpd` 或 `chronyd` 在运行时强制同步远程时间导致系统时钟跳动。
* 特别是使用 `ntpdate` 命令(非渐进式)会引起时间猛跳。
2. **虚拟化环境中宿主机时钟漂移**:
* 如果你部署在 KVM、VMware、容器等虚拟环境中,宿主机同步策略异常也会影响 guest。
3. **硬件故障或 BIOS 时间异常**
---
## ❗ 对 TiDB 集群的影响
PD 负责 **全局唯一时间戳 TSO**,一旦系统时间发生跳变:
| 情况 | 影响 |
| ------------- | ---------------------------------------------------------------- |
| 时间 **回拨(回退)** | 会导致 TSO 分配的时间戳不再单调递增,严重时触发 TiKV `timestamp fallback` 报错,**事务失效** |
| 时间 **跳跃(加速)** | TSO 正常,但可能触发事务提前超时或 commit timestamp 异常偏大 |
---
## ✅ 建议处理
### 🔸1. 禁止使用 `ntpdate`,统一使用 `chronyd` 或 `ntpd`
* 优选 `chronyd`,设置为 **渐进式同步**
```bash
yum install chrony -y
systemctl enable --now chronyd
```
* 配置 `/etc/chrony.conf` 中的 `makestep` 参数,仅允许启动初期允许跳变:
```conf
makestep 1.0 3
```
### 🔸2. 所有 PD / TiKV 节点系统时间应统一配置
建议如下:
```bash
timedatectl set-ntp yes
timedatectl set-timezone Asia/Shanghai
```
确认:
```bash
timedatectl status
```
确保 `NTP service` 处于同步状态,系统时间无回拨风险。
---
### 🔸3. 设置 `panic-on-time-jump`(v6.2+)
若使用的是 TiDB v6.2+,PD 支持在时钟异常时自动退出(防止发出错误 TSO):
```yaml
# pd config:
replication:
enable-placement-rules: true
schedule:
panic-on-time-jump: true
```
---
### 🔸4. 检查是否为虚拟化环境时钟漂移
对于 VM:
* 使用 `host` 模式同步宿主机时间
* 开启 `hypervclock` / `kvmclock` 驱动
* 避免同时启用多种时钟源
---
## ✅ 结论
你的 PD 节点时钟发生了 160\~213ms 的跳动,属于轻微问题,但:
* 如果跳动频繁、幅度更大(> 500ms),可能导致整个集群 TSO 异常
* 建议尽快统一所有 PD/TiKV/TiDB 节点的时间同步机制,并使用渐进同步(如 `chronyd`)
---
需要我写一个 Ansible 规则,检查所有机器 NTP 配置是否一致并收集时间状态吗?