MySQL增量备份实战指南

一、Xtrabackup基础与优势

1.1 Xtrabackup简介

Xtrabackup是一个开源的MySQL热备份工具,支持InnoDB、XtraDB存储引擎的在线备份,无需停止数据库服务即可完成数据拷贝。它分为两个组件:xtrabackup​(处理InnoDB/XtraDB表空间)和innobackupex​(封装脚本,支持MyISAM等表类型)。

1.2 增量备份原理

增量备份基于全量备份后的变更日志(如InnoDB的redo log),仅复制自上次备份以来修改过的数据页。Xtrabackup通过比较文件校验和或LSN(Log Sequence Number)识别变更,实现高效增量备份。

1.3 Xtrabackup优势

  • 非阻塞备份:在线备份,不影响业务运行。
  • 增量支持:显著减少备份时间和存储需求。
  • 压缩与加密:支持备份文件压缩和加密,增强安全性。
  • 跨平台兼容:支持Linux及Windows(需额外配置)。

二、增量备份前的准备工作

2.1 环境确认

  • MySQL版本:确保MySQL 5.6及以上,或Percona Server对应版本。(Xtrabackup推荐和MySQL版本一模一样)
  • 存储引擎:主要表使用InnoDB或XtraDB。
  • 磁盘空间:备份目录需有足够空间存放增量文件

2.2 安装Xtrabackup

  1. 更新软件包列表:在终端中运行以下命令以确保您的软件包列表是最新的:

    (版本要和MySQL的版本的一模一样)

    复制代码
    sudo apt update
  1. 安装XtraBackup:使用以下命令安装XtraBackup:

    复制代码
    # Ubuntu
    sudo apt install percona-xtrabackup-80
    
    # cenios
    wget https://downloads.percona.com/downloads/Percona-XtraBackup-8.4/Percona-XtraBackup-8.4.0-1/binary/redhat/7/x86_64/percona-xtrabackup-84-8.4.0-1.1.el7.x86_64.rpm
    
    yum -y install libev
    
    yum -y install perl-Digest-MD5
    
    yum install perl-DBD-MySQL -y
    
    yum install -y epel-release
    
    yum install -y https://repo.percona.com/yum/percona-release-latest.noarch.rpm
    percona-release enable-only tools release   # 只启用 tools 和 release 两个仓库
    yum clean all
    
    yum install -y ./percona-xtrabackup-84-8.4.0-1.1.el7.x86_64.rpm
  1. 验证安装:安装完成后,您可以使用以下命令检查XtraBackup的版本,以确认安装成功

    复制代码
    xtrabackup --version

三、全量备份、增量备份

