MySQL 完全备份与增量备份
场景要求:对 company 数据库进行自动备份: 完全备份: 每周六 01:00 执行,保存至 /backup/mysql/full/。 增量备份: 每天 03:00 执行,保存至 /backup/mysql/increment/。 使用 Shell 脚本 + Crontab 实现自动备份,通过 Binlog 实现增量备份,并完成数据恢复测试。
两项定时任务:
-
每周六 01:00:使用
mysqldump备份所有数据库到/backup/mysql/full/。 -
每天 03:00:切换 Binlog,并将已关闭的 Binlog 文件归档到
/backup/mysql/increment/。
兼容 MySQL 5.7 / 8.0 和 CentOS 7。
一、完整 Shell 脚本
创建文件:
vi /usr/local/bin/mysql_backup.sh
以下为完整内容:
#!/bin/bash
user="root"
pass="Root@123456"
export MYSQL_PWD="$pass"
full="/backup/mysql/full"
inc="/backup/mysql/increment"
marker="/backup/mysql/midnight_binlog"
set -o pipefail
mkdir -p "$full" "$inc" || exit 1
if [ "$1" = "rotate" ]; then
mysql -u"$user" -e "FLUSH BINARY LOGS" || exit 1
current=$(mysql -u"$user" -Nse \
"SHOW MASTER STATUS" | awk '{print $1}') || exit 1
[ -n "$current" ] || exit 1
echo "$current" > "$marker.tmp" &&
mv "$marker.tmp" "$marker" || exit 1
elif [ "$1" = "full" ]; then
[ "$(date +%w)" = "6" ] || exit 0
backup_date=$(date +%F_%H-%M-%S)
backup_file="$full/full_$backup_date.sql.gz"
if ! mysqldump -u"$user" --all-databases \
--single-transaction --master-data=2 \
--routines --events --triggers \
| gzip > "$backup_file"; then
rm -f "$backup_file"
exit 1
fi
elif [ "$1" = "increment" ]; then
[ -s "$marker" ] || exit 1
marker_name=$(cat "$marker")
index=$(mysql -u"$user" -Nse \
"SHOW VARIABLES LIKE 'log_bin_index'" | awk '{print $2}') || exit 1
[ -n "$index" ] && [ -r "$index" ] || exit 1
found=0
while IFS= read -r log; do
[ -n "$log" ] || continue
[[ "$log" != /* ]] && log="$(dirname "$index")/$log"
name=$(basename "$log")
if [ "$name" = "$marker_name" ]; then
found=1
break
fi
[ -f "$inc/$name" ] && continue
cp "$log" "$inc/$name.tmp" &&
mv "$inc/$name.tmp" "$inc/$name" || exit 1
done < "$index"
[ "$found" = "1" ] || exit 1
else
echo "Usage: $0 rotate|full|increment"
exit 1
fi
二、定时任务及赋权
执行 crontab -e,添加以下三条:
0 0 * * * /usr/local/bin/mysql_backup.sh rotate >> /var/log/mysql_backup.log 2>&1
0 1 * * 6 /usr/local/bin/mysql_backup.sh full >> /var/log/mysql_backup.log 2>&1
0 3 * * * /usr/local/bin/mysql_backup.sh increment >> /var/log/mysql_backup.log 2>&1
赋予脚本执行权限:
chmod +x /usr/local/bin/mysql_backup.sh
三、每天的执行顺序
时间 操作
00:00 刷新 Binlog,并记录新日志文件名作为归档边界
01:00(周六) 执行全量热备份
03:00 归档边界之前已关闭的 Binlog,也就是前一天的日志
四、手动测试
先手动测试增量归档:
/usr/local/bin/mysql_backup.sh increment
周六测试全量备份:
/usr/local/bin/mysql_backup.sh full
查看备份文件:
ls -lh /backup/mysql/full/
ls -lh /backup/mysql/increment/
tail -30 /var/log/mysql_backup.log