The Script
Copy this into mysql-backup.sh, edit the configuration block, then make it executable.
Never hardcode database passwords
Use ~/.my.cnf so the password never appears in process listings or script files. Create the file:
Then chmod 600 ~/.my.cnf and drop the -u and -p flags from the mysqldump command — credentials are read automatically.
Step-by-Step Setup
Step 1 — Create the script file
Paste the script above, then press Ctrl+X → Y → Enter to save.
Step 2 — Configure your credentials securely
Never hardcode the database password in the script file — it appears in process listings when the script runs. Use ~/.my.cnf instead:
Paste this (replace with your actual credentials):
Save, then lock down the file so only your user can read it:
Now remove the -u"$DB_USER" -p"$DB_PASS" flags from the mysqldump line in the script — MySQL reads credentials from ~/.my.cnf automatically.
Step 3 — Set your database and backup directory
Edit these four variables at the top of the script:
| Variable | Example | What it means |
|---|---|---|
| DB_NAME | myapp_production | The MySQL database to back up |
| BACKUP_DIR | /var/backups/mysql | Where backup files are stored |
| KEEP_DAYS | 7 | Delete backups older than this many days |
| DATE | (auto) | Timestamp — never change this |
Step 4 — Make it executable and run a test
A successful run shows:
Step 5 — Verify the backup is restorable
A backup you have never tested is a backup you cannot trust. Test a restore to a scratch database:
Do this once after your first backup. Do it again after any major schema change.
How It Works
-u"$DB_USER" and -p"$DB_PASS" — These pass the MySQL username and password to mysqldump. Putting the flags adjacent to the quoted variables (-u"root") avoids a space between -p and the password, which mysqldump expects when you supply the password on the command line. Prefer ~/.my.cnf in production so the password never appears in process listings or the script file.
Gzip pipe — mysqldump writes SQL to standard output. The pipe sends that stream into gzip, which compresses it before the shell redirects the result into ${BACKUP_DIR}/${FILENAME}. You get a single .sql.gz file without an intermediate uncompressed dump on disk.
find … -mtime +"$KEEP_DAYS" -delete — -mtime +N matches files last modified more than N days ago. Combined with -name '*.sql.gz', only compressed dumps in your backup directory are removed. This keeps disk usage bounded while still honoring roughly “last seven daily backups” when you run the script once per day.
mkdir -p "$BACKUP_DIR" — Creates the backup directory (and any missing parents) without error if it already exists, so the script can run on a fresh path or under cron without manual setup.
Schedule It with Cron
Open your crontab and point it at the full path of the script:
Cron PATH
If the job fails silently, set an explicit PATH at the top of the crontab or use absolute paths to mysqldump and gzip. Cron runs with a minimal environment.
Variations
| Use case | What to change |
|---|---|
| Backup all databases | Run mysqldump --all-databases (and adjust FILENAME if you want a fixed name like all-databases_DATE.sql.gz). Omit the single-database argument. |
| Backup to a remote server | After a successful local dump, copy the file with scp or rsync to another host or object storage. Keeps data off the machine you are backing up. |
| MariaDB | The flow is the same. Use the MariaDB client tools: often mariadb-dump instead of mysqldump, and mariadb for restores — options align closely with MySQL. |
Frequently Asked Questions
How do I backup a MySQL database with bash?
Use mysqldump: mysqldump -u username -p dbname > backup.sql. In a script, pass the password with -p'password' or use a .my.cnf credentials file.
How do I automate MySQL backups with cron?
Write a mysqldump script, chmod +x it, then add to crontab: 0 2 * * * /home/user/mysql-backup.sh to run every night at 2am.
How do I keep only the last 7 MySQL backups?
Use find to delete old files: find /backup/ -name '*.sql.gz' -mtime +7 -delete. This removes any backup files older than 7 days.
Should I compress MySQL backups?
Yes. Pipe mysqldump output through gzip: mysqldump ... | gzip > backup.sql.gz. A typical database compresses 80–90%, saving significant disk space.
How do I backup all MySQL databases at once?
Use mysqldump --all-databases instead of specifying one database name. This creates a single dump of all databases.