• Skip to secondary menu
  • Skip to main content
  • Skip to primary sidebar
  • Home
  • Projects
  • Products
  • Themes
  • Tools
  • Request for Quote

Vengala Vinay

Having 9+ Years of Experience in Software Development

  • Home
  • WordPress
  • PHP
    • Codeigniter
  • Django
  • Magento
  • Selenium
  • Server
Home » Disaster Recovery 101: Architecting Auto-Failovers for MySQL and WooCommerce Deployments on OVH

Disaster Recovery 101: Architecting Auto-Failovers for MySQL and WooCommerce Deployments on OVH

Establishing a Robust MySQL Replication Topology for High Availability

For any mission-critical application, particularly e-commerce platforms like WooCommerce, database availability is paramount. A single point of failure in the database layer can lead to significant revenue loss and reputational damage. This section details the architecture for a highly available MySQL setup leveraging asynchronous replication, a foundational element for automated failover.

We will configure a primary-replica topology. The primary instance handles all write operations, while one or more replica instances asynchronously replicate the primary’s binary logs. This setup allows for read scaling and, crucially, provides a standby instance ready to take over in case of primary failure.

Primary MySQL Server Configuration

On the primary MySQL server, ensure binary logging is enabled and configured appropriately. This is essential for replication. We’ll use `binlog_format=ROW` for maximum compatibility and data integrity.

[mysqld]
server-id = 1
log_bin = /var/log/mysql/mysql-bin.log
binlog_format = ROW
expire_logs_days = 7
relay_log = /var/log/mysql/mysql-relay-bin.log
read_only = OFF
innodb_flush_log_at_trx_commit = 1
sync_binlog = 1

After modifying the configuration, restart the MySQL service:

sudo systemctl restart mysql

Next, create a dedicated replication user on the primary server. This user will be used by the replica to connect and fetch binary logs.

CREATE USER 'replicator'@'%' IDENTIFIED BY 'your_strong_password';
GRANT REPLICATION SLAVE ON *.* TO 'replicator'@'%';
FLUSH PRIVILEGES;

Replica MySQL Server Configuration

On the replica server, configure it with a unique `server-id`. It should also have binary logging enabled if it’s intended to be promoted to a primary later or to serve as a source for further replicas. For a simple primary-replica setup, `read_only = ON` is crucial to prevent accidental writes.

[mysqld]
server-id = 2
log_bin = /var/log/mysql/mysql-bin.log
binlog_format = ROW
expire_logs_days = 7
relay_log = /var/log/mysql/mysql-relay-bin.log
read_only = ON
innodb_flush_log_at_trx_commit = 1
sync_binlog = 1

Restart the MySQL service on the replica:

sudo systemctl restart mysql

Establishing the Replication Channel

Before initiating replication, it’s vital to ensure the replica has a consistent snapshot of the primary’s data. The most robust method is to take a backup of the primary while locking tables briefly, or by using `mysqldump` with specific options to capture the binary log position.

On the primary, execute the following to get the current binary log file and position. This should be done just before starting the data transfer to the replica.

SHOW MASTER STATUS;

Note down the `File` and `Position` from the output. Then, on the replica, configure it to connect to the primary. Replace `primary_ip_address` and `your_strong_password` with your actual values.

CHANGE MASTER TO
  MASTER_HOST='primary_ip_address',
  MASTER_USER='replicator',
  MASTER_PASSWORD='your_strong_password',
  MASTER_LOG_FILE='mysql-bin.XXXXXX', -- From SHOW MASTER STATUS
  MASTER_LOG_POS=YYYYYY; -- From SHOW MASTER STATUS

START SLAVE;

Verify the replication status on the replica:

SHOW SLAVE STATUS\G

Ensure `Slave_IO_Running: Yes` and `Slave_SQL_Running: Yes`. Also, check `Seconds_Behind_Master` to be consistently low (ideally 0 or very close to it).

Orchestrating Automated Failover with Orchestrator

While MySQL replication provides the foundation for high availability, manual intervention is still required for failover. To achieve automated failover, we introduce Orchestrator, a powerful, open-source tool designed for MySQL topology management and automated failover.

Orchestrator Installation and Configuration

Orchestrator can be installed on a separate, highly available management node. The installation process typically involves downloading a pre-compiled binary or building from source. For this example, we’ll assume a Linux environment.

Download the latest release:

