health: 사본이 호스트를 벗어나지 못했으면 백업 행은 ok 가 아니다 - #39
Merged
Conversation
지난주 들어온 일일 백업 cron 은 스냅샷을 뜨고 PRAGMA integrity_check 로 "이 파일이 실제로 복원되는가"까지 확인한다. 그 두 질문에는 답하지만 세 번째 질문에는 답하지 않는다 — 이 호스트의 디스크가 아닌 곳에 사본이 있는가. 스냅샷은 ~/backups/alpha 에 떨어지고 그건 원본 DB 와 같은 볼륨이다 (프로덕션 실측: 원본 /home/atrn/data/moss_land.sqlite 와 사본 6개 모두 /dev/mapper/ubuntu--vg-ubuntu--lv). BACKUP_REMOTE 는 설정돼 있지 않다. 그런데 /api/health 의 db_backup 행은 ok 였다. 디스크 하나 죽으면 원본과 백업이 같이 사라지는 상태에 대해서. 이건 trackable_calls 가 95일 무산출 동안 ok 를 보고하던 것과 같은 모양이고, 그때와 같은 방식으로 고친다: heartbeat 판정 위에 두 번째 의견을 얹는다. - scripts/backup-db.ts 가 heartbeat note 앞에 offhost=none|ok|fail 을 적는다. - lib/health.ts 의 applyOffHostGap 이 그 토큰만 읽고 none 이면 warn 으로 내린다. - 토큰은 lib/cron-heartbeat.ts 에 둔다. 쓰는 쪽과 읽는 쪽이 각자의 문자열 리터럴로 갈라지면 이 행은 조용히 ok 로 돌아간다. warn 에서 멈추고 fail 로 가지 않는다. cron 자체는 건강하고, ?strict=1 이 설정 공백을 503 으로 바꾸면 안 된다. 다만 ok 는 과장이었다. 토큰이 없는 옛 heartbeat 는 건드리지 않는다 — 토큰의 부재가 사본의 부재를 뜻하지는 않으므로 추측하지 않고, 다음 03:00 실행이 사실을 채운다. 오프호스트 목적지 자체는 이 커밋의 범위가 아니다. Alpha 는 Signal 로 흡수될 예정이라, 무엇을 이관하고 무엇을 폐기할지 목록이 먼저 나와야 백업 대상이 DB 전체인지 테이블 두어 개인지 정해진다. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
무엇
/api/health의db_backup행이 off-host 사본이 없는 상태를ok로 보고하던 것을warn으로 내린다.왜
지난주 들어온 일일 백업 cron 은 두 가지에 답한다 — cron 이 돌았는가(heartbeat), 이 파일이 실제로 복원되는가(
PRAGMA integrity_check). 세 번째 질문에는 답하지 않는다: 이 호스트의 디스크가 아닌 곳에 사본이 있는가.프로덕션 실측 (2026-08-26, 읽기 전용):
디스크 하나가 죽으면 원본과 백업이 같이 사라진다. 그 상태에 대해 화면은
ok였다.scripts/backup-db.ts의 헤더 주석이 스스로 적어둔 문장이 정확하다 — "그건 백업이 아니라 실행 취소다."이건
trackable_calls가 95일 무산출 동안ok를 보고하던 것과 같은 모양이고,applyContentStaleness가 그때 쓴 방식(heartbeat 판정 위에 두 번째 의견을 얹는다)을 그대로 따른다.어떻게
scripts/backup-db.ts가 heartbeat note 맨 앞에offhost=none|ok|fail을 적는다.lib/health.ts의applyOffHostGap이 그 토큰만 읽고none이면warn으로 내린다.lib/cron-heartbeat.ts에 둔다 — heartbeat note 규약이 사는 곳이고, 쓰는 쪽과 읽는 쪽이 각자의 문자열 리터럴로 갈라지면 이 행은 조용히ok로 돌아간다.tests/offhost.test.ts가 그 드리프트를 막는다.warn에서 멈추고fail로 가지 않는다. cron 자체는 건강하고,?strict=1이 설정 공백을 503 으로 바꾸면 안 된다. 다만ok는 과장이었다.토큰이 없는 옛 heartbeat 는 건드리지 않는다. 토큰의 부재가 사본의 부재를 뜻하지는 않으므로 추측하지 않고, 다음 03:00 실행이 사실을 채운다.
검증
getSystemHealth()를 임시 DB 로 직접 돌린 결과:offhost=none · …offhost=ok · …pnpm typecheck통과 ·pnpm test28/28 통과 (신규 4) ·pnpm buildexit 0.범위 밖
오프호스트 목적지를 설정하는 것. Alpha 는 Signal 로 흡수될 예정이라, 무엇을 이관하고 무엇을 폐기할지 목록이 먼저 나와야 백업 대상이 DB 전체인지 테이블 두어 개인지 정해진다 — 통폐합 문서 §5.5 는 콜 원장을 '없앨 것' 첫 줄에 적어두었다. 이 PR 은 그 결정을 기다리는 동안 화면이 거짓말을 하지 않게만 한다.
참고로 rsync 경로(
BACKUP_REMOTE)는 공짜가 아니다 — writer 는 Lightsail 로 ssh 가 안 되고(키 없음, 테일넷에도 없음) 키 배포부터 필요하다. 같은 박스의 signalmap 은 rclone 으로 S3 에 밀고 있고(~/bin/rclone,[sm-backup], 마지막 성공 2026-08-25T22:04Z) 자격증명이 이미 작동한다.🤖 Generated with Claude Code