- Tools/Manual-Tools.md: fallback_state_reset.sh marked not yet built; manual workaround added; TOC entry updated; failover→fallback rename throughout - Watchdogs/Manual-Watchdogs.md: System Watchdog config block updated — remove pre-split vars (MEM_WARN_GB, MEM_SHUTDOWN_GB, MEM_GB, MEM_RECOVER_GB, SYS_WATCHDOG_MEM_SHUTDOWN_EXCLUDED, SYS_WATCHDOG_REQUIRED_CONTAINERS); add SYS_WATCHDOG_MEM_GB (reboot trigger only); fix state file path names (watchdog_state.db → container_watchdog_state.db, sys_watchdog_state.db → system_watchdog_state.db) - Orchestrators/README-Orchestrators.md: add monthly_maintenance.sh section with two-gate model, configuration reference, and usage examples - Monitors/README-Monitors.md: add mesh_monitor.sh to both tables and diagram - Monitors/Manual-Monitors.md: add mesh_monitor.sh section - README-User_Script_Plug-in.md, Rsync/README-Rsync.md, Rsync/Manual-Rsync.md, README.md: emby-failover → emby-fallback (missed from prior batch)
7.5 KiB
━━━━━ RSYNC ━━━━━
The transfer engine for the two-server ecosystem. rsync.sh is the single script
called by every orchestrator that moves data between servers — it handles profiles,
pre-flight checks, container stops, the actual transfer, and bandwidth logging.
Orchestrators decide what to sync and when. rsync.sh decides how to do it safely.
Never schedule rsync.sh directly for daily/weekly syncs. Use the orchestrators in
Orchestrators/. rsync.sh is called directly only for manual runs and the 30-minute Emby dirty sync, which needs its own cron entry.
━━━ THE PROBLEM THAT BUILT THIS ━━━
rsync Alone Isn't Safe Enough for Live Databases
Running rsync against a share while SQLite databases are being written produces
corrupt snapshots on the remote. The arr databases, Emby library database, and
Authelia session store all write continuously. A plain rsync copies them mid-write.
The remote gets a file that opens cleanly but has internal inconsistencies.
Fix: profiles stop specific containers before syncing and restart them after.
The database is quiesced, rsync runs against a static snapshot, containers come back up.
Each Share Needs Different Behavior
Media shares (Movies, TV) just spread files — nothing stops, no --delete
(arr cleanup scripts own deletions, and arr_sync ensures both arrs already
track incoming files before they arrive). Arr databases need containers stopped,
clean SQLite snapshot, restart. Emby has two modes: weekly full-stop clean mirror
and 30-minute dirty sync while Emby stays running (WAL files excluded). Critical-Data
stops the auth stack, waits for Authelia to come back after restart delay.
Fix: the profile system — one script, behavior defined entirely by the profile key.
A Failed Remote Shouldn't Corrupt a Live Sync
If the remote's rootfs is nearly full, an rsync that starts will write partial files
then fail mid-transfer, leaving the remote in a worse state than before. If the remote's
backing disks are offline, rsync writes to an empty mount point and "succeeds."
Fix: pre-flight checks abort before touching anything if remote conditions are wrong.
━━━ WHAT THIS FOLDER DOES ━━━
One script. One job: move data from this server to the remote safely.
rsync.sh handles the full transfer lifecycle:
- Infer or accept a profile for the given directory
- Run pre-flight checks (connectivity, rootfs, disk temps, remote share exists)
- Stop containers specified by the profile (both sides)
- Run rsync with profile flags, excludes, and bandwidth limit
- Restart containers (with delay if configured)
- Restart remote containers if dirty-sync profile specifies it
- Log the transfer to bandwidth_monitor.sh
Everything else — deciding which shares to sync, in what order, on what schedule — lives in the orchestrators.
━━━ RELATIONSHIP TO OTHER FOLDERS ━━━
Media/
arr_sync.sh ── runs before rsync in daily window ──────────► all arrs agree on library
↓
Orchestrators/ ← decides what to sync, when, and in what order
daily_sync_maintenance.sh ──────────────────────────────────► rsync.sh (per share)
weekly_sync_maintenance.sh ──────────────────────────────────► rsync.sh (emby, critical-data)
critical_sync_maintenance.sh ────────────────────────────────► rsync.sh (partnership shares)
Cron (direct):
*/30 * * * * ──────────────────────────────────► rsync.sh --profile=emby-fallback
Monitors/
bandwidth_monitor.sh ◄─── called by rsync.sh after each sync (--log-transfer)
Fallback/
fallback.sh ──── rsync writeback during handback ──► rsync.sh
rsync.sh never calls other scripts except bandwidth_monitor.sh at the end of a sync.
All orchestration logic lives in the callers. arr_sync.sh (Media/) is a peer that runs
before rsync in the daily window — it is not called by rsync.sh directly.
━━━ THE PROFILE SYSTEM ━━━
Profile key = directory basename lowercased. --profile=name overrides.
| Profile | What It Syncs | Containers Stopped | Notes |
|---|---|---|---|
| (none) | Media shares (Movies, TV, Music…) | None | Bidirectional spread — no --delete in DEFAULT_RSYNC_OPTS. Arr cleanup scripts own deletions. |
arrs_stack |
Arr databases | Sonarr, Radarr, Lidarr, Prowlarr, Bazarr, Pinchflat | Clean SQLite snapshot |
critical-data |
Auth stack | Mariadb-Authelia, Redis-Authelia, NPM, Lldap | Authelia has restart delay |
important-data |
NextCloud + Postgres | Postgres-NextCloud | NextCloud has restart delay |
emby |
Full Emby mirror | Emby (both sides) | Weekly — Sunday 2:30am |
emby-fallback |
Emby watch state delta | None | Dirty sync — Emby stays running |
For full profile definitions see Manual-Rsync.md.
━━━ SCRIPTS IN THIS FOLDER ━━━
| Script | Role | When It Runs |
|---|---|---|
rsync.sh |
Core transfer engine — profile resolution, pre-flights, container management, transfer, bandwidth logging | Called by orchestrators; directly for manual and 30-min Emby dirty sync |
━━━ HOW THE SCRIPTS RELATE ━━━
Callers (Orchestrators/) ──────────────────────────────────────────────────────
daily_sync_maintenance.sh │
weekly_sync_maintenance.sh rsync.sh /path/to/share [--profile=name] │
critical_sync_maintenance.sh ─────────────────────────────────────────────► │
fallback.sh (writeback) │
Direct cron (emby-fallback) │
▼
┌─────────────────────────────────────┐
│ 1. Infer/accept profile │
│ 2. Pre-flight checks │
│ - connectivity │
│ - rootfs / disk temp / disks │
│ - remote share exists │
│ 3. Stop containers (profile) │
│ 4. rsync transfer │
│ 5. Restart containers │
│ 6. Remote restart (dirty sync) │
│ 7. Log to bandwidth_monitor.sh │
└─────────────────────────────────────┘