对于DBA来说,数据库备份就像程序员的「Ctrl+S」——平时不起眼,出事了能救命,而且是最重要的救命手段,没有之一。
相信很多DBA都有过这样的惊魂时刻:开发手滑,一条没有WHERE条件的DELETE语句下去,用户表瞬间清空;服务器宕机,数据目录损坏,眼看业务停摆,领导在身后催得焦头烂额……
我至今还记得2018年的那次事故:开发误删用户全量数据,当时只有每天凌晨1次的全量备份,事故发生在下午5点,我们硬生生靠binlog恢复了4个小时,业务停摆半天,损失惨重。
从那以后,我们彻底重构了备份策略——从“裸奔式”每日全备,升级为「全量备份+增量备份+binlog归档」的黄金组合,RTO(恢复时间目标)从4小时压缩到30分钟,RPO(恢复点目标)从24小时缩减到5分钟,再也不用为数据丢失夜不能寐。
今天,就把这份沉淀了多年的MySQL备份恢复实战攻略,毫无保留分享给大家——涵盖mysqldump和xtrabackup两大核心工具,从基础用法到生产实战,从故障排查到最佳实践,新手能上手,老手能避坑。
一、先搞懂:两大备份工具,该选谁?
MySQL备份工具千千万,但生产环境最常用、最靠谱的,就两个:mysqldump 和 Percona XtraBackup。它们就像两把“双刃剑”,各有专攻,选对了能省90%的麻烦。
核心结论:小型数据库选mysqldump(简单省心),大型数据库选XtraBackup(高效低影响),跨版本迁移必用mysqldump。
1.1 mysqldump:MySQL官方“轻量选手”
mysqldump是MySQL自带的逻辑备份工具,说白了就是“把数据库里的数据,导出成SQL语句”,就像把一本书的内容逐字抄下来,可读性强,操作简单。
特性详细说明备份类型逻辑备份(导出SQL语句,肉眼可看)锁机制默认锁表,可用--single-transaction实现InnoDB一致性读(不锁表)速度较慢(要逐行查询、生成SQL),大数据量会“卡壳”适用场景小型数据库(50GB)、生产环境低影响备份优点快速、低影响、支持增量备份,恢复速度快缺点只支持同版本恢复,配置比mysqldump复杂,需要额外安装1.3 场景对应表(直接抄作业)
不用纠结,对照下面的场景选工具,准没错:
应用场景推荐工具备份策略开发测试环境mysqldump每日全备(简单省事)小型生产(500GB)XtraBackup每周全备 + 每日增量 + 流式备份跨版本迁移mysqldump逻辑导出导入(兼容性强)表级恢复mysqldump单表导出(精准恢复,不影响其他表)时间点恢复(PITR)XtraBackup + binlog全备 + binlog应用(恢复到任意时间点)1.4 环境要求(必看,避免踩坑)
环境不匹配,备份必失败!提前核对以下版本和配置:
组件版本要求关键说明MySQL Server8.0.35+ 或 8.4 LTS稳定版优先,避免使用测试版Percona XtraBackup8.0.35+版本必须与MySQL匹配(比如MySQL 8.0.35,XtraBackup也用8.0.35)操作系统Rocky 9 / Ubuntu 24.04生产环境推荐,兼容性最好磁盘空间数据量的2-3倍预留备份、压缩、恢复的空间,避免空间不足导致备份失败qpress最新版XtraBackup压缩备份必需工具二、实战操作:从准备到备份,一步到位
铺垫再多,不如动手操作。这部分是核心,每一步都有详细命令,直接复制粘贴就能用(记得替换自己的密码和目录)。
2.1 准备工作(3步搞定,避免后续踩坑)
2.1.1 安装备份工具
分两种操作系统,按需选择:
✅ Rocky Linux 9 / CentOS Stream 9
- # 安装Percona仓库(XtraBackup需要)
- sudo dnf install -y https://repo.percona.com/yum/percona-release-latest.noarch.rpm
- sudo percona-release setup pxb-80
- # 安装XtraBackup
- sudo dnf install -y percona-xtrabackup-80
- # 安装压缩工具(备份压缩必需)
- sudo dnf install -y qpress lz4
- # 验证安装(出现版本号即成功)
- xtrabackup --version
- # 正常输出:xtrabackup version 8.0.35-30 based on MySQL server 8.0.35
复制代码 ✅ Ubuntu 24.04
- sudo apt-get update
- sudo apt-get install -y wget gnupg2 lsb-release
- wget https://repo.percona.com/apt/percona-release_latest.generic_all.deb
- sudo dpkg -i percona-release_latest.generic_all.deb
- sudo percona-release setup pxb-80
- sudo apt-get install -y percona-xtrabackup-80 qpress
复制代码 2.1.2 创建备份专用用户
不要用root用户备份!创建专用备份用户,分配最小权限,更安全:- -- 登录MySQL,执行以下SQL
- CREATE USER 'backup'@'localhost' IDENTIFIED BY 'BackupPass@2024'; -- 密码替换成自己的
- -- mysqldump所需权限(复制粘贴即可)
- GRANT SELECT, SHOW VIEW, TRIGGER, LOCK TABLES, EVENT ON *.* TO 'backup'@'localhost';
- -- XtraBackup所需权限(复制粘贴即可)
- GRANT RELOAD, PROCESS, LOCK TABLES, REPLICATION CLIENT ON *.* TO 'backup'@'localhost';
- GRANT BACKUP_ADMIN ON *.* TO 'backup'@'localhost'; -- MySQL 8.0+ 必需
- GRANT SELECT ON performance_schema.log_status TO 'backup'@'localhost';
- GRANT SELECT ON performance_schema.keyring_component_status TO 'backup'@'localhost';
- FLUSH PRIVILEGES; -- 刷新权限,立即生效
复制代码 2.1.3 规划备份目录
目录混乱会导致后续恢复找不到文件,建议按以下结构创建,一目了然:- # 创建备份目录结构(一次性执行)
- sudo mkdir -p /backup/mysql/{full,incremental,binlog,scripts,logs}
- sudo chown -R mysql:mysql /backup/mysql # 授权mysql用户,避免权限不足
- sudo chmod 750 /backup/mysql # 限制访问权限,更安全
- # 目录说明(记好,后续用得到):
- # /backup/mysql/full - 存放全量备份
- # /backup/mysql/incremental - 存放增量备份
- # /backup/mysql/binlog - 存放binlog归档
- # /backup/mysql/scripts - 存放备份脚本
- # /backup/mysql/logs - 存放备份日志
- # 重要提醒:备份目录建议用独立磁盘或NFS挂载,避免和数据目录在同一磁盘(防止磁盘损坏一起丢)
复制代码 2.2 核心操作:mysqldump实战用法
适合小型数据库,操作简单,以下是最常用的几种场景,覆盖90%的需求:
✅ 备份单个数据库
- mysqldump -u backup -p'BackupPass@2024' \
- --single-transaction \ # InnoDB不锁表,关键参数
- --routines \ # 备份存储过程和函数
- --triggers \ # 备份触发器
- --events \ # 备份事件调度器
- mydb > /backup/mysql/full/mydb_$(date +%Y%m%d).sql # 备份到指定目录,带日期
复制代码 ✅ 备份多个数据库
- mysqldump -u backup -p'BackupPass@2024' \
- --single-transaction \
- --routines \
- --triggers \
- --databases db1 db2 db3 > /backup/mysql/full/multi_db_$(date +%Y%m%d).sql
复制代码 ✅ 备份所有数据库(最常用)
- mysqldump -u backup -p'BackupPass@2024' \
- --single-transaction \
- --routines \
- --triggers \
- --events \
- --all-databases > /backup/mysql/full/all_db_$(date +%Y%m%d).sql
复制代码 ✅ 备份单个表(精准恢复,不影响其他表)
- mysqldump -u backup -p'BackupPass@2024' \
- --single-transaction \
- mydb users > /backup/mysql/full/mydb_users_$(date +%Y%m%d).sql # mydb是库名,users是表名
复制代码 ✅ 生产环境推荐参数组合(带压缩,更省空间)
这是我平时用的配置,兼顾安全和效率,直接复制用:- mysqldump -u backup -p'BackupPass@2024' \
- --single-transaction \ # InnoDB一致性读,不锁表(必需)
- --source-data=2 \ # 记录binlog位置(注释形式,方便恢复)
- --routines \ # 包含存储过程和函数
- --triggers \ # 包含触发器
- --events \ # 包含事件调度器
- --set-gtid-purged=AUTO \ # GTID自动处理(MySQL 8.0+ 推荐)
- --hex-blob \ # 二进制数据用十六进制,避免乱码
- --quick \ # 逐行读取,减少内存占用
- --max-allowed-packet=512M \ # 支持大数据包,避免导出失败
- --default-character-set=utf8mb4 \ # 字符集,避免乱码
- --all-databases \
- | gzip > /backup/mysql/full/all_db_$(date +%Y%m%d).sql.gz # 压缩备份,省空间
复制代码 注意:MySQL 8.0.26+ 版本,--master-data 参数已改为 --source-data,别用错了!
2.3 核心操作:XtraBackup实战用法
适合大型数据库,热备份、速度快,重点掌握全量和增量备份(生产环境最常用)。
✅ 全量备份(基础,增量备份的前提)
- # 基础全量备份
- xtrabackup --backup \
- --user=backup \
- --password='BackupPass@2024' \
- --target-dir=/backup/mysql/full/$(date +%Y%m%d) # 备份目录带日期,方便区分
- # 备份并压缩(推荐,省空间)
- xtrabackup --backup \
- --user=backup \
- --password='BackupPass@2024' \
- --target-dir=/backup/mysql/full/$(date +%Y%m%d) \
- --compress \ # 开启压缩
- --compress-threads=4 # 4线程压缩,提升速度
- # 流式备份到远程(大型库推荐,避免本地磁盘不够)
- xtrabackup --backup \
- --user=backup \
- --password='BackupPass@2024' \
- --stream=xbstream \ # 流式输出
- --compress \
- | ssh backup@remote-server "cat > /backup/mysql/full_$(date +%Y%m%d).xbstream" # 传输到远程服务器
复制代码 ✅ 增量备份(省空间,适合大型库)
增量备份只备份上次备份后变化的数据,比全量备份小很多,步骤如下(必须基于全量备份):- # 第一步:创建全量备份(基准备份,只做一次)
- xtrabackup --backup \
- --user=backup \
- --password='BackupPass@2024' \
- --target-dir=/backup/mysql/full/base
- # 第二步:创建第一次增量备份(基于全量备份)
- xtrabackup --backup \
- --user=backup \
- --password='BackupPass@2024' \
- --target-dir=/backup/mysql/incremental/inc1 \
- --incremental-basedir=/backup/mysql/full/base # 指定基准备份目录
- # 第三步:创建第二次增量备份(基于第一次增量)
- xtrabackup --backup \
- --user=backup \
- --password='BackupPass@2024' \
- --target-dir=/backup/mysql/incremental/inc2 \
- --incremental-basedir=/backup/mysql/incremental/inc1 # 指定上一次增量备份目录
复制代码 ✅ 备份准备与恢复(关键,备份了不能恢复等于白做)
XtraBackup备份后不能直接恢复,必须先“准备”(应用redo log,确保数据一致性):- # 1. 准备全量备份(基准备份)
- xtrabackup --prepare \
- --apply-log-only \ # 只应用redo log,不做其他操作(增量备份必需)
- --target-dir=/backup/mysql/full/base
- # 2. 应用第一次增量备份到基准备份
- xtrabackup --prepare \
- --apply-log-only \
- --target-dir=/backup/mysql/full/base \
- --incremental-dir=/backup/mysql/incremental/inc1
- # 3. 应用第二次增量备份(最后一次增量,不用加--apply-log-only)
- xtrabackup --prepare \
- --target-dir=/backup/mysql/full/base \
- --incremental-dir=/backup/mysql/incremental/inc2
- # 4. 最终准备(确保数据完整)
- xtrabackup --prepare \
- --target-dir=/backup/mysql/full/base
- # 恢复备份(停止MySQL后执行)
- xtrabackup --copy-back \
- --target-dir=/backup/mysql/full/base
- # 恢复后设置权限(必须,否则MySQL启动失败)
- chown -R mysql:mysql /data/mysql/data # /data/mysql/data是你的MySQL数据目录
复制代码 三、生产实战:脚本+案例,直接落地
手动执行备份太麻烦,而且容易忘,生产环境一定要用脚本+定时任务,实现自动化备份。另外,附上3个高频故障恢复案例,帮你应对突发情况。
3.1 生产环境备份脚本(直接复制可用)
✅ mysqldump备份脚本(小型数据库)
文件路径:/backup/mysql/scripts/mysqldump_backup.sh,记得替换配置中的密码和目录:- #!/bin/bash
- # 文件:/backup/mysql/scripts/mysqldump_backup.sh
- # 功能:生产环境mysqldump自动化备份脚本
- # 用法:./mysqldump_backup.sh [full|single] [database_name]
- set -e # 执行出错立即退出
- # 配置(按需修改)
- MYSQL_USER="backup"
- MYSQL_PASS="BackupPass@2024" # 替换成你的备份用户密码
- MYSQL_HOST="localhost"
- BACKUP_DIR="/backup/mysql/full"
- LOG_DIR="/backup/mysql/logs"
- RETENTION_DAYS=7 # 备份保留7天,自动清理
- DATE=$(date +%Y%m%d_%H%M%S)
- LOG_FILE="${LOG_DIR}/mysqldump_${DATE}.log"
- # 备份元数据库(记录备份信息,可选)
- META_DB="backup_meta"
- RECORD_BACKUP=true
- # 初始化目录
- mkdir -p ${BACKUP_DIR} ${LOG_DIR}
- # 日志函数
- log() {
- echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a ${LOG_FILE}
- }
- # 记录备份结果到元数据库
- record_backup() {
- local status=$1
- local error_msg=$2
- local end_time=$(date '+%Y-%m-%d %H:%M:%S')
- local backup_size=$(stat -c%s ${BACKUP_FILE} 2>/dev/null || echo 0)
- local compressed_size=$(stat -c%s ${BACKUP_FILE}.gz 2>/dev/null || echo 0)
- if [ "$RECORD_BACKUP" = true ]; then
- mysql -u${MYSQL_USER} -p${MYSQL_PASS} ${META_DB} << EOF
- UPDATE backup_history SET
- end_time = '${end_time}',
- duration_seconds = TIMESTAMPDIFF(SECOND, start_time, '${end_time}'),
- status = '${status}',
- backup_size_bytes = ${backup_size},
- compressed_size_bytes = ${compressed_size},
- error_message = '${error_msg}'
- WHERE id = ${BACKUP_ID};
- EOF
- fi
- }
- # 全量备份
- do_full_backup() {
- log "Starting full backup..."
- BACKUP_FILE="${BACKUP_DIR}/all_databases_${DATE}.sql"
- # 获取binlog位置(用于时间点恢复)
- BINLOG_INFO=$(mysql -u${MYSQL_USER} -p${MYSQL_PASS} -N -e "SHOW MASTER STATUS")
- BINLOG_FILE=$(echo $BINLOG_INFO | awk '{print $1}')
- BINLOG_POS=$(echo $BINLOG_INFO | awk '{print $2}')
- GTID_EXECUTED=$(mysql -u${MYSQL_USER} -p${MYSQL_PASS} -N -e "SELECT @@global.gtid_executed" | tr '\n' ' ')
- # 记录备份开始
- if [ "$RECORD_BACKUP" = true ]; then
- BACKUP_ID=$(mysql -u${MYSQL_USER} -p${MYSQL_PASS} ${META_DB} -N -e "
- INSERT INTO backup_history (backup_type, backup_tool, backup_path, start_time, binlog_file, binlog_position, gtid_executed)
- VALUES ('full', 'mysqldump', '${BACKUP_FILE}', NOW(), '${BINLOG_FILE}', ${BINLOG_POS}, '${GTID_EXECUTED}');
- SELECT LAST_INSERT_ID();
- ")
- fi
- # 执行备份
- log "Backup file: ${BACKUP_FILE}"
- log "Binlog: ${BINLOG_FILE}:${BINLOG_POS}"
- mysqldump -u${MYSQL_USER} -p${MYSQL_PASS} -h${MYSQL_HOST} \
- --single-transaction \
- --source-data=2 \
- --routines \
- --triggers \
- --events \
- --set-gtid-purged=AUTO \
- --hex-blob \
- --quick \
- --max-allowed-packet=512M \
- --default-character-set=utf8mb4 \
- --all-databases > ${BACKUP_FILE} 2>>${LOG_FILE}
- if [ $? -eq 0 ]; then
- log "Backup completed successfully"
- # 压缩备份
- log "Compressing backup..."
- gzip ${BACKUP_FILE}
- log "Compressed size: $(du -h ${BACKUP_FILE}.gz | cut -f1)"
- record_backup "success" ""
- else
- log "Backup FAILED!"
- record_backup "failed" "mysqldump failed"
- exit 1
- fi
- }
- # 单库备份
- do_single_backup() {
- local DB_NAME=$1
- log "Starting single database backup: ${DB_NAME}"
- BACKUP_FILE="${BACKUP_DIR}/${DB_NAME}_${DATE}.sql"
- mysqldump -u${MYSQL_USER} -p${MYSQL_PASS} -h${MYSQL_HOST} \
- --single-transaction \
- --source-data=2 \
- --routines \
- --triggers \
- --set-gtid-purged=AUTO \
- --hex-blob \
- --quick \
- ${DB_NAME} > ${BACKUP_FILE} 2>>${LOG_FILE}
- if [ $? -eq 0 ]; then
- log "Single database backup completed: ${DB_NAME}"
- gzip ${BACKUP_FILE}
- else
- log "Single database backup FAILED: ${DB_NAME}"
- exit 1
- fi
- }
- # 清理旧备份(保留7天)
- cleanup_old_backups() {
- log "Cleaning up backups older than ${RETENTION_DAYS} days..."
- find ${BACKUP_DIR} -name "*.sql.gz" -mtime +${RETENTION_DAYS} -delete
- find ${LOG_DIR} -name "*.log" -mtime +${RETENTION_DAYS} -delete
- log "Cleanup completed"
- }
- # 主程序
- case "$1" in
- full)
- do_full_backup
- ;;
- single)
- if [ -z "$2" ]; then
- log "Error: Database name required"
- exit 1
- fi
- do_single_backup $2
- ;;
- *)
- do_full_backup # 默认执行全量备份
- ;;
- esac
- cleanup_old_backups
- log "Backup script completed"
复制代码 ✅ XtraBackup备份脚本(大型数据库)
文件路径:/backup/mysql/scripts/xtrabackup_backup.sh,支持全量和增量备份:✅ 定时任务配置(自动化备份关键)
用crontab设置定时任务,让脚本自动执行,不用手动操作:- # 编辑crontab(执行命令)
- crontab -e
- # -------------- 小型数据库(mysqldump)--------------
- # 每天凌晨2点执行全备,日志写入cron.log
- 0 2 * * * /backup/mysql/scripts/mysqldump_backup.sh full >> /backup/mysql/logs/cron.log 2>&1
- # -------------- 大型数据库(XtraBackup)--------------
- # 每周日凌晨2点执行全备
- 0 2 * * 0 /backup/mysql/scripts/xtrabackup_backup.sh full >> /backup/mysql/logs/cron.log 2>&1
- # 周一到周六凌晨2点执行增量备份
- 0 2 * * 1-6 /backup/mysql/scripts/xtrabackup_backup.sh incremental >> /backup/mysql/logs/cron.log 2>&1
- # -------------- binlog归档(每小时一次)--------------
- 0 * * * * /backup/mysql/scripts/binlog_archive.sh >> /backup/mysql/logs/cron.log 2>&1
复制代码 3.2 高频故障恢复案例(实战必备)
案例一:误删数据恢复(最常见)
场景:开发误执行DELETE语句,删除了users表中当天的数据(本想删除无效用户,忘了加WHERE条件)。- -- 误操作SQL(噩梦开始)
- DELETE FROM users WHERE created_at >= '2024-01-15';
- -- 正确SQL(应该加条件)
- DELETE FROM users WHERE created_at >= '2024-01-15' AND status = 'inactive';
复制代码 恢复步骤(关键:立即记录binlog位置,避免数据覆盖):- # 第一步:立即记录当前binlog位置(重中之重,防止binlog滚动)
- mysql -uroot -p -e "SHOW MASTER STATUS"
- # 记录结果:File: mysql-bin.000150, Position: 123456789
- # 第二步:找到最近的全量备份
- ls -la /backup/mysql/full/
- # 假设最新备份:all_databases_20240115_020000.sql.gz
- # 第三步:解压备份,恢复到临时库(避免影响生产库)
- # 解压备份
- gunzip -c /backup/mysql/full/all_databases_20240115_020000.sql.gz > /tmp/restore.sql
- # 创建临时库
- mysql -uroot -p -e "CREATE DATABASE users_recovery"
- # 只恢复users表(精准恢复,节省时间)
- # 方法1:用sed提取users表
- sed -n '/^-- Table structure for table `users`/,/^-- Table structure for table/p' /tmp/restore.sql > /tmp/users_table.sql
- # 方法2:用awk提取(更精准)
- awk '/^-- Table structure for table `users`/{f=1} f; /^UNLOCK TABLES;/{if(f) exit}' /tmp/restore.sql > /tmp/users_table.sql
- # 导入到临时库
- mysql -uroot -p users_recovery < /tmp/users_table.sql
- # 第四步:确认备份的binlog位置(从备份文件中提取)
- grep "CHANGE MASTER TO" /tmp/restore.sql | head -1
- # 输出:-- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000145', MASTER_LOG_POS=789012;
- # 第五步:应用binlog,恢复到误删之前
- # 先找到误删操作的binlog位置
- mysqlbinlog /data/mysql/binlog/mysql-bin.000145 mysql-bin.000146 \
- --start-position=789012 \
- --database=mydb \
- -v | grep -B5 -A5 "DELETE FROM.*users"
- # 找到误删位置后,应用binlog到误删前
- mysqlbinlog /data/mysql/binlog/mysql-bin.000145 mysql-bin.000146 \
- --start-position=789012 \
- --stop-position=误删操作位置 \ # 替换成实际误删位置
- --database=mydb | mysql -uroot -p users_recovery
- # 第六步:将恢复的数据导回生产库
- mysqldump -uroot -p users_recovery users | mysql -uroot -p mydb
复制代码 案例二:时间点恢复(PITR)
场景:数据库因误操作、病毒攻击等,需要恢复到指定时间点(比如2024-01-15 14:30:00)。- #!/bin/bash
- # 文件:point_in_time_recovery.sh
- # 功能:MySQL时间点恢复脚本
- # 用法:直接执行,修改配置中的恢复时间和目录
- RECOVERY_TIME="2024-01-15 14:30:00" # 目标恢复时间
- BACKUP_DIR="/backup/mysql/full/20240115" # 最近的全量备份目录
- BINLOG_DIR="/data/mysql/binlog" # binlog目录
- RECOVERY_DIR="/data/mysql_recovery" # 恢复临时目录
- # 第一步:准备备份(解压+应用redo log)
- echo "Preparing backup..."
- cp -r ${BACKUP_DIR} ${RECOVERY_DIR}
- # 解压压缩的备份文件(如果是压缩备份)
- cd ${RECOVERY_DIR}
- for f in *.qp; do
- qpress -d $f ./
- done
- # 准备备份,确保数据一致性
- xtrabackup --prepare --target-dir=${RECOVERY_DIR}
- # 第二步:获取备份的binlog位置(从备份文件中提取)
- BINLOG_INFO=$(cat ${RECOVERY_DIR}/xtrabackup_binlog_info)
- BINLOG_FILE=$(echo $BINLOG_INFO | awk '{print $1}')
- BINLOG_POS=$(echo $BINLOG_INFO | awk '{print $2}')
- echo "Backup binlog position: ${BINLOG_FILE}:${BINLOG_POS}"
- # 第三步:找到需要应用的binlog文件
- BINLOG_FILES=$(ls ${BINLOG_DIR}/mysql-bin.* | sort | awk -v start="${BINLOG_FILE}" '$0 >= start')
- # 第四步:应用binlog到指定时间点
- echo "Applying binlog until ${RECOVERY_TIME}..."
- mysqlbinlog ${BINLOG_FILES} \
- --start-position=${BINLOG_POS} \
- --stop-datetime="${RECOVERY_TIME}" \
- > ${RECOVERY_DIR}/binlog_recovery.sql
- # 第五步:恢复数据到生产环境
- echo "Stopping MySQL..."
- systemctl stop mysqld
- # 备份当前生产数据目录(安全起见,防止恢复失败)
- mv /data/mysql/data /data/mysql/data_old_$(date +%Y%m%d_%H%M%S)
- # 恢复备份
- xtrabackup --copy-back --target-dir=${RECOVERY_DIR}
- chown -R mysql:mysql /data/mysql/data # 设置权限
- # 启动MySQL
- systemctl start mysqld
- # 应用binlog增量,完成时间点恢复
- echo "Applying binlog recovery..."
- mysql -uroot -p < ${RECOVERY_DIR}/binlog_recovery.sql
- echo "Point-in-time recovery completed to ${RECOVERY_TIME}"
复制代码 案例三:大表备份与恢复(500GB+)
场景:orders表有5亿条数据,单表500GB,直接备份/恢复会卡死,用分区导出导入,提升效率。
[code]# 备份脚本:large_table_backup.sh(分区导出)#!/bin/bashTABLE="orders"DB="ecommerce"BACKUP_DIR="/backup/mysql/large_tables"DATE=$(date +%Y%m%d)PARALLEL_JOBS=4 # 4线程并行,按需调整mkdir -p ${BACKUP_DIR}/${DATE}# 获取表的主键范围(按主键分区)MAX_ID=$(mysql -ubackup -p'BackupPass@2024' -N -e "SELECT MAX(id) FROM ${DB}.${TABLE}")BATCH_SIZE=$((MAX_ID / PARALLEL_JOBS))# 并行导出(按主键分段,避免单线程卡死)for i in $(seq 1 ${PARALLEL_JOBS}); do START_ID=$(( (i-1) * BATCH_SIZE + 1 )) END_ID=$(( i * BATCH_SIZE )) if [ $i -eq ${PARALLEL_JOBS} ]; then END_ID=${MAX_ID} # 最后一段包含剩余数据 fi echo "Exporting ${TABLE} rows ${START_ID} to ${END_ID}..." mysqldump -ubackup -p'BackupPass@2024' \ --single-transaction \ --no-create-info \ # 只导出数据,表结构单独导出 --where="id >= ${START_ID} AND id |