MySQL数据库5

  • mysqldump备份恢复数据库
  • 冷备份还原数据库
  • 逻辑卷快照备份还原数据库
  • xtrabackup备份还原数据库

1. 备份和恢复概述

  • 适用场景

    硬件故障、软件故障、自然灾害、黑客攻击、误操作测试等数据丢失场景

  • 备份注意要点

    1. 能容忍最多丢失多少数据
    2. 恢复数据需要在多长时间内完成
    3. 需要恢复哪些数据
    4. 还原要点
    5. 做还原测试,用于测试备份的可用性
    6. 还原演练
  • 备份类型

    二进制日志文件不应该与数据文件放在同一磁盘

    1. 按备份范围

      1. 完全备份:整个数据集
      2. 部分备份:只备份数据子集,如部分库或表
    2. 按备份时间
      1. 增量备份:仅备份最近一次完全备份或增量备份(如果存在增量)以来变化的数据,备份较快,还原复杂,备份的是二进制文件
      2. 差异备份:仅备份最近一次完全备份以来变化的数据,备份较慢,还原简单
  • 冷、温、热备份

    1. 冷备

      读写操作均不可进行,类似复制文件操作, 数据库对应的数据文件,二进制日志、InnoDB的事务日志, 服务器的配置文件
    2. 温备

      读操作可执行;但写操作不可执行
    3. 热备

      读写操作均可执行
  • 常用存储引擎支持备份类型

    1. MyISAM:温备,不支持热备
    2. InnoDB:都支持
  • 备份方法

    1. 物理备份

      直接复制数据文件进行备份,与存储引擎有关,占用较多的空间,速度快,可能将没有释放空间的空数据文件一起备份,占用空间
    2. 逻辑备份

      从数据库中“导出”数据另存而进行的备份,与存储引擎无关,占用空间少,速度慢,可能丢失精度,通过mysql协议连接到mysql的数据库,执行命令将数据查出来,导出到备份主机上,有什么数据拿什么数据。
  • 备份时需要考虑的因素

    1. 温备的持锁多久
    2. 备份产生的负载
    3. 备份过程的时长
    4. 恢复过程的时长
  • 备份什么

    1. 数据
    2. 二进制日志、InnoDB的事务日志
    3. 程序代码(存储过程、函数、触发器、事件调度器)
    4. 服务器的配置文件
  • 备份工具

    1. cp, tar等复制归档工具:

      物理备份工具,适用所有存储引擎;只支持冷备;完全和部分备份
    2. LVM的快照:

      为保证数据一致性,先对真个实例加锁,做快照后解锁,几乎热备;借助文件系统工具进行备份
    3. mysqldump

      逻辑备份工具,适用所有存储引擎,温备;支持完全或部分备份;对InnoDB存储引擎支持热备,结合binlog的增量备份
    4. xtrabackup:

      由Percona公司提供支持对InnoDB做热备(物理备份)的工具,支持完全备份、增量备份
    5. MariaDB Backup:

      从MariaDB 10.1.26开始集成,基于Percona XtraBackup 2.3.8实现
    6. mysqlbackup:

      热备份, MySQL Enterprise Edition(企业版)组件
    7. mysqlhotcopy:

      PERL 语言实现,几乎冷备,仅适用于MyISAM存储引擎,使用LOCK TABLES、FLUSH TABLES和cp或scp来快速备份数据库

2. 冷备份示例

  • 实验目标

    冷备方法备份数据,还原数据到另一台主机上
  • 实验步骤
    1. 数据库停止服务
      [root@hai7-6 hellodb]$systemctl stop mariadb
      • 1
    2. 打包数据文件,并传送给预还原主机
      1. '打包数据库工作目录并压缩'
      [root@hai7-8 data]$tar Jcvf /data/mysql.bak.`date +%F`.tar.xz /data/mysql/
      2. '将数据发送到预还原主机上'
      [root@hai7-8 data]$scp /data/mysql.bak.2018-10-13.tar.xz 192.168.50.100:/data
      3. '将配置文件发送到预还原主机'
      [root@hai7-8 data]$scp /etc/my.cnf 192.168.50.100:/data
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
    3. 将备份的配置文件覆盖还原主机上的配置文件
      [root@hai7-8 mysql]$mv /data/my.cnf   /etc/my.cnf
      • 1
    4. 解压文件到/var/lib/mysql目录下,并重启服务,还原完成
      [root@hai7-8 mysql]$tar xf mysql.2018-10-13.tar.xz
      [root@hai7-8 mysql]$mv * /var/lib/mysql
      • 1
      • 2

