diff --git a/docs/recovery/u8-sqlite-instance-guard.md b/docs/recovery/u8-sqlite-instance-guard.md index 52a4936a..7b78b808 100644 --- a/docs/recovery/u8-sqlite-instance-guard.md +++ b/docs/recovery/u8-sqlite-instance-guard.md @@ -11,7 +11,7 @@ | 规则 | 行为 | |---|---| | 路径 | 先 `Abs`,已存在的路径再 `EvalSymlinks`。数据库文件若是符号链接,锁放在解析后的真实文件旁边 | -| 锁文件 | `.lock`(默认名 `agent-system.db.lock`)。`O_RDWR\|O_CREAT\|O_CLOEXEC`,模式 0600。永不 unlink | +| 锁文件 | `.lock`。`O_RDWR\|O_CREAT\|O_CLOEXEC\|O_NOFOLLOW`,模式 0600。永不 unlink。数据目录不存在时,活动服务在取锁前创建该目录 | | 互斥 | `flock(LOCK_EX\|LOCK_NB)`。占用返回「活动服务已在运行」,调用方不得打开库 | | 替换检测 | 取锁后比较 fd 与路径的 device/inode,不一致则关闭并重试,仍不一致则拒绝 | | 硬链接 | 解析后的数据库 `nlink>1` 直接拒绝,不能用 adopt 绕过 | @@ -33,7 +33,9 @@ svc 的 `runtime//.start.lock` 只串行化脚本生命周期,挡不住 `instance_id` 取 `AGENT_SYSTEM_INSTANCE_ID`。表和锁文件都已有非空值且与本次不一致时拒绝。本次为空则不比较,保留表内原值。 -显式 `--adopt-instance-guard`(仅 `serve` 与 `migrate`)在已持锁的前提下重写两边记录。硬链接拒绝不受该标志影响。 +显式 `--adopt-instance-guard`(仅 `serve` 与 `migrate`)在已持锁的前提下重写两边记录。它只接受「数据库文件还在但 inode 已变」和「锁记录损坏」。记录还在而数据库文件消失时,adopt 也不打开、不新建空库。锁文件若是指向数据库的符号链接,或与数据库同一 inode,直接拒绝且不写入。硬链接拒绝不受该标志影响。 + +身份校验在写入守卫之前完成。`AGENT_SYSTEM_INSTANCE_ID` 已设置但与库内身份不符时,不留下本次的 instance id。 ## 3. 耐久 diff --git a/modules/backend b/modules/backend index 89acd16c..1f7bcac6 160000 --- a/modules/backend +++ b/modules/backend @@ -1 +1 @@ -Subproject commit 89acd16ca5c46e4a2d2fc58f9e598dccf55be65c +Subproject commit 1f7bcac6e0b4d9df1f5b601a755c4de7da65ba6a