diff --git a/docs/deployment.md b/docs/deployment.md index bff888b6..6cfe70d9 100644 --- a/docs/deployment.md +++ b/docs/deployment.md @@ -512,7 +512,7 @@ investigate old denials must raise the retention before starting the restored server, not after. The write log's segments are trimmed the same way, against `[capacity] write_log_retention_days`. -**A restore does not recover four things, and each fails differently:** +**A restore does not recover five things, and each fails differently:** - **Sessions.** Every access and refresh token is in-process memory. A restore is a restart, so every signed-in client is logged out, and the failure is @@ -534,6 +534,16 @@ way, against `[capacity] write_log_retention_days`. to the issuer's rate limits on a name that has been issued repeatedly. - **Anything written since the snapshot.** Up to twenty-four hours of accounts and records. There is no point-in-time recovery here and no log shipping. +- **The position of `com.atproto.sync.subscribeRepos`.** The restart floor is + whatever the restored log carries, so the stream resumes below the numbers + the lost run handed out and issues those same numbers to different commits. + A relay holding a cursor from the lost run is not told: from the restored + server's side the numbers are new, and its repository heads are behind what + the relay already applied, so the next commit the relay does receive names a + `prev` it does not hold. **Reset every consumer of that stream after a + restore rather than letting it resume.** `/firehose` is not affected — its + cursor names the run that minted it, so a consumer of that one is told + `OutdatedCursor` and reads the repositories for the gap. **The restore drill.** Step 4 is the whole of it: a snapshot that attaches and mounts proves the filesystem, not the log.