MySQL8.x逻辑备份_基于mysqldump的MySQL 8.x全量逻辑备份脚本_最新更新时间20260318

发布时间:2026/5/23 3:00:50

MySQL8.x逻辑备份_基于mysqldump的MySQL 8.x全量逻辑备份脚本_最新更新时间20260318 本脚本为 MySQL 8.0 设计的实例级 mysqldump 逻辑全备脚本可对整个数据库实例进行备份完整涵盖数据、表结构、存储过程、函数、事件、触发器等所有对象。1 备份脚本本地备份#!/bin/bash # MySQL 8.0 全实例自动备份脚本 # 功能备份所有数据库包含存储过程、函数、事件、触发器 # 配置区 # MySQL 连接配置 MYSQL_USERroot # MySQL 用户名 MYSQL_PASSyour_password # MySQL 密码建议使用配置文件免密 MYSQL_HOSTlocalhost # MySQL 主机 MYSQL_PORT3306 # MySQL 端口 # 备份路径配置 BACKUP_BASE_DIR/data/mysql_backup # 备份根目录 DATE_STAMP$(date %Y%m%d_%H%M%S) # 时间戳格式 BACKUP_DIR${BACKUP_BASE_DIR}/full_${DATE_STAMP} # 本次备份目录 # 备份保留天数自动清理旧备份 RETENTION_DAYS7 # 日志文件 LOG_FILE${BACKUP_BASE_DIR}/backup.log # 函数定义 # 记录日志函数 log_message() { echo [$(date %Y-%m-%d %H:%M:%S)] $1 ${LOG_FILE} } # 检查错误函数 check_error() { if [ $? -ne 0 ]; then log_message 错误: $1 exit 1 fi } # 主程序开始 log_message MySQL全量备份开始 # 1. 创建备份目录 mkdir -p ${BACKUP_DIR} check_error 创建备份目录失败 # 2. 设置权限保护备份文件 chmod 750 ${BACKUP_DIR} log_message 备份目录创建成功: ${BACKUP_DIR} # 3. 执行全实例备份关键参数说明 log_message 开始执行mysqldump全实例备份... mysqldump --user${MYSQL_USER} \ --password${MYSQL_PASS} \ --host${MYSQL_HOST} \ --port${MYSQL_PORT} \ --all-databases \ --single-transaction \ --routines \ --events \ --triggers \ --flush-logs \ --source-data2 \ --set-gtid-purgedOFF \ --default-character-setutf8mb4 \ --max-allowed-packet1G \ --hex-blob \ --result-file${BACKUP_DIR}/mysql_full_backup_${DATE_STAMP}.sql check_error mysqldump备份执行失败 log_message MySQL全实例备份完成: ${BACKUP_DIR}/mysql_full_backup_${DATE_STAMP}.sql # 4. 备份MySQL配置文件重要 cp /etc/my.cnf ${BACKUP_DIR}/my.cnf_backup_${DATE_STAMP} 2/dev/null || log_message 警告: 未找到/etc/my.cnf跳过配置文件备份 # 5. 压缩备份文件节省空间 log_message 开始压缩备份文件... gzip ${BACKUP_DIR}/mysql_full_backup_${DATE_STAMP}.sql check_error 备份文件压缩失败 log_message 备份文件压缩完成: ${BACKUP_DIR}/mysql_full_backup_${DATE_STAMP}.sql.gz # 6. 生成MD5校验文件验证备份完整性 md5sum ${BACKUP_DIR}/mysql_full_backup_${DATE_STAMP}.sql.gz ${BACKUP_DIR}/backup.md5 log_message 生成MD5校验文件 # 7. 清理旧备份按保留天数设置 log_message 清理${RETENTION_DAYS}天前的旧备份... find ${BACKUP_BASE_DIR} -name full_* -type d -mtime ${RETENTION_DAYS} -exec rm -rf {} \; 2/dev/null # 8. 输出备份信息 BACKUP_SIZE$(du -sh ${BACKUP_DIR} | cut -f1) log_message 备份完成! 备份大小: ${BACKUP_SIZE}, 备份位置: ${BACKUP_DIR} # 9. 验证备份文件完整性 log_message 验证备份文件完整性... md5sum -c ${BACKUP_DIR}/backup.md5 ${LOG_FILE} 21 if [ $? -eq 0 ]; then log_message 备份文件完整性验证通过 else log_message 警告: 备份文件完整性验证失败 fi log_message MySQL全量备份结束 echo 备份已完成! 文件位置: ${BACKUP_DIR}/mysql_full_backup_${DATE_STAMP}.sql.gz脚本名称命名为 mysql_full_backup.sh2 使用教程0.创建备份目录放 /data 上别霍霍根盘 mkdir -p /data/mysql_backup chown root:root /data/mysql_backup chmod 750 /data/mysql_backup ls -ld /data/mysql_backup 1. 保存脚本并赋予执行权限 cd /data/mysql_backup vim mysql_full_backup.sh #把脚本复制粘贴进来配置信息根据实际修改 chown root:root mysql_full_backup.sh chmod 750 mysql_full_backup.sh 2. 配置MySQL免密认证​​可选推荐避免密码明文 在/root/.my.cnf中添加 [client] userroot passwordyour_password hostlocalhost port3306 然后设置权限chmod 600 /root/.my.cnf 3. 先手工跑一次建议用 bash 显式执行排除环境差异 bash /data/mysql_backup/mysql_full_backup.sh echo $? 因为在 Linux/Unix 里命令执行完都会给系统一个退出码exit code用来告诉你“这事儿干成没”。 0 成功一切正常 非 0 失败或异常不同数字代表不同类型的问题 所以你执行完脚本后敲的 echo $? $? 就是上一条命令的退出码。你看到 0说明脚本最后是“成功结束”的。 4.验收产物是否完整 ls -ltr /data/mysql_backup | tail ls -lh /data/mysql_backup/full_*/mysql_full_backup_*.sql.gz | tail -n 2 ls -lh /data/mysql_backup/full_*/backup.md5 | tail -n 2 5.验收日志看关键字 tail -n 80 /data/mysql_backup/backup.log 6. 最后配置定时任务每日凌晨0点执行 # 编辑crontabcrontab -e 添加如下内容并保存 crontab -e 0 0 * * * /data/mysql_backupmysql_full_backup.sh #运行时尽量不抢占服务器资源 0 1 * * * nice -n 19 ionice -c2 -n7 /data/mysql_backup/mysql_full_backup.sh 7.每次运行的日志管理 因为现在日志写在同一个文件/data/mysql_backup/backup.log 方案 A: 最靠谱、最“企业标准”的做法用 logrotate 给 /data/mysql_backup/backup.log 做轮转切割保留压缩。这样日志不会一直堆积还能留历史可追溯。 cat /etc/logrotate.d/mysql_full_backup EOF /data/mysql_backup/backup.log { daily rotate 14 compress delaycompress missingok notifempty copytruncate dateext dateformat -%Y%m%d create 640 root root } EOF 这份配置的意思 daily每天切一次 rotate 14保留 14 天历史你想 7/30 改数字就行 compress旧日志自动 gzip 压缩 copytruncate不重启脚本/服务也能安全轮转对你这种“脚本追加写日志”很适配 dateext文件名带日期查日志不费劲 7.1立刻测试一下不等到明天 logrotate -vf /etc/logrotate.d/mysql_full_backup ls -lh /data/mysql_backup/backup.log* 方案 B简单粗暴每天清空只保留当天日志 如果你不需要历史只要“今天跑没跑”那就在 cron 里每天跑前截断 0 0 * * * : /data/mysql_backup/backup.log /data/mysql_backup/mysql_full_backup.sh ⚠️ 缺点历史全没了排查“前几天发生了啥”会很尴尬。3 恢复备份​​文件1.解压.gz备份文件为sql文件 cd /tmp #首先进入备份存放路径 gunzip mysql_full_backup_20260318_010001.sql.gz 2.恢复(日常生产恢复用方式 2 就可以了。) 2.1方式1闷头干活的恢复 mysql -u root -p mysql_full_backup_20260318_010001.sql 2.2方式2tee留日志版 mysql -u root -p xxx.sql 21 | tee /tmp/restore.log 2.3方式3大文件首选pv tee 版 pv xxx.sql | mysql -u root -p 21 | tee /tmp/restore.log 3.恢复后校验恢复完成后登录 MySQL 3.1 mysql -u root -p 输入密码进入 3.2确认数据库是否存在 SHOW DATABASES; 3.3确认表数量是否正常 SHOW TABLES; SHOW FULL TABLES; 或者 SELECT COUNT(*) AS table_count FROM information_schema.tables WHERE table_schema 你的库名 AND table_type BASE TABLE; 3.4确认具体表清单 SELECT table_name FROM information_schema.tables WHERE table_schema 你的库名 AND table_type BASE TABLE ORDER BY table_name; 3.5如需查看表和视图一起 SELECT table_name, table_type FROM information_schema.tables WHERE table_schema 你的库名 ORDER BY table_type, table_name; 3.6关键表数据校验 把下面表名替换成你实际业务表。 USE 你的库名; SELECT 表1 AS table_name, COUNT(*) AS row_count FROM 表1 UNION ALL SELECT 表2, COUNT(*) FROM 表2 UNION ALL SELECT 表3, COUNT(*) FROM 表3; 3.7抽查表数据内容 SELECT * FROM 表1 LIMIT 10; SELECT * FROM 表1 ORDER BY create_time DESC LIMIT 10;4 优化后备份脚本本地异地备份用法和2一样只是加了传输至异地备份服务器。1. 创建备份目录2. 设置权限3. 执行mysqldump4. 备份my.cnf5. 压缩6. 生成MD57. 清理本地7天前备份8. 输出备份信息9. 校验MD510. 上传异地这里用到5异地备份SSH免密登录操作指南11. 清理异地7天前备份12. 结束#!/bin/bash # MySQL 8.0 全实例自动备份脚本 # 功能备份所有数据库包含存储过程、函数、事件、触发器 # 配置区 # MySQL 连接配置 MYSQL_USERroot # MySQL 用户名 MYSQL_PASSyour_password # MySQL 密码建议使用配置文件免密 MYSQL_HOSTlocalhost # MySQL 主机 MYSQL_PORT3306 # MySQL 端口 # 备份路径配置 BACKUP_BASE_DIR/data/mysql_backup # 备份根目录 DATE_STAMP$(date %Y%m%d_%H%M%S) # 时间戳格式 BACKUP_DIR${BACKUP_BASE_DIR}/full_${DATE_STAMP} # 本次备份目录 # 备份保留天数自动清理旧备份 RETENTION_DAYS7 # 日志文件 LOG_FILE${BACKUP_BASE_DIR}/backup_$(date %F).log # 异地备份服务器配置这里本地→异地做了ssh免密登录 REMOTE_USERyour_remote_user REMOTE_HOSTyour_remote_host REMOTE_DIR/path/to/remote_backup_dir # 异地备份保留天数 REMOTE_RETENTION_DAYS7 # 函数定义 # 记录日志函数 log_message() { echo [$(date %Y-%m-%d %H:%M:%S)] $1 ${LOG_FILE} } # 检查错误函数 check_error() { if [ $? -ne 0 ]; then log_message 错误: $1 exit 1 fi } # 0. 清理7天前日志文件 find ${BACKUP_BASE_DIR} -type f -name backup_*.log -mtime 7 -delete 2/dev/null # 本次备份任务主程序开始 log_message MySQL全量备份开始 # 1. 创建备份目录 mkdir -p ${BACKUP_DIR} check_error 创建备份目录失败 # 2. 设置权限保护备份文件 chmod 750 ${BACKUP_DIR} log_message 备份目录创建成功: ${BACKUP_DIR} # 3. 执行全实例备份关键参数说明 log_message 开始执行mysqldump全实例备份... mysqldump --user${MYSQL_USER} \ --password${MYSQL_PASS} \ --host${MYSQL_HOST} \ --port${MYSQL_PORT} \ --all-databases \ --single-transaction \ --routines \ --events \ --triggers \ --flush-logs \ --source-data2 \ --set-gtid-purgedOFF \ --default-character-setutf8mb4 \ --max-allowed-packet1G \ --hex-blob \ --result-file${BACKUP_DIR}/mysql_full_backup_${DATE_STAMP}.sql check_error mysqldump备份执行失败 log_message MySQL全实例备份完成: ${BACKUP_DIR}/mysql_full_backup_${DATE_STAMP}.sql # 4. 备份MySQL配置文件重要 cp /etc/my.cnf ${BACKUP_DIR}/my.cnf_backup_${DATE_STAMP} 2/dev/null || log_message 警告: 未找到/etc/my.cnf跳过配置文件备份 # 5. 压缩备份文件节省空间 log_message 开始压缩备份文件... gzip ${BACKUP_DIR}/mysql_full_backup_${DATE_STAMP}.sql check_error 备份文件压缩失败 log_message 备份文件压缩完成: ${BACKUP_DIR}/mysql_full_backup_${DATE_STAMP}.sql.gz # 6. 生成MD5校验文件验证备份完整性 md5sum ${BACKUP_DIR}/mysql_full_backup_${DATE_STAMP}.sql.gz ${BACKUP_DIR}/backup.md5 log_message 生成MD5校验文件 # 7. 清理旧备份按保留天数设置 log_message 清理${RETENTION_DAYS}天前的旧备份... find ${BACKUP_BASE_DIR} -name full_* -type d -mtime ${RETENTION_DAYS} -exec rm -rf {} \; 2/dev/null # 8. 输出备份信息 BACKUP_SIZE$(du -sh ${BACKUP_DIR} | cut -f1) log_message 备份完成! 备份大小: ${BACKUP_SIZE}, 备份位置: ${BACKUP_DIR} # 9. 验证备份文件完整性 log_message 验证备份文件完整性... md5sum -c ${BACKUP_DIR}/backup.md5 ${LOG_FILE} 21 if [ $? -eq 0 ]; then log_message 备份文件完整性验证通过 else log_message 警告: 备份文件完整性验证失败 exit 1 fi # 10. 传输本次最新备份到异地备份服务器 log_message 开始传输本次最新备份到异地服务器: ${REMOTE_HOST}:${REMOTE_DIR} scp ${BACKUP_DIR}/mysql_full_backup_${DATE_STAMP}.sql.gz \ ${REMOTE_USER}${REMOTE_HOST}:${REMOTE_DIR}/ check_error 传输备份文件到异地服务器失败 scp ${BACKUP_DIR}/backup.md5 \ ${REMOTE_USER}${REMOTE_HOST}:${REMOTE_DIR}/backup_${DATE_STAMP}.md5 check_error 传输MD5校验文件到异地服务器失败 log_message 本次最新备份传输完成: ${REMOTE_HOST}:${REMOTE_DIR} # 11. 清理异地7天前备份文件 log_message 清理异地${REMOTE_RETENTION_DAYS}天前的旧备份... ssh ${REMOTE_USER}${REMOTE_HOST} find ${REMOTE_DIR} -type f \( -name mysql_full_backup_*.sql.gz -o -name backup_*.md5 \) -mtime ${REMOTE_RETENTION_DAYS} -delete check_error 清理异地旧备份失败 log_message 异地旧备份清理完成 log_message MySQL全量备份结束 echo 备份已完成! 文件位置: ${BACKUP_DIR}/mysql_full_backup_${DATE_STAMP}.sql.gz5 异地备份SSH免密登录简洁操作指南# SSH 免密登录简洁操作指南 # 目标从本地服务器 源服务器IP 免密登录到异地备份服务器 目标服务器IP # 1. 先查看本地是否已有 SSH 密钥 ls -l ~/.ssh # 重点看是否存在以下文件之一 # id_rsa / id_rsa.pub # 或 # id_ed25519 / id_ed25519.pub # 2. 如果没有密钥则生成 SSH 密钥 ssh-keygen -t rsa -b 2048 # 提示输入保存路径时直接回车 # 提示输入密码短语时直接回车留空 # 3. 将公钥拷贝到远端服务器 ssh-copy-id root目标服务器IP # 首次连接提示是否继续时输入yes # 然后输入远端 root 密码 # 4. 测试是否免密成功 ssh root目标服务器IP # 如果不再提示输入密码说明免密配置成功 # 5. 测试文件传输 echo backup test /tmp/test_backup.txt scp /tmp/test_backup.txt root目标服务器IP:/path/to/remote_backup_dir/ ssh root目标服务器IP cat /path/to/remote_backup_dir/test_backup.txt # 如果输出 backup test说明 scp 传输也正常

相关新闻