插件窝 干货文章 干货:MySQL增量备份脚本

干货:MySQL增量备份脚本

备份 binlog backup MySQL 378    来源:    2025-05-16

MySQL增量备份脚本指南

基本概念

MySQL增量备份是指只备份自上次备份以来发生变化的数据,相比全量备份可以节省存储空间和备份时间。增量备份通常基于二进制日志(binlog)实现。

增量备份脚本实现

方案1:基于binlog的增量备份

#!/bin/bash

# MySQL增量备份脚本
# 需要先开启MySQL的binlog功能

# 配置参数
MYSQL_USER="backup_user"
MYSQL_PASSWORD="your_password"
MYSQL_HOST="localhost"
BACKUP_DIR="/data/backups/mysql/incremental"
DATE=$(date +%Y%m%d_%H%M%S)
LOG_FILE="/var/log/mysql_incremental_backup.log"

# 创建备份目录
mkdir -p ${BACKUP_DIR}/${DATE}

# 获取当前binlog文件及位置
BINLOG_INFO=$(mysql -u${MYSQL_USER} -p${MYSQL_PASSWORD} -h${MYSQL_HOST} -e "SHOW MASTER STATUS" | awk 'NR==2 {print $1, $2}')

if [ -z "$BINLOG_INFO" ]; then
    echo "[$(date +'%Y-%m-%d %H:%M:%S')] Error: Cannot get binlog info" >> ${LOG_FILE}
    exit 1
fi

BINLOG_FILE=$(echo $BINLOG_INFO | awk '{print $1}')
BINLOG_POS=$(echo $BINLOG_INFO | awk '{print $2}')

# 刷新日志,生成新的binlog文件
mysqladmin -u${MYSQL_USER} -p${MYSQL_PASSWORD} -h${MYSQL_HOST} flush-logs

# 备份旧的binlog文件
BINLOG_DIR=$(mysql -u${MYSQL_USER} -p${MYSQL_PASSWORD} -h${MYSQL_HOST} -e "SHOW VARIABLES LIKE 'log_bin_basename'" | awk 'NR==2 {print $2}')
BINLOG_DIR=$(dirname $BINLOG_DIR)

# 获取需要备份的binlog文件列表
BINLOGS=$(ls -tr ${BINLOG_DIR}/${BINLOG_FILE%.*}* | grep -v "${BINLOG_FILE}$")

for binlog in $BINLOGS; do
    cp $binlog ${BACKUP_DIR}/${DATE}/
    if [ $? -eq 0 ]; then
        echo "[$(date +'%Y-%m-%d %H:%M:%S')] Copied $binlog to ${BACKUP_DIR}/${DATE}" >> ${LOG_FILE}
    else
        echo "[$(date +'%Y-%m-%d %H:%M:%S')] Error copying $binlog" >> ${LOG_FILE}
    fi
done

# 记录本次备份信息
echo "${DATE} ${BINLOG_FILE} ${BINLOG_POS}" >> ${BACKUP_DIR}/binlog_index.txt

# 删除过期备份(保留最近7天)
find ${BACKUP_DIR} -type d -mtime +7 -exec rm -rf {} \;

echo "[$(date +'%Y-%m-%d %H:%M:%S')] Incremental backup completed" >> ${LOG_FILE}

方案2:使用mysqlbinlog工具

#!/bin/bash

# MySQL增量备份脚本(使用mysqlbinlog工具)

# 配置参数
MYSQL_USER="backup_user"
MYSQL_PASSWORD="your_password"
MYSQL_HOST="localhost"
BACKUP_DIR="/data/backups/mysql/incremental"
DATE=$(date +%Y%m%d_%H%M%S)
LOG_FILE="/var/log/mysql_incremental_backup.log"
LAST_BACKUP_FILE="${BACKUP_DIR}/last_backup_info"

# 创建备份目录
mkdir -p ${BACKUP_DIR}/${DATE}