3.1 要备份的数据

  1. 我们去单独设计一个脚本,模拟1000个用户数据

    (先单独创建一个test的库)

    复制代码
    #!/usr/bin/env bash
    DB_HOST="127.0.0.1"
    DB_PORT=3306
    DB_USER="root"
    DB_PWD="123"
    DB_NAME="test"
    TB_NAME="t_user"
    RECORDS=1000
    # 数据量,可以自定义的
    
    USER_ARR=(Alice Bob Carol Dave Eva Fred Gina Henry Iris Jack Kate Leo Mona Nick Olga Peter Quinn Rose Sammy Tina Uma Victor Wendy Xavier Yolanda Zoe)
    MOBILE_PREFIX=(130 131 132 133 134 135 136 137 138 139 150 151 152 153 155 156 157 158 159 170 171 172 173 174 175 176 177 178 180 181 182 183 184 185 186 187 188 189)
    
    rand_ip()    { printf "%d.%d.%d.%d" $((RANDOM%256)) $((RANDOM%256)) $((RANDOM%256)) $((RANDOM%256)) ; }
    rand_user()  { echo "${USER_ARR[RANDOM%${#USER_ARR[@]}]}$((RANDOM%9000+1000))" ; }
    rand_mobile(){ echo "${MOBILE_PREFIX[RANDOM%${#MOBILE_PREFIX[@]}]}$((RANDOM%90000000+10000000))" ; }
    
    SQL="INSERT INTO $TB_NAME(ip,username,mobile) VALUES "
    for ((i=1;i<=RECORDS;i++)); do
      SQL+="('$(rand_ip)','$(rand_user)','$(rand_mobile)')"
      ((i<RECORDS)) && SQL+=","
    done
    mysql -h"$DB_HOST" -P"$DB_PORT" -u"$DB_USER" -p"$DB_PWD" "$DB_NAME" <<<"
    CREATE TABLE IF NOT EXISTS $TB_NAME(
      id       INT AUTO_INCREMENT PRIMARY KEY,
      ip       VARCHAR(15) NOT NULL,
      username VARCHAR(50) NOT NULL,
      mobile   CHAR(11)    NOT NULL,
      KEY idx_mobile(mobile)
    );
    $SQL;
    "
    
    echo "OK 添加 $RECORDS 数据到 $DB_NAME.$TB_NAME"
  1. 验证

    复制代码
    +------+-----------------+-------------+-------------+
    |    1 | 212.54.185.3    | Xavier9139  | 17510020394 |
    |    2 | 63.213.194.35   | Tina1623    | 15710011462 |
    |    3 | 5.32.136.84     | Dave8354    | 15010021720 |
    |    4 | 60.87.255.140   | Peter7920   | 13010030954 |
    |    5 | 134.159.124.74  | Tina3999    | 18710002815 |
    |    6 | 85.46.241.126   | Xavier6694  | 18410011074 |
    |    7 | 139.221.152.147 | Xavier9325  | 18410029894 |
    |    8 | 122.72.212.176  | Leo1702     | 13710017541 |
    |    9 | 242.2.44.145    | Jack7906    | 18310029171 |
    |   10 | 237.28.147.143  | Fred2537    | 18210023547 |
    |   11 | 31.149.72.54    | Alice2085   | 17410002319 |
    |   12 | 212.190.81.254  | Quinn9569   | 18710000674 |
    |   13 | 125.91.133.126  | Alice1473   | 15010014431 |
    |   14 | 90.122.97.60    | Eva5135     | 13010006979 |
    |   15 | 87.250.191.12   | Fred6919    | 15210031312 |

3.2 全量备份

  1. 要备份目录

    复制代码
    mkdir -p /home/backup/full
  1. 创建权限用户

    复制代码
    CREATE USER 'backup'@'localhost' IDENTIFIED BY 'Backup@123';
    GRANT RELOAD, LOCK TABLES, PROCESS, REPLICATION CLIENT, BACKUP_ADMIN ON *.* TO 'backup'@'localhost';
  1. 命令测试

    复制代码
    xtrabackup --defaults-file=/etc/my.cnf \
      --backup \
      --target-dir=/home/backup/full \
      --user=root \
      --password=123 \
      --host=127.0.0.1 \
      --port=3306
    
    
    --backup:备份
    --datadir:mysql文件目录
    --target-dir:要备份到的目录
    --user:数据库帐号
    --password:数据库密码
    --port:端口
    --host:IP
    --no-server-version-check:不检查mysql与percona-xtrabackup版本差别
    --defaults-file:指定上一步复制出来的my.cnf文件(安装在var/lib/mysql的可不加该参数)
  1. 检查

    复制代码
     ls /home/backup/full
    backup-my.cnf  ib_buffer_pool  mysql.ibd           sys       undo_002                xtrabackup_info         zabbix
    binlog.000006  ibdata1         performance_schema  test      xtrabackup_binlog_info  xtrabackup_logfile
    binlog.index   mysql           ry@002dvue          undo_001  xtrabackup_checkpoints  xtrabackup_tablespaces
  1. 恢复数据

    复制代码
    # 删除数据库(测试使用,真实环境想想就行的,不,想都不要想)
    drop database test;
    
    # 停止数据库
    systemctl stop mysqld
    
    # 将数据变成可恢复的数据
    xtrabackup --prepare --target-dir=/home/backup
    
    # (删除)源Data
    mv /usr/local/mysql/data/full /usr/local/mysql/data.bak
    
    # copy-back(真实恢复数据)
    xtrabackup --copy-back --target-dir=/home/backup/full
    
    # 修权限
    chown -R mysql:mysql /usr/local/mysql/data
    
    # MySQL
    systemctl start mysqld
  1. 验证

    复制代码
    mysql -u root -p123 -e "show databases;"
    mysql: [Warning] Using a password on the command line interface can be insecure.
    +--------------------+
    | Database           |
    +--------------------+
    | information_schema |
    | mysql              |
    | performance_schema |
    | ry-vue             |
    | sys                |
    | test               |
    | zabbix             |
    +--------------------+