wget https://github.com/openark/orchestrator/releases/download/v3.2.7/orchestrator-3.2.7-linux-amd64.tar.gz
tar -zxvf orchestrator-3.2.7-linux-amd64.tar.gz
sudo mv orchestrator-3.2.7-linux-amd64 /usr/local/orchestrator

Orchestrator requires a backend database to store its topology information. A dedicated MySQL instance (or even a local SQLite database for testing) can be used. For production, a separate, highly available MySQL instance is recommended.

Create a configuration file, e.g., `/etc/orchestrator/orchestrator.conf.json`:

{
  "Debug": false,
  "ListenAddress": ":3000",
  "MySQLTopologyUser": "orchestrator",
  "MySQLTopologyPassword": "your_orchestrator_db_password",
  "MySQLOrchestratorHost": "127.0.0.1",
  "MySQLOrchestratorPort": 3306,
  "MySQLOrchestratorDatabase": "orchestrator",
  "DiscoveryPeriodSeconds": 10,
  "FailureDetectionPeriodSeconds": 10,
  "PromotionLagQuery": "SELECT * FROM mysql.slave_master_info WHERE Master_Host IS NOT NULL AND Slave_IO_Running = 'Yes' AND Slave_SQL_Running = 'Yes' ORDER BY Seconds_Behind_Master DESC LIMIT 1",
  "SlaveLagQuery": "SELECT * FROM mysql.slave_master_info WHERE Master_Host IS NOT NULL AND Slave_IO_Running = 'Yes' AND Slave_SQL_Running = 'Yes' ORDER BY Seconds_Behind_Master DESC LIMIT 1",
  "DetectClusterAliasConflicts": true,
  "SnapshotTopologiesOnStartup": true,
  "PostponePromotionOnClusterDiscovery": true,
  "RecoveryPeriodBlockSeconds": 300,
  "RecoveryPeriodBlockUnsuccessfulSeconds": 600,
  "PreemptivePaging": false,
  "Hooks": [
    {
      "name": "mysql-replication-lag",
      "script": "/etc/orchestrator/hooks/mysql-replication-lag.sh",
      "timeout": 60,
      "discovery": true,
      "replication-analysis": true
    },
    {
      "name": "mysql-unreachable",
      "script": "/etc/orchestrator/hooks/mysql-unreachable.sh",
      "timeout": 60,
      "unreachable": true
    }
  ],
  "GlobalUserACL": [
    "*"
  ],
  "GlobalWriteACL": [
    "*"
  ]
}

Create the Orchestrator database and user on your backend MySQL instance:

CREATE DATABASE orchestrator;
CREATE USER 'orchestrator'@'%' IDENTIFIED BY 'your_orchestrator_db_password';
GRANT ALL PRIVILEGES ON orchestrator.* TO 'orchestrator'@'%';
FLUSH PRIVILEGES;

Initialize the Orchestrator database schema:

/usr/local/orchestrator/orchestrator-client -c discover -i 127.0.0.1:3306 -u orchestrator -p your_orchestrator_db_password

Now, configure Orchestrator to discover your MySQL topology. You can do this via the API or by adding entries to its configuration. For a simple setup, you can point it to one of your MySQL instances, and it will discover the rest.

# Add this to orchestrator.conf.json
"MySQLOrchestratorHost": "your_primary_mysql_ip",
"MySQLOrchestratorPort": 3306

Start the Orchestrator service. It’s recommended to run it under a systemd service for proper management.

# Create a systemd service file, e.g., /etc/systemd/system/orchestrator.service
[Unit]
Description=Orchestrator MySQL HA Manager
After=network.target

[Service]
User=orchestrator
Group=orchestrator
ExecStart=/usr/local/orchestrator/orchestrator -c /etc/orchestrator/orchestrator.conf.json
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable orchestrator
sudo systemctl start orchestrator

Configuring Orchestrator for Automated Failover

Orchestrator’s power lies in its ability to detect failures and automatically promote a replica. This is configured through its hooks and recovery settings. The `PromotionLagQuery` and `SlaveLagQuery` are critical for Orchestrator to determine the best replica to promote.

The `hooks` section in `orchestrator.conf.json` allows you to define scripts that run when specific events occur. For automated failover, we’ll focus on `mysql-unreachable` and potentially `mysql-replication-lag`.

Create a hook script for handling unreachable MySQL instances, e.g., `/etc/orchestrator/hooks/mysql-unreachable.sh`:

#!/bin/bash

# This script is executed by Orchestrator when a MySQL instance is detected as unreachable.
# It should contain logic to trigger failover or alert.

