|
|
@@ -0,0 +1,65 @@
|
|
|
+# 夜间同步核查记录(业务日 2026-10-31)
|
|
|
+
|
|
|
+核查窗口:北京时间 2026-10-31 23:43 — 2026-11-01 00:28。本轮只监测,不重复执行、不走同步桥、不抢占租约、不删除目录锁。
|
|
|
+
|
|
|
+## 结论
|
|
|
+
|
|
|
+**业务日 2026-10-31 的夜间同步未完成,判定为「阻塞 / 未完成」,没有服务端成功回执。**
|
|
|
+
|
|
|
+- 真实 23:00 触发已发生:服务端 runId `579148c2-4320-46e7-9304-8bf38498a481`,`startedAt = 2026-10-31T15:00:06.098Z`(北京时间 23:00:06),`finishedAt` 至今为 `null`。
|
|
|
+- 服务端状态仍显示 `running`,但没有任何完成回执、没有 `summary`、没有 9 个数据集的 `reconciled` 记录。这属于「挂起」而非「成功」,不能按成功计。
|
|
|
+- 本机同一 runId 每 5 分钟重试一次,全部以 `blocked / legacy_account_identity_conflict` 结束;零点后的重试(业务日已翻为 2026-11-01)返回 `another_sync_running`,因为旧运行仍持有服务端租约。
|
|
|
+- 10 分钟间隔、连续 4 次轮询(23:58 / 00:08 / 00:18 / 00:28)状态零变化,阻塞为确定性原因,不会自行恢复。
|
|
|
+
|
|
|
+## 阻塞根因
|
|
|
+
|
|
|
+`legacy_account_identity_conflict: resolve reading-generated IDs before syncing business records`
|
|
|
+
|
|
|
+账号补缺阶段发现 1 处身份冲突:某个旧系统用户编号被新系统中「阅读账号生成的编号」占用。按既定保护策略(阅读账号生成的编号不能代表旧系统身份),同步在投影任何业务数据之前即停止,避免把真实学员的课程挂到阅读账号上。
|
|
|
+
|
|
|
+| 项目 | 2026-10-30(上次成功) | 2026-10-31(本次) | 变化 |
|
|
|
+| --- | ---: | ---: | --- |
|
|
|
+| 源账号数 | 748 | 749 | +1 |
|
|
|
+| 已匹配 | 744 | 744 | 0 |
|
|
|
+| 账号资料差异(保留冲突) | 167 | 170 | +3 |
|
|
|
+| 身份冲突 identityConflicts | 0 | 1 | **+1** |
|
|
|
+| 已排除(已删除 / SyncExcluded) | 4 | 4 | 0 |
|
|
|
+| 终态 | completed-with-preserved-conflicts | blocked(未完成) | 成功 → 失败 |
|
|
|
+
|
|
|
+2026-10-30 晚间的同类冲突(旧编号 1869 / 1870 与阅读账号 熊紫羽 / 彭宇哲高三 相撞)是在用户明确授权退休这两个阅读账号后才解除的,运行于 2026-10-31 00:06 完成。本次冲突尚未经人工核实与决策,因此任务停在原地。
|
|
|
+
|
|
|
+## 9 个业务数据集核验结果
|
|
|
+
|
|
|
+全部未执行。运行缓存目录 `direct-579148c2-4320-46e7-9304-8bf38498a481/` 为空,日志中没有产生任何分页进度行。
|
|
|
+
|
|
|
+| 数据集 | 是否执行 | 服务端 reconciled |
|
|
|
+| --- | --- | --- |
|
|
|
+| 专项训练 | 否 | 否 |
|
|
|
+| 词库 | 否 | 否 |
|
|
|
+| 课程绑定 | 否 | 否 |
|
|
|
+| 每日学习 | 否 | 否 |
|
|
|
+| 练习 | 否 | 否 |
|
|
|
+| 抗遗忘 | 否 | 否 |
|
|
|
+| 预约 | 否 | 否 |
|
|
|
+| 上课 | 否 | 否 |
|
|
|
+| 测评 | 否 | 否 |
|
|
|
+
|
|
|
+- 账号:源 749、新增 0、匹配 744、缺失 0、排除 4、保留冲突 170、身份冲突 1;现有账户余额未改动(`existingAccountBalancesUntouched: true`)。
|
|
|
+- 栏目:源 461、新增 0、匹配 461、缺失 0(只补缺,符合策略)。
|
|
|
+- 财务分组(会员流水 stype=1/2/3/4):未执行,无回读核对。
|
|
|
+- `failed = 1`,`settlementReady = false`,冲突只记录未自动解决,来源 `old-api/WXAPP`、`bridgeUsed = false`。
|
|
|
+
|
|
|
+## 本机任务与日志证据
|
|
|
+
|
|
|
+- LaunchAgent `cn.xiaoshu.legacy-direct-sync-nightly`:program 为 `/usr/local/bin/node --env-file=… /Users/mac/Library/Application Support/XiaoshuSync/scripts/run-nightly-direct-sync.mjs --scheduled`,`TZ=Asia/Shanghai`,日历触发 `Hour=23 / Minute=0`,`runs = 25`,`last exit code = 1`。配置项与要求一致。
|
|
|
+- `launchagent.log` 尾部重复出现 `blocked / legacy_account_identity_conflict`(runId 579148c2)与 `another_sync_running` 交替。
|
|
|
+- `launchagent-error.log` 最后写入时间为 2026-10-19,今晚没有新的进程级异常;历史 `ERR_MODULE_NOT_FOUND: sync-alerts.mjs` 已不存在(该模块已于 2026-10-15 安装到位),不是本次阻塞原因。
|
|
|
+- 告警状态 `direct-alert-state.json`:`{"failed":true,"lastKey":"failure","conflicts":4193,...}`。
|
|
|
+
|
|
|
+## 需要人工决策的事项
|
|
|
+
|
|
|
+1. 核实今晚新增的那 1 处身份冲突:确认该旧系统编号对应的真实学员,并决定是退休/停用占用的阅读账号,还是保留冲突不做投影。2026-10-30 用的是「授权退休冲突账号」这条路。
|
|
|
+2. 该运行仍持有服务端租约;在它被收口之前,2026-11-01 业务日的夜间同步同样会以 `another_sync_running` 被挡住。本核查按约束未删除锁、未抢占租约、未做任何写操作。
|
|
|
+3. 未设置 `settlementReady`;工资结算仍不能使用本结果,也不能用它替代专项核验。
|
|
|
+
|
|
|
+私有运行报告位于 `~/.local/state/xiaoshu/legacy-sync/2026-10-31-direct-579148c2-4320-46e7-9304-8bf38498a481.json`,心跳文件为同目录 `heartbeat-23-status-2026-10-31.json`(0600)。报告与本文档均不含任何凭据内容。
|