3. 基于LVM的备份

  • 实验目的

    1. 将数据库数据文件和二进制文件分别存放
    2. 利用逻辑卷快照功能备份并恢复丢失数据
  • 准备逻辑卷
    1. 拿现有干净分区sda7作为物理卷
      [root@hai7-6 data]$pvcreate /dev/sda7
      • 1
    2. 将物理卷加入卷组
      [root@hai7-6 data]$vgcreate vg_mysql /dev/sda7
      • 1
    3. 建立两个逻辑卷分别存放数据mysqldata和二进制文件mysqlbin
      [root@hai7-6 data]$lvcreate -n mysqldata -L 2G vg_mysql
      [root@hai7-6 data]$lvcreate -n mysqlbin -L 4G vg_mysql
      • 1
      • 2
    4. 格式化文件系统
      [root@hai7-6 data]$mkfs.xfs /dev/vg_mysql/mysqlbin
      [root@hai7-6 data]$mkfs.xfs /dev/vg_mysql/mysqldata
      • 1
      • 2
    5. 建立两个挂载点,分别挂载mysqldata与mysqlbin
      [root@hai7-6 data]$mkdir /vg_data/{mysqlbin,mysqldata} -pv
      '将逻辑卷分别挂载到目录上'
      [root@hai7-6 data]$mount /dev/vg_mysql/mysqlbin /vg_data/mysqlbin/
      [root@hai7-6 data]$mount /dev/vg_mysql/mysqldata /vg_data/mysqldata/
      • 1
      • 2
      • 3
      • 4
  • 数据备份
    1. 修改以上逻辑卷挂载目录权限,确保mysql程序有写权限
      [root@hai7-6 data]$chown mysql.mysql /vg_data/
      • 1
    2. 修改配置文件指定数据保存路径,启动服务
      [root@hai7-6 ~]$vim /etc/my.cnf
      [mysqld]
      innodb_file_per_table
      datadir=/vg_data/mysqldata <=将数据库路径修改为刚才建立的路径
      log_bin=/vg_data/mysql-bin <=将二进制日志保存路径修改为以上建立的新目录
      '启动服务'
      [root@hai7-6 data]$systemctl start mariadb
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
    3. 进入mysql,清空二进制日志文件
      MariaDB [(none)]> reset master;
      • 1
    4. 准备一些数据库文件,这里导入数据库hellodb
      [root@hai7-6 data]$mysql < hellodb_innodb.sql
      • 1
    5. 请求锁定所有表
      [root@hai7-6 data]$mysql -e 'FLUSH TABLES WITH READ LOCK'
      • 1
    6. 记录二进制文件及事件位置,方便以后使用二进制日志文件恢复备份时间点以后的文件
      [root@hai7-6 data]$mysql -e 'SHOW MASTER logs' > bin.log
      [root@hai7-6 data]$cat bin.log
      Log_name File_size
      mysql-bin.000001 7655 <==备份时二进制日志位置
      • 1
      • 2
      • 3
      • 4
    7. 创建快照
      [root@hai7-6 mapper]$lvcreate -p r -s -n snap_mysql -L 1G  /dev/mapper/vg_mysql-mysqld
      • 1
    8. 释放锁
      [root@hai7-6 mapper]$mysql -e 'UNLOCK TABLES'
      • 1
    9. 在mysql中增加几条记录,后续使用二进制恢复到最新状态
      MariaDB [hellodb]> INSERT teachers values(6,'B','30','F');
      MariaDB [hellodb]> SHOW BINARY LOGS;
      +------------------+-----------+
      | Log_name | File_size |
      +------------------+-----------+
      | mysql-bin.000001 | 8059 | <==二进制日志文件更新后大小
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
  • 数据恢复

    还原阶段需要拒绝客户访问,保证数据不变,利用防火墙或者锁等工具实现

    1. 挂载快照卷,执行数据备份
      由于UUID相同,所以挂载快照卷需要加-o nouuid,norecovery
      [root@hai7-6 vg_mysql]$mount -o nouuid,norecovery /dev/vg_mysql/snap_mysql /mnt
      将快照下备份的数据拷贝到出来
      [root@hai7-6 vg_mysql]$cp -av /mnt/* /data/
      • 1
      • 2
      • 3
      • 4
    2. 备份完成后,删除快照卷(快照会影响系统性能)
      取消挂载
      [root@hai7-6 vg_mysql]$umount /mnt
      删除逻辑快照
      [root@hai7-6 vg_mysql]$lvremove /dev/vg_mysql/snap_mysql
      • 1
      • 2
      • 3
      • 4
    3. 模拟损坏,删除存放数据库的目录下所有文件
      [root@hai7-6 vg_mysql]$rm -rf /vg_data/mysqldata/*
      • 1
    4. 将备份的文件拷贝回数据库目录下,保留原属性
      [root@hai7-6 vg_mysql]$cp -av /data/*  /vg_data/mysqldata/
      • 1
    5. 利用二进制日志还原数据到最
      '备份数据时已经记录的二进制日志位置为mysql-bin.000001 7655 ,导出之后所有记录,多个文件需追加到同一文件'
      [root@hai7-6 ~]$mysqlbinlog --start-position=7655 /vg_data/mysql-bin.000001 > /root/binlong.sql
      [root@hai7-6 ~]$mysqlbinlog /vg_data/mysql-bin.000002 >> /root/binlong.sql
      • 1
      • 2
      • 3
    6. 进入数据库,暂时关闭二进制日志记录功能,防止导入数据时生成新的二进制日志
      MariaDB [(none)]> SET sql_log_bin=off;
      • 1
    7. 将导出的二进制日志数据导入mysql中,在数据库中直接进行,命令为SOURCE
      MariaDB [(none)]> SOURCE /root/binlong.sql
      • 1
    8. 启动二进制日志记录功能,查看还原效果
      MariaDB [(none)]> SET sql_log_bin=on;
      MariaDB [hellodb]> SELECT * FROM teachers;
      • 1
      • 2

4. 逻辑备份工具(mysqldump, mydumper, phpMyAdmin)

  • 备份原理

    在mysql正常工作的情况下,利用mysql协议,就像mysql客户端一样,直接连接到mysql数据库上,发出查询指令,把所有的数据库读出来
  • 参考资料

    https://dev.mysql.com/doc/refman/5.7/en/mysqldump.html
  • 缺点

    schema和数据存储在一起、巨大的SQL语句、单个巨大的备份文件

4.1 mysqldump工具

  • 语法格式

    mysqldump [OPTIONS] database [tables]

    mysqldump [OPTIONS] --databases [OPTIONS] DB1 [DB2 DB3…]

    mysqldump [OPTIONS] --all-databases [OPTIONS]

  • 常见选项

    1. -A| --all-databases :备份所有数据库,含create database

    2. -B| --databases db_name… :指定备份的数据库,包括create database语句

    3. -E| --events:备份相关的所有event scheduler(调度器),计划任务之类的,-A包含-E

    4. -R| --routines:备份所有存储过程和自定义函数, -A包含

    5. --triggers:备份表相关触发器,默认启用,用--skip-triggers,不备份触发器

    6. --default-character-set=utf8 :指定字符集

    7. --master-data[=#]: 此选项须启用二进制日志

      1. 所备份的数据之前加一条记录为CHANGE MASTER TO语句,非注释,不指定#,默认为1
      2. 记录为注释的CHANGE MASTER TO语句

        此选项会自动关闭–lock-tables功能,自动打开-x | --lock-all-tables功能(除非开启–single-transaction)
        '记录备份时,二进制日志文件所在位置,说明在此位置之前的数据做了备份'
        [root@hai7-6 data]$mysqldump -A --master-data=1 > all.sql
        '查看备份数据'
        [root@hai7-6 data]$vim all.sql
        '多出如下行,如果设置为--master-data=2,只是将如下行注释掉,仅做描述'
        CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000002', MASTER_LOG_POS=34742814;
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6
    8. -F, --flush-logs :备份前滚动日志,锁定表完成后,执行flush logs命令,生成新的二进制日志文件,配合-A 或 -B 选项时,会导致刷新多次数据库。建议在同一时刻执行转储和日志刷新,可通过和--single-transaction-x--master-data一起使用实现,此时只刷新一次日志,添加此选项可以区分备份前二进制文件和备份后二进制文件,不需要去文件中找备份位置

      1. '当前二进制日志文件是两个1和2'
      [root@hai7-6 data]$mysql -e 'show master logs;'
      +------------------+-----------+
      | Log_name | File_size |
      +------------------+-----------+
      | mysql-bin.000001 | 8078 |
      | mysql-bin.000002 | 34742814 |
      +------------------+-----------+
      2. '备份两个数据库hi和mysql'
      [root@hai7-6 data]$mysqldump -F -B hi mysql > ba.back.sql
      3. '生成2个新的日志文件,也就是选项描述中-A、-B是会刷新多次,和备份多少个数据库有关'
      [root@hai7-6 data]$mysql -e 'show master logs;'
      +------------------+-----------+
      | Log_name | File_size |
      +------------------+-----------+
      | mysql-bin.000001 | 8078 |
      | mysql-bin.000002 | 34742857 |
      | mysql-bin.000003 | 288 | <==刷新的二进制日志文件
      | mysql-bin.000004 | 245 | <==刷新的二进制日志文件
      +------------------+-----------+
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
    9. --compact: 去掉注释,适合调试,导出的文件没有注释描述,不推荐使用,有可能丢失关键信息,比如master-data=2记录的二进制备份位置

    10. -d, --no-data: 只备份表结构

    11. -t, --no-create-info: 只备份数据,不备份create table

    12. -n,--no-create-db: 不备份create database,可被-A或-B覆盖

    13. --flush-privileges:备份系统数据库mysql时需要使用

    14. -f, --force: 忽略SQL错误,继续执行

    15. --hex-blob: 使用十六进制符号转储二进制列(例如,“abc”变为0x616263),受影响的数据类型包括BINARY, VARBINARY,BLOB,BIT

    16. -q, --quick: 不缓存查询,直接输出,加快备份速度

  • 备份还原示例

    1. 示例一: 默认设置读取数据库数据,并还原(不建议使用,需要手动创建数据库,数据库创建信息很可能不准确)

      1. 读取数据库hellodb数据,导出到文件hellodb_back.sql中
        [root@hai7-6 data]$mysqldump hellodb > /data/hellodb_bak.sql
        • 1
      2. 模拟数据库破坏,删除hellodb数据库
        [root@hai7-6 data]$mysql -e 'drop database hellodb'
        • 1
      3. 使用默认选项读出来的数据,并没有创建数据库命令,还原数据库需要手动创建数据库
        1. '创建数据库,很可能与原创建属性不同'
        [root@hai7-6 data]$mysql -e 'create database hi'
        2. '将数据导入新建的数据库中(这里必须指定数据库),完成恢复'
        [root@hai7-6 data]$mysql hi < /data/hellodb_bak.sql
        • 1
        • 2
        • 3
        • 4
    2. 示例二:加上选项-A、-B备份,只要有的数据库都会备份,使输出的信息更完整包括创建命令
      1. 备份所有数据库

        选项-A
        [root@hai7-6 mysqldata]$mysqldump -A  > /data/all'data+%F'.sql
        查看导出的数据
        [root@hai7-6 mysqldata]$vim /data/alldata+%F.sql
        CREATE DATABASE /*!32312 IF NOT EXISTS*/ `hi` /*!40100 DEFAULT CHARACTER SET latin1 */;
        USE `hi`; <==创建数据库的SQL语句,只要有的数据库都会输出创建语句
        • 1
        • 2
        • 3
        • 4
        • 5

        选项-B

        '可以同时备份多个,例如hi和mysql两个数据库'
        [root@hai7-6 mysqldata]$mysqldump -B hi mysql > /data/b'data+%F'.sql
        • 1
        • 2
      2. 模拟故障,删除数据库
        [root@hai7-6 mysqldata]$mysql -e 'drop database hi'
        [root@hai7-6 mysqldata]$mysql -e 'drop database mysql'
        '查看删除后数据库保留情况'
        [root@hai7-6 mysqldata]$mysql -e 'show databases'
        +--------------------+
        | Database |
        +--------------------+
        | information_schema |
        | performance_schema |
        | test |
        +--------------------+
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6
        • 7
        • 8
        • 9
        • 10
        • 11
      3. 还原,由于备份中已经有库创建语句,可以直接导入
        [root@hai7-6 mysqldata]$mysql < /data/bdata+%F.sql
        [root@hai7-6 mysqldata]$mysql -e 'show databases'
        +--------------------+
        | Database |
        +--------------------+
        | information_schema |
        | hi |
        | mysql |
        | performance_schema |
        | test |
        +--------------------+
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6
        • 7
        • 8
        • 9
        • 10
        • 11
  • 输出备份数据时同时压缩

    压缩工具默认是读取屏幕输出,压缩导入指定文件,可以配合mysqldump工具,直接压缩备份文件

    [root@hai7-6 ~]$mysqldump -B hi |gzip > /data/a.sql.gz
    • 1
  • 编制脚本,实现将mysql中的数据库分库备份

    1. 数据库库信息输出格式如下所示,首先挑出不需要备份的库
      [root@hai7-6 data]$mysql -e 'show databases' |cat
      Database <==表头,不需要备份
      information_schema <==状态信息,不需要备份
      hi
      mysql
      performance_schema <==状态信息,不需要备份
      test
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
    2. 实现方法

      方法1:while…do…done
      [root@hai7-6 data]$mysql -e 'show databases' | grep -Ev 'Database|information|performance'|while read dbname ;do mysqldump -B $dbname|gzip > /data/${dbname}_bak`date +%F`.gz;done
      • 1

      方法2 :使用sed语句实现

      bash可以接收标准输出,标准输出是一个可执行的脚本就可以执行

      [root@hai7-6 data]$mysql -e 'show databases'|grep -Ev '^Database|info|perfor'|sed -r 's@(.*)@mysqldump -B \1| gzip > /data/\1_bak`date +%F`.gz@'|bash
      • 1

      方法3:使用for循环

      [root@hai7-6 data]$for db in `mysql -e 'show databases'|grep -Ev '^Database|info|perfor'`;do mysqldump -B $db |gzip > /data/${db}_bak`date +%F`.gz;done
      • 1