3.2 增量备份

增量备份要基于全量备份

  1. 第一次全量备份

    复制代码
    xtrabackup --defaults-file=/etc/my.cnf \
      --backup \
      --target-dir=/home/backup/full \
      --user=root \
      --password=123 \
      --host=127.0.0.1 \
      --port=3306
  2. 使用脚本再添加新的数据(但其实,再执行上一个脚本就好了)

    复制代码
    #!/usr/bin/env bash
    
    DB_HOST="127.0.0.1"
    DB_PORT=3306
    DB_USER="root"
    DB_PWD="123"
    DB_NAME="test"
    TB_NAME="t_user"
    RECORDS=1000  # 新增数据条数
    
    USER_ARR=(Alice Bob Carol Dave Eva Fred Gina Henry Iris Jack Kate Leo Mona Nick Olga Peter Quinn Rose Sammy Tina Uma Victor Wendy Xavier Yolanda Zoe)
    MOBILE_PREFIX=(130 131 132 133 134 135 136 137 138 139 150 151 152 153 155 156 157 158 159 170 171 172 173 174 175 176 177 178 180 181 182 183 184 185 186 187 188 189)
    
    rand_ip()    { printf "%d.%d.%d.%d" $((RANDOM%256)) $((RANDOM%256)) $((RANDOM%256)) $((RANDOM%256)) ; }
    rand_user()  { echo "${USER_ARR[RANDOM%${#USER_ARR[@]}]}$((RANDOM%9000+1000))" ; }
    rand_mobile(){ echo "${MOBILE_PREFIX[RANDOM%${#MOBILE_PREFIX[@]}]}$((RANDOM%90000000+10000000))" ; }
    
    MAX_ID=$(mysql -h"$DB_HOST" -P"$DB_PORT" -u"$DB_USER" -p"$DB_PWD" -N -B -e "SELECT IFNULL(MAX(id),0) FROM $DB_NAME.$TB_NAME;")
    
    SQL="INSERT INTO $TB_NAME(ip,username,mobile) VALUES "
    for ((i=1;i<=RECORDS;i++)); do
      SQL+="('$(rand_ip)','$(rand_user)','$(rand_mobile)')"
      ((i<RECORDS)) && SQL+=","
    done
    
    mysql -h"$DB_HOST" -P"$DB_PORT" -u"$DB_USER" -p"$DB_PWD" "$DB_NAME" <<<"
    CREATE TABLE IF NOT EXISTS $TB_NAME(
      id       INT AUTO_INCREMENT PRIMARY KEY,
      ip       VARCHAR(15) NOT NULL,
      username VARCHAR(50) NOT NULL,
      mobile   CHAR(11)    NOT NULL,
      KEY idx_mobile(mobile)
    );
    $SQL;
    "
    
    echo "OK. $RECORDS 新的数据添加到 $DB_NAME.$TB_NAME (starting from ID $((MAX_ID+1)))."
  1. 检查新的数据

    复制代码
    1 | 50.211.173.1    | Mona7447    | 18810022676 |
    | 1972 | 114.131.146.69  | Quinn8745   | 18310001620 |
    | 1973 | 187.141.110.177 | Sammy2000   | 15210020323 |
    | 1974 | 237.120.189.245 | Fred4123    | 13310001165 |
    | 1975 | 152.219.97.35   | Tina1293    | 17610012998 |
    | 1976 | 162.60.130.93   | Henry6128   | 17210023533 |
    | 1977 | 39.58.149.148   | Kate6250    | 15610014183 |
    | 1978 | 136.100.199.174 | Olga1198    | 15310027067 |
    | 1979 | 38.212.135.174  | Peter1276   | 15910025391 |
    | 1980 | 16.69.13.175    | Wendy7280   | 13510003224 |
    | 1981 | 80.84.213.199   | Gina2395    | 17710008313 |
    | 1982 | 125.69.66.27    | Jack5749    | 18410019520 |
    | 1983 | 26.78.245.53    | Tina3497    | 18910002653 |
    | 1984 | 149.236.231.49  | Carol1518   | 15010030166 |
    | 1985 | 228.32.242.161  | Carol5839   | 18510021882 |
    | 1986 | 37.251.12.255   | Zoe2381     | 15910003784 |
    | 1987 | 54.130.196.55   | Quinn6112   | 18710024819 |
    | 1988 | 165.26.157.46   | Uma2973     | 18710005858 |
    | 1989 | 116.15.159.140  | Leo4047     | 17710018837 |
    | 1990 | 186.60.139.253  | Gina9965    | 13010031614 |
    | 1991 | 32.116.12.63    | Tina4830    | 13910027045 |
    | 1992 | 192.21.80.180   | Wendy5562   | 17510024954 |
    | 1993 | 140.173.190.205 | Henry3787   | 13810007033 |
    | 1994 | 235.76.87.6     | Mona7221    | 18510024924 |
    | 1995 | 48.12.213.4     | Mona5646    | 17810027487 |
    | 1996 | 202.57.152.34   | Jack8709    | 13610001444 |
    | 1997 | 170.40.89.50    | Xavier2580  | 13510007627 |
    | 1998 | 207.247.89.180  | Carol4984   | 17510003099 |
    | 1999 | 11.74.42.191    | Leo3005     | 17010005401 |
    | 2000 | 77.214.127.12   | Quinn6290   | 13910028577 |
    +------+-----------------+-------------+-------------+
  1. 第一次增量备份(基于全量备份)

    复制代码
    xtrabackup --backup \
      --target-dir=/home/backup/inc01 \
      --incremental-basedir=/home/backup/full \
      --user=root \
      --password=123 \
      --host=127.0.0.1 \
      --port=3306
  2. 第二次增量备份(基于inc01)

    1. 执行脚本去再加入数据

      复制代码
      | 2976 | 11.189.78.19    | Iris2046    | 17310006847 |
      | 2977 | 43.45.39.70     | Mona8625    | 13210008013 |
      | 2978 | 218.198.189.169 | Henry3688   | 17110012440 |
      | 2979 | 171.69.14.86    | Tina9156    | 17410002798 |
      | 2980 | 44.249.121.140  | Wendy6370   | 18610017135 |
      | 2981 | 219.173.37.70   | Fred5309    | 15310000622 |
      | 2982 | 16.211.254.200  | Yolanda1638 | 18310017474 |
      | 2983 | 99.155.149.176  | Iris1431    | 15910015020 |
      | 2984 | 21.50.219.134   | Fred3068    | 13110020478 |
      | 2985 | 192.217.2.158   | Dave9980    | 15210008564 |
      | 2986 | 117.137.17.59   | Dave8888    | 15010024830 |
      | 2987 | 151.50.244.184  | Alice2742   | 17710013259 |
      | 2988 | 23.87.230.116   | Alice6977   | 13310029974 |
      | 2989 | 246.74.136.28   | Eva4844     | 17810013224 |
      | 2990 | 251.48.107.176  | Sammy6930   | 15610001694 |
      | 2991 | 161.241.175.52  | Uma7078     | 13610031252 |
      | 2992 | 47.186.191.13   | Uma7239     | 15210022271 |
      | 2993 | 95.142.141.154  | Olga5257    | 13610029869 |
      | 2994 | 8.103.209.200   | Victor9020  | 18010016082 |
      | 2995 | 182.234.232.220 | Leo6194     | 13510009070 |
      | 2996 | 86.251.175.245  | Mona7331    | 13110014020 |
      | 2997 | 182.41.194.168  | Alice7727   | 17810022203 |
      | 2998 | 221.63.142.142  | Victor7877  | 15710006483 |
      | 2999 | 184.37.170.148  | Peter6793   | 17010032764 |
      | 3000 | 23.197.68.206   | Bob9457     | 13510019290 |
      +------+-----------------+-------------+-------------+
    2. 增量备份()

      复制代码
      xtrabackup --backup \
        --target-dir=/home/backup/inc02 \
        --incremental-basedir=/home/backup/inc01 \
        --user=root \
        --password=123 \
        --host=127.0.0.1 \
        --port=3306
  1. 合并到全量备份数据

    复制代码
    # 1. 准备全量备份
    xtrabackup --prepare --apply-log-only --target-dir=/home/backup/full
    
    # 2. 合并第一次增量
    xtrabackup --prepare --target-dir=/home/backup/full \
              --incremental-dir=/home/backup/inc01
    
    # 3. 合并第二次增量(重新执行 1)
    xtrabackup --prepare --target-dir=/home/backup/full \
              --incremental-dir=/home/backup/inc02
    
    # 4. 将完整数控重新变成可恢复的备份
    xtrabackup --prepare --target-dir=/home/backup/full

