MySQL Agent
Standalone backup agent for MySQL and MariaDB databases. Supports logical and physical backups with point-in-time recovery.
Features
- MySQL 5.7, 8.0+ and MariaDB 10.3+ support
- Logical backups (mysqldump) and physical backups (Percona XtraBackup)
- Binary log backup for point-in-time recovery
- Compression and encryption at rest
- Scheduled and on-demand backups
- Single database or all databases backup
- Automatic source identifier for backup tracking
Quick Start
Docker Compose
# docker-compose.yml
version: '3.8'
services:
mysql:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_DATABASE: myapp
volumes:
- mysql_data:/var/lib/mysql
lox-mysql-agent:
image: loxbackup/mysql-agent:latest
environment:
LOX_API_KEY: ${LOX_API_KEY}
MYSQL_HOST: mysql
MYSQL_PORT: 3306
MYSQL_USER: root
MYSQL_PASSWORD: ${MYSQL_ROOT_PASSWORD}
BACKUP_SCHEDULE: "0 3 * * *"
BACKUP_NAME: "myapp-mysql"
depends_on:
- mysql
volumes:
mysql_data:Standalone Binary
# Download the agent curl -L https://releases.backlox.com/mysql-agent/latest/linux-amd64 -o lox-mysql-agent chmod +x lox-mysql-agent # Configure export LOX_API_KEY="lox_xxxxxxxxxxxx" export MYSQL_HOST="localhost" export MYSQL_USER="backup_user" export MYSQL_PASSWORD="secure_password" # Run a backup ./lox-mysql-agent backup # Or run as daemon with schedule ./lox-mysql-agent daemon --schedule "0 3 * * *"
Environment Variables
Connection Settings
| Variable | Default | Description |
|---|---|---|
| MYSQL_HOST | localhost | MySQL server hostname |
| MYSQL_PORT | 3306 | MySQL server port |
| MYSQL_USER | root | MySQL username |
| MYSQL_PASSWORD | - | MySQL password (required) |
| MYSQL_DATABASE | all | Specific database or "all" for all databases |
| MYSQL_SOCKET | - | Unix socket path (alternative to host/port) |
Backup Settings
| Variable | Default | Description |
|---|---|---|
| LOX_API_KEY | - | LOX API key (required) |
| BACKUP_NAME | mysql-backup | Backup name prefix |
| BACKUP_SCHEDULE | 0 3 * * * | Cron schedule expression |
| BACKUP_RETENTION | 30 | Days to retain backups |
| BACKUP_TYPE | logical | Backup type: logical or physical |
| BACKUP_ON_START | false | Run backup when agent starts |
| SOURCE_IDENTIFIER | auto | Custom source ID (auto-generated if not set) |
Source Identifier
The agent automatically generates a unique source_identifier for each database instance (format: mysql-hostname-database-hash). This enables tracking backups across multiple servers and identifying their origin in the dashboard.
Advanced Options
| Variable | Default | Description |
|---|---|---|
| COMPRESSION | gzip | Compression: gzip, zstd, lz4, or none |
| SINGLE_TRANSACTION | true | Use single transaction (InnoDB) |
| LOCK_TABLES | false | Lock tables during backup |
| ROUTINES | true | Include stored procedures and functions |
| TRIGGERS | true | Include triggers |
| EVENTS | true | Include scheduled events |
| EXCLUDE_TABLES | - | Comma-separated tables to exclude |
| MYSQLDUMP_EXTRA_ARGS | - | Additional mysqldump arguments |
Database User Setup
Create a dedicated backup user with minimum required privileges:
-- For logical backups (mysqldump) CREATE USER 'lox_backup'@'%' IDENTIFIED BY 'secure_password'; GRANT SELECT, SHOW VIEW, TRIGGER, LOCK TABLES, EVENT ON *.* TO 'lox_backup'@'%'; GRANT PROCESS ON *.* TO 'lox_backup'@'%'; GRANT RELOAD ON *.* TO 'lox_backup'@'%'; -- Required for FLUSH FLUSH PRIVILEGES; -- For physical backups (XtraBackup) - additional privileges needed GRANT BACKUP_ADMIN, REPLICATION CLIENT ON *.* TO 'lox_backup'@'%'; FLUSH PRIVILEGES;
Security Note
Always use a dedicated backup user with minimum required privileges. Never use the root account for automated backups.
Backup Types
Logical Backup (Default)
Uses mysqldump to create SQL dump files. Best for smaller databases and cross-version compatibility.
| Pros | Cons |
|---|---|
|
|
Physical Backup
Uses Percona XtraBackup for hot physical backups. Best for large databases requiring minimal downtime.
lox-mysql-agent:
image: loxbackup/mysql-agent:latest
environment:
LOX_API_KEY: ${LOX_API_KEY}
MYSQL_HOST: mysql
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
BACKUP_TYPE: physical
BACKUP_SCHEDULE: "0 2 * * *"Point-in-Time Recovery
Enable binary log backup for point-in-time recovery (PITR):
lox-mysql-agent:
image: loxbackup/mysql-agent:latest
environment:
LOX_API_KEY: ${LOX_API_KEY}
MYSQL_HOST: mysql
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
# Enable binary log backup
BINLOG_BACKUP: "true"
BINLOG_SCHEDULE: "*/15 * * * *" # Every 15 minutes
# Full backup daily
BACKUP_SCHEDULE: "0 3 * * *"MySQL Server Configuration
Ensure binary logging is enabled in your MySQL configuration:
[mysqld] log_bin = mysql-bin binlog_format = ROW expire_logs_days = 7
Examples
Single Database Backup
lox-mysql-agent:
image: loxbackup/mysql-agent:latest
environment:
LOX_API_KEY: ${LOX_API_KEY}
MYSQL_HOST: mysql
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
MYSQL_DATABASE: myapp # Only backup this database
BACKUP_NAME: "myapp-db"
BACKUP_SCHEDULE: "0 */4 * * *" # Every 4 hoursExclude Large Tables
lox-mysql-agent:
image: loxbackup/mysql-agent:latest
environment:
LOX_API_KEY: ${LOX_API_KEY}
MYSQL_HOST: mysql
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
MYSQL_DATABASE: analytics
# Skip large log/audit tables
EXCLUDE_TABLES: "audit_log,access_log,metrics_raw"
BACKUP_NAME: "analytics-db"Amazon RDS / Cloud MySQL
lox-mysql-agent:
image: loxbackup/mysql-agent:latest
environment:
LOX_API_KEY: ${LOX_API_KEY}
MYSQL_HOST: mydb.xxxx.us-east-1.rds.amazonaws.com
MYSQL_PORT: 3306
MYSQL_USER: admin
MYSQL_PASSWORD: ${RDS_PASSWORD}
MYSQL_DATABASE: all
# RDS doesn't allow SUPER privilege, disable some features
SINGLE_TRANSACTION: "true"
ROUTINES: "true"
TRIGGERS: "true"
BACKUP_NAME: "rds-mysql-prod"MariaDB with Galera Cluster
lox-mysql-agent:
image: loxbackup/mysql-agent:latest
environment:
LOX_API_KEY: ${LOX_API_KEY}
# Connect to one node
MYSQL_HOST: mariadb-node-1
MYSQL_PORT: 3306
MYSQL_USER: backup
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
# Galera-specific settings
SINGLE_TRANSACTION: "true"
MYSQLDUMP_EXTRA_ARGS: "--skip-add-locks"
BACKUP_NAME: "galera-cluster"Restoring Backups
Restore from Logical Backup
# Download the backup lox backup download <backup-id> -o backup.sql.gz # Decompress gunzip backup.sql.gz # Restore to MySQL mysql -h localhost -u root -p < backup.sql # Or for a specific database mysql -h localhost -u root -p myapp < backup.sql
Point-in-Time Recovery
# 1. Restore the full backup lox backup download <full-backup-id> -o backup.sql.gz gunzip backup.sql.gz mysql -h localhost -u root -p < backup.sql # 2. Download binary logs since the backup lox backup download <binlog-backup-id> -o binlogs.tar.gz tar -xzf binlogs.tar.gz # 3. Apply binary logs up to desired point mysqlbinlog --stop-datetime="2024-01-15 14:30:00" \ binlogs/mysql-bin.* | mysql -h localhost -u root -p
Monitoring
The agent exposes Prometheus metrics and health endpoints:
| Endpoint | Description |
|---|---|
| /health | Liveness check |
| /ready | Readiness check (DB connected) |
| /metrics | Prometheus metrics |
Key Metrics
# Backup metrics
lox_mysql_backup_total{status="success"}
lox_mysql_backup_total{status="failed"}
lox_mysql_backup_duration_seconds
lox_mysql_backup_size_bytes
lox_mysql_last_backup_timestamp
# Database metrics
lox_mysql_database_size_bytes{database="myapp"}
lox_mysql_tables_count{database="myapp"}Troubleshooting
Access denied for user
Verify the backup user has the correct privileges. Run SHOW GRANTS FOR 'lox_backup'@'%'; to check.
Lock wait timeout exceeded
Enable SINGLE_TRANSACTION: true to avoid table locks. For MyISAM tables, schedule backups during low-traffic periods.
Cannot connect to MySQL server
Check that MySQL is accepting remote connections. Verify bind-address in my.cnf and that the port is accessible.
Debug mode
Set LOG_LEVEL: debug to see detailed mysqldump commands and output.