Hourly Backup Addon
Premium hourly backup solution with advanced features and real-time protection
Hourly Backup Addon
Experience premium backup protection with our Hourly Backup Addon. Get real-time backup capabilities, advanced monitoring, and enterprise-grade features for maximum data protection.
Premium Features Overview
Real-Time Backup
- Instant Protection: Backup changes as they happen
- Continuous Monitoring: Never lose recent work
- Version Control: Multiple versions per hour
- Granular Recovery: Restore to specific moments
Advanced Scheduling
- Custom Intervals: Set backup frequency from minutes to hours
- Smart Scheduling: Avoid peak traffic periods automatically
- Priority Queuing: Manage backup job priorities
- Resource Optimization: Balance backup frequency with server resources
Setup and Configuration
Enable Hourly Backup
// Enable hourly backup addon
define('HOURLY_BACKUP_ENABLED', true);
define('HOURLY_BACKUP_INTERVAL', 60); // Minutes between backups
define('HOURLY_BACKUP_RETENTION', 24); // Hours to keep hourly backups
define('HOURLY_BACKUP_MAX_VERSIONS', 50); // Maximum versions to keepResource Configuration
// Resource limits for hourly backups
define('HOURLY_BACKUP_MAX_CPU', 30); // Maximum CPU usage percentage
define('HOURLY_BACKUP_MAX_MEMORY', 128); // Maximum memory usage in MB
define('HOURLY_BACKUP_NETWORK_LIMIT', 10); // Network bandwidth limit in MB/s
define('HOURLY_BACKUP_DISK_IO_LIMIT', 50); // Disk I/O limit in MB/sReal-Time Backup Engine
Change Detection System
class HourlyBackupChangeDetector {
private $last_backup_hash = array();
private $change_threshold = 1024; // 1KB minimum change
public function detect_changes() {
$current_state = $this->get_current_site_state();
$changes = array();
foreach ($current_state as $component => $hash) {
if (!isset($this->last_backup_hash[$component]) ||
$hash !== $this->last_backup_hash[$component]) {
$changes[$component] = array(
'old_hash' => $this->last_backup_hash[$component] ?? null,
'new_hash' => $hash,
'component' => $component
);
}
}
$this->last_backup_hash = $current_state;
return $changes;
}
private function get_current_site_state() {
return array(
'database' => $this->get_database_hash(),
'themes' => $this->get_directory_hash(get_theme_root()),
'plugins' => $this->get_directory_hash(WP_PLUGIN_DIR),
'uploads' => $this->get_directory_hash(wp_upload_dir()['basedir']),
'config' => $this->get_file_hash(ABSPATH . 'wp-config.php')
);
}
private function get_database_hash() {
global $wpdb;
$tables_hash = '';
$tables = $wpdb->get_col('SHOW TABLES');
foreach ($tables as $table) {
$count = $wpdb->get_var("SELECT COUNT(*) FROM `$table`");
$last_modified = $wpdb->get_var("SELECT MAX(updated_at) FROM `$table` WHERE updated_at IS NOT NULL");
$tables_hash .= $table . $count . ($last_modified ?: 'never') . '|';
}
return md5($tables_hash);
}
private function get_directory_hash($directory) {
if (!is_dir($directory)) return '';
$files_hash = '';
$iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($directory));
foreach ($iterator as $file) {
if ($file->isFile()) {
$files_hash .= $file->getPathname() . $file->getMTime() . $file->getSize() . '|';
}
}
return md5($files_hash);
}
private function get_file_hash($file_path) {
if (!file_exists($file_path)) return '';
return md5_file($file_path);
}
}Incremental Backup System
class HourlyIncrementalBackup {
private $backup_root;
private $current_backup_chain = array();
public function __construct() {
$this->backup_root = WP_CONTENT_DIR . '/hourly-backups/';
wp_mkdir_p($this->backup_root);
}
public function create_incremental_backup($changes) {
$timestamp = time();
$backup_id = 'hourly_' . date('Y-m-d_H-i-s', $timestamp);
$backup_path = $this->backup_root . $backup_id . '/';
wp_mkdir_p($backup_path);
// Create incremental backup for each changed component
foreach ($changes as $component => $change_info) {
$this->backup_component_incremental($component, $backup_path);
}
// Update backup chain
$this->current_backup_chain[] = array(
'id' => $backup_id,
'timestamp' => $timestamp,
'path' => $backup_path,
'changes' => $changes
);
// Maintain backup chain limit
$this->maintain_backup_chain_limit();
return array(
'backup_id' => $backup_id,
'path' => $backup_path,
'changes' => $changes
);
}
private function backup_component_incremental($component, $backup_path) {
switch ($component) {
case 'database':
$this->backup_database_incremental($backup_path);
break;
case 'themes':
$this->backup_directory_incremental(get_theme_root(), $backup_path . 'themes/');
break;
case 'plugins':
$this->backup_directory_incremental(WP_PLUGIN_DIR, $backup_path . 'plugins/');
break;
case 'uploads':
$this->backup_directory_incremental(wp_upload_dir()['basedir'], $backup_path . 'uploads/');
break;
case 'config':
copy(ABSPATH . 'wp-config.php', $backup_path . 'wp-config.php');
break;
}
}
private function backup_database_incremental($backup_path) {
global $wpdb;
// Get changes since last backup
$last_backup_time = $this->get_last_backup_time();
$changed_tables = $this->get_changed_tables($last_backup_time);
foreach ($changed_tables as $table) {
$sql_file = $backup_path . $table . '.sql';
$this->export_table_to_file($table, $sql_file, $last_backup_time);
}
}
private function backup_directory_incremental($source_dir, $backup_dir) {
wp_mkdir_p($backup_dir);
// Use rsync for efficient incremental backup
$command = sprintf(
'rsync -av --delete --link-dest="%s" "%s" "%s"',
$this->get_last_backup_path(),
$source_dir,
$backup_dir
);
exec($command);
}
private function maintain_backup_chain_limit() {
$max_backups = get_option('hourly_backup_max_chain_length', 24);
if (count($this->current_backup_chain) > $max_backups) {
// Remove oldest backups
$backups_to_remove = array_slice($this->current_backup_chain, 0, - $max_backups);
foreach ($backups_to_remove as $backup) {
$this->remove_backup_directory($backup['path']);
}
$this->current_backup_chain = array_slice($this->current_backup_chain, - $max_backups);
}
}
}Point-in-Time Recovery
Version Selection Interface
function render_point_in_time_recovery_interface() {
$backup_chains = get_option('hourly_backup_chains', array());
echo '<div class="pit-recovery-interface">';
echo '<h3>Point-in-Time Recovery</h3>';
foreach ($backup_chains as $chain) {
echo '<div class="backup-chain">';
echo '<h4>Backup Chain: ' . esc_html($chain['name']) . '</h4>';
if (!empty($chain['versions'])) {
echo '<ul class="backup-versions">';
foreach ($chain['versions'] as $version) {
$timestamp = date('M j, Y H:i:s', $version['timestamp']);
$size = size_format($version['size']);
$changes = count($version['changes']);
echo '<li class="backup-version">';
echo '<input type="radio" name="restore_version" value="' . esc_attr($version['id']) . '" id="' . esc_attr($version['id']) . '">';
echo '<label for="' . esc_attr($version['id']) . '">';
echo '<strong>' . esc_html($timestamp) . '</strong><br>';
echo '<small>Size: ' . esc_html($size) . ' | Changes: ' . esc_html($changes) . '</small>';
echo '</label>';
echo '</li>';
}
echo '</ul>';
}
echo '</div>';
}
echo '<div class="recovery-actions">';
echo '<button type="button" class="button button-primary" id="preview-recovery">Preview Recovery</button>';
echo '<button type="button" class="button" id="execute-recovery">Execute Recovery</button>';
echo '</div>';
echo '</div>';
}Granular Recovery Options
function execute_point_in_time_recovery($version_id, $recovery_options = array()) {
$version_info = get_backup_version_info($version_id);
if (!$version_info) {
return new WP_Error('version_not_found', 'Backup version not found.');
}
$recovery_result = array(
'version_id' => $version_id,
'timestamp' => $version_info['timestamp'],
'components_restored' => array(),
'errors' => array()
);
// Determine what to restore based on options
$components_to_restore = $recovery_options['components'] ?? array('database', 'files');
foreach ($components_to_restore as $component) {
try {
$result = $this->restore_component_from_version($component, $version_info);
if ($result['success']) {
$recovery_result['components_restored'][] = $component;
} else {
$recovery_result['errors'][] = "Failed to restore {$component}: " . $result['error'];
}
} catch (Exception $e) {
$recovery_result['errors'][] = "Exception restoring {$component}: " . $e->getMessage();
}
}
// Log recovery operation
log_recovery_operation($recovery_result);
return $recovery_result;
}
private function restore_component_from_version($component, $version_info) {
$backup_path = $version_info['path'];
switch ($component) {
case 'database':
return $this->restore_database_from_version($backup_path);
case 'themes':
return $this->restore_directory_from_version($backup_path . 'themes/', get_theme_root());
case 'plugins':
return $this->restore_directory_from_version($backup_path . 'plugins/', WP_PLUGIN_DIR);
case 'uploads':
return $this->restore_directory_from_version($backup_path . 'uploads/', wp_upload_dir()['basedir']);
case 'config':
return $this->restore_file_from_version($backup_path . 'wp-config.php', ABSPATH . 'wp-config.php');
default:
return array('success' => false, 'error' => 'Unknown component: ' . $component);
}
}Advanced Monitoring
Real-Time Backup Status
class HourlyBackupMonitor {
private $status_file;
private $metrics_file;
public function __construct() {
$this->status_file = WP_CONTENT_DIR . '/hourly-backup-status.json';
$this->metrics_file = WP_CONTENT_DIR . '/hourly-backup-metrics.json';
}
public function update_backup_status($status, $details = array()) {
$status_data = array(
'status' => $status,
'timestamp' => time(),
'details' => $details,
'server_load' => sys_getloadavg(),
'memory_usage' => memory_get_peak_usage(true),
'disk_usage' => disk_free_space(ABSPATH)
);
file_put_contents($this->status_file, wp_json_encode($status_data, JSON_PRETTY_PRINT));
}
public function get_backup_status() {
if (!file_exists($this->status_file)) {
return array('status' => 'unknown', 'timestamp' => 0);
}
$status_data = json_decode(file_get_contents($this->status_file), true);
// Add human-readable time
$status_data['time_ago'] = human_time_diff($status_data['timestamp']);
return $status_data;
}
public function record_backup_metrics($backup_id, $metrics) {
$existing_metrics = array();
if (file_exists($this->metrics_file)) {
$existing_metrics = json_decode(file_get_contents($this->metrics_file), true);
}
$existing_metrics[$backup_id] = array_merge($metrics, array(
'recorded_at' => time(),
'backup_id' => $backup_id
));
// Keep only last 100 entries
if (count($existing_metrics) > 100) {
$existing_metrics = array_slice($existing_metrics, -100, null, true);
}
file_put_contents($this->metrics_file, wp_json_encode($existing_metrics, JSON_PRETTY_PRINT));
}
public function get_backup_metrics($limit = 10) {
if (!file_exists($this->metrics_file)) {
return array();
}
$metrics = json_decode(file_get_contents($this->metrics_file), true);
// Sort by recorded time, newest first
uasort($metrics, function($a, $b) {
return $b['recorded_at'] - $a['recorded_at'];
});
return array_slice($metrics, 0, $limit, true);
}
}Dashboard Integration
Real-Time Status Widget
function add_hourly_backup_dashboard_widget() {
wp_add_dashboard_widget(
'hourly_backup_status',
'Hourly Backup Status',
'render_hourly_backup_status_widget'
);
}
function render_hourly_backup_status_widget() {
$monitor = new HourlyBackupMonitor();
$status = $monitor->get_backup_status();
$metrics = $monitor->get_backup_metrics(5);
echo '<div class="hourly-backup-status-widget">';
// Current status
$status_class = 'status-' . $status['status'];
echo '<div class="backup-status ' . esc_attr($status_class) . '">';
echo '<strong>Status:</strong> ' . esc_html(ucfirst($status['status']));
if (isset($status['time_ago'])) {
echo ' <small>(' . esc_html($status['time_ago']) . ' ago)</small>';
}
echo '</div>';
// Server metrics
if (isset($status['server_load'])) {
echo '<div class="server-metrics">';
echo '<strong>Server Load:</strong> ' . esc_html(implode(', ', array_map(function($load) {
return number_format($load, 2);
}, $status['server_load'])));
echo '</div>';
}
// Recent backups
if (!empty($metrics)) {
echo '<div class="recent-backups">';
echo '<h4>Recent Backups</h4>';
echo '<ul>';
foreach ($metrics as $backup_id => $metric) {
$duration = isset($metric['duration']) ? number_format($metric['duration'], 1) . 's' : 'N/A';
$size = isset($metric['size']) ? size_format($metric['size']) : 'N/A';
echo '<li>';
echo '<strong>' . esc_html(date('M j H:i', $metric['recorded_at'])) . '</strong>';
echo '<small> - ' . esc_html($duration) . ', ' . esc_html($size) . '</small>';
echo '</li>';
}
echo '</ul>';
echo '</div>';
}
echo '</div>';
}
add_action('wp_dashboard_setup', 'add_hourly_backup_dashboard_widget');Enterprise Features
Multi-Site Support
class HourlyBackupMultiSite {
private $sites_backup_status = array();
public function backup_all_sites() {
if (!is_multisite()) {
return new WP_Error('not_multisite', 'Multi-site support required.');
}
$sites = get_sites();
$results = array();
foreach ($sites as $site) {
switch_to_blog($site->blog_id);
$site_result = $this->backup_single_site($site);
$results[$site->blog_id] = $site_result;
restore_current_blog();
}
return $results;
}
private function backup_single_site($site) {
// Implement single site backup logic
$backup_result = create_hourly_backup_for_site($site->blog_id);
$this->sites_backup_status[$site->blog_id] = array(
'last_backup' => time(),
'status' => $backup_result['success'] ? 'success' : 'failed',
'site_id' => $site->blog_id,
'site_url' => get_site_url($site->blog_id)
);
return $backup_result;
}
public function get_sites_backup_status() {
return $this->sites_backup_status;
}
}Cloud Integration
class HourlyBackupCloudIntegration {
private $cloud_providers = array();
public function __construct() {
$this->cloud_providers = array(
'aws' => new HourlyBackupAWSProvider(),
'gcp' => new HourlyBackupGCPProvider(),
'azure' => new HourlyBackupAzureProvider()
);
}
public function upload_to_cloud($backup_path, $provider = 'aws') {
if (!isset($this->cloud_providers[$provider])) {
return new WP_Error('invalid_provider', 'Invalid cloud provider specified.');
}
$provider_instance = $this->cloud_providers[$provider];
try {
$upload_result = $provider_instance->upload_backup($backup_path);
// Log successful upload
log_cloud_upload($provider, $backup_path, $upload_result);
return $upload_result;
} catch (Exception $e) {
// Log upload failure
log_cloud_upload_error($provider, $backup_path, $e->getMessage());
return new WP_Error('upload_failed', $e->getMessage());
}
}
public function download_from_cloud($backup_id, $provider = 'aws') {
if (!isset($this->cloud_providers[$provider])) {
return new WP_Error('invalid_provider', 'Invalid cloud provider specified.');
}
$provider_instance = $this->cloud_providers[$provider];
try {
$download_result = $provider_instance->download_backup($backup_id);
return $download_result;
} catch (Exception $e) {
return new WP_Error('download_failed', $e->getMessage());
}
}
}Performance Optimization
Resource Management
class HourlyBackupResourceManager {
private $cpu_limit;
private $memory_limit;
private $io_limit;
public function __construct() {
$this->cpu_limit = get_option('hourly_backup_cpu_limit', 30);
$this->memory_limit = get_option('hourly_backup_memory_limit', 128);
$this->io_limit = get_option('hourly_backup_io_limit', 50);
}
public function can_run_backup() {
// Check CPU usage
$cpu_usage = $this->get_cpu_usage();
if ($cpu_usage > $this->cpu_limit) {
return false;
}
// Check memory usage
$memory_usage = memory_get_peak_usage(true) / 1024 / 1024; // MB
if ($memory_usage > $this->memory_limit) {
return false;
}
// Check I/O usage
$io_usage = $this->get_io_usage();
if ($io_usage > $this->io_limit) {
return false;
}
// Check concurrent backups
$concurrent_backups = $this->get_concurrent_backup_count();
$max_concurrent = get_option('hourly_backup_max_concurrent', 2);
if ($concurrent_backups >= $max_concurrent) {
return false;
}
return true;
}
private function get_cpu_usage() {
if (function_exists('sys_getloadavg')) {
$load = sys_getloadavg();
return $load[0] * 100; // Convert to percentage
}
return 0;
}
private function get_io_usage() {
// Implement I/O usage monitoring
// This would require system-specific tools
return 0; // Placeholder
}
private function get_concurrent_backup_count() {
global $wpdb;
$count = $wpdb->get_var("SELECT COUNT(*) FROM {$wpdb->options} WHERE option_name LIKE 'backup_in_progress_%'");
return intval($count);
}
}Security Features
Backup Encryption
class HourlyBackupEncryption {
private $encryption_key;
private $cipher = 'AES-256-CBC';
public function __construct() {
$this->encryption_key = get_option('hourly_backup_encryption_key');
if (!$this->encryption_key) {
$this->encryption_key = wp_generate_password(32, true, true);
update_option('hourly_backup_encryption_key', $this->encryption_key);
}
}
public function encrypt_backup($backup_path) {
$backup_content = file_get_contents($backup_path);
if (!$backup_content) {
return new WP_Error('read_failed', 'Failed to read backup file.');
}
// Generate initialization vector
$iv = openssl_random_pseudo_bytes(16);
// Encrypt content
$encrypted = openssl_encrypt(
$backup_content,
$this->cipher,
$this->encryption_key,
0,
$iv
);
if ($encrypted === false) {
return new WP_Error('encryption_failed', 'Failed to encrypt backup.');
}
// Combine IV and encrypted content
$encrypted_with_iv = $iv . $encrypted;
// Save encrypted backup
$encrypted_path = $backup_path . '.encrypted';
$result = file_put_contents($encrypted_path, $encrypted_with_iv);
if ($result === false) {
return new WP_Error('write_failed', 'Failed to write encrypted backup.');
}
// Remove original unencrypted file
unlink($backup_path);
return $encrypted_path;
}
public function decrypt_backup($encrypted_path) {
$encrypted_content = file_get_contents($encrypted_path);
if (!$encrypted_content) {
return new WP_Error('read_failed', 'Failed to read encrypted backup.');
}
// Extract IV and encrypted content
$iv = substr($encrypted_content, 0, 16);
$encrypted = substr($encrypted_content, 16);
// Decrypt content
$decrypted = openssl_decrypt(
$encrypted,
$this->cipher,
$this->encryption_key,
0,
$iv
);
if ($decrypted === false) {
return new WP_Error('decryption_failed', 'Failed to decrypt backup.');
}
return $decrypted;
}
}Best Practices
Performance Best Practices
- Smart Scheduling: Schedule backups during low-traffic periods
- Resource Monitoring: Monitor system resources during backup operations
- Incremental Backups: Use incremental backups to reduce resource usage
- Compression: Compress backups to minimize storage requirements
- Cleanup: Regularly clean up old backup versions
Security Best Practices
- Encryption: Always encrypt sensitive backup data
- Access Control: Limit access to backup files and settings
- Secure Storage: Use secure storage locations for backups
- Regular Audits: Audit backup integrity and security
- Monitoring: Monitor backup operations for anomalies
Reliability Best Practices
- Redundancy: Store backups in multiple locations
- Testing: Regularly test backup restoration
- Monitoring: Monitor backup success and failures
- Documentation: Document backup procedures and policies
- Training: Train staff on backup procedures
Enterprise-grade hourly backup solution with real-time protection and advanced features.