Repository navigation
[17.0-rc][疑似平台] os migrate apply 对运行中服务正在使用的 SQLite 库缺少占用检测 #526
Description
Activity
源码核实修正:migrate apply 确认全路径无占用检测,且 runtime.start() 在确认提示前就执行 schema-sync DDL;但原 issue 中「文件 inode 被替换」的猜测不成立——replace_unique_index 是纯索引 DDL,SQLite 列级重建也只在库内换表不换文件(sql-driver.ts:2816-2877),实际风险是 stale prepared statements / SQLITE_BUSY。已按修正后的事实上报平台:objectstack-ai/objectstack#3917
- added a commit that references this issue
on Jul 30, 2026 - addedupstream:objectstackBlocked on / caused by the ObjectStack platform — tracked upstreamBlocked on / caused by the ObjectStack platform — tracked upstream
on Aug 2, 2026 - added a commit that references this issue
on Aug 5, 2026 rc.2 retest: 已解除(occupancy detection + confirmation gate are both in place)
Retested on
@objectstack/*17.0.0-rc.2 (currentmain, commit 5a78f88), on an isolated dev server (port 4009, own DB file) so nothing shared was at risk. Full chain, each step observed:1.
migrate planagainst the live DB now warns up front:⚠ …/data.db is in use — it is open in pid 4468 (node) (data.db-wal, data.db-shm present). The plan below is still accurate — nothing is written — but "os migrate apply" will refuse until it is free (or you pass --force).2.
migrate apply --allow-destructiveagainst the live DB refuses before any DDL:→ Checking whether the database is in use… ✗ …/data.db is in use — it is open in pid 4468 (node) (data.db-wal, data.db-shm present). ⚠ Stop the process using it (a running "os dev"/"os serve" is the usual one) and re-run, or pass --force to migrate anyway.Verified nothing was written: the drift column I had planted (
crm_task.zz_orphan_probe, created directly in the disposable DB to have something to drop) was still present afterwards.3. Even with the server stopped, apply now demands explicit confirmation — rc.0's "DDL before confirmation" behaviour is gone:
⚠ Destructive changes assume your full app/plugin set is loaded. A column that looks "orphaned" here may belong to a plugin that is not part of this build. ⚠ Confirmation required. Re-run with --yes to apply, or use "os migrate plan" to preview.4. With the server stopped and
--yes:✓ Applied 1 change(s).and the probe column is gone.So both halves of this issue — no occupancy detection, and DDL issued before confirmation — are fixed, with an explicit
--forceescape hatch for the intentional case. Upstream objectstack#3917's remedy is present in the rc.2 CLI.One residual nit, recorded here rather than filed: the occupied-DB refusal exits with code 0. A CI script doing
os migrate apply && deploywould treat the refusal as success and deploy against an unmigrated schema. Worth a follow-up if the owner agrees; it is a much smaller defect than the one this issue tracked.Recommend closing after owner confirmation (this run's mandate is test-don't-fix, so I'm reporting rather than closing).
Generated by Claude Code
[17.0-rc2验收复核] 结论:已不复现(占用检测 + 拒绝执行均在;且拒绝以非零码退出)
证据:对本组自己的 scratch 库(dev server 运行中,WAL/SHM 在盘)实测:
# plan:预警但照常出计划(只读) pnpm exec objectstack migrate plan --database-url file:…/a1/data.db → ⚠ …/a1/data.db is in use — it is open in pid 9372 (node) (data.db-wal, data.db-shm present). The plan below is still accurate — nothing is written — but "os migrate apply" will refuse until it is free (or you pass --force). # apply:执行前拒绝 pnpm exec objectstack migrate apply --database-url file:…/a1/data.db → → Checking whether the database is in use… ✗ …/a1/data.db is in use — it is open in pid 9372 (node) … ⚠ Stop the process using it … or pass --force to migrate anyway. 退出码 = 1控制组:向该库故意
ALTER TABLE crm_task ADD COLUMN zz_a1_probe后,plan 正确判✗ crm_task.zz_a1_probe [drop_column](destructive)——即上面的干净结论出自活着的检测器;拒绝路径确认未写任何 DDL(探针列复查仍在,测毕已删)。一处与今晨复测(5a78f88)的差异,记录以免误传:该次记录「occupied-DB 拒绝 exit code 0」;本组在 0899b4f 上经
pnpm exec实测退出码为 1(echo $?直接取得)。CI 场景apply && deploy不会误判成功。停服 +--yes的确认门本组未复测(服务器需继续供其余项使用),今晨复测已单独验证过该半。环境:hotcrm@0899b4f + @objectstack 17.0.0-rc.2
建议:前提已过时建议关闭(objectstack#3917 的补救在 rc.2 CLI 确认存在)。
Generated by Claude Code
Closing — provenance
Closed as part of the GA close-out bookkeeping sweep (#1151, group 3), on the recorded on-card evidence below. No new probe was run; this is a bookkeeping close of a reading already taken.
(a) Version.
@objectstack/*17.0.0-rc.2 — read twice: once at repo commit5a78f88on an isolated dev server (port 4009, own DB file), once independently athotcrm@0899b4fagainst a scratch DB.(b) Probe.
os migrate planandos migrate applyrun against a SQLite database held open by a live dev server (WAL/SHM present on disk), with a deliberately planted drift column as the control:pnpm exec objectstack migrate plan --database-url file:…/data.db pnpm exec objectstack migrate apply --database-url file:…/data.db ALTER TABLE crm_task ADD COLUMN zz_a1_probe (control: gives the planner something real to find)(c) Result. Both halves of this card are fixed, and the
--forceescape hatch exists for the intentional case:- Occupancy detection exists.
planwarns up front — "…data.db is in use — it is open in pid 4468 (node) (data.db-wal, data.db-shm present)" — while still producing an accurate read-only plan. applyrefuses before any DDL, with "→ Checking whether the database is in use…" then "✗ …is in use… Stop the process using it… or pass --force to migrate anyway." Verified nothing was written: the planted probe column was still present afterwards.- The rc.0 "DDL before confirmation" behaviour is also gone — even with the server stopped,
applydemands--yesbefore applying; with--yesit reports✓ Applied 1 change(s).and the probe column is dropped. - The control group confirms the detector is alive rather than vacuous: with the probe column planted,
plancorrectly classifies✗ crm_task.zz_a1_probe [drop_column]as destructive.
Upstream objectstack#3917's remedy is present in the rc.2 CLI.
(d) Source comments.
- [17.0-rc][疑似平台] os migrate apply 对运行中服务正在使用的 SQLite 库缺少占用检测 #526 (comment) (isolated server at
5a78f88; full four-step chain) - [17.0-rc][疑似平台] os migrate apply 对运行中服务正在使用的 SQLite 库缺少占用检测 #526 (comment) (independent re-read at
0899b4f)
Both readings recommend closing.
(e) Authority. #1150, on maintainer ruling 2026-08-14 (verbatim 「同意」); dispatched as #1151 group 3.
One recorded disagreement between the two readings, resolved
The first reading flagged a residual: "the occupied-DB refusal exits with code 0", which would let a CI
apply && deploytreat a refusal as success. The second reading measured the exit code directly (echo $?afterpnpm exec) and got 1. The later, more direct measurement stands — the CI hazard does not exist. Recording it here so the first comment's nit is not carried forward as an open item.The confirmation gate with the server stopped (
--yes) was verified by the first reading only; the second did not re-run it because its server had to stay up for other work. That half is single-sourced but unambiguous.
Generated by Claude Code
Generated by Claude Code
- Occupancy detection exists.
- addedpriority:p2Medium: important, M3Medium: important, M3and removed
on Sep 9, 2026
现象
dev server 正在使用某个 SQLite 库时,对同一库执行
os migrate apply(含 replace_unique_index 等重建型变更)没有任何占用告警或拒绝。CLI 与运行中服务并发改库存在文件被替换/状态分叉的风险(本次测试未实际复现数据损坏,属预防性反馈)。建议 CLI 检测库被占用时给出警告或要求 --force。
详见分支
upgrade/objectstack-17的 docs/upgrade-17/test-report.md §3 P7。