[toc]

备份的原因

  • 运维工作的核心
    • 第一个是保护公司的数据.
    • 第二个是让网站能7*24小时提供服务(用户体验)。
  • 备份的意义
    • 备份就是为了恢复。
    • 尽量减少数据的丢失(公司的损失)

mysqldump做备份原理

  • 逻辑备份,备份所有的SQL语句
    • 如果表存在,则先删表
    • 根据原有的表结构重新创建一张新表
    • 锁表
    • 所有数据会以INSERT的形式插入到表中
    • 解锁
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
DROP TABLE IF EXISTS `stu_name`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `stu_name` (
`id` int(11) DEFAULT NULL,
`name` varchar(10) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Dumping data for table `stu_name`
--

LOCK TABLES `stu_name` WRITE;
/*!40000 ALTER TABLE `stu_name` DISABLE KEYS */;
INSERT INTO `stu_name` VALUES (1,'zhang3'),(2,'li4'),(3,'wang5');
/*!40000 ALTER TABLE `stu_name` ENABLE KEYS */;
UNLOCK TABLES;

备份的类型

  • 冷备份:
    • 需要停机停库停服务,不对外提供任何服务,进行备份
    • 备份时用户不能访问数据,因此无法读取或修改数据。脱机备份会阻止任何使用数据的活动。这类备份不会干扰正常运行的系统的性能。但是对于某些应用程序,无法接受在一段较长的时间里锁定或完全阻止用户访问数据。
  • 温备份:
    • 不需要停机停库停服务,正常做备份(需要锁表),用户无法写入数据
    • 次备份可以在读取数据时进行,但多数情况下,在备份时不能修改数据本身。这种中途备份的优点是不必完全锁定最终用户。但是,其不足之处在于无法在进行备份时修改数据集,某些应用程序不适用于这类的备份方式。在备份过程中无法修改数据可能产生性能问题。
  • 热备份:
    • 不需要停机停库停服务,也不锁表,备份时用户也可以正常写入数据
    • 这些动态备份在读取或修改数据的过程中进行,很少中断或者不中断传输或处理数据的功能。使用热备份时,系统仍可供读取和修改数据的操作访问。

备份的方式

  • 逻辑备份(基于SQL语句的备份)

    • binlog:通常做增量备份

    • into outfile:仅备份表数据

      1
      2
      3
      secure-file-priv=/tmp
      # 将查询出的表数据导出至指定文件
      select * from jiaoyi.money into outfile '/tmp/jiaoyi.data';
    • mysqldump:只能做全备

    • replication:主从复制(非备份功能)

  • 物理备份(基于数据文件的备份)

    • Xtrabackup:全备,增备,差异备(percona公司)
    • 备份最底层的物理文件:使用命令scp mv cp rsync

备份策略

  • 全量备份
    • 将所有数据都备份下来
  • 增量备份
    • 基于上一次备份的新增数据,做备份
  • 差异备份
    • 基于全量备份新增的数据,做备份
  • 不同的备份方案
    • 每天一次全备,每小时一次增备
    • 每周一次全备,每天一次增备
    • 每个月一次全备,每天一次增备
    • 每小时一次全备,每分钟一次增备

image-20230417161751947

MySQL的备份工具

  • mysqldump(逻辑)
    • mysql原生自带很好用的逻辑备份工具
  • mysqlbinlog(逻辑)
    • 实现binlog备份的原生态命令
  • xtrabackup(物理)
    • precona公司开发的性能很高的物理备份工具

备份工具使用

mysqldump逻辑备份

  • 常用选项:

    • -u:指定用户
    • -p:指定密码
    • -S:指定socket
    • -h:指定主机域
  • 备份选项

    • 不加备份选项

      1
      2
      3
      4
      5
      6
      7
      8
      9
      # 语句示例:默认为表级别备份
      mysqldump -uroot -p123 jiaoyi > /tmp/chenlin.sql
      ## 导出的sql文件不包含建库语句

      # 不加选项
      备份数据库库内的所有表,但不备数据库,恢复时需要指定一个数据库

      # 语句示例:单表备份
      mysqldump -uroot -p123 库名 表名 表名 > /tmp/chenlin.sql
    • -A:全备

      1
      2
      3
      4
      -A 或 --all-database

      # 语句示例
      mysqldump -uroot -p123 -A > /tmp/abc.sql
    • -B:指定库备份

      1
      2
      3
      4
      5
      6
      7
      8
      # 语句示例
      mysqldump -uroot -p123 -B jiaoyi > /tmp/chenlin.sql
      CREATE DATABASE /*!32312 IF NOT EXISTS*/ `chenlin` /*!40100 DEFAULT CHARACTER SET utf8 */;
      # 多库备份语句示例
      mysqldump -uroot -p123 -B 库名 库名 库名 > /tmp/chenlin.sql

      # 加-B选项
      备份数据库和库内的所有表以及数据,只能把数据恢复到原来的chenlin库中
    • -F:刷新binlog

      1
      2
      3
      4
      5
      # 加-F选项则在备份时刷新并生成当前库同数量的binlog
      mysqldump -uroot -p123 -A -F > /tmp/chenlin.sql
      mysqldump -uroot -p123 -A -F > /tmp/chenlin1.sql
      mysqldump -uroot -p123 -A -F > /tmp/chenlin2.sql
      mysqldump -uroot -p123 -A -F > /tmp/chenlin3.sql
    • –master-data:打点备份(温备)

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      --master-data=[0|1|2]
      0 # 不开启打点备份
      1 # change master语句不注释
      2 # change master语句注释

      # 打点备份语句示例
      mysqldump -uroot -p123@qqdianCOM -A --master-data=2 >/tmp/full_new.sql
      mysqldump -uroot -p123@qqdianCOM -A --master-data=1 >/tmp/full1_new.sql
      mysqldump -uroot -p123@qqdianCOM -A --master-data=0 >/tmp/full2_new.sql
      ## 注意:使用--master-data选项,则会打开`--lock-all-tables`选项,会锁表(温备)

      # 截取新增数据操作示例:
      ## 位置点1
      head -25 /tmp/full_new.sql
      起始位置点:57425
      mysqlbinlog --base64-output=decode-rows -vvv mysql-bin.000052 |grep drop -C 10
      结束位置点:72753

      ## 位置点2
      mysqlbinlog --base64-output=decode-rows -vvv mysql-bin.000052 |grep drop -C 10
      起始位置点:72845
      mysqlbinlog --base64-output=decode-rows -vvv mysql-bin.000052 |tail
      结束位置点:86845
    • –single-transaction:快照备份(热备)

      1
      2
      3
      4
        # 创建一个快照备份,把备份内容定格在某一时刻,不影响用户写入(热备)

      # 热备语句示例
      mysqldump -uroot -p123 -A --mastaer-data=2 --singletransaction > /tmp/full.sql
    • 压缩备份

      1
      2
      3
      4
      5
      6
      7
      8
      # 将备份sql文件进行压缩,以节省磁盘空间

      # 语句示例
      mysqldump -uroot -p123 -A --master-data=2 --single-transaction|gzip > /tmp/full_$(date +%F).sql.gz

      # 恢复数据
      mysql> source /tmp/full_2023-04-17.sql
      zcat /tmp/full_2023-04-17.sql.gz |mysql -uroot -p123
  • 备份选项:扩展

    • -R:备份MySQL的存储过程和函数

    • –triggers:备份MySQL的触发器

    • 语句示例

      1
      mysqldump -uroot -p123@qqdianCOM -A -R --triggers --master-data=2 --single-transaction > /tmp/full.sql
  • 不常用的备份选项

    • -t:仅备份数据
    • -d:仅备份表结构
    • -x:锁表备份

Xtrabackup物理备份

  • Xtrabackup安装

    • 安装环境

      1
      2
      3
      4
      5
      # 下载epel源
      wget -O /etc/yum.repos.d/epel.repo https://mirrors.aliyun.com/repo/epel-6.repo

      # 安装依赖
      yum -y install perl perl-devel libaio libaio-devel perl-Time-HiRes perl-DBD-MySQL
    • 下载并安装

      1
      2
      3
      4
      5
      # 下载Xtrabackup
      wget httpss://www.percona.com/downloads/XtraBackup/Percona-XtraBackup-2.4.4/binary/redhat/6/x86_64/percona-xtrabackup-24-2.4.4-1.el6.x86_64.rpm

      # 安装rpm包
      yum localinstall -y percona-xtrabackup-24-2.4.4-1.el6.x86_64.rpm
    • 备份命令

      1
      2
      3
      4
      5
      # 老版本
      xtrabackup

      # 新版本
      innobackupex
  • 备份方式(物理备份)

    • 对于非innodb表(比如myisam)直接锁表cp数据文件,属于一种温备。
    • 对于innodb的表(支持事务)不锁表,cp数据页最终以数据文件方式保存下来,并且把redo和undo一并备份,属于热备方式。
    • 备份时读取配置文件/etc/my.cnf
  • 备份选项

    • 基础选项

      1
      2
      3
      --user:指定用户
      --password:指定密码
      --socket:指定socket文件
    • 备份选项

      1
      2
      3
      4
      5
      6
      --apply-log              # 重做redo 回滚undo (手动模拟CSR)
      --copy-back # 将全备恢复到datadir中
      --incremental # 开启增量备份
      --incremental-basedir # 上一次备份的目录
      --no-timestamp # 不使用时间戳
      --incremental-dir # 合并增备时,指定增备的目录
  • 物理备份-全备

    • 全备-备份

      • 备份规则

        • 备份时,立即将已经commit过的内存中的数据页刷新到磁盘
        • 备份时,有可能会有其他数据写入,已备走的数据文件就不会再发生变化了
        • 在备份过程中,备份软件会一直监控着redo和undo,一旦有变化会将日志一并备份
      • 备份流程

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        # 1.指定MySQL用户名和密码及备份文件存放位置,进行全备
        innobackupex --user=root --password=Help9090 /backup

        # a.避免文件名为时间戳,自定义路径名
        innobackupex --user=root --password=Help9090 --no-timestamp /backup/full_$(date +%F)

        # 2.查看备份路径中的内容
        ll /backup/full_2023-04-18

        xtrabackup_binlog_info # 记录binlog文件名和binlog的打点位置
        xtrabackup_checkpoints # 日志版本号文件
        xtrabackup_info # 备份汇总信息
        xtrabackup_logfile # 备份的redo文件
    • 全备-恢复

      • 恢复前提

        • 被恢复的目录是空的
        • 被恢复的数据库实例是关闭的
      • 准备备份(模拟CSR)

        • 将redo进行重做,已提交的写到数据文件,未提交的使用undo回滚,模拟CSR的过程

          1
          innobackupex --user=root --password=Help9090 --apply-log /backup/full_2023-04-18
      • 恢复流程

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        # 1.停库
        systemctl stop mysqld

        # 2.备份并清空data目录
        mv /app/mysql/data/ /opt/

        # 3.手动模拟CSR,重做redo,回滚undo
        innobackupex --apply-log /backup/full_2023-04-18

        # 4.恢复数据
        # a.自动恢复
        innobackupex --copy-back /backup/full_2023-04-18
        # b.手动恢复
        cp -r /backup/full_2023-04-18/ /app/mysql/data

        # 5.授权
        chown -R mysql.mysql /app/mysql/*
  • 物理备份-增备

    • 增备-备份

      • 备份规则

        • 基于上一次备份进行增量
      • 备份流程

        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
        # 1.全备
        innobackupex --user=root --password=Help9090 --no-timestamp /backup/full_$(date +%F)
        # a.查看备份日志版本号信息
        cat /backup/full_2023-04-18/xtrabackup_checkpoints
        backup_type = full-backuped
        from_lsn = 0
        to_lsn = 2767419
        last_lsn = 2767428
        compact = 0
        recover_binlog_info = 0

        # 2.第一次增量备份
        innobackupex --user=root --password=Help9090 --incremental --incremental-basedir=/backup/full_2023-04-18/ /backup/inc1
        # a.查看备份日志版本号信息
        cat /backup/inc1/2023-04-18_16-42-19/xtrabackup_checkpoints
        backup_type = incremental
        from_lsn = 2767419
        to_lsn = 2769836
        last_lsn = 2868158
        compact = 0
        recover_binlog_info = 0

        # 3.第二次增量备份
        innobackupex --user=root --password=Help9090 --incremental --incremental-basedir=/backup/inc1/2023-04-18_16-42-19/ /backup/inc2
        # a.查看备份日志版本号信息
        cat /backup/inc2/2023-04-18_16-45-04/xtrabackup_checkpoints
        backup_type = incremental
        from_lsn = 2769836
        to_lsn = 2890217
        last_lsn = 2902649
        compact = 0
        recover_binlog_info = 0
    • 增备-恢复

      • 恢复前提

        • 增量备份无法单独恢复,必须基于全备进行恢复
        • 所有增量必须要按顺序合并到全备当中
      • 恢复步骤

        1. 全备,仅redo模拟CSR
        2. 第一次增量备份合并到全备中,仅redo模拟CSR
        3. 第…次增量备份合并到全备中,仅redo模拟CSR
        4. 最后一次增量合并到全备中时,redo和undo都模拟CSR
        5. 合并完的全备目录,redo和undo都模拟CSR
      • 恢复流程

        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
        # 1.先停库
        /etc/init.d/mysqld stop

        # 2.备份并清空data目录
        mv /app/mysql/data/ /opt/

        # 3.全备,仅redo模拟CSR
        innobackupex --apply-log --redo-only /backup/full_2023-04-18/

        # 4.第一次增量备份合并到全备中,仅redo模拟CSR
        innobackupex --apply-log --redo-only --incrementaldir=/backup/inc1 /backup/full_2023-04-18/

        # 5.最后一次增量合并到全备中时,redo和undo都模拟CSR
        innobackupex --apply-log --incrementaldir=/backup/inc2 /backup/full_2023-04-18/

        # 6.合并完的全备目录,redo和undo都模拟CSR
        innobackupex --apply-log /backup/full_2023-04-18/

        # 7.恢复数据
        innobackupex --copy-back /backup/full_2023-04-18/

        # 8.授权
        chown -R mysql.mysql /app/mysql*

        # 9.查看打点位置
        cat /backup/inc2/2023-04-18_16-45-04/xtrabackup_binlog_info
        mysql_bin.000001 37346

        # 10.查看二进制日志结束位置码
        mysqlbinlog --base64-output=decode-rows -vvv /opt/data/mysql_bin.000001|tail
        # at 48956
        #230418 16:56:15 server id 1 end_log_pos 48979 CRC32 0x12c110b0 Stop

        # 11.截取日志
        mysqlbinlog --start-position=37346 --stop-position=48979 /opt/data/mysql_bin.000001 > /tmp/a.sql

        # 12.启动mysql
        /etc/init.d/mysqld start

        # 13.登陆mysql
        mysql -uroot -pHelp9090

        # 14.关闭binlog日志记录
        mysql> set sql_log_bin=0;

        # 15.恢复数据
        mysql> source /tmp/a.sql

        # 16.打开binlog日志记录
        mysql> set sql_log_bin=1;
  • 物理备份-差异备份

    • 差异备份-备份

      • 备份规则

        • 同增量备份,始终基于全备的备份文件进行备份
      • 备份流程

        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
        # 1.全备
        innobackupex --user=root --password=Help9090 --no-timestamp /backup/full_$(date +%F)
        # a.查看备份日志版本号信息
        cat /backup/full_2023-04-18/xtrabackup_checkpoints
        backup_type = full-backuped
        from_lsn = 0
        to_lsn = 2814375
        last_lsn = 2814384
        compact = 0
        recover_binlog_info = 0

        # 2.第一次差异备份
        innobackupex --user=root --password=Help9090 --no-timestamp --incremental --incremental-basedir=/backup/full_2023-04-18 /backup/chayi1
        # a.查看备份日志版本号信息
        cat /backup/chayi1/xtrabackup_checkpoints
        backup_type = incremental
        from_lsn = 2814375
        to_lsn = 2814375
        last_lsn = 2829710
        compact = 0
        recover_binlog_info = 0

        # 3.第二次差异备份
        innobackupex --user=root --password=Help9090 --no-timestamp --incremental --incremental-basedir=/backup/full_2023-04-18 /backup/chayi2
        # a.查看备份日志版本号信息
        cat /backup/chayi2/xtrabackup_checkpoints
        backup_type = incremental
        from_lsn = 2814375
        to_lsn = 2836155
        last_lsn = 2853870
        compact = 0
        recover_binlog_info = 0
    • 差异备份-恢复

      • 恢复前提(同增量备份)

        • 增量备份无法单独恢复,必须基于全备进行恢复
        • 所有增量必须要按顺序合并到全备当中
      • 恢复步骤

        • 全备模拟CSR,只做redo不做undo
        • 最后一次差异备份合并到全备中,模拟CSR,redo和undo都做整体全
        • 备目录做一次redo和undo
      • 恢复流程

        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
        # 1.先停库
        /etc/init.d/mysqld stop

        # 2.备份并清空data目录
        mv /app/mysql/data/ /opt/

        # 3.全备,仅redo模拟CSR
        innobackupex --apply-log --redo-only /backup/full_2023-04-18/

        # 4.最后一次差异备份合并到全备中时,redo和undo都模拟CSR
        innobackupex --apply-log --incrementaldir=/backup/chayi2 /backup/full_2023-04-18/

        # 5.合并完的全备目录,redo和undo都模拟CSR
        innobackupex --apply-log /backup/full_2023-04-18/

        # 6.恢复数据
        innobackupex --copy-back /backup/full_2023-04-18/

        # 7.授权
        chown -R mysql.mysql /app/mysql*

        # 8.查看打点位置
        cat /backup/chayi2/xtrabackup_binlog_info
        mysql_bin.000001 28296

        # 9.查看二进制日志结束位置码
        mysqlbinlog --base64-output=decode-rows -vvv /opt/data/mysql_bin.000001|tail
        # at 33972
        #230418 18:03:10 server id 1 end_log_pos 33995 CRC32 0x9c8fa6fe Stop

        # 10.截取日志
        mysqlbinlog --start-position=28296 --stop-position=33972 /opt/data/mysql_bin.000001 > /tmp/a.sql

        # 11.启动mysql
        /etc/init.d/mysqld start

        # 12.登陆mysql
        mysql -uroot -pHelp9090

        # 13.关闭binlog日志记录
        mysql> set sql_log_bin=0;

        # 14.恢复数据
        mysql> source /tmp/a.sql

        # 15.打开binlog日志记录
        mysql> set sql_log_bin=1;

企业故障恢复案例

背景:

正在运行的网站系统,MySQL数据库,数据量25G,日业务增量10-15M。

备份策略:

每天23:00,计划任务调用mysqldump执行全备脚本

故障时间点:

上午10点开发人员误删除一个核心业务表,如何恢复?

解决方案

  • 创建全备定时任务

    1
    2
    3
    4
    5
    # 新建定时任务
    crontab -e

    # 输入定时任务脚本
    */1 * * * * /app/mysql/bin/mysqldump -uroot -pHelp9090 -A -R --triggers --master-data=2 --single-transaction |gzip > /tmp/full_$(date +%F).sql.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
    # 模拟用户写入数据
    vim a.sh
    #!/bin/bash
    mysql -uroot -pHelp9090 -e 'drop database chenlin;'
    mysql -uroot -pHelp9090 -e 'create database if not exists chenlin;'
    mysql -uroot -pHelp9090 -e 'use chenlin;create table if not exists chenlin1(id int);'
    num=0
    while true;do
    ((num ++))
    mysql -uroot -pHelp9090 -e "insert into chenlin.chenlin1
    values($num);commit;"
    sleep 1
    done

    # 模拟用户误删除表1
    mysql> drop table test1.test_a;

    # 模拟用户误删除表2
    mysql> drop table test2.test_b;

    create1
    create2
    DML
    DML
    DML
    drop table1
    DML
    DML
    DML
    drop table2
    DML
    DML
  • 恢复步骤

    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
    # 1.准备新环境
    ./mysqld --initialize-insecure --user=mysql --basedir=/app/mysql --
    datadir=/app/mysql/data

    # 2.启动MySQL服务
    /etc/init.d/mysqld start

    # 3.将旧库的全备发送到新环境
    scp /tmp/full_2023-04-18.sql.gz 172.16.1.53:/tmp

    # 4.将旧库的全备恢复到新环境
    mysql> set sql_log_bin=0;
    mysql> \! zcat /tmp/full_2023-04-18.sql.gz |mysql -uroot -pHelp9090

    # 5.找第一段binlog位置点
    zcat full_2023-04-17.sql.gz |head -25
    起始位置点:29368
    mysqlbinlog --base64-output=decode-rows -vvv mysql_bin.000001 |grep DROP -C 10
    结束位置点:29469

    # 6.找第二段binlog位置点
    mysqlbinlog --base64-output=decode-rows -vvv mysql_bin.000001 |grep DROP -C 10
    起始位置点:29593
    mysqlbinlog --base64-output=decode-rows -vvv mysql_bin.000001 |grep DROP -C 10
    结束位置点:31722

    # 7.找第三段binlog位置点
    mysqlbinlog --base64-output=decode-rows -vvv mysql_bin.000001 |grep DROP -C 10
    起始位置点:31846
    mysqlbinlog --base64-output=decode-rows -vvv mysql-bin.000001|tail
    结束位置点:32878

    # 8.截取binlog
    mysqlbinlog --start-position=29368 --stop-position=29469 mysql_bin.000001 > /tmp/1.sql
    mysqlbinlog --start-position=29593 --stop-position=31722 mysql_bin.000001 > /tmp/2.sql
    mysqlbinlog --start-position=31846 --stop-position=32878 mysql_bin.000001 > /tmp/3.sql

    # 9.发送到新环境
    scp /tmp/*.sql 172.16.1.53:/tmp/

    # 10.恢复数据之前,关闭binlog记录
    mysql> set sql_log_bin=0;

    # 11.恢复数据
    mysql> source /tmp/1.sql
    mysql> source /tmp/2.sql
    mysql> source /tmp/3.sql

    # 12.恢复数据之前,打开binlog记录
    mysql> set sql_log_bin=1;
  • 恢复业务两种方式

    • 应用割接

      • 修改连接数据的库代码
      • 运维要做一次代码上线
    • 导出数据(新环境做全备)

      1
      2
      3
      4
      5
      6
      # 新环境做全备
      mysqldump -uroot -pHelp9090 -A -R --triggers --master-data=2 --single-transaction|gzip > /tmp/full_$(date +%F).sql.gz

      # 将备份的数据恢复到旧库中
      mysql> set sql_log_bin=0;
      mysql> \! zcat /tmp/full_2023-04-18.sql.gz |mysql -uroot -pHelp9090

企业级增量恢复案例

背景:

某大型网站,mysql数据库,数据量500G,每日更新量100M-200M

备份策略:

xtrabackup,每周六0:00进行全备,周一到周五及周日00:00进行增量备份。

故障场景:

周三下午2点出现数据库意外删除表操作。
如何恢复???

解决方案

  • 模拟用户操作

    • 模拟用户写入数据

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      vim a.sh
      #!/bin/bash
      mysql -uroot -pHelp9090 -e 'drop database chenlin;'
      mysql -uroot -pHelp9090 -e 'create database if not exists chenlin;'
      mysql -uroot -pHelp9090 -e 'use chenlin;create table if not exists chenlin1(id int);'
      num=0
      while true;do
      ((num ++))
      mysql -uroot -pHelp9090 -e "insert into chenlin.chenlin1
      values($num);commit;"
      sleep 1
      done
    • 模拟用户误删除数据库

      1
      2
      # 模拟用户误删除表1
      mysql> drop table chenlin.chenlin1;
  • 恢复步骤

    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
    # 1.准备新环境(配置文件一定要统一)
    ./mysqld --initialize-insecure --user=mysql --basedir=/app/mysql --datadir=/app/mysql/data

    # 2.先停库
    /etc/init.d/mysqld stop

    # 3.备份并清空data目录
    rm -fr /app/mysql/data/

    # 4.全备,仅redo模拟CSR
    innobackupex --apply-log --redo-only /backup/full_2023-04-18/

    # 5.第一次增量备份合并到全备中,仅redo模拟CSR
    innobackupex --apply-log --redo-only --incrementaldir=/backup/inc1 /backup/full_2023-04-18/

    # 6.最后一次增量合并到全备中时,redo和undo都模拟CSR
    innobackupex --apply-log --incrementaldir=/backup/inc2 /backup/full_2023-04-18/

    # 7.合并完的全备目录,redo和undo都模拟CSR
    innobackupex --apply-log /backup/full_2023-04-18/

    # 8.将旧库的全备发送到新环境
    scp /backup/full_2023-04-18/ 172.16.1.51:/backup

    # 9.恢复数据
    innobackupex --copy-back /backup/full_2023-04-18/

    # 10.授权
    chown -R mysql.mysql /app/mysql*

    # 11.查看打点位置
    cat /backup/inc2/2023-04-18_16-45-04/xtrabackup_binlog_info
    mysql_bin.000001 37346

    # 12.查看二进制日志结束位置码
    mysqlbinlog --base64-output=decode-rows -vvv /opt/data/mysql_bin.000001|tail
    # at 48956
    #230418 16:56:15 server id 1 end_log_pos 48979 CRC32 0x12c110b0 Stop

    # 13.截取日志
    mysqlbinlog --start-position=37346 --stop-position=48979 /opt/data/mysql_bin.000001 > /tmp/a.sql

    # 14.将旧库截取好的日志发送到新环境
    scp /tmp/a.sql 172.16.1.51:/tmp

    # 15.启动mysql
    /etc/init.d/mysqld start

    # 16.登陆mysql
    mysql -uroot -pHelp9090

    # 17.关闭binlog日志记录
    mysql> set sql_log_bin=0;

    # 18.恢复数据
    mysql> source /tmp/a.sql

    # 19.打开binlog日志记录
    mysql> set sql_log_bin=1;
  • 恢复业务两种方式

    • 应用割接

      • 修改连接数据的库代码
      • 运维要做一次代码上线
    • 导出数据(新环境做全备)

      1
      2
      3
      4
      5
      6
      # 新环境做全备
      mysqldump -uroot -pHelp9090 -A -R --triggers --master-data=2 --single-transaction|gzip > /tmp/full_$(date +%F).sql.gz

      # 将备份的数据恢复到旧库中
      mysql> set sql_log_bin=0;
      mysql> \! zcat /tmp/full_2023-04-18.sql.gz |mysql -uroot -pHelp9090

阿里云DTS数据传输

DTS简介

数据传输服务(Data Transmission Service,简称DTS)支持关系型数据库、NoSQL、大数据(OLAP)等数据源,集数据迁移、订阅及实时同步功能于一体,能够解决公共云、混合云场景下,远距离、秒级异步数据传输难题。其底层基础设施采用阿里双11异地多活架构,为数千下游应用提供实时数据流,已在线上稳定运行7年之久。

功能描述

相对于传统数据迁移或同步工具,DTS为您提供功能更丰富、传输性能更强、易用性更高且安全可靠的服务,帮助您简化复杂的数据交互工作,专注于上层的业务开发。DTS有如下多种优势:

  • 方便快捷
    • 提供可视化管理界面,让您快速了解DTS控制台。
    • 提供向导式的链路创建流程,您可以简单轻松地创建自己的传输链路。
  • 丰富多样
    • 支持各种源库和目标库之间的数据传输,这些数据源基于不同的数据库引擎和架构。
    • 支持多种数据传输方式,包括数据迁移、数据集成、数据同步及数据订阅。
  • 高性能
    • 使用高规格服务器来保证每条迁移同步链路都能拥有良好的传输性能。
    • 对核心基础设施进行了大量优化,峰值数据传输速率可以达到70 MB/秒,RPS最高可达35万行/秒(以平均每行0.2KB计算)。
    • 链路支持多并发压缩传输,降低传输链路对带宽的占用。
  • 安全可靠
    • 支持节点的故障容灾,可实现链路的秒级恢复。
    • 支持断点续传,可有效解决因硬件和网络等异常导致的传输中断。
    • 支持基于RAM的访问授权,您可以定义细粒度的授权策略来管理DTS任务。
    • 支持数据校验,确保源端迁移和同步到目标端数据的完整性和一致性。