# 获取当前binlog信息
BINLOG_INFO=$(mysql -u${MYSQL_USER} -p${MYSQL_PASSWORD} -h${MYSQL_HOST} -e "SHOW MASTER STATUS" | awk 'NR==2 {print $1, $2}')

if [ -z "$BINLOG_INFO" ]; then
    echo "[$(date +'%Y-%m-%d %H:%M:%S')] Error: Cannot get binlog info" >> ${LOG_FILE}
    exit 1
fi

CURRENT_BINLOG=$(echo $BINLOG_INFO | awk '{print $1}')
CURRENT_POS=$(echo $BINLOG_INFO | awk '{print $2}')

# 读取上次备份的位置
if [ -f "$LAST_BACKUP_FILE" ]; then
    LAST_BACKUP_INFO=$(cat $LAST_BACKUP_FILE)
    LAST_BINLOG=$(echo $LAST_BACKUP_INFO | awk '{print $1}')
    LAST_POS=$(echo $LAST_BACKUP_INFO | awk '{print $2}')
else
    # 如果是第一次备份,则从当前binlog的开头开始
    LAST_BINLOG=$CURRENT_BINLOG
    LAST_POS=4  # binlog文件通常从位置4开始
fi

# 生成增量备份
BACKUP_FILE="${BACKUP_DIR}/${DATE}/incremental_${DATE}.sql"

# 使用mysqlbinlog工具导出增量数据
mysqlbinlog --start-position=${LAST_POS} --stop-position=${CURRENT_POS} \
    -u${MYSQL_USER} -p${MYSQL_PASSWORD} -h${MYSQL_HOST} \
    ${LAST_BINLOG} > ${BACKUP_FILE}

if [ $? -eq 0 ]; then
    echo "[$(date +'%Y-%m-%d %H:%M:%S')] Incremental backup created: ${BACKUP_FILE}" >> ${LOG_FILE}
    # 记录本次备份位置
    echo "${CURRENT_BINLOG} ${CURRENT_POS}" > ${LAST_BACKUP_FILE}
else
    echo "[$(date +'%Y-%m-%d %H:%M:%S')] Error creating incremental backup" >> ${LOG_FILE}
    exit 1
fi

# 压缩备份文件
gzip ${BACKUP_FILE}

# 删除过期备份(保留最近7天)
find ${BACKUP_DIR} -type d -mtime +7 -exec rm -rf {} \;

echo "[$(date +'%Y-%m-%d %H:%M:%S')] Incremental backup completed" >> ${LOG_FILE}

使用说明

  1. 准备工作

    • 确保MySQL已开启binlog功能(在my.cnf中设置log_bin=mysql-bin
    • 创建备份专用用户并授予必要权限: sql CREATE USER 'backup_user'@'localhost' IDENTIFIED BY 'your_password'; GRANT RELOAD, SUPER, REPLICATION CLIENT ON *.* TO 'backup_user'@'localhost'; GRANT SELECT ON mysql.* TO 'backup_user'@'localhost'; FLUSH PRIVILEGES;
  2. 脚本部署

    • 将脚本保存为mysql_incremental_backup.sh
    • 添加可执行权限:chmod +x mysql_incremental_backup.sh
    • 设置定时任务(如每天凌晨2点执行): bash 0 2 * * * /path/to/mysql_incremental_backup.sh
  3. 恢复数据

    • 先恢复最近的全量备份
    • 然后按顺序应用增量备份: bash mysql -u root -p < full_backup.sql mysqlbinlog incremental_backup.000001 | mysql -u root -p mysqlbinlog incremental_backup.000002 | mysql -u root -p

注意事项

  1. 增量备份必须与全量备份配合使用
  2. 定期测试备份的可用性
  3. 确保备份文件的安全性(加密或限制访问权限)
  4. 监控备份日志,确保备份成功执行
  5. 根据业务需求调整备份保留策略

高级方案

对于生产环境,可以考虑使用专业的备份工具: - Percona XtraBackup(支持热备份) - MySQL Enterprise Backup - mydumper/myloader

这些工具提供了更完善的备份恢复功能,适合大规模生产环境使用。