202 lines
14 KiB
Markdown
202 lines
14 KiB
Markdown
# 两机 `lib/` 差异面核对与 106 补齐(第 22 棒 · 执行棒)
|
||||
|
|
|
|||
|
|
> **线**:插件投放与分库线 | **棒**:第 22 棒(执行棒)| **日期**:2026-09-25 11:58–12:2x
|
|||
|
|
> **一句话**:106 的 `lib/` 停在 **09-23 08:04 那次构建**(+此后少量零散补投)⇒ 代码面缺 **46 件**;已按 **47 生产部署面**(=本机构建产物,抽样逐字一致)补齐 ⇒ **代码面差异面归零(368 = 368,内容不同 0)**。⛔ 全程未重启 106。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 一、结论(先行)
|
|||
|
|
|
|||
|
|
| 判据 | 结果 | 关键读数 |
|
|||
|
|
|---|---|---|
|
|||
|
|
| ① 完整差异清单 | ✅ | 47 **389** 件 / 106 **357** 件;逐字一致 **322**;内容不同 **23**;仅 47 有 **44**;仅 106 有 **12** |
|
|||
|
|
| ② 补齐后差异面归零 | ✅ | 代码面 **368 = 368**、内容不同 **0**、单向缺失 **0**(`p22-verify.py` rc=0) |
|
|||
|
|
| ③ 待重启才生效的文件 | ✅ 已列 | **46 件全部**(106 `dshs-worker` 起于 `09-25 09:52:11`,写入在其后);其中运行时 `.js` **21 件** |
|
|||
|
|
|
|||
|
|
**判据口径(本棒立 · 后棒沿用)**:两侧 `lib` 树里各自留有历史部署快照(`.s3bak-*` / `.s0bak-*` / `*.bak-*`),
|
|||
|
|
它们**不是代码面**、两机时间戳本就不同 ⇒ 判据**只在代码面**(368 件)上要求归零。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 二、判据① · 完整差异清单
|
|||
|
|
|
|||
|
|
### 2.1 方法(3 条命令,第三方可复现)
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# 1) 两机各出一份「路径|md5|大小|mtime」全量清单(relpath 相对各自 lib 根)
|
|||
|
|
ssh bt-server 'cd /opt/dshs/lib && find . -type f | sort | while read -r f; do m=$(md5sum "$f"); m=${m%% *}; printf "%s|%s|%s|%s\n" "$f" "$m" "$(stat -c%s "$f")" "$(stat -c%Y "$f")"; done' > tmp/p22-lib47.tsv
|
|||
|
|
ssh test106 'cd /opt/dshs-cluster/lib && find . -type f | sort | while read -r f; do m=$(md5sum "$f"); m=${m%% *}; printf "%s|%s|%s|%s\n" "$f" "$m" "$(stat -c%s "$f")" "$(stat -c%Y "$f")"; done' > tmp/p22-lib106.tsv
|
|||
|
|
# 2) 对比出清单
|
|||
|
|
python tmp/p22-diff.py tmp/p22-lib47.tsv tmp/p22-lib106.tsv tmp/p22-diff-pre.tsv
|
|||
|
|
# 3) 复核(排除备份残留,rc=0 即归零)
|
|||
|
|
python tmp/p22-verify.py
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
- 两机代码根:47 = `/opt/dshs`(Manager);106 = `/opt/dshs-cluster`(Worker)。**⛔ 两机根目录名不同是既定事实**,不影响本判据(比的是各自 `lib/` 内相对路径)。
|
|||
|
|
- 原始差异面 **79 条** → 其中**代码面 46 条** + **部署备份残留 33 条**(47 侧 21 条、106 侧 12 条)。
|
|||
|
|
|
|||
|
|
### 2.2 差异面构成
|
|||
|
|
|
|||
|
|
| 类别 | 条数 | 说明 |
|
|||
|
|
|---|---|---|
|
|||
|
|
| `DIFF`(两机都有、md5 不同) | **23** | 全部是 106 停在 09-23 版;含 `business-plugins.js`、`db/*.js`、`im/hub.js`、`web/server.js` 等 |
|
|||
|
|
| `ONLY_47` 中**代码件**(106 缺) | **23** | `db/plugin-data/*`、`im/backends|connection-backend|keepalive|presence-ingest`、`web/routes/plugin-data.js`、`web/essential-plugins.js` |
|
|||
|
|
| `ONLY_47` 中**备份残留** | 21 | `.s3bak-20260920-174307/`、`.s0bak-20260920-165634/`、`net/relay/*.bak-*`、`web/server.js.bak-seq19-*` |
|
|||
|
|
| `ONLY_106`(47 无) | 12 | **全部是 106 自己的备份残留**(`.bak-20260917-155841` / `.bak-seq19-…-180218`)⇒ 代码面多出 **0** |
|
|||
|
|
|
|||
|
|
⇒ **代码面差异面 = 23 + 23 = 46 件**(21 件运行时 `.js` + 25 件 `.d.ts`/`.js.map`)。
|
|||
|
|
|
|||
|
|
### 2.3 关于 33 条备份残留(⛔ 本棒未投、未删)
|
|||
|
|
|
|||
|
|
- **不投**:它们是 47 侧**改前快照**(时间戳 09-17 / 09-20),投到 106 只会让 106 多出一批**过时代码副本**,属净变差(可维护性)。判据不是"字节级全等",而是**代码面全等**。
|
|||
|
|
- **不删**:删除属**不可逆**、且是**别处部署面的历史留档**,超出"两机差异核对"范围 ⇒ 只报告。
|
|||
|
|
|
|||
|
|
### 2.4 本次补齐的 46 件(清单 + 两侧指纹)
|
|||
|
|
|
|||
|
|
| 路径 | 类型 | 47 md5 | 106 改前 md5 | 说明 |
|
|||
|
|
|---|---|---|---|---|
|
|||
|
|
| `./db/pg.js` | 运行时 .js | `8f7923fb0414` | 38375 | `b79bf5ce6af8` | 37989 |
|
|||
|
|
| `./db/plugin-data/registry.d.ts` | 声明/映射 | `adef48d3ffbf` | 5414 | `—` | — |
|
|||
|
|
| `./db/plugin-data/registry.js` | 运行时 .js | `44d3b5c424f7` | 9333 | `—` | — |
|
|||
|
|
| `./db/plugin-data/registry.js.map` | 声明/映射 | `e83f9b4c0504` | 6615 | `—` | — |
|
|||
|
|
| `./db/plugin-data/runtime.d.ts` | 声明/映射 | `31cc1acdad96` | 8561 | `—` | — |
|
|||
|
|
| `./db/plugin-data/runtime.js` | 运行时 .js | `45daf7c5b2b6` | 20309 | `—` | — |
|
|||
|
|
| `./db/plugin-data/runtime.js.map` | 声明/映射 | `d8f91115fcaf` | 15637 | `—` | — |
|
|||
|
|
| `./db/repo.js` | 运行时 .js | `fe8bc9a698ab` | 40132 | `47f82e9617ba` | 39384 |
|
|||
|
|
| `./db/schema.js` | 运行时 .js | `cf62c2b43cac` | 41287 | `1cb43ade2db8` | 40487 |
|
|||
|
|
| `./db/sqlite.js` | 运行时 .js | `f05eb1a8e816` | 14478 | `62ae95ce50a5` | 14285 |
|
|||
|
|
| `./db/types.js` | 运行时 .js | `20bd54a22f6c` | 7766 | `c1caff6f1ed4` | 7601 |
|
|||
|
|
| `./im/backends/gateway.d.ts` | 声明/映射 | `693cea8cf738` | 7131 | `—` | — |
|
|||
|
|
| `./im/backends/gateway.js` | 运行时 .js | `7f0638c89d48` | 12077 | `—` | — |
|
|||
|
|
| `./im/backends/gateway.js.map` | 声明/映射 | `61950bd7abf7` | 6470 | `—` | — |
|
|||
|
|
| `./im/backends/native.d.ts` | 声明/映射 | `c2ca6034ae13` | 2323 | `—` | — |
|
|||
|
|
| `./im/backends/native.js` | 运行时 .js | `2d14f373325c` | 3168 | `—` | — |
|
|||
|
|
| `./im/backends/native.js.map` | 声明/映射 | `8b652f7acfa9` | 1165 | `—` | — |
|
|||
|
|
| `./im/connection-backend.d.ts` | 声明/映射 | `505e22d66ff5` | 8241 | `—` | — |
|
|||
|
|
| `./im/connection-backend.js` | 运行时 .js | `19ddbb402dd9` | 3342 | `—` | — |
|
|||
|
|
| `./im/connection-backend.js.map` | 声明/映射 | `2525a78e9dcc` | 2150 | `—` | — |
|
|||
|
|
| `./im/hub.d.ts` | 声明/映射 | `9f1c235ec084` | 12414 | `b6ec9ae149d8` | 10871 |
|
|||
|
|
| `./im/hub.js` | 运行时 .js | `cf405a4b5a10` | 13468 | `f36638808680` | 11868 |
|
|||
|
|
| `./im/hub.js.map` | 声明/映射 | `1afee241b41d` | 9325 | `8361b2e081ae` | 8538 |
|
|||
|
|
| `./im/keepalive.d.ts` | 声明/映射 | `042ca5b4943c` | 5015 | `—` | — |
|
|||
|
|
| `./im/keepalive.js` | 运行时 .js | `efb3963f4e40` | 6462 | `—` | — |
|
|||
|
|
| `./im/keepalive.js.map` | 声明/映射 | `31d8cc60d92e` | 4269 | `—` | — |
|
|||
|
|
| `./im/presence-ingest.d.ts` | 声明/映射 | `7ed47172720d` | 6641 | `—` | — |
|
|||
|
|
| `./im/presence-ingest.js` | 运行时 .js | `bb9e599f0b84` | 6607 | `—` | — |
|
|||
|
|
| `./im/presence-ingest.js.map` | 声明/映射 | `8eef921f5597` | 4701 | `—` | — |
|
|||
|
|
| `./supervisor/plugin-assembly.d.ts` | 声明/映射 | `e896c0c53bfb` | 13955 | `e0d3a15b8751` | 8762 |
|
|||
|
|
| `./supervisor/plugin-assembly.js.map` | 声明/映射 | `f3eb2523919c` | 13104 | `dc9aad3f62a4` | 10274 |
|
|||
|
|
| `./supervisor/remote-spawner.d.ts` | 声明/映射 | `589b9bca7a53` | 11968 | `85ed46970499` | 10372 |
|
|||
|
|
| `./supervisor/remote-spawner.js` | 运行时 .js | `269d3d20ffce` | 20564 | `bea5d38cdc3f` | 18525 |
|
|||
|
|
| `./supervisor/remote-spawner.js.map` | 声明/映射 | `218758f06bb5` | 11105 | `6ced34702565` | 10963 |
|
|||
|
|
| `./web/dsh-install.js` | 运行时 .js | `ce82eef48c4c` | 6628 | `f707c77e505f` | 8504 |
|
|||
|
|
| `./web/essential-plugins.js` | 运行时 .js | `9e79a5fd5665` | 6606 | `—` | — |
|
|||
|
|
| `./web/routes/admin.js` | 运行时 .js | `3c5a64cb1c4d` | 19066 | `e794cad96c90` | 18184 |
|
|||
|
|
| `./web/routes/business-plugins.d.ts` | 声明/映射 | `72fee3739477` | 5640 | `d50990983ad6` | 2944 |
|
|||
|
|
| `./web/routes/business-plugins.js` | 运行时 .js | `3a752e01e4f1` | 135308 | `70d5c0f2085a` | 114041 |
|
|||
|
|
| `./web/routes/business-plugins.js.map` | 声明/映射 | `d919d78e8a53` | 73109 | `545ed8c21cf2` | 59079 |
|
|||
|
|
| `./web/routes/im.js` | 运行时 .js | `14dd9a0cf7c9` | 36738 | `d6ee03187ca1` | 27355 |
|
|||
|
|
| `./web/routes/im.js.map` | 声明/映射 | `62d1cb88348e` | 22653 | `576a3c7f8ad6` | 18494 |
|
|||
|
|
| `./web/routes/plugin-data.js` | 运行时 .js | `fac8f4dfe0d5` | 15523 | `—` | — |
|
|||
|
|
| `./web/server.js` | 运行时 .js | `fcbbb9b34764` | 75298 | `c935e916d4fe` | 74822 |
|
|||
|
|
| `./worker/agent.d.ts` | 声明/映射 | `e8799f5b6d55` | 7275 | `9cd56a9a914e` | 3445 |
|
|||
|
|
| `./worker/agent.js.map` | 声明/映射 | `6a09bb376d7f` | 36616 | `2cf708d046f3` | 23514 |
|
|||
|
|
|
|||
|
|
> 完整 79 条原始清单(含两侧 md5/大小/mtime)= `tmp/p22-diff-pre.tsv`;补齐清单 = `tmp/p22-fill-list.txt`。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 三、判据② · 补齐与归零
|
|||
|
|
|
|||
|
|
### 3.1 动作与读数
|
|||
|
|
|
|||
|
|
| 步 | 动作 | 读数 |
|
|||
|
|
|---|---|---|
|
|||
|
|
| 1 | 106 全量备份(改前) | `/opt/dsh/backups/lib-p22/106-pre-p22-20260925-120615.tgz`(sha256 `9612e4c0f63e024db3a7aceaa3088c26474e886c67cdafd848c80a8eba739233`)+ 同目录改前指纹清单 `…-manifest-20260925-120615.tsv` |
|
|||
|
|
| 2 | 47 侧按清单打包 | `/tmp/p22-fill.tgz` = **232651 B** / 46 件,md5 `1ac3922cb3a3239a3f9d4cf59f7beb4f` |
|
|||
|
|
| 3 | 传输完整性 | 106 收到后 md5 **同为** `1ac3922cb3a3239a3f9d4cf59f7beb4f` ✅ |
|
|||
|
|
| 4 | 解包落地 | `tar xzf` rc=0;`lib` 文件数 **357 → 380**(+23 缺件);新建目录 `db/plugin-data`、`im/backends` 属主 **root:root 755** ✅(与既有目录一致) |
|
|||
|
|
| 5 | 复核 | 重采 106 全量清单 ⇒ **代码面 368 = 368、内容不同 0、单向缺失 0**,`p22-verify.py` **rc=0** |
|
|||
|
|
|
|||
|
|
### 3.2 基准成立性(为什么拿 47 当基准是对的)
|
|||
|
|
|
|||
|
|
- 47 = **Manager 现行运行单元**(`dshs.service` 起于 `09-25 11:47:33`)所加载的那份代码 ⇒ 生产口径。
|
|||
|
|
- 抽样验证 47 ≡ 本机构建产物 `D:/github/dsh_shenxian/lib`:`db/pg.js` `8f7923fb…`、`supervisor/remote-spawner.js` `269d3d20…`、`web/routes/business-plugins.js` `3a752e01…` **三件逐字一致**。
|
|||
|
|
- ⚠️ 但**本机构建产物 ≠ 生产部署面全等**(见 §五-2)⇒ 本棒的基准**只取 47 生产面**。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 四、判据③ · 106 待重启才生效的文件
|
|||
|
|
|
|||
|
|
### 4.1 106 的运行形态(现场取证)
|
|||
|
|
|
|||
|
|
- 单元:**只有 `dshs-worker.service`**(active,`ExecMainStartTimestamp = Fri 2026-09-25 09:52:11 CST`)+ `dshs-relay.service`;**⛔ 无 `dshs.service`**。
|
|||
|
|
- 入口:`ExecStart = /usr/bin/node /opt/dshs-cluster/lib/cli.js worker --port 19000 --host 127.0.0.1 --host-id w-106 …`。
|
|||
|
|
- ⚠️ 关键:`cli.js` **顶层静态 import** 了 `./db/index.js`(→ `./pg.js`、`./sqlite.js`)与 `./web/server.js`(静态 import **14 条 routes**)⇒ **web/db 层同样在 106 worker 的模块图内**(不是"106 用不到的库存")。
|
|||
|
|
|
|||
|
|
### 4.2 待重启清单
|
|||
|
|
|
|||
|
|
- **全部 46 件**(写入时刻 12:06+ **晚于** 进程启动 09:52:11)⇒ 进程内仍是旧版;**下次 `dshs-worker` 重启后才生效**。
|
|||
|
|
- 其中 **运行时 `.js` 21 件**(其余 25 件为 `.d.ts`/`.js.map`,不参与运行)。
|
|||
|
|
- **本棒改盘对运行中进程的行为影响 = 0**:ESM 静态图在启动时已全部求值并缓存,改盘不改变已加载模块。
|
|||
|
|
- ⚠️ **残留理论窗口**:`web/routes/admin.js`、`web/routes/dsh.js`、`web/plugin-compat*.js` 内存在**动态 `import()`** ⇒ 若某目标模块在重启前**首次**被动态加载,会读到新文件,与内存中旧模块并存。未观测到异常;47 上"同版本组合"已在跑 ⇒ 判**低风险**;彻底消除 = 重启(⛔ 待用户给窗口,见入口 §5-19)。
|
|||
|
|
- 📌 与 §5-19 **同源但不同事**:§5-19 说的是"p20 的 `plugin-assembly.js` 待重启";本棒补的是**另外 46 件**的待重启面。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 五、新发现(⛔ 本棒未动 · 已登记入口 §5)
|
|||
|
|
|
|||
|
|
### 5.1 106 落后面远大于第 21 棒顺带看到的那一件
|
|||
|
|
|
|||
|
|
第 21 棒只看到 `web/routes/business-plugins.js` 落后(`70d5c0f2…` / 114041 B / mtime `09-25 00:28`,而 47 为 `4109ba34…` 投前)。本棒全量核对:**代码面落后 46 件**,`business-plugins.js` 只是其中之一。该文件的落后 = **缺第 17 棒(可观测性 + `-w` 修)、第 19 棒(`essential` 标记)、第 21 棒(`reconcile` 口)三轮改动**。
|
|||
|
|
|
|||
|
|
### 5.2 🔴 本机构建产物 ≠ 生产部署面(后棒 ⛔ 别拿本机 `lib` 当基准)
|
|||
|
|
|
|||
|
|
`D:/github/dsh_shenxian/lib`(**09-25 11:44 新构建**)与两机部署面(09-23 20:59 的 IM 版)不同,且**两机缺的是同一批**(不是 106 独有):
|
|||
|
|
|
|||
|
|
| 类 | 件 | 本机 | 47 / 106 |
|
|||
|
|
|---|---|---|---|
|
|||
|
|
| 运行时 `.js` 内容不同 | `im/backends/gateway.js` | 16241 B | 12077 B |
|
|||
|
|
| 运行时 `.js` 内容不同 | `im/connection-backend.js` | 4154 B | 3342 B |
|
|||
|
|
| 运行时 `.js` 内容不同 | `web/routes/im.js` | 47262 B | 36738 B |
|
|||
|
|
| 本机独有 | `im/gateway-token.{js,d.ts,js.map}` | 7280 B(`.js`) | **两机都没有** |
|
|||
|
|
| 本机独有 | `web/essential-plugins.{d.ts,js.map}`、`web/routes/plugin-data.{d.ts,js.map}` | — | 两机只有 `.js` |
|
|||
|
|
|
|||
|
|
- 另有 31 件 `.d.ts`/`.js.map` 差异(本机构建与部署面构建不同次 ⇒ 声明/映射产物不同),**运行时 `.js` 不受影响**。
|
|||
|
|
- ⇒ 定性:本机 `lib` 含 **IM 线尚未投放的改动**(本机文件更大 + 多出新件)。**⛔ 本棒未据此改任何一侧**(超出"两机差异核对"范围;且那批件属 IM 线投放决定)。**已登记为待查项。**
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 六、未做 / 未闭合(⛔ 不得据本文宣称"运行面验收通过")
|
|||
|
|
|
|||
|
|
| # | 项 | 为什么没做 |
|
|||
|
|
|---|---|---|
|
|||
|
|
| 1 | **106 重启以使 46 件生效** | 中断在线用户 ⇒ **待用户给窗口**(同 §5-19) |
|
|||
|
|
| 2 | **运行面读数**(重启后 106 上实跑新代码) | 依赖第 1 项 ⇒ 本棒**只完成"文件面归零"**,⛔ 未验证运行面 |
|
|||
|
|
| 3 | 投本机独有 7 件(`im/gateway-token.*` 等) | 超出范围 + 属 IM 线未投放件 |
|
|||
|
|
| 4 | 清两侧 33 条备份残留 | 不可逆 + 别处部署面历史留档 ⇒ 只报告 |
|
|||
|
|
| 5 | 46 件在 106 上的**功能影响面**核对(哪几件 106 真的会用) | 已做模块图取证(`cli.js` → `db/index.js` + `web/server.js` 14 routes ⇒ 全在图内),未逐件做行为核对 |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 七、回滚
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# 106 回滚(恢复改前整棵 lib)
|
|||
|
|
cd /opt/dshs-cluster && tar xzf /opt/dsh/backups/lib-p22/106-pre-p22-20260925-120615.tgz
|
|||
|
|
# 或按需只回滚单件:从该 tgz 内取对应路径(题录:./db/pg.js 等,相对 lib 根)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
- 47 侧**零改动**(本棒只读 47,只写 106)。⛔ 未 commit / push;⛔ `src/web/routes/im.ts` 零改动;⛔ 未手改用户 `home` 下 profile / `.pnpm`。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 八、卫生
|
|||
|
|
|
|||
|
|
- 47 `/tmp/p22-fill.tgz`、106 `/tmp/p22-fill.tgz`、`/tmp/p22-lib106.tsv`:本棒临时件(入口 §9 口径:`tmp/` 留 7 天)。
|
|||
|
|
- 新建目录仅 `106:/opt/dsh/backups/lib-p22/`(备份)与工作区 `tmp/p22-*`。
|
|||
|
|
- 锁:本棒域锁(`aliyun-dsh-server/接续入口_插件投放与分库线_20260922.md`)收口时释放。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
*生成:`tmp/p22-report-gen.py`(表由清单现算,非手抄)。*
|