A flexible MySQL backup script with automatic rotation and multiple backup modes.
- Multiple backup modes: Individual databases or all-databases in a single file
- Automatic backup rotation: Configurable number of backup copies to retain
- Selective backups: Backup specific databases via command-line arguments
- System database filtering: Automatically skips system databases (information_schema, performance_schema, mysql)
- Environment variable support: Easy configuration for containerized environments
- Directory validation: Safety checks before executing backups
- Compression: All backups are gzip compressed to save space
-
Place the script in
/usr/local/sbin(or your preferred location):sudo cp mysql-backup.sh /usr/local/sbin/ sudo chmod 700 /usr/local/sbin/mysql-backup.sh
-
Create a MySQL user with appropriate permissions:
CREATE USER 'backup'@'localhost' IDENTIFIED BY 'secure_password'; GRANT SELECT, RELOAD, LOCK TABLES ON *.* TO 'backup'@'localhost'; FLUSH PRIVILEGES;
-
Create the backup directory:
sudo mkdir -p /var/myexport sudo chown mysql:mysql /var/myexport # Or appropriate user -
(Optional) Schedule with cron for automatic backups:
# Edit crontab sudo crontab -e # Run backup 3 times a day (at 2am, 10am, and 6pm) 0 2,10,18 * * * /usr/local/sbin/mysql-backup.sh
Edit the configuration section at the top of the script:
USER="${MYSQL_USER:-root}"
PASS="${MYSQL_ROOT_PASSWORD:-}"
COPIES=2 # Number of backup copies to keep
BASE="${BACKUP_PATH:-/var/myexport}" # Backup directoryMYSQL_USER: MySQL username (default: root)MYSQL_ROOT_PASSWORD: MySQL password (optional if using socket authentication)BACKUP_PATH: Backup directory location (default: /var/myexport)
When running in a container, set environment variables:
docker run -e MYSQL_ROOT_PASSWORD=mypassword \
-e BACKUP_PATH=/mnt \
-v /host/backup:/mnt \
mysql-container /path/to/mysql-backup.sh --all-databases./mysql-backup.shCreates separate compressed files for each database: dbname.sql.0.gz, dbname.sql.1.gz, etc.
./mysql-backup.sh --all-databasesCreates a single file containing all databases: databases.sql.0.gz
./mysql-backup.sh myapp_db analytics_dbOnly backs up the specified databases.
The script maintains multiple copies of each backup using a rotation system:
database.sql.0.gz- Most recent backupdatabase.sql.1.gz- Previous backupdatabase.sql.2.gz- Older backup (if COPIES=3)
Each time the script runs, it rotates existing backups:
- Deletes the oldest backup (beyond COPIES limit)
- Renames existing backups (0 → 1, 1 → 2, etc.)
- Creates new backup as .0.gz
export MYSQL_USER=backup
export MYSQL_ROOT_PASSWORD=secure_password
export BACKUP_PATH=/var/myexport
./mysql-backup.sh# Decompress and restore
gunzip < /var/myexport/mydb.sql.0.gz | mysql -u root -p mydb
# Or restore all databases
gunzip < /var/myexport/databases.sql.0.gz | mysql -u root -pls -lh /var/myexport/*.gzError: Backup directory not available
- Ensure the directory exists:
mkdir -p /var/myexport - Check permissions: The user running the script needs write access
Authentication errors
- Verify MySQL credentials
- For socket authentication, ensure the script runs as the appropriate user
- Check if password contains special characters (may need quoting)
No databases found
- Verify MySQL is running:
systemctl status mysql - Check user has appropriate permissions:
SHOW GRANTS FOR 'backup'@'localhost';
This repository previously contained three separate scripts that have been consolidated:
container.sh- Container-focused all-databases backupextended.sh- Feature-rich individual database backupsoriginal.sh- Basic backup functionality
These have been combined into the unified mysql-backup.sh script.
Free to use and modify.