Skip to content

Backup & Restore

Harish Dhanraj Sugandhi edited this page Mar 4, 2026 · 1 revision

Backup & Restore

OpenWP creates full SQL database snapshots before high-risk action execution, providing rollback capability.

Architecture

Component File Purpose
Backup_Service inc/Backup/Backup_Service.php Create, restore, list, cleanup
Backup_Repository inc/Backup/Backup_Repository.php Database CRUD for backup records
BackupServiceInterface inc/Backup/BackupServiceInterface.php Interface contract

When Backups Are Created

Backups are automatically created when:

  1. An action has requires_backup: true (set during registration)
  2. A mutating action has high or critical risk level (auto-elevated by PolicyEngine)
  3. An MCP admin tool is called via mcp_admin_tool bridge

Backup Creation Flow

Action_Executor detects requires_backup
    │
    ▼
Backup_Service::create($user_id, $reason)
    │
    ├── 1. Create backup directory (wp-content/uploads/openwp-backups/)
    ├── 2. Generate unique filename: openwp-{date}-{random}.sql
    ├── 3. Write full SQL dump:
    │       ├── SET FOREIGN_KEY_CHECKS=0
    │       ├── For each table:
    │       │   ├── DROP TABLE IF EXISTS
    │       │   ├── CREATE TABLE (from SHOW CREATE TABLE)
    │       │   └── INSERT INTO (all rows)
    │       └── SET FOREIGN_KEY_CHECKS=1
    ├── 4. Compress to .sql.gz (gzencode, level 6)
    ├── 5. Delete uncompressed .sql
    ├── 6. Compute SHA-256 checksum
    ├── 7. Calculate expiration (log_retention_days setting)
    └── 8. Insert backup record into openwp_backups table

Backup Restoration

Backup_Service::restore($backup_id)
    │
    ├── 1. Load backup record from database
    ├── 2. Verify file exists on disk
    ├── 3. Verify SHA-256 checksum matches stored checksum
    ├── 4. Decompress gzip content
    ├── 5. Split into individual SQL statements
    ├── 6. Execute each statement sequentially
    └── 7. Return count of executed statements

Safety Checks

  • File existence verification
  • Checksum integrity verification (SHA-256)
  • Empty backup detection
  • Statement-by-statement execution with error detection

Cleanup

Expired backups are cleaned up hourly via the openwp_cleanup_backups cron hook:

Backup_Service::cleanup_expired_backups()
    ├── Find backups where expires_at < now()
    ├── Delete physical .sql.gz files
    └── Delete database records

Default retention is controlled by the log_retention_days setting (default: 90 days).

Storage

Backups are stored in: wp-content/uploads/openwp-backups/

Filename pattern: openwp-{YYYYMMDD}-{HHmmss}-{random8}.sql.gz

API Endpoints

Method Endpoint Description
GET /openwp/v1/backups List backups with pagination
POST /openwp/v1/backups/{id}/restore Restore a backup
DELETE /openwp/v1/backups/{id} Delete a backup

Rollback Service

Separate from full backups, the Rollback_Service (inc/Logs/Rollback_Service.php) handles per-action rollbacks using rollback_snapshot data stored in the logs table. This allows reverting individual actions without a full database restore.

Clone this wiki locally