4.2 MyISAM、InnoDB再mysqldump中特殊的备份选项

  • MyISAM

    支持温备;不支持热备,所以必须先锁定要备份的库,而后启动备份操作

    锁定方法如下:

    1. -x,--lock-all-tables:加全局读锁,锁定所有库的所有表,同时加–single-transaction或–lock-tables选项会关闭此选项功能

      注意:数据量大时,可能会导致长时间无法并发访问数据库
    2. -l,--lock-tables:对于需要备份的每个数据库,在启动备份之前分别锁定其所有表,默认为on,--skip-lock-tables选项可禁用,对备份MyISAM的多个库,可能会造成数据不一致

      注:以上选项对InnoDB表一样生效,实现温备,但不推荐使用
  • InnoDB备份选项

    支持热备,可用温备但不建议用温备

    1. 选项

      --single-transaction:单事务转储

      此选项Innodb中推荐使用,不适用MyISAM

      备份大型表时,建议将–single-transaction选项和–quick结合一起使用
    2. 作用

      此选项会开始备份前,先执行START TRANSACTION指令开启事务,通过在单个事务中转储所有表来创建一致的快照;仅适用于存储在支持多版本控制的存储引擎中的表(目前只有InnoDB可以); 转储不保证与其他存储引擎保持一致。
    3. 注意实现
      1. 在进行单事务转储时,要确保有效的转储文件(正确的表内容和二进制日志位置),没有其他连接使用以下语句:ALTER TABLE,DROP TABLE,RENAME TABLE,TRUNCATE TABLE(清空表),因为事务开启时默认级别3,可重复读状态对DDL语言起不到完全隔离作用,只有读过的表才会上锁,没有读的表,其他事务是可以做删除等操作的,再去读取数据就会不同。
      2. 此选项和–lock-tables(此选项隐含提交挂起的事务)选项是相互排斥