3.4 恢复数据

  1. 删除库(测试环境)

    复制代码
    drop database test;
  1. 使用最新数据恢复

    复制代码
    # 停止数据库
    systemctl stop mysqld
    
    # 将数据变成可恢复的数据
    xtrabackup --prepare --target-dir=/home/backup/full
    
    # (删除)源Data
    mv /usr/local/mysql/data /usr/local/mysql/data.bak
    
    # copy-back(真实恢复数据)
    xtrabackup --copy-back --target-dir=/home/backup/full
    
    # 修权限
    chown -R mysql:mysql /usr/local/mysql/data
    
    # MySQL
    systemctl start mysqld
  1. 检查数据

    复制代码
    | 2983 | 99.155.149.176  | Iris1431    | 15910015020 |
    | 2984 | 21.50.219.134   | Fred3068    | 13110020478 |
    | 2985 | 192.217.2.158   | Dave9980    | 15210008564 |
    | 2986 | 117.137.17.59   | Dave8888    | 15010024830 |
    | 2987 | 151.50.244.184  | Alice2742   | 17710013259 |
    | 2988 | 23.87.230.116   | Alice6977   | 13310029974 |
    | 2989 | 246.74.136.28   | Eva4844     | 17810013224 |
    | 2990 | 251.48.107.176  | Sammy6930   | 15610001694 |
    | 2991 | 161.241.175.52  | Uma7078     | 13610031252 |
    | 2992 | 47.186.191.13   | Uma7239     | 15210022271 |
    | 2993 | 95.142.141.154  | Olga5257    | 13610029869 |
    | 2994 | 8.103.209.200   | Victor9020  | 18010016082 |
    | 2995 | 182.234.232.220 | Leo6194     | 13510009070 |
    | 2996 | 86.251.175.245  | Mona7331    | 13110014020 |
    | 2997 | 182.41.194.168  | Alice7727   | 17810022203 |
    | 2998 | 221.63.142.142  | Victor7877  | 15710006483 |
    | 2999 | 184.37.170.148  | Peter6793   | 17010032764 |
    | 3000 | 23.197.68.206   | Bob9457     | 13510019290 |
    +------+-----------------+-------------+-------------+

