MySQL Agent

Standalone backup agent for MySQL and MariaDB databases. Supports logical and physical backups with point-in-time recovery.

v1.0.0Updated 2026-01-01

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

VariableDefaultDescription
MYSQL_HOSTlocalhostMySQL server hostname
MYSQL_PORT3306MySQL server port
MYSQL_USERrootMySQL username
MYSQL_PASSWORD-MySQL password (required)
MYSQL_DATABASEallSpecific database or "all" for all databases
MYSQL_SOCKET-Unix socket path (alternative to host/port)

Backup Settings

VariableDefaultDescription
LOX_API_KEY-LOX API key (required)
BACKUP_NAMEmysql-backupBackup name prefix
BACKUP_SCHEDULE0 3 * * *Cron schedule expression
BACKUP_RETENTION30Days to retain backups
BACKUP_TYPElogicalBackup type: logical or physical
BACKUP_ON_STARTfalseRun backup when agent starts
SOURCE_IDENTIFIERautoCustom 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

VariableDefaultDescription
COMPRESSIONgzipCompression: gzip, zstd, lz4, or none
SINGLE_TRANSACTIONtrueUse single transaction (InnoDB)
LOCK_TABLESfalseLock tables during backup
ROUTINEStrueInclude stored procedures and functions
TRIGGERStrueInclude triggers
EVENTStrueInclude 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.

ProsCons
  • Portable across MySQL versions
  • Human-readable SQL format
  • Selective table restore
  • Slower for large databases
  • Higher server load during backup
  • Larger file size

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 hours

Exclude 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:

EndpointDescription
/healthLiveness check
/readyReadiness check (DB connected)
/metricsPrometheus 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.