# 运维与排障手册（业务视角）

本文档聚焦两件事：
- 出错时先看哪里。
- 日志里的状态到底代表什么业务问题。

## 1. 先看什么（快速定位）

1. 看运行日志（`sync_log`）：
	 - 重点关注 `状态机流转`、`reason=`、`depends=[...]`。
2. 看持久化数据库：
	 - 重点字段：`binding_status`、`action`、`status`、`error`。
3. 对照状态机文档：
	 - `docs/state_machine.md`
	 - `docs/node_state_definition.md`

## 2. 阶段化排障

### 2.1 bind 阶段

常见表现：节点停在 `S03/S04/S05/S13`。

- `S03(ABNORMAL)`：节点数据损坏或核心绑定异常。
- `S04(WARNING)`：自动绑定关闭、键缺失、歧义等不可自动处理情况。
- `S05(DEPENDENCY_ERROR)`：依赖节点不存在或依赖状态不正常。
- `S13(PEER_CREATING)`：对侧创建进行中，尚未提交完成。

典型日志：
- `reason=依赖项不满足 | depends=[company_id status=peer_creating -> not_normal]`

业务解释：
- 上游依赖还没进入 `NORMAL`，下游业务会被严格阻断。

### 2.2 create 阶段

常见表现：节点长时间停在 `S13` 或 `S10C`。

- `S13`：已判定需要创建，但创建提交未完成。
- `S10C`：CREATE 异步执行中。
- `S12C`：CREATE 失败。

优先检查：
- API 侧是否返回任务 ID 与成功回执。
- 轮询参数（`poll_max_retries` / `poll_interval`）是否过小。

### 2.3 update 阶段

常见表现：节点进入 `S08` 或 `S12U`。

- `S08(PRECONDITION_FAILED)`：前置条件失败（如缺 data_id、依赖 ID 解析失败）。
- `S12U`：UPDATE 调用失败。
- `S14`：UPDATE 被 handler 降级为 NONE 并跳过。

优先检查：
- `update_direction` 是否符合预期。
- 目标节点是否具备 `data_id`。

## 3. 常见配置误区与症状

- `auto_bind=false`
	- 症状：MISSING 节点更容易进入 `WARNING`，不会走自动创建识别。
- `local_orphan_action=none` + `remote_orphan_action=none` + `update_direction=none`
	- 症状：该类型会被整体跳过，常被误以为“配置没生效”。
- `load_mode=persisted_only`
	- 症状：数据只来自持久化，不主动拉取新数据。
- `update_direction=none`
	- 症状：不做 update，即使有差异也不会提交更新。

## 4. 推荐操作顺序

1. 先用 `run_profiles/preset/jsonl_to_jsonl.default.yaml` 跑通基线。
2. 再切到 `run_profiles/*.local.yaml` 做最小覆盖。
3. 每次只改一类字段（比如只改 `project` 的依赖策略）。
4. 改完看一次 `sync_log`，确认状态流转与预期一致。

## 5. UI 排障（可选）

1. 启动：`python -m ui.main --host 127.0.0.1 --port 8765`
2. 打开：`http://127.0.0.1:8765`
3. 在“运行与日志”查看实时状态变化。
4. 在“记录与数据库”检查节点状态与绑定记录。
