diff --git a/cmd/storage-migrate/main.go b/cmd/storage-migrate/main.go index cfee408..39bc0c2 100644 --- a/cmd/storage-migrate/main.go +++ b/cmd/storage-migrate/main.go @@ -295,6 +295,8 @@ var copyOrder = []string{ "login_keys", // U1 I3:服务实例 DB 身份(无外键;迁移须保留以免目标库丢锚) "agent_system_identity", + // U8:活动服务锁的库内标记(无外键;迁移须保留以免目标库丢掉锁根) + "instance_guard", } const controlDDL = ` diff --git a/internal/instanceguard/guard_test.go b/internal/instanceguard/guard_test.go index 9c125cc..b2c1807 100644 --- a/internal/instanceguard/guard_test.go +++ b/internal/instanceguard/guard_test.go @@ -75,9 +75,32 @@ func TestDatabaseReplacementRefusedBeforeOpen(t *testing.T) { if err := os.Remove(db); err != nil { t.Fatal(err) } - if err := os.WriteFile(db, []byte("replaced"), 0o600); err != nil { + raw, err := os.ReadFile(db + ".lock") + if err != nil { t.Fatal(err) } + rec, err := parseRecord(string(raw)) + if err != nil || rec == nil { + t.Fatal(err) + } + for i := 0; i < 16; i++ { + if err := os.WriteFile(db, []byte("replaced"), 0o600); err != nil { + t.Fatal(err) + } + _, ino, exists, err := statFile(db) + if err != nil { + t.Fatal(err) + } + if exists && ino != rec.DBIno { + break + } + if err := os.Remove(db); err != nil { + t.Fatal(err) + } + if err := os.WriteFile(filepath.Join(dir, "inode-burn-"+string(rune('a'+i))), []byte("x"), 0o600); err != nil { + t.Fatal(err) + } + } lease, err := Acquire(dir) if err != nil { t.Fatal(err)