完成真实成对异机备份(07-26-internal-ops-recovery-baseline)
ci-e2e / e2e (push) Waiting to run
ci-minimal / check-minimal (push) Waiting to run

这个提交包含在:
2026-07-26 21:47:44 +08:00
父节点 7658051321
当前提交 9a624700d0
共修改 8 个文件,包含 133 行新增和 13 行删除
@@ -530,6 +530,8 @@ bash scripts/qa/run-local-candidate.sh full
- Paired backup: `DB_TOOL_MODE=docker DB_CONTAINER=<name> ./scripts/backup-all.sh`.
- Optional safe batch identifier: `BACKUP_RUN_ID=<safe-id>`.
- Manifest writer: host `node` is preferred; host `python3` is an equivalent
fallback for Docker-only runtime machines.
- DB shadow restore requires `RESTORE_SCOPE=shadow`,
`RESTORE_CONFIRM_DATABASE=<actual-current-database>` and `DATABASE_URL`.
- Storage shadow restore:
@@ -543,6 +545,13 @@ bash scripts/qa/run-local-candidate.sh full
- A complete recovery point is one batch directory containing `database.dump`,
`storage.tar.gz` and a final `manifest.json`. The manifest contains only safe
relative names, byte sizes, SHA-256 hashes, batch time and optional build SHA.
- Manifest generation uses exclusive creation and preserves the same schema
under Node and Python 3; if neither runtime exists, fail before publishing the
final batch directory.
- For an approved live backup, do not assume the deployment `.env` still matches
the running database. Confirm that the selected PostgreSQL container's database
and user match at least one active application `DATABASE_URL`, then pass the
verified runtime values without logging their contents.
- The DB dump must pass `pg_restore --list` and the storage archive must pass
`tar -tzf` before the manifest may say `complete`.
- DB restore queries `current_database()` and compares it exactly with
@@ -571,13 +580,22 @@ bash scripts/qa/run-local-candidate.sh full
- Corrupt dump/tar or dangerous/link archive member -> fail before restore.
- Host PostgreSQL tools mismatch in `auto` mode -> docker fallback is allowed
only when the explicit target container and required DB variables exist.
- Neither Node nor Python 3 is available -> fail manifest generation and remove
the temporary batch; do not publish a partial recovery point.
- Deployment `.env`, PostgreSQL container and active application connection do
not identify the same database/user -> stop the live backup; never guess
credentials or expose values in diagnostics.
### 5. Good/Base/Bad Cases
- Good: one command creates a validated pair, the complete batch is copied off
host, and a disposable shadow drill restores the DB marker and attachment hash.
- Good: a Docker-only host uses Python 3 to write the same manifest contract
after the active application connection is matched to the database container.
- Base: backup succeeds locally but off-host copy and deployed `/ready` evidence
remain explicitly pending; do not claim formal recovery readiness.
- Bad: source a stale deployment `.env` and treat a failed dump as a prompt to
guess or print credentials.
- Bad: source the active trial `.env` and run a cleaning restore directly, or
restore attachments into a non-empty live directory.
@@ -589,6 +607,8 @@ bash scripts/qa/run-local-candidate.sh full
target and dangerous tar path.
- Validate manifest relative paths, absence of connection secrets and matching
SHA-256 values.
- Run the synthetic drill with Node available and with a `PATH` that excludes
Node but includes Python 3; both paths must complete the same round trip.
- Real-instance restore and `/ready` remain separately approved evidence and
must never be fabricated from the local drill.
@@ -598,6 +618,7 @@ bash scripts/qa/run-local-candidate.sh full
```bash
source deploy/trialrun/.env
./scripts/backup-all.sh
./scripts/restore-db.sh some.dump
./scripts/restore-storage.sh some.tar.gz deploy/trialrun/data/storage
```
@@ -606,5 +627,8 @@ source deploy/trialrun/.env
```bash
./scripts/qa/run-backup-restore-drill.sh
# Before an approved live backup, compare the selected DB container identity
# with an active app connection using redacted boolean diagnostics.
DB_TOOL_MODE=docker DB_CONTAINER=<verified-container> ./scripts/backup-all.sh
# Real restore remains an approved incident operation after shadow evidence.
```