INSTANCE_KEY="$1" # e.g., "hostname:port"
INSTANCE_HOST=$(echo "$INSTANCE_KEY" | cut -d: -f1)
INSTANCE_PORT=$(echo "$INSTANCE_KEY" | cut -d: -f2)

echo "MySQL instance $INSTANCE_KEY is unreachable. Initiating automated failover..."

# Trigger Orchestrator's recovery mechanism.
# Orchestrator will automatically attempt to promote a replica if configured.
# You can also add custom logic here, e.g., sending alerts.

# Example: Triggering failover via Orchestrator API (requires orchestrator-client)
# This is a simplified example; robust error handling and idempotency are crucial.
# orchestrator-client -c discover -i $INSTANCE_HOST:$INSTANCE_PORT
# orchestrator-client -c promote-to-primary -i $INSTANCE_KEY --skip-discover

# For automated failover, Orchestrator's internal logic is usually sufficient
# if configured correctly. This hook primarily serves for alerting or custom actions.

# Example: Sending an alert (e.g., via Slack or PagerDuty)
# curl -X POST -H 'Content-type: application/json' --data '{"text":"MySQL instance '$INSTANCE_KEY' is unreachable. Automated failover initiated."}' YOUR_SLACK_WEBHOOK_URL

exit 0

Make the script executable:

sudo chmod +x /etc/orchestrator/hooks/mysql-unreachable.sh

Ensure your `orchestrator.conf.json` has the correct `RecoveryPeriodBlockSeconds` and `RecoveryPeriodBlockUnsuccessfulSeconds` set to reasonable values to prevent rapid, repeated failover attempts.

Integrating WooCommerce with the HA MySQL Cluster

WooCommerce, by default, connects to a single MySQL database. To leverage the high availability setup orchestrated by Orchestrator, we need to ensure that WooCommerce can connect to the *current* primary instance. This typically involves a load balancer or a proxy layer.

Using a Proxy Layer (ProxySQL)

ProxySQL is an excellent choice for this. It sits between your application and your MySQL servers, intelligently routing traffic. ProxySQL can be configured to monitor MySQL servers and automatically switch traffic to a new primary if the current one becomes unavailable.

Install ProxySQL on a separate node or co-located with your Orchestrator management node.

# Example for Ubuntu/Debian
sudo apt update
sudo apt install proxysql

Configure ProxySQL’s `mysql_servers` table to include your primary and replica instances. ProxySQL will use this information to monitor the servers and their roles.

-- Connect to ProxySQL's admin interface
mysql -u admin -padmin -h 127.0.0.1 -P6032

-- Add your primary server
INSERT INTO mysql_servers (hostname, hostgroup_id, port, weight) VALUES ('primary_mysql_ip', 10, 3306, 1000);

-- Add your replica server(s)
INSERT INTO mysql_servers (hostname, hostgroup_id, port, weight) VALUES ('replica_mysql_ip', 20, 3306, 1000);

-- Define hostgroups for read/write splitting and failover
-- Hostgroup 10: Primary (writes and reads)
-- Hostgroup 20: Replica (reads only, candidate for promotion)
-- Hostgroup 30: All servers (for failover detection)
LOAD MYSQL SERVERS TO RUNTIME;
LOAD MYSQL USERS TO RUNTIME;
LOAD MYSQL QUERY RULES TO RUNTIME;
LOAD MYSQL CACHED STATEMENTS TO RUNTIME;
LOAD MYSQL MIRRORED ACCOUNTS TO RUNTIME;
LOAD MYSQL BINLOG LOGINS TO RUNTIME;

-- Configure hostgroups for failover
-- Hostgroup 10: Primary
-- Hostgroup 20: Replica
-- Hostgroup 30: All servers (for monitoring)
-- This requires careful configuration of ProxySQL's internal monitoring and failover logic.
-- A common approach is to use ProxySQL's ability to detect server failures and
-- then use its query rules to redirect traffic.

-- Example: Configure ProxySQL to monitor servers and perform failover
-- This is a simplified example. For robust failover, consider integrating
-- ProxySQL with Orchestrator or using its native failover capabilities.

-- Ensure ProxySQL's scheduler is running to perform checks
-- SET mysql-monitor_interval=1000; -- milliseconds
-- SET mysql-monitor_connect_interval=1000;
-- SET mysql-monitor_read_only_interval=1000;

