first commit
This commit is contained in:
@@ -0,0 +1,152 @@
|
||||
# 节点状态持久化与人工介入规范
|
||||
|
||||
> **代码实现**:`sync_system_new/common/state_reset.py`
|
||||
|
||||
---
|
||||
|
||||
## 1. 持久化规则
|
||||
|
||||
### 1.1 持久化目标
|
||||
|
||||
| 目标 | 说明 |
|
||||
|------|------|
|
||||
| **可恢复性** | 系统重启后能从上次状态继续 |
|
||||
| **可观测性** | 失败和异常状态要保留,供人工查看 |
|
||||
| **可追溯性** | 失败信息持久化,不自动重试,需人工确认 |
|
||||
| **绑定稳定性** | 手工绑定一旦建立,永不自动改变 |
|
||||
|
||||
### 1.2 分阶段重置设计
|
||||
|
||||
状态重置分为两个阶段执行:
|
||||
|
||||
#### 阶段1:加载时重置(Collection.load_from_persistence)
|
||||
|
||||
| 字段 | 性质 | 持久化 | 阶段1重置 |
|
||||
|------|------|--------|-----------|
|
||||
| `node_id` | 恒定标识 | ✅ 必须 | ❌ 不重置 |
|
||||
| `data_id` | 业务主键 | ✅ 必须 | ❌ 不重置 |
|
||||
| `data` | 业务数据 | ✅ 必须 | ✅ **重置**(每次重新取数) |
|
||||
| `origin_data` | 原始快照 | ✅ 必须 | ✅ **重置**(每次重新取数) |
|
||||
| `depend_ids` | 依赖列表 | ❌ **不持久化** | ✅ **初始化为[]**(bind 阶段从 data 实时计算) |
|
||||
| `binding_status` | 绑定状态 | ✅ 必须 | ✅ **重置为 UNCHECKED** |
|
||||
| `action` | 同步意图 | ✅ 保存 | ❌ **保留**(用于阶段2判断) |
|
||||
| `status` | 执行状态 | ✅ 保存 | ❌ **保留**(全部保留,不重置) |
|
||||
| `error` | 错误信息 | ✅ 保存 | ✅ **重置为None**(清空上次错误) |
|
||||
| `context` | 扩展上下文 | ✅ 保存 | ❌ 不重置 |
|
||||
|
||||
#### 阶段2:数据加载后清理(Pipeline._cleanup_create_failed_zombies)
|
||||
|
||||
在数据加载完成后、策略执行前,执行CREATE失败节点清理:
|
||||
|
||||
1. **检查条件**:
|
||||
- 本地节点 `action == CREATE`(上次尝试创建)
|
||||
- 本地节点 `status == FAILED`(创建失败)
|
||||
|
||||
2. **清理动作**:
|
||||
- **删除本地失败节点**(从 collection 中移除)
|
||||
- 如果有绑定记录:
|
||||
- 解除绑定关系
|
||||
- 删除远程 collection 中的僵尸节点
|
||||
|
||||
3. **最后重置 action**:
|
||||
- 所有剩余节点的 `action` 重置为 NONE
|
||||
- 准备进入策略阶段
|
||||
|
||||
4. **下次同步的自动恢复**:
|
||||
- 被删除的节点会从数据源重新加载
|
||||
- 如果远程实际已创建成功(网络波动导致未获取到结果)→ 绑定阶段会自动绑定上
|
||||
- 如果远程实际也失败了 → 重新尝试创建
|
||||
|
||||
5. **UPDATE 阶段保护**:
|
||||
- UPDATE 操作会跳过所有 `status == FAILED` 的节点
|
||||
- 防止 UPDATE 阶段覆盖 CREATE/UPDATE 失败的状态和错误信息
|
||||
- 确保失败节点的 action 和 error 信息保持不变,直到下次同步清理
|
||||
|
||||
> **说明**:
|
||||
> - `data` / `origin_data`:每次运行从数据源重新获取,保证数据最新
|
||||
> - `depend_ids`:**不持久化**,每次 bind 阶段从 data 的业务字段(如 contract_id, project_id)实时提取
|
||||
> - `binding_status`:持久化用于审计,加载时重置为 `UNCHECKED`,由 bind() 重新判定
|
||||
> - `error`:**阶段1清空**,避免上次错误影响本次运行,新错误会在各阶段重新生成
|
||||
> - `action`:**阶段1保留**用于识别 CREATE 失败的节点,**阶段2清理后重置**
|
||||
> - `status`:**阶段1全部保留**(包括 FAILED、PRECONDITION_FAILED 等),不自动重置
|
||||
> - **CREATE 失败节点会被自动删除并重新加载**,UPDATE/DELETE 失败保留需人工处理
|
||||
> - **UPDATE 操作会跳过 FAILED 节点**,避免覆盖失败状态和错误信息
|
||||
|
||||
### 1.3 绑定记录 vs binding_status
|
||||
|
||||
| 概念 | 存储位置 | 持久性 | 如何改变 |
|
||||
|------|---------|--------|---------|
|
||||
| **绑定记录** | `bindings` 表 | **永久保留** | 只能手工 bind/unbind,或 CREATE 失败自动清理 |
|
||||
| **binding_status** | `nodes` 表 | 保存但可重判 | 每次 bind() 重新判定 |
|
||||
|
||||
### 1.4 CREATE 失败的自动恢复
|
||||
|
||||
当 CREATE 操作失败时,会产生"僵尸绑定":
|
||||
- 绑定记录已建立(local_id → remote_node_id)
|
||||
- 但远程节点的 `data_id` 为空(API 未返回真实 ID)
|
||||
|
||||
**下次同步时的自动恢复流程**:
|
||||
1. 阶段1加载:保留 `action=CREATE`
|
||||
2. 阶段2清理:检测到僵尸绑定,自动清理
|
||||
3. 本地节点恢复为 MISSING 状态
|
||||
4. 策略阶段重新判定,再次尝试 CREATE
|
||||
|
||||
---
|
||||
|
||||
## 2. 人工介入规范
|
||||
|
||||
### 2.1 介入时机
|
||||
|
||||
| 时机 | 场景 | 操作 |
|
||||
|------|------|------|
|
||||
| **运行前** | 查看上次失败记录 | 查看持久化的 error,决定是否修复后重试 |
|
||||
| **bind() 后** | 出现 ABNORMAL/WARNING | 检查数据一致性,手工修复或确认 |
|
||||
| **bind() 后** | 1:N / N:N 映射 | 手工绑定指定远程记录 |
|
||||
| **sync() 后** | 批量失败 | 分析失败原因,决定重试策略 |
|
||||
|
||||
### 2.2 binding_status 与介入需求
|
||||
|
||||
| binding_status | 含义 | 需要介入 | 说明 |
|
||||
|----------------|------|---------|------|
|
||||
| `UNCHECKED` | 未检查 | ❌ | 等待 bind() 判定 |
|
||||
| `NORMAL` | 绑定正常 | ❌ | 自动处理 |
|
||||
| `MISSING` | 无绑定记录 | ❌ | 自动创建 |
|
||||
| `WARNING` | 本地有绑定但远程无数据 | ⚠️ 可选 | 可能是远程删除,需确认 |
|
||||
| `ABNORMAL` | 状态不一致 | ✅ **必须** | 需人工排查 |
|
||||
| `DEPENDENCY_ERROR` | 依赖未就绪 | ❌ | 等依赖解决后自动重试 |
|
||||
|
||||
### 2.3 人工绑定操作
|
||||
|
||||
```python
|
||||
# 手工绑定(1:N 场景)
|
||||
binding_manager.bind(node_id="local_xxx", data_id="remote_xxx")
|
||||
|
||||
# 手工解绑
|
||||
binding_manager.unbind(node_id="local_xxx")
|
||||
```
|
||||
|
||||
绑定记录一旦建立,永不自动改变,只能手工操作。
|
||||
|
||||
### 2.4 职责分工
|
||||
|
||||
| 职责 | 系统自动 | 人工介入 |
|
||||
|------|---------|---------|
|
||||
| 1:1 自动绑定 | ✅ | - |
|
||||
| 1:N / N:N 绑定 | ❌ | ✅ |
|
||||
| NORMAL 节点同步 | ✅ | - |
|
||||
| MISSING 节点创建 | ✅ | - |
|
||||
| CREATE 失败重试 | ✅(自动清理僵尸) | ⚠️(需确认后手动重置) |
|
||||
| UPDATE 失败重试 | ❌(保留FAILED状态) | ✅(需确认后手动重置) |
|
||||
| ABNORMAL 处理 | ❌ | ✅ |
|
||||
| WARNING 确认 | ❌ | ✅(可选) |
|
||||
|
||||
---
|
||||
|
||||
## 3. 总结
|
||||
|
||||
1. **分阶段重置**:
|
||||
- 阶段1(加载时):只重置 binding_status,**保留 action/status/error**
|
||||
- 阶段2(数据加载后):清理 CREATE 失败僵尸,然后重置 action
|
||||
2. **失败状态持久化**:FAILED 状态和 error 信息保留,不自动重试
|
||||
3. **绑定记录**:永久保留,除非 CREATE 失败自动清理或手工操作
|
||||
4. **人工介入**:失败需确认后手动重置,ABNORMAL/WARNING 需人工处理,1:N 绑定需手工指定
|
||||
Reference in New Issue
Block a user