mysql冷备份
环境:mysql 有挂volume 的mysql in docker,否则主机要有mysqldump,以下为其中一台示例,其余修改ip即可
一、服务器信息表
1 2 3 4
| | 服务器名称 | IP地址 | 用途 | |------------|------------|--------------------| | 服务器1 | 10.1.1.12 | 主数据库服务器 | | 服务器2 | 10.1.1.13 | 备用服务器/从库 |
|
二、全量备份脚本(/var/lib/mysql/backup.sh)
1
| vim /var/lib/mysql/backup.sh
|
制下述内容并粘贴到文件里(注:红色部分为服务器的IP,请确认是否为当前服务器)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| #!/bin/bash
DB_USER="root" DB_PASSWORD="123456" DB_HOST="10.1.1.12" DB_NAME="sys"
BACKUP_DIR="/backups/full" LOG_FILE="/var/log/mysql_backup.log" TIMESTAMP=$(date +"%Y%m%d")
mkdir -p ${BACKUP_DIR}
echo "[$(date +'%F %T')] 开始全量备份" >> ${LOG_FILE} mysqldump -u${DB_USER} -p${DB_PASSWORD} -h${DB_HOST} \ --single-transaction \ --routines \ --events \ --databases ${DB_NAME} \ > ${BACKUP_DIR}/${DB_NAME}_full_${TIMESTAMP}.sql
tar -czvf ${BACKUP_DIR}/${DB_NAME}_full_${TIMESTAMP}.tar.gz \ -C ${BACKUP_DIR} ${DB_NAME}_full_${TIMESTAMP}.sql rm -f ${BACKUP_DIR}/${DB_NAME}_full_${TIMESTAMP}.sql
find ${BACKUP_DIR} -name "*.tar.gz" -mtime +7 -exec rm -f {} \;
echo "[$(date +'%F %T')] 全量备份完成" >> ${LOG_FILE}
|
三、增量备份脚本(/var/lib/mysql/incremental.sh)
1. 复制下述内容并粘贴到文件里(注:红色部分为服务器的IP,请确认是否为当前服务器):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
|
DB_USER="root" DB_PASSWORD="123456" DB_HOST="10.1.1.12" DB_NAME="sys"
BACKUP_DIR="/backups/incremental" LOG_FILE="/var/log/mysql_backup.log" TIMESTAMP=$(date +"%Y%m%d_%H%M%S")
BINLOG_DIR="/var/lib/mysql" POSITION_FILE="/backups/binlog_position.txt"
mkdir -p ${BACKUP_DIR}
echo "[$(date +'%F %T')] 开始增量备份" >> ${LOG_FILE}
CURRENT_STATUS=$(mysql -u${DB_USER} -p${DB_PASSWORD} -h${DB_HOST} -e "SHOW MASTER STATUS;" 2>>${LOG_FILE}) if [ $? -ne 0 ]; then echo "[ERROR] 无法获取MASTER STATUS" >> ${LOG_FILE} exit 1 fi
CURRENT_BINLOG=$(echo "${CURRENT_STATUS}" | awk 'NR==2 {print $1}') CURRENT_POSITION=$(echo "${CURRENT_STATUS}" | awk 'NR==2 {print $2}')
if [ ! -f ${POSITION_FILE} ]; then echo "${CURRENT_BINLOG} ${CURRENT_POSITION}" > ${POSITION_FILE} echo "[WARNING] 首次运行,仅记录初始位置" >> ${LOG_FILE} exit 0 fi
LAST_BINLOG=$(awk '{print $1}' ${POSITION_FILE}) LAST_POSITION=$(awk '{print $2}' ${POSITION_FILE})
echo "正在处理二进制日志:${LAST_BINLOG} 从位置 ${LAST_POSITION}" >> ${LOG_FILE} mysqlbinlog --start-position=${LAST_POSITION} \ ${BINLOG_DIR}/${LAST_BINLOG} \ > ${BACKUP_DIR}/${DB_NAME}_inc_${TIMESTAMP}.sql 2>>${LOG_FILE}
if [ ! -s ${BACKUP_DIR}/${DB_NAME}_inc_${TIMESTAMP}.sql ]; then echo "[ERROR] 增量备份文件为空或未创建" >> ${LOG_FILE} exit 2 fi
echo "${CURRENT_BINLOG} ${CURRENT_POSITION}" > ${POSITION_FILE}
tar -czvf ${BACKUP_DIR}/${DB_NAME}_inc_${TIMESTAMP}.tar.gz \ -C ${BACKUP_DIR} ${DB_NAME}_inc_${TIMESTAMP}.sql rm -f ${BACKUP_DIR}/${DB_NAME}_inc_${TIMESTAMP}.sql
echo "[$(date +'%F %T')] 增量备份完成" >> ${LOG_FILE}
|
四、定时任务配置
使用键盘按下i键之后输入
1 2 3 4 5 6
| crontab -e
0 8 * * * /usr/bin/docker exec mysql /bin/bash /var/lib/mysql/incremental.sh 0 8 * * 1 /usr/bin/docker exec mysql /bin/bash /var/lib/mysql/backup.sh
|
检查机制
您提出的补充检查机制非常重要,以下是为备份方案增加的详细检查流程设计:
MySQL备份检查方案
一、基础状态检查
1 2 3 4 5 6 7 8 9 10 11
| crontab -l systemctl status cron
ls -lh /backups/full/ ls -lh /backups/incremental/
file /backups/full/*.tar.gz tar -ztvf /backups/full/sys_full_20231001.tar.gz
|
二、日志分析
1 2 3 4 5
| tail -f /var/log/mysql_backup.log
grep 'mysql_backup' /var/log/cron
|
三、自动化检查脚本
创建 /scripts/check_backup.sh:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| #!/bin/bash
BACKUP_DIRS=("/backups/full" "/backups/incremental") MIN_SIZE=10240 MAX_AGE=48
check_files() { for dir in "${BACKUP_DIRS[@]}"; do latest_file=$(find ${dir} -type f -name "*.tar.gz" -printf '%T@ %p\n' | sort -n | tail -1 | cut -f2- -d" ")
if [ -z "$latest_file" ]; then echo "[ERROR] ${dir} 无备份文件存在!" exit 1 fi
file_size=$(du -b "$latest_file" | awk '{print $1}') file_age=$(( ( $(date +%s) - $(stat -c %Y "$latest_file") ) / 3600 ))
if [ "$file_size" -lt "$MIN_SIZE" ]; then echo "[WARNING] ${latest_file} 文件大小异常(${file_size} bytes)" fi
if [ "$file_age" -gt "$MAX_AGE" ]; then echo "[ERROR] ${dir} 最近备份已超过${MAX_AGE}小时!" exit 2 fi done }
check_files echo "[OK] 备份状态正常" exit 0
|
四、恢复验证(关键步骤)
1 2 3 4 5 6 7 8 9 10 11
| mysql -uroot -p123456 -h10.1.1.12 -e "CREATE DATABASE backup_test;"
tar -zxvf sys_full_20231001.tar.gz -C /tmp/
mysql -uroot -p123456 -h10.1.1.12 backup_test < /tmp/sys_full_20231001.sql
mysql -uroot -p123456 -h10.1.1.12 -e "USE backup_test; SHOW TABLES;"
|
五、监控集成方案
1 2 3 4 5 6
| UserParameter=mysql.backup.status[*], /scripts/check_backup.sh $1
echo "mysql_backup_timestamp $(date +%s)" > /var/lib/node_exporter/mysql_backup.prom
|
六、常见故障排查表
| 现象 |
检查命令 |
解决方案 |
| 无备份文件生成 |
ls /backups/* |
检查脚本权限:chmod +x /var/lib/mysql/*.sh |
| 备份文件大小为0 |
du -sh /backups/* |
验证数据库连接:mysql -u$USER -p$PASS -h$HOST -e "STATUS;" |
| 定时任务未执行 |
grep 'CRON' /var/log/syslog |
修正crontab中的docker拼写错误 |
| 增量备份中断 |
cat /backups/binlog_position.txt |
检查二进制日志是否开启:SHOW VARIABLES LIKE 'log_bin'; |
检查方案部署步骤
添加检查脚本
1 2 3 4
| sudo mkdir -p /scripts sudo nano /scripts/check_backup.sh
sudo chmod +x /scripts/check_backup.sh
|
设置每日自动检查
1
| (crontab -l ; echo "0 9 * * * /scripts/check_backup.sh >> /var/log/backup_check.log 2>&1") | crontab -
|
配置邮件报警(示例)
1 2 3 4 5 6
| ALERT_EMAIL="admin@example.com"
if [ $? -ne 0 ]; then mail -s "MySQL备份异常报警" $ALERT_EMAIL < /tmp/error.log fi
|
手动测试全量备份
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| root@txpc:/var/lib/mysql + DB_USER=root + DB_PASSWORD=123456 + DB_HOST=localhost + DB_NAME=sys + BACKUP_DIR=/backups/full + LOG_FILE=/var/log/mysql_backup.log ++ date +%Y%m%d + TIMESTAMP=20250331 + mkdir -p /backups/full ++ date '+%F %T' + echo '[2025-03-31 20:51:55] 开始全量备份' + mysqldump -uroot -p123456 -hlocalhost --single-transaction --routines --events --databases sys mysqldump: [Warning] Using a password on the command line interface can be insecure. + tar -czvf /backups/full/sys_full_20250331.tar.gz -C /backups/full sys_full_20250331.sql sys_full_20250331.sql + rm -f /backups/full/sys_full_20250331.sql + find /backups/full -name '*.tar.gz' -mtime +7 -exec rm -f '{}' ';' ++ date '+%F %T' + echo '[2025-03-31 20:51:56] 全量备份完成' root@txpc:~ [2025-03-31 20:51:55] 开始全量备份 [2025-03-31 20:51:56] 全量备份完成 root@txpc:~ . .. sys_full_20250331.tar.gz
|
增量备份测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| root@txpc:/var/lib/mysql + DB_USER=root + DB_PASSWORD=123456 + DB_HOST=localhost + DB_NAME=sys + BACKUP_DIR=/backups/incremental + LOG_FILE=/var/log/mysql_backup.log ++ date +%Y%m%d_%H%M%S + TIMESTAMP=20250331_211234 + BINLOG_DIR=/var/lib/mysql + POSITION_FILE=/backups/binlog_position.txt + mkdir -p /backups/incremental ++ date '+%F %T' + echo '[2025-03-31 21:12:34] 开始增量备份' ++ mysql -uroot -p123456 -hlocalhost -e 'SHOW MASTER STATUS;' + CURRENT_STATUS='File Position Binlog_Do_DB Binlog_Ignore_DB Executed_Gtid_Set binlog.000023 157 ' + '[' 0 -ne 0 ']' ++ echo 'File Position Binlog_Do_DB Binlog_Ignore_DB Executed_Gtid_Set binlog.000023 157 ' ++ awk 'NR==2 {print $1}' + CURRENT_BINLOG=binlog.000023 ++ echo 'File Position Binlog_Do_DB Binlog_Ignore_DB Executed_Gtid_Set binlog.000023 157 ' ++ awk 'NR==2 {print $2}' + CURRENT_POSITION=157 + '[' '!' -f /backups/binlog_position.txt ']' ++ awk '{print $1}' /backups/binlog_position.txt + LAST_BINLOG=binlog.000023 ++ awk '{print $2}' /backups/binlog_position.txt + LAST_POSITION=157 + echo '正在处理二进制日志:binlog.000023 从位置 157' + mysqlbinlog --start-position=157 /var/lib/mysql/binlog.000023 + '[' '!' -s /backups/incremental/sys_inc_20250331_211234.sql ']' + echo 'binlog.000023 157' + tar -czvf /backups/incremental/sys_inc_20250331_211234.tar.gz -C /backups/incremental sys_inc_20250331_211234.sql sys_inc_20250331_211234.sql + rm -f /backups/incremental/sys_inc_20250331_211234.sql ++ date '+%F %T' + echo '[2025-03-31 21:12:34] 增量备份完成' root@txpc:/var/lib/mysql [2025-03-31 21:12:34] 开始增量备份 mysql: [Warning] Using a password on the command line interface can be insecure. 正在处理二进制日志:binlog.000023 从位置 157 [2025-03-31 21:12:34] 增量备份完成 root@txpc:/var/lib/mysql 总计 4.0K -rw-r--r-- 1 root root 680 3月 31 21:12 sys_inc_20250331_211234.tar.gz
|
