How to Set Up Automated Mysql Backups with Cron Jobs and Bash Scripts
Learning how to set up automated MySQL backups with cron jobs and bash scripts is essential for database administrators and server managers who need reliable data protection. This comprehensive tutorial will walk you through creating a robust backup system that runs automatically without manual intervention.
Database backups are critical for any production environment. Manual backups are prone to human error and often forgotten during busy periods. Automated systems ensure your MySQL databases are consistently backed up according to your schedule, whether that’s daily, weekly, or hourly.
In this guide, you’ll learn to create a bash script that handles MySQL dumps, compress the backups to save storage space, and set up cron jobs to run these scripts automatically. We’ll also cover backup rotation to prevent your server from running out of disk space and include error handling to notify you when backups fail.
By the end of this tutorial, you’ll have a fully functional automated backup system that protects your MySQL databases and gives you peace of mind. The techniques covered here work on Ubuntu, CentOS, and most Linux distributions.
Prerequisites and Requirements for Automated MySQL Backups
Before you begin setting up automated MySQL backups with cron jobs and bash scripts, ensure you have the following requirements in place.
You need root access or sudo privileges on your Linux server. This tutorial assumes you’re working with Ubuntu 20.04 or newer, though the commands work on most Linux distributions. Basic knowledge of command-line operations and MySQL administration is helpful but not strictly required.
Your server must have MySQL or MariaDB installed and running. You’ll also need sufficient disk space for backup storage – plan for at least 2-3 times your database size to account for multiple backup copies and compression.
The mysqldump utility should be available on your system. This comes standard with MySQL installations. You’ll also need the gzip compression tool, which is installed by default on most Linux systems.
Create a dedicated MySQL user for backups with appropriate privileges. This follows security best practices by avoiding the use of the root MySQL account for automated scripts. You’ll need the SELECT, SHOW VIEW, TRIGGER, and LOCK TABLES privileges.
Estimated completion time for this tutorial is 30-45 minutes, including testing your backup system.
Step-by-Step Guide to Creating Automated MySQL Backup Scripts
Related article: Host File Edit: Viewing Websites Without DNS
Let’s start by creating the backup directory structure and MySQL user account for our automated backup system.
Step 1: Create the backup directory structure on your server.
sudo mkdir -p /var/backups/mysql
sudo mkdir -p /var/log/mysql-backup
sudo chown $(whoami):$(whoami) /var/backups/mysql
sudo chown $(whoami):$(whoami) /var/log/mysql-backup
These directories will store your backup files and log files respectively. Setting proper ownership ensures your backup script can write to these locations.
Step 2: Create a dedicated MySQL user for backups.
Log into MySQL as root and execute these commands:
mysql -u root -p
CREATE USER 'backup_user'@'localhost' IDENTIFIED BY 'secure_backup_password';
GRANT SELECT, SHOW VIEW, TRIGGER, LOCK TABLES ON . TO 'backup_user'@'localhost';
FLUSH PRIVILEGES;
EXIT;
Replace ‘secure_backup_password’ with a strong password. This user has minimal privileges needed for backups, following security best practices.
Step 3: Create the main backup script.
Create a new file called mysql_backup.sh:
nano /home/$(whoami)/mysql_backup.sh
Add the following content to create your automated MySQL backup script:
#!/bin/bash
# MySQL backup configuration
DB_USER="backup_user"
DB_PASS="secure_backup_password"
DB_HOST="localhost"
BACKUP_DIR="/var/backups/mysql"
LOG_FILE="/var/log/mysql-backup/backup.log"
DATE=$(date +%Y%m%d_%H%M%S)
RETENTION_DAYS=7
# Function to log messages
log_message() {
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> $LOG_FILE
}
# Start backup process
log_message "Starting MySQL backup process"
# Get list of all databases except system databases
DATABASES=$(mysql -u$DB_USER -p$DB_PASS -h$DB_HOST -e "SHOW DATABASES;" | tr -d "| " | grep -v Database | grep -v information_schema | grep -v performance_schema | grep -v mysql | grep -v sys)
# Backup each database
for DB in $DATABASES; do
log_message "Backing up database: $DB"
# Create backup with mysqldump and compress
mysqldump -u$DB_USER -p$DB_PASS -h$DB_HOST --single-transaction --routines --triggers $DB | gzip > $BACKUP_DIR/${DB}_${DATE}.sql.gz
# Check if backup was successful
if [ $? -eq 0 ]; then
log_message "Successfully backed up database: $DB"
else
log_message "ERROR: Failed to backup database: $DB"
fi
done
# Clean up old backups
log_message "Cleaning up backups older than $RETENTION_DAYS days"
find $BACKUP_DIR -name ".sql.gz" -type f -mtime +$RETENTION_DAYS -delete
log_message "MySQL backup process completed"
Step 4: Make the script executable and test it.
chmod +x /home/$(whoami)/mysql_backup.sh
/home/$(whoami)/mysql_backup.sh
Check the backup directory and log file to verify the script worked correctly:
ls -la /var/backups/mysql/
cat /var/log/mysql-backup/backup.log
Step 5: Set up the cron job for automated execution.
Open the crontab editor:
crontab -e
Add this line to run backups daily at 2:00 AM:
0 2 /home/$(whoami)/mysql_backup.sh >/dev/null 2>&1
For different schedules, modify the cron expression. For example, use 0 /6 for every 6 hours, or 0 2 0 for weekly backups on Sunday.
Step 6: Create a backup verification script.
Create an additional script to verify backup integrity:
nano /home/$(whoami)/verify_backup.sh
#!/bin/bash
BACKUP_DIR="/var/backups/mysql"
LOG_FILE="/var/log/mysql-backup/verification.log"
DATE=$(date +%Y%m%d)
echo "$(date '+%Y-%m-%d %H:%M:%S') - Starting backup verification" >> $LOG_FILE
# Find today's backup files
BACKUP_FILES=$(find $BACKUP_DIR -name "${DATE}.sql.gz" -type f)
for FILE in $BACKUP_FILES; do
# Test gzip integrity
if gzip -t $FILE; then
echo "$(date '+%Y-%m-%d %H:%M:%S') - PASS: $FILE" >> $LOG_FILE
else
echo "$(date '+%Y-%m-%d %H:%M:%S') - FAIL: $FILE is corrupted" >> $LOG_FILE
fi
done
echo "$(date '+%Y-%m-%d %H:%M:%S') - Backup verification completed" >> $LOG_FILE
Make it executable and add to cron to run 30 minutes after backups:
chmod +x /home/$(whoami)/verify_backup.sh
Add this line to your crontab:
30 2 /home/$(whoami)/verify_backup.sh
Troubleshooting Common MySQL Backup Issues
When implementing how to set up automated MySQL backups with cron jobs and bash scripts, you may encounter several common issues. Here are the most frequent problems and their solutions.
Permission denied errors are common when scripts can’t write to backup directories. Ensure your backup directories have correct ownership and permissions:
sudo chown -R $(whoami):$(whoami) /var/backups/mysql
sudo chmod 755 /var/backups/mysql
If your MySQL connection fails, verify your backup user credentials and permissions. Test the connection manually:
mysql -u backup_user -p -e "SHOW DATABASES;"
Large database backups may timeout or consume too much memory. Add these options to your mysqldump command for better performance with large databases:
mysqldump -u$DB_USER -p$DB_PASS --single-transaction --quick --lock-tables=false $DB
Cron jobs running in a limited environment may not find required commands. Use full paths in your scripts:
/usr/bin/mysqldump -u$DB_USER -p$DB_PASS $DB | /bin/gzip > $BACKUP_DIR/${DB}_${DATE}.sql.gz
If backups are consuming too much disk space, adjust the retention period or implement differential backups. You can also compress backups further using xz instead of gzip for better compression ratios.
Monitor your backup logs regularly for errors. Set up email notifications by adding this to your script:
if [ $? -ne 0 ]; then
echo "Backup failed for database $DB" | mail -s "MySQL Backup Failed" [email protected]
fi
For more detailed MySQL backup strategies, refer to the <a href="https://dev.
