Scheduled Postgres backup, restore check, backup warnings in health, payment result logging

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-08 17:32:06 +03:30
parent a5feee053a
commit 7d81d193bd
11 changed files with 449 additions and 5 deletions

View File

@@ -72,9 +72,27 @@ curl -i https://mathapi.tadrisino2.ir/api/health
## بکاپ و بازیابی
دیتابیسِ سرور Postgres است (cluster جدای `zareian`، پورت ۵۴۴۰، فقط localhost؛ راهنمای کامل: `گزارش-۲۹/راهنمای-Postgres-و-Redis.html`). `deploy.sh` پیش از `migrate`
با `pg_dump -Fc` بکاپ می‌گیرد (`.deploy-backups/db-before-deploy-<زمان>.pgdump`، ۲ تای آخر) و اگر بکاپ نشد migrate را اجرا نمی‌کند. بازیابی از آن روی دیتابیسِ جدا آزموده نشده.
بکاپ روی همان ماشین است؛ نسخه‌ی بیرون از ماشین هنوز نیست. بدون `DB_NAME` برنامه روی `db.sqlite3` (فقط توسعه‌ی محلی) می‌ماند. بکاپِ دستیِ SQLite (توسعه‌ی محلی):
دیتابیسِ سرور Postgres است (cluster جدای `zareian`، پورت ۵۴۴۰، فقط localhost؛ راهنمای کامل: `گزارش-۲۹/راهنمای-Postgres-و-Redis.html`). سه لایه:
| لایه | چه زمانی | نگه‌داری | کجا |
|---|---|---|---|
| پیش از migrate | هر `./deploy.sh` (`pg_dump -Fc`؛ اگر نشد migrate اجرا نمی‌شود) | ۲ تای آخر | `.deploy-backups/db-before-deploy-*.pgdump` |
| روزانه | cron: `python manage.py backup_db` (`statuslog/backup.py`) | ۷ روزِ آخر + ۴ هفته‌ی آخر | `.deploy-backups/scheduled/` + `status.json` |
| بیرونِ ماشین | همان فرمان، اگر `BACKUP_OFFSITE_CMD` در `.env` باشد (فرمانی با `{file}`، مثلاً rsync/scp/rclone) | دست‌ِ مقصد | مقصد را ادمین تعیین می‌کند؛ تا تعیین نشده `/api/health` هشدار می‌دهد |
نصبِ بکاپِ شبانه (یک بار، با `crontab -e` حسابِ `administrator`؛ بکاپِ crontab را پیش از ویرایش بگیرید):
```
15 2 * * * cd /home/administrator/mathapp-v2 && venv/bin/python manage.py backup_db >> .deploy-backups/scheduled/cron.log 2>&1
```
**آزمونِ بازیابی (ماهی یک بار، و پس از هر تغییرِ بکاپ):** `venv/bin/python manage.py backup_verify` آخرین بکاپ را روی دیتابیسِ آزمایشیِ `<DB_NAME>_restorecheck` برمی‌گرداند، شمارشِ کاربر/ورود/سفارش/تراکنش/لاگِ وضعیت را با لحظه‌ی بکاپ می‌سنجد و آن دیتابیس را می‌اندازد؛ به دیتابیسِ اصلی دست نمی‌زند. نقشِ برنامه باید `CREATEDB` داشته باشد (`ALTER ROLE zareian_app CREATEDB;` با ادمینِ Postgres). فایلِ دست‌خورده را با هش رد می‌کند.
**بازیابیِ واقعی** (دیتابیسِ اصلی خراب شد): `sudo systemctl stop zareian-mathapp` ← از دیتابیسِ فعلی یک `pg_dump` دیگر بگیرید ← `dropdb`/`createdb` ← `pg_restore --no-owner -d zareian_mathapp <فایل>` ← `start` ← `/api/health`. سفارش‌های بعد از زمانِ بکاپ را با پنلِ زرین‌پال/بازار تطبیق دهید.
آزموده‌شده: بکاپ، نگه‌داری، بازیابی و رد‌شدنِ فایلِ خراب روی Postgresِ لپ‌تاپ. آزموده‌نشده: زیر cron روی سرور، دیسکِ نزدیک به پُر، `BACKUP_OFFSITE_CMD` واقعی.
بکاپِ دستیِ SQLite (توسعه‌ی محلی):
```bash