MySQL中万能备份脚本的实现详解
作者:liuziyi
此脚本适用于 MySQL 各个生命周期的版本
#!/bin/bash
# mybackup.sh
# 备份保留天数,建议保留三天
days=7
# 备份时间
time=$(date +%Y%m%d%H%M%S)
# 备份保存路径
backup_dir=/opt/backup
# 备份工具
tool=mysqldump
# 端口
port="3306"
# 是否采用 --all-databases 备份所有数据库,是填写 Y,否填其他
read -p "是否备份所有数据库?(Y/N): " bak_all
# 将要备份的数据库,填写将要备份的数据库名
if [ "$bak_all" != "Y" ]; then
read -p "请输入要备份的数据库名,多个数据库用空格分隔: " database_input
IFS=' ' read -r -a database_arr <<< "$database_input"
fi
# 输入账号和密码
read -p "请输入 MySQL 用户名: " username
read -s -p "请输入 MySQL 密码: " password
echo
# 检查文件夹是否存在,不存在则创建
if [ ! -d "$backup_dir/mysqlbak_$time" ]; then
mkdir -p "$backup_dir/mysqlbak_$time"
fi
# 备份数据库
if [ "$bak_all" == "Y" ]; then
$tool -u"$username" -p"$password" -P"$port" --master-data=2 --single-transaction --set-gtid-purged=on --all-databases | gzip > "$backup_dir/mysqlbak_$time/mysqlbak_all_$time.sql.gz"
else
for database in "${database_arr[@]}"; do
$tool -u"$username" -p"$password" -P"$port" --master-data=2 --single-transaction --set-gtid-purged=on "$database" | gzip > "$backup_dir/mysqlbak_$time/mysqlbak_${database}_${time}.sql.gz"
done
fi
# 备份 binlog 日志
# 获取当前的 binlog 文件列表
binlog_files=$(mysql -u"$username" -p"$password" -P"$port" -e "SHOW BINARY LOGS;" | awk 'NR>1 {print $1}')
for binlog_file in $binlog_files; do
mysqlbinlog -u"$username" -p"$password" -P"$port" "$binlog_file" > "$backup_dir/mysqlbak_$time/${binlog_file}_${time}.log"
done
# 删除指定天数前的备份
find "$backup_dir" -maxdepth 1 -type d -mtime +$days -name 'mysqlbak*' -exec rm -rf {} \;
脚本说明:
账号和密码输入:使用 read 命令在脚本运行时提示用户输入 MySQL 用户名和密码,其中 -s 选项用于隐藏密码输入。
数据库选择:询问用户是否备份所有数据库,如果选择否,则让用户输入要备份的数据库名,多个数据库名用空格分隔。
备份数据库:根据用户的选择,使用 mysqldump 备份所有数据库或指定的数据库,并将备份文件压缩保存。
备份 binlog 日志:
- 使用
mysql -e命令获取当前的 binlog 文件列表。 - 遍历 binlog 文件列表,使用
mysqlbinlog命令将每个 binlog 文件备份到指定的备份目录。
删除旧备份:使用 find 命令删除指定天数前的备份文件夹。
使用方法:
将上述脚本保存为 mybackup.sh。
给脚本添加执行权限:
chmod +x mybackup.sh
运行脚本:
./mybackup.sh
注意事项:
确保用户输入的账号和密码具有足够的权限来执行备份操作。
方法补充
以下是小编为大家整理的其他MySQL 备份脚本,希望对大家有所帮助
脚本代码:
#!/bin/bash
# 定义变量
USER="root"
PASSWORD="123456"
BACKUP_DIR="/backup/mysql"
DATE=$(date +%Y%m%d)
WEEKDAY=$(date +%u) # 1=星期一, 7=星期日
# 创建备份目录
mkdir -p $BACKUP_DIR
# 周日全备份,其他日子增量备份
if [ $WEEKDAY -eq 7 ]; then
# 全备份
echo "$(date): 开始全备份" >> $BACKUP_DIR/backup.log
mysqldump -u$USER -p$PASSWORD --all-databases --single-transaction | gzip > $BACKUP_DIR/full_$DATE.sql.gz
echo "$(date): 全备份完成" >> $BACKUP_DIR/backup.log
else
# 增量备份(备份binlog)
echo "$(date): 开始增量备份" >> $BACKUP_DIR/backup.log
mysql -u$USER -p$PASSWORD -e "FLUSH LOGS"
# 复制最新的binlog文件
cp /usr/local/mysql/data/mysql-bin.$(mysql -u$USER -p$PASSWORD -e "SHOW MASTER STATUS" | awk 'NR==2{print $1}' | sed 's/mysql-bin.//') $BACKUP_DIR/binlog_$DATE
echo "$(date): 增量备份完成" >> $BACKUP_DIR/backup.log
fi
# 删除7天前的备份
find $BACKUP_DIR -name "*.gz" -mtime +7 -delete
find $BACKUP_DIR -name "binlog_*" -mtime +7 -delete脚本解析
1. 变量定义
USER="root" # MySQL用户名 PASSWORD="your_password" # MySQL密码(使用时替换为实际密码) BACKUP_DIR="/backup/mysql" # 备份文件存储目录 DATE=$(date +%Y%m%d) # 当前日期(格式:20231006) WEEKDAY=$(date +%u) # 星期几(1=星期一,7=星期日) #!/bin/bash:指定用Bash解释器执行脚本。
关键变量:
- USER/PASSWORD:连接MySQL的用户和密码。
- BACKUP_DIR:所有备份文件将存储在此目录。
- DATE和WEEKDAY:用于按日期命名备份文件和控制备份类型。
2. 创建备份目录
mkdir -p $BACKUP_DIR -p:如果目录不存在则创建,避免报错。
3. 备份逻辑(核心部分)
情况一:周日全备份
if [ $WEEKDAY -eq 7 ]; then
echo "$(date): 开始全备份" >> $BACKUP_DIR/backup.log
mysqldump -u $USER -p $PASSWORD --all-databases --single-transaction | gzip > $BACKUP_DIR/full_$DATE.sql.gz
echo "$(date): 全备份完成" >> $BACKUP_DIR/backup.logmysqldump关键参数:
--all-databases:备份所有数据库。
--single-transaction:在事务中执行备份,确保数据一致性。
gzip:压缩备份文件以节省空间。
> full_$DATE.sql.gz :输出到以日期命名的压缩文件(如full_20231006.sql.gz)
情况二:其他日期增量备份
else
echo "$(date): 开始增量备份" >> $BACKUP_DIR/backup.log
mysql -u$USER -p$PASSWORD -e "FLUSH LOGS"
cp /usr/local/mysql/data/mysql-bin.$(mysql -u$USER -p$PASSWORD -e "SHOW MASTER STATUS" | awk 'NR==2{print $1}' | sed 's/mysql-bin.//') $BACKUP_DIR/binlog_$DATE
echo "$(date): 增量备份完成" >> $BACKUP_DIR/backup.log
fiFLUSH LOGS:强制MySQL创建新的binlog文件,确保增量备份的边界清晰。(如从mysql-bin.000123切换到mysql-bin.000124)
mysql -u$USER -p$PASSWORD -e "SHOW MASTER STATUS":获取当前binlog文件名(如mysql-bin.000123)。
awk 'NR==2{print $1}' :从SHOW MASTER STATUS的输出中提取第二行的第一列(即 mysql-bin.000123)
sed 's/mysql-bin.//':去掉mysql-bin.前缀把 mysql-bin.000123变成 000123。
/usr/local/mysql/data/mysql-bin.$(...):
作用:组合MySQL的binlog存储路径 + 文件名。
示例:
如果 SHOW MASTER STATUS返回 mysql-bin.000123,则最终路径是:
/var/lib/mysql/mysql-bin.000123
cp ... $BACKUP_DIR/binlog_$DATE
作用:将binlog文件复制到备份目录,并按日期命名(如 binlog_20231006)。
示例:
cp /var/lib/mysql/mysql-bin.000123 /backup/mysql/binlog_20231006
增量备份原理:MySQL的binlog记录了所有数据变更,通过定期保存binlog实现增量备份。
如果没有binlog文件 则再/etc/my.cnf 的 [mysqld] 里添加这一行 log_bin = mysql-bin (启用binlog,文件前缀为mysql-bin)
4. 清理旧备份
find $BACKUP_DIR -name "*.gz" -mtime +7 -delete find $BACKUP_DIR -name "binlog_*" -mtime +7 -delete
作用:自动删除7天前的全备份(.gz文件)和增量备份(binlog_*文件)。
-mtime +7:匹配修改时间超过7天的文件。
-delete:直接删除文件
5. 日志记录
所有操作均通过echo追加到$BACKUP_DIR/backup.log,格式示例:
Mon Oct 6 03:00:01 UTC 2023: 开始全备份
Mon Oct 6 03:02:30 UTC 2023: 全备份完成
关键注意事项
MySQL配置要求:
必须启用binlog(检查my.cnf中是否有log_bin=ON)。
确保/usr/local/mysql/data是正确的binlog路径(根据实际配置调整)。
到此这篇关于MySQL中万能备份脚本的实现详解的文章就介绍到这了,更多相关MySQL备份脚本内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