四、定时任务

当然,手动完全是不健康的,那么为什么不去做一个脚本,然后定时任务去定时执行脚本

4.1 完整脚本脚本

当然,你可以备份到另外一个主机上,也可以本机放一,另一个主机也放,双保证

vim back.sh

复制代码
   #!/bin/bash
   set -euo pipefail

   # 基本变量
   DB_IP="127.0.0.1"
   DB_PASSWORD="Backup@123"
   DB_USER="backup"
   DB_PORT="3306"

   # 全量备份目录
   FULL_DIR="/home/backup/full"

   # 增量备份目录(带时间戳)
   ICN_DIR="/home/backup/inc_$(date +%Y%m%d_%H%M%S)"

   # 临时归档目录
   TAR_DIR="/home/backup/tar"

   # 远程备份仓库
   REMOTE_IP="root@192.168.129.251"
   REMOTE_CONT="/var/DB1292_BACK/"
   REMOTE_FULL="FULL-$(date +%Y%m%d_%H%M%S).tar"

   # 创建目录
   mkdir -p "$ICN_DIR"
   mkdir -p "$TAR_DIR"

   echo "[$(date '+%Y-%m-%d %H:%M:%S')] 开始增量备份..."

   # 增量备份
   xtrabackup --backup \
     --target-dir="$ICN_DIR" \
     --incremental-basedir="$FULL_DIR" \
     --user="$DB_USER" \
     --password="$DB_PASSWORD" \
     --host="$DB_IP" \
     --port="$DB_PORT"

   echo "[$(date '+%Y-%m-%d %H:%M:%S')] 增量备份完成"

   # 合并到全量备份
   # 全量备份初步 prepare
   xtrabackup --prepare --apply-log-only --target-dir="$FULL_DIR"
   echo "[$(date '+%Y-%m-%d %H:%M:%S')] 全量备份初步 prepare 完成"

   # 应用增量备份
   xtrabackup --prepare \
     --target-dir="$FULL_DIR" \
     --incremental-dir="$ICN_DIR"
   echo "[$(date '+%Y-%m-%d %H:%M:%S')] 增量备份合并完成"

   # 最终 prepare 生成可恢复备份
   xtrabackup --prepare --target-dir="$FULL_DIR"
   echo "[$(date '+%Y-%m-%d %H:%M:%S')] 最终 prepare 完成,可恢复备份已生成"

   # 打包归档并发送
   tar -cf "$TAR_DIR/$REMOTE_FULL" -C "$FULL_DIR" .
   scp "$TAR_DIR/$REMOTE_FULL" "$REMOTE_IP:$REMOTE_CONT"

   echo -e "[$(date '+%Y-%m-%d %H:%M:%S')] 增量备份完成,已合并到全量备份并发送到远程服务器"
  1. 设置定时任务

    复制代码
    crontab -e
    
    # 每天晚上12点执行脚本,并把执行过程归档到日志中
    0 0 * * * /bin/bash /home/backup/backup_incremental.sh >> /home/backup/backup.log 2>&1
相关推荐
等....4 小时前
Minio使用
数据库
win x5 小时前
Redis 使用~如何在Java中连接使用redis
java·数据库·redis
迷枫7126 小时前
DM8 数据库安装实战:从零搭建达梦数据库环境(附全套工具链接)
数据库
XDHCOM7 小时前
PostgreSQL 25001: active_sql_transaction 报错原因分析,故障修复步骤详解,远程处理解决方案
数据库·sql·postgresql
卤炖阑尾炎7 小时前
PostgreSQL 日常运维全指南:从基础操作到备份恢复
运维·数据库·postgresql
daad7778 小时前
wifi_note
运维·服务器·数据库
计算机毕设vx_bysj68698 小时前
【免费领源码】77196基于java的手机银行app管理系统的设计与实现 计算机毕业设计项目推荐上万套实战教程JAVA,node.js,C++、python、大屏数据可视化
java·mysql·智能手机·课程设计
吴声子夜歌8 小时前
ES6——正则的扩展详解
前端·mysql·es6
xixingzhe29 小时前
Mysql统计空间增量
数据库·mysql
程序员萌萌9 小时前
Java之mysql实战讲解(三):聚簇索引与非聚簇索引
java·mysql·聚簇索引