Files
gold_land_server/docs/restore-production-db.md
T

74 lines
2.5 KiB
Markdown
Raw Normal View History

# Restore SQLite onto the live database path
The restore script **refuses to write directly** to the path in `DB_PATH` while that variable still points at the live file. That avoids accidental overwrite with the service running.
`RESTORE_ACK_STOPPED=YES` is an **operator acknowledgment** only — the script does **not** detect whether the backend process is stopped. You must stop the service yourself before swapping files.
## Prerequisites
- Backend **stopped** (no open handles on `app.db`, `-wal`, `-shm`).
- A validated backup from `npm run backup:sqlite` (WAL-safe, schema-checked).
- Shell access to the data directory (host path or mounted volume).
## Recommended procedure (same logical database)
Replace `/app/data/app.db` with your paths.
1. **Stop backend**
```powershell
docker compose stop backend
# or: stop the Node process / systemd unit
```
2. **Optional safety backup of current file**
```powershell
$env:DB_PATH = "/app/data/app.db"
$env:BACKUP_DIR = "./backups"
npm run backup:sqlite
```
3. **Restore to a sibling file** (not the live `DB_PATH` target)
```powershell
npm run restore:sqlite -- ./backups/app-2026-01-01T12-00-00.db /app/data/app-restored.db
```
Use `RESTORE_ACK_STOPPED=YES` if `/app/data/app-restored.db` already exists from a prior attempt.
4. **Verify** (optional second check)
```powershell
node -e "import('./scripts/sqlite-app-schema.mjs').then(m=>console.log(m.validateAppSqliteFile('/app/data/app-restored.db')))"
```
5. **Swap files** (preserve previous DB on disk)
```powershell
mv /app/data/app.db /app/data/app.db.pre-restore-<timestamp>
rm -f /app/data/app.db-wal /app/data/app.db-shm
mv /app/data/app-restored.db /app/data/app.db
```
6. **Start backend** and check readiness
```powershell
docker compose start backend
curl http://127.0.0.1:<frontend-port>/health/ready
```
## What the script enforces
| Rule | Meaning |
|------|---------|
| No restore when `target === DB_PATH` | Use a sibling path, then rename after stop |
| `RESTORE_ACK_STOPPED=YES` if target exists | Confirms you intend to overwrite an existing file |
| Schema + `integrity_check` | Backup must match app migrations |
| Failed validation | Staging removed; live file unchanged |
| Existing target | Moved to `*.pre-restore-<timestamp>.bak` before replace |
## Development
Restoring to a **new temp path** does not require stopping production. See `npm run restore:sqlite -- backup.db ./tmp/restored.db`.