-- Configure query rules to direct writes to the primary hostgroup
-- and reads to either primary or replica.
-- This is a complex topic and depends on your specific needs.
-- For automated failover, ProxySQL needs to be aware of the *current* primary.
-- This can be achieved by:
-- 1. ProxySQL monitoring Orchestrator's actions.
-- 2. Orchestrator updating ProxySQL's configuration upon promotion.

-- A common pattern is to have Orchestrator trigger a script that updates ProxySQL.
-- Example hook in Orchestrator:
-- {
--   "name": "update-proxysql",
--   "script": "/etc/orchestrator/hooks/update-proxysql.sh",
--   "promotion": true,
--   "demotion": true
-- }

-- The update-proxysql.sh script would then:
-- 1. Get the new primary from Orchestrator's API.
-- 2. Update ProxySQL's mysql_servers table (e.g., change hostgroup_id for the new primary).
-- 3. Reload ProxySQL configuration.

-- Example of a simplified update-proxysql.sh script:
-- #!/bin/bash
-- NEW_PRIMARY_HOST="$1"
-- NEW_PRIMARY_PORT="$2"
--
-- mysql -uadmin -padmin -h127.0.0.1 -P6032 <



Update your WooCommerce `wp-config.php` to point to the ProxySQL instance's IP address and port (default is 3306).

define( 'DB_HOST', 'proxysql_ip_address:3306' );
define( 'DB_USER', 'your_woocommerce_db_user' );
define( 'DB_PASSWORD', 'your_woocommerce_db_password' );
define( 'DB_NAME', 'your_woocommerce_db_name' );

OVH Specific Considerations

When deploying on OVH, consider the following:

  • Network Latency: Ensure your MySQL primary, replicas, Orchestrator, and ProxySQL are deployed within the same OVH region and ideally the same availability zone to minimize latency. High latency can lead to replication lag and impact failover performance.
  • Instance Sizing: Choose appropriate instance types for your MySQL servers, Orchestrator, and ProxySQL. Database instances require sufficient CPU, RAM, and IOPS.
  • Security Groups/Firewalls: Configure OVH security groups or firewall rules to allow necessary traffic between your MySQL instances, Orchestrator, ProxySQL, and your application servers. Restrict access to the minimum required ports (e.g., 3306 for MySQL, 3000 for Orchestrator UI, 6032 for ProxySQL admin).
  • Managed Databases: If using OVH's managed MySQL services, investigate their built-in HA and failover capabilities. While they might simplify setup, ensure they meet your specific requirements for automation and control. Orchestrator can still be used to manage failover for managed instances if they expose the necessary replication status.
  • Monitoring and Alerting: Implement comprehensive monitoring for your MySQL instances, replication status, Orchestrator, and ProxySQL. OVH's monitoring tools, combined with external solutions like Prometheus/Grafana, are essential for proactive issue detection.

Testing and Validation

Thorough testing is non-negotiable. Simulate various failure scenarios:

  • Primary Server Crash: Stop the MySQL process on the primary. Observe Orchestrator's logs and verify that it detects the failure, promotes a replica, and updates ProxySQL (if integrated). Check WooCommerce's connectivity.
  • Network Partition: Simulate network issues between the primary and replicas.
  • Replica Failure: Stop a replica and ensure the remaining replicas continue to function and that the primary is unaffected.
  • Orchestrator Node Failure: If Orchestrator is deployed in a highly available manner (e.g., active-passive with a virtual IP or using its built-in clustering), test its failover.

Monitor `Seconds_Behind_Master` on replicas during and after failover. Ensure that the promotion process is swift and that WooCommerce experiences minimal downtime. Document your failover procedures and regularly review them.

Primary Sidebar

A little about the Author

Having 9+ Years of Experience in Software Development.
Expertised in Php Development, WordPress Custom Theme Development (From scratch using underscores or Genesis Framework or using any blank theme or Premium Theme), Custom Plugin Development. Hands on Experience on 3rd Party Php Extension like Chilkat, nSoftware.

Recent Posts

  • Disaster Recovery 101: Architecting Auto-Failovers for Redis and PHP Deployments on OVH
  • How We Audited a High-Traffic WooCommerce Enterprise Stack on Google Cloud and Mitigated Race conditions during high-concurrency payment processing
  • Disaster Recovery 101: Architecting Auto-Failovers for Elasticsearch and Magento 2 Deployments on DigitalOcean
  • An Auditor’s Checklist for Securing WordPress Backends on OVH
  • Step-by-Step: Diagnosing Perl script high CPU throttling due to unoptimized regular expressions on AWS Servers

Copyright © 2026 · Vinay Vengala