4.3 生产环境实战备份策略

  • InnoDB建议备份策略
    mysqldump -uroot -A -F -E -R --single-transaction --master-data=1 --flush-privileges --triggers --default-character-set=utf8 --hex-blob >/backup/fullbak_$BACKUP_TIME.sql
    • 1
  • MyISAM建议备份策略
    mysqldump -uroot -A -F -E -R -x --master-data=1  --flush-privileges  --triggers  --default-character-set=utf8 --hex-blob >/BACKUP/fullbak_$BACKUP_TIME.sql
    • 1
  • 示例
  1. 目的

    模拟生产环境数据库恢复,完全备份,并还原至最新状态
  2. 步骤
    1. 将数据文件和二进制日志文件分开存放,修改配置文件,并启动二进制日志功能
      [root@hai7-6 ~]$vim /etc/my.cnf
      datadir=/vg_data/mysqldata <==数据文件路径
      log_bin=/vg_data/mysqlbin/mysql_bin <==二进制日志文件路径
      • 1
      • 2
      • 3
    2. 备份数据
      [root@hai7-6 ~]$mysqldump -A -F --single-transaction  --master-data=2  --hex-blob|gzip > /data/all_back.aql.gz
      • 1
    3. 备份后,再创建几条记录,供二进制日志还原使用
      MariaDB [hi]> INSERT teachers VALUES(10,'A',40,'M')
      MariaDB [hi]> INSERT teachers VALUES(11,'B',50,'M');
      • 1
      • 2
    4. 模拟故障,删除所有数据文件
      [root@hai7-6 data]$rm -rf /vg_data/mysqldata/*
      • 1
    5. 开始还原数据,从这里开始禁止用户访问,直到还原完成,停止mariadb服务,再启动服务,生成系统数据库文件,如果是自编译安装,需要运行系统脚本生成
      [root@hai7-6 mysqlbin]$systemctl stop mariadb
      '启动服务,让系统自动生成系统数据库'
      [root@hai7-6 mysqlbin]$systemctl start mariadb
      • 1
      • 2
      • 3
    6. 解压备份文件
      [root@hai7-6 data]$gzip -d all_back.aql.gz
      • 1
    7. 停止二进制日志服务,避免导入备份文件时生成大量二进制数据,影响备份时间点后的数据恢复,将备份文件导入mysql中
      1. '停止二进制日志服务'
      MariaDB [(none)]> SET sql_log_bin=off;
      2. '还原完全备份数据'
      MariaDB [(none)]> source /data/all_back.aql
      3. '查看完全备份还原效果'
      MariaDB [hi]> SELECT * FROM teachers; <==没有第3步添加的,备份后数据
      +-----+---------------+-----+--------+
      | TID | Name | Age | Gender |
      +-----+---------------+-----+--------+
      | 1 | Song Jiang | 45 | M |
      | 2 | Zhang Sanfeng | 94 | M |
      | 3 | Miejue Shitai | 77 | F |
      | 4 | Lin Chaoying | 93 | F |
      | 5 | a | 20 | M |
      | 6 | B | 30 | F |
      | 8 | c | 100 | M |
      +-----+---------------+-----+--------+
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
    8. 查看备份文件,确认二进制日志文件备份位置,将备份后生成的数据位置导入文件,恢复到最新状态,开放用户访问数据库
      1. '查看备份文件,确认二进制日志文件完全备份时位置'
      [root@hai7-6 data]$vim all_back.aql
      -- CHANGE MASTER TO MASTER_LOG_FILE='mysql_bin.000002', MASTER_LOG_POS=245;
      2. '将245位置后的二进制日志内容导入至文件in.sql中'
      [root@hai7-6 data]$mysqlbinlog --start-position=245 /vg_data/mysqlbin/mysql_bin.000002 > in.sql
      3. '进入mysql,停止二进制日志功能'
      MariaDB [(none)]> SET sql_log_bin=off;
      4. '将备份后生成的二进制文件导入数据库中'
      MariaDB [hi]> SOURCE /data/in.sql
      5. '恢复二进制日志记录功能'
      MariaDB [hi]> SET sql_log_bin=on
      6. '查看恢复效果'
      MariaDB [hi]> SELECT * FROM teachers;
      +-----+---------------+-----+--------+
      | TID | Name | Age | Gender |
      +-----+---------------+-----+--------+
      | 1 | Song Jiang | 45 | M |
      | 2 | Zhang Sanfeng | 94 | M |
      | 3 | Miejue Shitai | 77 | F |
      | 4 | Lin Chaoying | 93 | F |
      | 5 | a | 20 | M |
      | 6 | B | 30 | F |
      | 8 | c | 100 | M |
      | 10 | A | 40 | M | <==备份后数据,恢复成功
      | 11 | B | 50 | M |
      +-----+---------------+-----+--------+
      • 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

4.4 误删除文件,导致系统问题

前面步骤相同,在恢复到备份文件点后,需要在二进制日志文件中,找出误删除操作,注释掉或者删除,然后将备份后二进制日志文件追加导出至指定文件,再导入系统

[root@hai7-6 data]$mysqlbinlog --start-position=245  /vg_data/mysqlbin/mysql_bin.000002 > in.sql
[root@hai7-6 data]$mysqlbinlog /vg_data/mysqlbin/mysql_bin.000003 >> in.sql
  • 1
  • 2

5. 专业恢复工具xtrabackup

5.1 概述

  • 官方网站

    xtrabackup是由Percona公司开发的工具

    官网:https://www.percona.com

    手册:https://www.percona.com/doc/percona-xtrabackup/LATEST/index.html

  • 简介

    percona提供的mysql数据库备份工具,惟一开源的能够对innodb和xtradb数据库进行热备的工具

  • 特点:

    1. 备份还原过程快速、可靠
    2. 备份过程不会打断正在执行的事务
    3. 能够基于压缩等功能节约磁盘空间和流量
    4. 自动实现备份检验
    5. 开源,免费
  • Xtrabackup备份过程

    1. 开启innobackupex 脚本,打开调用xtrabackup
    2. xtrabackup二进制程序创建一些对应线程,redo拷贝线程,来拷贝事务日志
    3. 开启另外一个线程ibd拷贝线程来拷贝数据库文件,待数据库文件拷贝完成,结束线程,通知innobackupex 脚本,数据库文件拷贝完成
    4. innobackupex 脚本收到通知,马上加一个全局锁,开始复制MyISAM 数据库存储引擎的相关数据,当MyISAM 数据库相关数据拷贝结束,发出停止redo拷贝的指令,xtrabackup收到指令后停止redo拷贝线程
    5. 解锁,然后等待子进程xtrabackup结束退出,整个备份结束

5.2 旧版(2.2之前)与新版xtrabackup区别

  • 旧版

    1. 包括4个可执行文件:

      1. innobackupex:Perl 脚本

        1. 脚本用来备份非 InnoDB 表,同时会调用 xtrabackup 命令来备份 InnoDB 表,还会和 MySQL Server 发送命令进行交互,如加全局读锁(FTWRL)、获取位点(SHOW SLAVE STATUS)等。即innobackupex是在 xtrabackup 之上做了一层封装实现的
        2. 虽然目前一般不用 MyISAM 表,只是 MySQL 库下的系统表是 MyISAM 的,因此备份基本都通过 innobackupex 命令进行
      2. xtrabackup:C/C++ 编译的二进制

        用来备份 InnoDB 表的,不能备份非 InnoDB 表,和 MySQL Server 没有交互
      3. xbcrypt:加解密
      4. xbstream:支持并发写的流文件格式
  • 新版变化

    xtrabackup版本升级到2.4后,相比之前的2.1有了比较大的变化

    1. innobackupex 功能全部集成到 xtrabackup 里面,只有一个 binary程序
    2. 为了兼容考虑,innobackupex作为 xtrabackup 的软链接,即xtrabackup现在支持非Innodb表备份,
    3. Innobackupex在下一版本中移除,建议通过xtrabackup替换innobackupex

5.3 xtrabackup语法选项

  • 安装xtrabackup

    1. 在EPEL源中

      yum install percona-xtrabackup
    2. 最新版本下载安装:下载格式为rpm可以直接使用yum安装,需要依赖EPEL源中一些程序

      https://www.percona.com/downloads/XtraBackup/LATEST/

      新版将xtrabackup和innobackupex组合在一起,显示为软连接
      [root@hai7-6 data]$ll /usr/bin/innobackupex
      lrwxrwxrwx 1 root root 10 Oct 14 18:23 /usr/bin/innobackupex -> xtrabackup
      • 1
      • 2
  • Xtrabackup备份

    1. 语法格式

      innobackupex [option] BACKUP-ROOT-DIR
    2. 选项说明

      https://www.percona.com/doc/percona-xtrabackup/LATEST/genindex.html

      1. --user

        该选项表示备份账号
      2. --password

        该选项表示备份的密码
      3. --host

        该选项表示备份数据库的地址
      4. --databases

        该选项接受的参数为数据库名,如果要指定多个数据库,彼此间需要以空格隔开;如:“xtra_test dba_test”,同时,在指定某数据库时,也可以只指定其中的某张表。如:“mydatabase.mytable”。该选项对innodb引擎表无效,还是会备份所有innodb表
      5. --defaults-file

        该选项指定从哪个文件读取MySQL配置,必须放在命令行第一个选项位置
      6. --incremental

        该选项表示创建一个增量备份,需要指定–incremental-basedir
      7. --incremental-basedir

        该选项指定为前一次全备份或增量备份的目录,与–incremental同时使用
      8. --incremental-dir

        该选项表示还原时增量备份的目录
      9. --include=name

        指定表名,格式:databasename.tablename
  • Xtrabackup准备阶段(Prepare)

    1. 语法格式

      innobackupex --apply-log [option] BACKUP-DIR
    2. 选项说明:
      1. --apply-log

        一般情况下,在备份完成后,数据尚且不能用于恢复操作,因为备份的数据中可能会包含尚未提交的事务或已经提交但尚未同步至数据文件中的事务。因此,此时数据文件仍处理不一致状态。此选项作用是通过回滚未提交的事务及同步已经提交的事务至数据文件使数据文件处于一致性状态,最后一次还原需要做的,例如下图中的T3回滚到T4,相当于零时目录的扎口,说明数据补入到此完成
      2. --use-memory

        --apply-log选项一起使用,当prepare 备份时,做crash recovery分配的内存大小,单位字节,也可1MB,1M,1G,1GB等,推荐1G
      3. --export

        表示开启可导出单独的表之后再导入其他Mysql中
      4. --redo-only

        此选项在prepare base full backup,往其中合并增量备份时候使用,但不包括对最后一个增量备份的合并,用在T3之前的备份,确保事务不回滚,新版本为--apply-log-only
  • Xtrabackup还原阶段

    1. 语法格式

      innobackupex --copy-back [选项] BACKUP-DIR

      innobackupex --move-back [选项] [–defaults-group=GROUP-NAME] BACKUP-DIR
    2. 选项说明
      1. --copy-back

        做数据恢复时将备份数据文件拷贝到MySQL服务器的datadir
      2. --move-back

        这个选项与–copy-back相似,唯一的区别是它不拷贝文件,而是移动文件到目的地。这个选项移除backup文件,用时候必须小心。使用场景:没有足够的磁盘空间同事保留数据文件和Backup副本
      3. --force-non-empty-directories

        指定该参数时候,使得innobackupex --copy-back--move-back选项转移文件到非空目录,已存在的文件不会被覆盖。如果--copy-back--move-back文件需要从备份目录拷贝一个在datadir已经存在的文件,会报错失败

5.4 Xtrabackup还原原理

  • Xtrabackup使用这个过程分为三个阶段

    1. 备份阶段
    2. 准备阶段:整理数据
    3. 还原阶段
  • 还原工作原理

    1. Xtrabackup在备份时会执行redo进程将事务日志进行备份,可能出现事务日志不完全备份情况,如上图所示事务A和B,在2次增量备份中各备份了一半
    2. Xtrabackup在准备阶段会找一个零时目录,在目录中将T1、T2、T3都还原进去,凑齐完整数据,之后再进行还原阶段操作
      1. 在准备阶段,先进行完全备份还原T1(假设T1没有不完整事务,实际工作中晚完全备份也可能存在不完整事务,原理相同)
      2. 还原增量备份T2,由于存在不完整事务,需要增加--apply-log-only或--read-only,使其处于中间状态,在还原T3时,凑齐另一半,尽可能的保证数据完整
      3. 还原增量备份T3(后续没有备份),只能还原事务B的一半,当系统工作时事务B就会回滚,所以真实还原的时间点为回滚后的T4
      4. 如果二进制日志没有丢可以通过二进制日志找回事务B
  • 还原注意事项

    1. datadir目录必须为空。

      除非指定innobackupex --force-non-empty-directorires选项指定(强制使用非空目录 ),否则–copy-backup选项不会覆盖
    2. 在restore之前,必须shutdown MySQL实例,不能将一个运行中的实例restore到datadir目录中
    3. 由于文件属性会被保留,大部分情况下需要在启动实例之前将文件的属主改为mysql,这些文件将属于创建备份的用户

      chown -R mysql:mysql /data/mysql

      以上需要在用户调用innobackupex之前完成
  • 备份生成的相关文件

    使用innobakupex备份时,其会调用xtrabackup备份所有的InnoDB表,复制所有关于表结构定义的相关文件(.frm)、以及MyISAM、MERGE、CSV和ARCHIVE表的相关文件,同时还会备份触发器和数据库配置信息相关的文件。这些文件会被保存至一个以时间命名的目录中,在备份时,innobackupex还会在备份目录中创建如下文件:

    1. xtrabackup_info:innobackupex

      工具执行时的相关信息,包括版本,备份选项,备份时长,备份LSN(log sequence number日志序列号),BINLOG的位置
    2. xtrabackup_checkpoints

      备份类型(如完全或增量)、备份状态(如是否已经为prepared状态)和LSN范围信息。数据库存放数据同样是以块(InnoDB页)为单位(16k大小),每个块都会包含一个日志序列号,即LSN,系统备份会根据LSN记录此次备份位置,在下次增量备份时,以此位置的LSN序列号向后备份都最新数据。LSN是整个数据库系统的系统版本号,每个页面相关的LSN能够表明此页面最近是如何发生改变的
    3. xtrabackup_binlog_info

      MySQL服务器当前正在使用的二进制日志文件及至备份这一刻为止二进制日志事件的位置,可利用实现基于binlog的恢复
    4. backup-my.cnf

      备份命令用到的配置选项信息
    5. xtrabackup_logfile

      备份生成的日志文件,xtrabackip还原过程的日志

5.5 旧版Xtrabackup完全备份及还原

  • 在原主机

    1. 备份数据到目录/backups下

      innobackupex --user=root /backups
    2. 将备份数据传送到目标主机

      scp -r /backups/2018-02-23_11-55-57/ 目标主机:/data/

      旧版会自动在备份目录下生成以时间格式命名的目录如2018-02-23_11-55-57
  • 在目标主机
    1. 整理数据,将不完整的事务回滚

      innobackupex --apply-log /data/2018-02-23_11-55-57/
    2. 停止服务

      systemctl stop mariadb
    3. 删除原数据库数据

      rm -rf /var/lib/mysql/*
    4. 将整理过的数据复制到数据库工作目录,系统会自动根据配置文件找到工作目录

      innobackupex --copy-back /data/2018-02-23_11-55-57/
    5. 修改权限是mysql具有写权限

      chown -R mysql.mysql /var/lib/mysql/
    6. 启动服务

      systemctl start mariadb

5.5 新版Xtrabackup完全备份及还原

  • 在原主机

    1. 做完全备份到/data目录下
      [root@hai7-6 ~]$xtrabackup --backup --target-dir=/data
      • 1
    2. 将备份拷贝到目标目录
      [root@hai7-6 ~]$scp -r /data  192.168.50.111:/data
      • 1
  • 在目标主机上

    1. 模拟故障,停止服务,清空数据库
      [root@hai7-6 ~]$systemctl stop mariadb
      [root@hai7-6 ~]$rm -rf /var/lib/mysql/*
      • 1
      • 2
    2. 预准备:确保数据一致,提交完成的事务,回滚未完成的事务
      [root@hai7-8 data]$xtrabackup --prepare --target-dir=/data/data
      • 1
    3. 复制到数据库目录

      注意:数据库目录必须为空,MySQL服务不能启动
      [root@hai7-8 data]$xtrabackup --copy-back --target-dir=/data/data
      • 1
    4. 还原属性
      '拷贝完成后的属性'
      [root@hai7-8 ~]$ll /var/lib/mysql/
      drwxr-x--- 2 root root 310 Oct 15 10:04 hi
      '还原属性'
      [root@hai7-8 ~]$chown -R mysql:mysql /var/lib/mysql
      • 1
      • 2
      • 3
      • 4
      • 5
    5. 启动服务

      systemctl start mariadb

5.6 旧版Xtrabackup完全,增量备份及还原

  • 在原主机

    1. 完全备份数据

      innobackupex /backups
    2. 建立两个目录存放增量备份

      mkdir /backups/inc{1,2}
    3. 修改数据库内容,做第一增量备份,加--incremental选项,表示为增量备份
      innobackupex --incremental /backups/inc1 --incremental-basedir=/backups/2018-02-23_14-21-42(完全备份生成的路径)
      • 1
    4. 再次修改数据库内容,基于inc1再次增量备份
      innobackupex --incremental /backups/inc2 --incremental-basedir=/backups/inc1/2018-02-23_14-26-17 (上次增量备份生成的路径)
      • 1
    5. 全部备份后,将数据发送给目标端

      scp -r /backups/* 目标主机:/data/
  • 在目标主机
    1. 不启动mariadb,删除数据库原工作目录下所有文件

      rm -rf /var/lib/mysql/*
    2. 第一次整理,完全备份

      innobackupex --apply-log --redo-only /data/2018-02-23_14-21-42/
    3. 第二次整理,将增量备份与完全备份整理在一起
      innobackupex --apply-log --redo-only /data/2018-02-23_14-21-42/ --incremental-dir=/data/inc1/2018-02-23_14-26-17
      • 1
    4. 第三次整理,将第三次增量与第二次整理结果整理在一起
      innobackupex --apply-log /data/2018-02-23_14-21-42/ --incremental-dir=/data/inc2/2018-02-23_14-28-29/
      • 1
    5. 将整理好的数据复制到数据库工作目录

      innobackupex --copy-back /data/2018-02-23_14-21-42/
    6. 修改权限

      chown -R mysql.mysql /var/lib/mysql/
    7. 启动服务

      systemctl start mariadb

5.6 新版Xtrabackup完全,增量备份及还原

  • 原主机,备份过程

    1. 备份过程,服务器必须启动

      建立3各目录,分别存放完全备份和2次增量备份
      [root@hai7-6 data]$mkdir {base,inc1,inc2}
      • 1
    2. 完全备份
      [root@hai7-6 data]$xtrabackup --backup --target-dir=/data/base
      • 1
    3. 第一次修改数据
      [root@hai7-6 data]$mysql -e 'use hi; INSERT teachers VALUES(12,"AB",25,"F")'
      • 1
    4. 第一次基于完全备份的增量备份inc1
      [root@hai7-6 data]$xtrabackup --backup --target-dir=/data/inc1 --incremental-basedir=/data/base
      • 1
    5. 第二次修改数据
      [root@hai7-6 data]$mysql -e 'use hi; INSERT teachers VALUES(13,"BB",31,"M")'
      • 1
    6. 基于inc1的二次增量备份
      [root@hai7-6 data]$xtrabackup --backup --target-dir=/data/inc2 --incremental-basedir=/data/inc1
      • 1
    7. 拷贝备份文件到目标主机
      [root@hai7-6 data]$scp -r /data/ 192.168.50.111:/data
      • 1
  • 目标主机准备阶段(prepare)
    1. 整理完全备份,此选项–apply-log-only阻止回滚未完成的事务
      [root@hai7-8 data]$xtrabackup --prepare --apply-log-only --target-dir=/data/data/base
      • 1
    2. 合并第1次增量备份到完全备份
      [root@hai7-8 data]$xtrabackup --prepare --apply-log-only --target-dir=/data/data/base  --incremental-dir=/data/data/inc1
      • 1
    3. 合并第2次增量备份到完全备份:最后一次还原不需要加选项–apply-log-only
      [root@hai7-8 data]$xtrabackup --prepare --target-dir=/data/data/base  --incremental-dir=/data/data/inc2
      • 1
  • 目标主机还原阶段
    1. 复制到数据库目录,注意数据库目录必须为空,MySQL服务不能启动
      [root@hai7-8 data]$xtrabackup --copy-back --target-dir=/data/data/base
      • 1
    2. 还原属性,启动服务
      [root@hai7-8 base]$chown -R mysql:mysql /var/lib/mysql
      [root@hai7-8 base]$systemctl start mariadb
      • 1
      • 2

5.7 Xtrabackup单表备份与还原

  • 版本要求

    mariadb在5.6以上版本
  • 实验目标

    用Xtrabackup备份单表,并恢复
  • 步骤
    1. 单表备份hellodb数据库的students表: --include表示指定哪个表来备份,后跟导出目录
      [root@hai7-8 ~]$innobackupex  -uroot  -p123456  --include='hellodb.students'  /backups
      • 1
    2. 备份表结构,备份文件内有描述信息,还原时需要删除
      [root@hai7-8 ~]$mysql -p123456 -e 'SHOW CREATE TABLE hellodb.students'> students.sql
      • 1
    3. 模拟误操作,删除表
      [root@hai7-8 ~]$mysql  -pfree123456  -e 'DROP TABLE hellodb.students'
      • 1
    4. 将备份的表设为导出状态,关键词--export
      '导出后会在备份目录多出2个文件students.cfg和students.exp'
      [root@hai7-8 ~]$innobackupex --apply-log --export /backups/2018-10-15_11-19-23/
      • 1
      • 2
    5. 按照表结构创建表,参考步骤2中的表结构,从CREATE开始往后的内容,创建表后会生成表结构文件students.frm和空的数据文件students.ibd(直接拷贝文件到数据库中,会报错‘doesn’t exist in engine’,系统数据库是识别不了的)
      MariaDB [hellodb]> CREATE TABLE `students`
      > (\n `StuID` int(10) unsigned NOT NULL AUTO_INCREMENT,
      > \n `Name` varchar(50) NOT NULL,
      > \n `Age` tinyint(3) unsigned NOT NULL,
      > \n `Gender` enum('F','M') NOT NULL,
      > \n `ClassID` tinyint(3) unsigned DEFAULT NULL,
      > \n `TeacherID` int(10) unsigned DEFAULT NULL,
      > \n PRIMARY KEY (`StuID`),
      > \n KEY `index_age` (`Age`),
      > \n KEY `idx_name_age` (`Name`,`Age`)\n)
      > ENGINE=InnoDB
      > AUTO_INCREMENT=26
      > DEFAULT CHARSET=utf8;
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
    6. 删除表空间,也就是students.ibd文件,不能直接覆盖,需要执行SQL语句
      MariaDB [hellodb]> ALTER TABLE students DISCARD TABLESPACE;
      • 1
    7. 将备份表下的cfg,exp,ibd三个文件,拷贝到对应数据库工作目录
      [root@hai7-8 ~]$cp /backups/2018-02-23_15-03-23/hellodb/students.{cfg,exp,ibd}  /data/mysql/hellodb/
      • 1
    8. 修改权限属性
      [root@hai7-8 hellodb]$ chown -R mysql.mysql  /data/mysql/hellodb
      • 1
    9. 将表空间数据文件恢复回去,只拷贝过去不识别
      MariaDB [hellodb]> ALTER TABLE hellodb.students IMPORT TABLESPACE;
      • 1
        </div>
<link href="https://csdnimg.cn/release/phoenix/mdeditor/markdown_views-7f770a53f2.css" rel="stylesheet">
</div>

最新文章

  1. 13,SFDC 管理员篇 - 移动客户端
  2. ArcGIS线转面的方法
  3. 【代码笔记】iOS-和当前时间比较
  4. webApp前端开发技巧总结
  5. Fedora 25 Alpha版本今天发布啦
  6. sql数据库批量替换dedecms内容关键字
  7. JsRender系列demo(7)compline
  8. javascript读取xml的方法【转载】
  9. Nagios监控memcached
  10. hdu1172猜数字
  11. 我是小白之&lt;%%&gt;用法
  12. Swift - 从ALAsset中获取照片的原图并转换成NSData
  13. JS-运动基础(一)续
  14. [python学习笔记] String格式化
  15. 使用Hexo+Github一步步搭建属于自己的博客(进阶)
  16. Mybatis框架解析之Builder解析
  17. 【LightOJ1370】Bi-shoe and Phi-shoe(欧拉函数)
  18. swiftmailer时没有设置https的选项,才可以发送成功。在linux下面
  19. __x__(12)0906第三天__&lt;meta&gt;标签
  20. 基于C#实现的自动化测试框架:发布自动触发自动化回归测试

热门文章

  1. USACO Section 1.2PROB Miking Cows
  2. ZOJ1450 Minimal Circle 最小圆覆盖
  3. 使用Oracle Sql Developer将SQL SERVER 2008数据库移植到Oracle 11g
  4. ubuntu16.04 查看CPU是几核
  5. 理解javascript中的事件模型
  6. 【培训】MySQL
  7. 乐字节Java8核心特性之方法引用
  8. python/shell脚本报异常^M: bad interpreter: No such file or directory
  9. ROS-USB摄像头
  10. Hive insert into directory 命令输出的文件没有列分隔符分析和解决