MYSQL数据库(八)数据库备份和恢复

成功不易,加倍努力!

      • 5 备份和恢复
        • 5.1 备份恢复概述
          • 5.1.1 为什么要备份
          • 5.1.2 备份类型
          • 5.1.3 备份什么
          • 5.1.4 备份注意要点
          • 5.1.5 还原要点
          • 5.1.6 备份工具
          • 5.1.6 基于 LVM 的快照备份
          • 5.1.7 实战案例:数据库冷备份和还原
        • 5.2 mysqldump备份工具
          • 5.2.1 mysqldump 说明
          • 5.2.2 生产环境实战备份策略
          • 5.2.3 mysqldump 备份还原实战案例
        • 5.3 xtrabackup备份工具
          • 5.3.1 xtrabackup工具介绍
          • 5.3.2 xtrabackup安装
          • 5.3.3 xtrabackup用法
          • 5.3.4 实战案例:利用xtrabackup实现完全备份及还原
          • 5.3.6 实战案例:xtrabackup单表导出和导入

5 备份和恢复

5.1 备份恢复概述

5.1.1 为什么要备份

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

5.1.2 备份类型
  • 完全备份,部分备份
    完全备份:整个数据集
    部分备份:只备份数据子集,如部分库或表
  • 完全备份、增量备份、差异备份
    增量备份:仅备份最近一次完全备份或增量备份(如果存在增量)以来变化的数据,备份较快,还原复杂

MYSQL数据库(八)数据库备份和恢复_第1张图片

差异备份:仅备份最近一次完全备份以来变化的数据,备份较慢,还原简单

MYSQL数据库(八)数据库备份和恢复_第2张图片

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

  • 冷、温、热备份
    冷备:读、写操作均不可进行,数据库停止服务
    温备:读操作可执行;但写操作不可执行
    热备:读、写操作均可执行
    MyISAM:温备,不支持热备
    InnoDB:都支持

  • 物理和逻辑备份
    物理备份:直接复制数据文件进行备份,与存储引擎有关,占用较多的空间,速度快(需要停服务)
    逻辑备份:从数据库中“导出”数据另存而进行的备份,与存储引擎无关,占用空间少,速度慢,可能丢失精度

5.1.3 备份什么
  • 数据
  • 二进制日志、InnoDB的事务日志
  • 用户帐号,权限设置,程序代码(存储过程、函数、触发器、事件调度器)
  • 服务器的配置文件
5.1.4 备份注意要点
  • 能容忍最多丢失多少数据
  • 备份产生的负载
  • 备份过程的时长
  • 温备的持锁多久
  • 恢复数据需要在多长时间内完成
  • 需要备份和恢复哪些数据
5.1.5 还原要点
  • 做还原测试,用于测试备份的可用性
  • 还原演练,写成规范的技术文档
5.1.6 备份工具
  • cp, tar等复制归档工具:物理备份工具,适用所有存储引擎;只支持冷备;完全和部分备份(需要停服务,无法保证数据时间一致性
  • LVM的快照:先加读锁,做快照后解锁,几乎热备;借助文件系统工具进行备份(用的不多
  • mysqldump:逻辑备份工具,适用所有存储引擎,对MyISAM存储引擎进行温备;支持完全或部分备份;对InnoDB存储引擎支持热备,结合binlog的增量备份(主流工具
  • xtrabackup:由Percona提供支持对InnoDB做热备(物理备份)的工具,支持完全备份、增量备份(相对较少
  • MariaDB Backup: 从MariaDB 10.1.26开始集成,基于Percona XtraBackup 2.3.8实现(付费
  • mysqlbackup:热备份, MySQL Enterprise Edition组件
  • mysqlhotcopy:PERL 语言实现,几乎冷备,仅适用于MyISAM存储引擎,使用LOCK TABLES、FLUSH TABLES和cp或scp来快速备份数据库(用的越来越少
5.1.6 基于 LVM 的快照备份

生产中用的较少,前提是事先要把数据库存到逻辑卷里

(1) 请求锁定所有表
mysql> FLUSH TABLES WITH READ LOCK;
(2) 记录二进制日志文件及事件位置
mysql> FLUSH LOGS;          #刷新日志,生成新的二进制日志
mysql> SHOW MASTER STATUS;  #看到当前二进制大小和使用文件是谁
mysql -e 'SHOW MASTER STATUS' > /PATH/TO/SOMEFILE
(3) 创建快照
lvcreate -L # -s -p r -n NAME /DEV/VG_NAME/LV_NAME
(4) 释放锁
mysql> UNLOCK TABLES;
(5) 挂载快照卷,执行数据备份
(6) 备份完成后,删除快照卷     #不删的话只要有数 据更新就会写入快照,影响性能
(7) 制定好策略,通过原卷备份二进制日志
5.1.7 实战案例:数据库冷备份和还原
#在目标服务器(10.0.0.18)安装mariadb-server,不启动服务
[root@centos8 ~]#dnf install mariadb-server

#在源主机(10.0.0.8)先启用二进制日志  (实验需要)
[root@centos8 ~]#vim /etc/my.cnf.d/mariadb-server.cnf 
[mysqld]
log-bin=/data/logbin/mysql-bin
[root@centos8 ~]#mkdir /data/logbin
[root@centos8 ~]#chown mysql.mysql /data/logbin
[root@centos8 ~]#systemctl restart mariadb
[root@centos8 ~]#ll /data/logbin/
total 8
-rw-rw---- 1 mysql mysql 328 Jun 12 21:37 mysql-bin.000001
-rw-rw---- 1 mysql mysql  30 Jun 12 21:37 mysql-bin.index

#在源主机(10.0.0.8)执行停止服务
[root@centos8 ~]# systemctl stop mariadb

#复制相关文件
[root@centos8 ~]# scp /etc/my.cnf.d/mariadb-server.cnf 10.0.0.18:/etc/my.cnf.d/
[root@centos8 ~]# scp -r /var/lib/mysql/* 10.0.0.18:/var/lib/mysql/
[root@centos8 ~]# scp -r /data/logbin/ 10.0.0.18:/data/ #10.0.0.18事先存在/data/目录

#保留属性:推荐使用
[root@centos8 ~]#rsync -av /var/lib/mysql/ 10.0.0.18:/var/lib/mysql/
[root@centos8 ~]#rsync -av /data/logbin 10.0.0.18:/backup  #数据库更新之前的二进制日志
[root@centos8 ~]#rsync -a /etc/my.cnf.d/mariadb-server.cnf  10.0.0.18:/backup
[root@centos8 ~]#ll /data/logbin/
total 8
-rw-rw---- 1 mysql mysql 351 Jun 12 21:44 mysql-bin.000001
-rw-rw---- 1 mysql mysql  30 Jun 12 21:37 mysql-bin.index
-rw-rw---- 1 mysql mysql   0 Jun 12 21:44 mysql-bin.state

#若源主机在备份之后又更新了数据库,则需要将最新的二进制日志也进行备份
[root@centos8 ~]#rsync -av /data/logbin 10.0.0.18:/backup/newlogbin
[root@centos8 ~]#ll /backup/newlogbin/
total 12
-rw-r----- 1 root root 351 Jun 13 23:16 mysql-bin.000001
-rw-r----- 1 root root 913 Jun 13 23:16 mysql-bin.000002
-rw-r----- 1 root root  60 Jun 13 23:16 mysql-bin.index
[root@centos8 ~]#mysqlbinlog /backup/newlogbin/mysql-bin.000002 > logbin.sql  #mysqlbinlog可以查看二进制日志
MariaDB [(none)]> show variables like 'sql_log_bin';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| sql_log_bin   | ON    |
+---------------+-------+
1 row in set (0.001 sec)

MariaDB [(none)]> set sql_log_bin=0;
Query OK, 0 rows affected (0.000 sec)

MariaDB [(none)]> show variables like 'sql_log_bin';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| sql_log_bin   | OFF   |
+---------------+-------+
1 row in set (0.001 sec)

MariaDB [(none)]> source /root/logbin.sql
MariaDB [hellodb]> set sql_log_bin=1;
#到此更新后的数据也都还原了

#在目标主机(10.0.0.18)执行
[root@centos8 ~]#chown -R mysql.mysql /var/lib/mysql/
[root@centos8 ~]#chown -R mysql.mysql /data/logbin/
[root@centos8 ~]#systemctl start mariadb

注意

还原数据时要把二进制日志功能停掉sql_log_bin,不然还原的过程也会存到日志里

5.2 mysqldump备份工具

5.2.1 mysqldump 说明

逻辑备份工具

mysqldump, mydumper, phpMyAdmin
Schema和数据存储在一起、巨大的SQL语句、单个巨大的备份文件

mysqldump:是MySQL的客户端命令,通过mysql协议连接至mysql服务器进行备份

命令格式:

mysqldump [OPTIONS] database [tables] #支持指定数据库和指定多表的备份,但数据库本身定义不备份,造成的问题较多,如字符集,排序规则等若没有提前备份,则数据库不可用
mysqldump [OPTIONS] –B DB1 [DB2 DB3...] #支持指定数据库备份,包含数据库本身定义也会备份
mysqldump [OPTIONS] –A [OPTIONS] #备份所有数据库,包含数据库本身定义也会备份
[root@centos8 ~]#mysqldump -uroot -p'' hellodb students > students.sql
#利用students.sql就可以进行还原

mysqldump参考:

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

mysqldump 常见通用选项:

-A, --all-databases 	 #备份所有数据库,含create database; 不包含information_schema和performance_schema这两个库
-B, --databases db_name… #指定备份的数据库,包括create database语句
-E, --events:			#备份相关的所有event scheduler
-R, --routines:			#备份所有存储过程和自定义函数(mysql数据库包含了存储过程和自定义函数,不加-R选项直接备份nysql数据库也可以)
--triggers:				#备份表相关触发器,默认启用,用--skip-triggers,不备份触发器
--default-character-set=utf8 #指定字符集  (拉丁字符集被utf8所包含)
--master-data[=#]: 		#此选项须启用二进制日志
#1:所备份的数据之前加一条记录为CHANGE MASTER TO语句,非注释,不指定#,默认为1,适合于主从复制多机使用
#2:记录为被注释的#CHANGE MASTER TO语句,适合于单机使用
#此选项会自动关闭--lock-tables功能,自动打开-x | --lock-all-tables功能(除非开启--single-transaction)
-F, --flush-logs #备份前滚动日志,锁定表完成后,执行flush logs命令,生成新的二进制日志文件,配合-A 或 -B 选项时,会导致刷新多次数据库。建议在同一时刻执行转储和日志刷新,可通过和--single-transaction或-x,--master-data 一起使用实现,此时只刷新一次二进制日志
--compact 			 	#去掉注释,适合调试,生产不使用
-d, --no-data 			#只备份表结构
-t, --no-create-info    #只备份数据,不备份create table
-n,--no-create-db 		#不备份create database,可被-A或-B覆盖
--flush-privileges 	 	#备份mysql或相关时需要使用
-f, --force 			#忽略SQL错误,继续执行
--hex-blob 				#使用十六进制符号转储二进制列,当有包括BINARY, VARBINARY,BLOB,BIT的数据类型的列时使用,避免乱码
-q, --quick 			#不缓存查询,直接输出,加快备份速度

mysqldump的MyISAM存储引擎相关的备份选项

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

-x,--lock-all-tables #加全局读锁,锁定所有库的所有表,同时加--single-transaction或--lock-tables选项会关闭此选项功能,注意:数据量大时,可能会导致长时间无法并发访问数据库
-l,--lock-tables #对于需要备份的每个数据库,在启动备份之前分别锁定其所有表,默认为on,--skip-lock-tables选项可禁用,对备份MyISAM的多个库,可能会造成数据不一致
#注:以上选项对InnoDB表一样生效,实现温备,但不推荐使用

mysqldump的InnoDB存储引擎相关的备份选项

InnoDB 存储引擎支持事务,可以利用事务的相应的隔离级别,实现热备,也可以实现温备但不建议用

--single-transaction
#此选项Innodb中推荐使用,不适用MyISAM,此选项会开始备份前,先执行START TRANSACTION指令开启事务
#此选项通过在单个事务中转储所有表来创建一致的快照。 仅适用于存储在支持多版本控制的存储引擎中的表(目前只有InnoDB可以); 转储不保证与其他存储引擎保持一致。 在进行单事务转储时,要确保有效的转储文件(正确的表内容和二进制日志位置),没有其他连接应该使用以下语句:ALTER TABLE,DROPTABLE,RENAME TABLE,TRUNCATE TABLE,此选项和--lock-tables(此选项隐含提交挂起的事务)选项是相互排斥,备份大型表时,建议将--single-transaction选项和--quick结合一起使用
5.2.2 生产环境实战备份策略

InnoDB建议备份策略

mysqldump –uroot -p –A –F –E –R --triggers --single-transaction --master-data=1 --flushprivileges  --default-character-set=utf8 --hex-blob
>${BACKUP}/fullbak_${BACKUP_TIME}.sql
#A全备份  --hex-blob十六进制保存  -F生成新的二进制日志   -E备份事务 

MyISAM建议备份策略

mysqldump –uroot -p –A –F –E –R –x --master-data=1 --flush-privileges --triggers --default-character-set=utf8 --hex-blob
>${BACKUP}/fullbak_${BACKUP_TIME}.sql
#-x锁定整个数据库
5.2.3 mysqldump 备份还原实战案例

MYSQL数据库(八)数据库备份和恢复_第3张图片

备份还原的思路:
1.禁止用户访问,业务升级,skip-networking
2.先还原数据到两点,找到两点以后的二进制日志生成sql语句,导出来后,2:00到10:10的二进制日志中有删表的操作,把此操作删除后再恢复
3.二进制日志功能关闭,先恢复两点之前数据,在恢复两点之后数据
4.一个库里表和表时间不统一(假设10:10点的表是库存表,10:30分的表是订单表),10:10时库存表被删了,而订单却一直在变,库存却没有对应减少,影响业务。这种情况下数据就最好恢复到删表之前的状态,删表之后的状态只能丢弃

具体步骤如下:
#导出日志
[root@centos8 ~]#mysqldump -A --master-data=2 > /backup/all_2.sql
[root@centos8 ~]#less /backup/alll_2.sql  #查看数据更新到哪个点
-- CHANGE MASTER TO MASTER_LOG_FILE='mysql_bin.000001', MASTER_LOG_POS=328;
[root@centos8 ~]#mysqlbinlog /data/logbin/mysql_bin.000001 --start-position=328 > /backup/inc.sql

#删表操作删除
[root@centos8 ~]#sed -i.bak '/^DROP TABLE/d' /backup/inc.sql

#关闭二进制日志功能
MariaDB [(none)]> set sql_log_bin=off;
Query OK, 0 rows affected (0.000 sec)

MariaDB [(none)]> select @@sql_log_bin;
+---------------+
| @@sql_log_bin |
+---------------+
|             0 |
+---------------+
1 row in set (0.000 sec)

#数据还原
MariaDB [(none)]> source /backup/all_2.sql
MariaDB [mysql]> source /backup/inc.sql
MariaDB [hellodb]> set sql_log_bin=on;

5.2.3.1 实战案例:特定数据库的备份脚本

[root@centos8 ~]#cat backup_hellodb.sh
#!/bin/bash
TIME=`date +%F_%H-%M-%S`
DIR=/backup
DB=hellodb
PASS=magedu

mysqldump -uroot -p "$PASS" -F –E –R --triggers --single-transaction --master-data=2 --default-character-set=utf8 -q -B $DB | gzip > ${DIR}/${DB}_${TIME}.sql.gz
#-B指定某个库备份

5.2.3.2 实战案例:分库备份并压缩

[root@centos8 ~]#for db in `mysql -uroot -e 'show databases'|grep -Ev
'^(Database|information_schema|performance_schema)$'`;do mysqldump -B $db | gzip > /data/$db.sql.gz;done

[root@centos8 ~]#for db in `mysql -e 'show databases' | grep -Ev 'Database|information_schema|performance_schema'`;do mysqldump -B $db > /backup/${db}_`date +%F`.sql;done

[root@centos8 ~]#mysql -uroot -e 'show databases'|sed -rn '/^(Database|information_schema|performance_schema)$/!s#(.*)#mysqldump -B \1 |gzip > /data/\1.sql.gz#p' |bash

[root@centos8 ~]#mysql -uroot -e 'show databases'|grep -Ev
'^(Database|information_schema|performance_schema)$' | sed -rn 's# (.*)#mysqldump -B \1 | gzip > /data/\1.sql.gz#p' |bash

[root@centos8 ~]#mysql -uroot -e 'show databases'|grep -Ev
'^(Database|information_schema|performance_schema)$'|while read db;do mysqldump -B $db | gzip > /data/$db.sql.gz;done


[root@centos8 ~]#ll /backup/
total 484
-rw-r--r-- 1 root root   7803 Jun 13 10:07 hellodb_2020-06-13.sql
-rw-r--r-- 1 root root   3012 Jun 13 10:07 hellodb2_2020-06-13.sql
-rw-r--r-- 1 root root 481308 Jun 13 10:07 mysql_2020-06-13.sql

5.2.3.3 实战案例:分库备份的实战脚本

[root@centos8 ~]#cat backup_db.sh
#!/bin/bash
TIME=`date +%F_%H-%M-%S`
DIR=/backup
PASS=magedu

[ -d "$DIR" ] || mkdir $DIR

for DB in `mysql -uroot -p "$PASS" -e 'show databases' | grep -Ev
"^Database|.*schema$"`;do
	mysqldump -F --single-transaction --master-data=2 --default-characterset=utf8 -q -B $DB | gzip > ${DIR}/${DB}_${TIME}.sql.gz
done

5.2.3.4 实战案例:完全备份和还原

#开启二进制日志
[root@centos8 ~]#vim /etc/my.cnf.d/mariadb-server.cnf
[mysqld]
log-bin

#备份
[root@centos8 ~]#mysqldump -uroot -pmagedu -A -F --single-transaction --masterdata=2 |gzip > /backup/all-`date +%F`.sql.gz

#还原
[root@centos8 backup]#dnf install mariadb-server
[root@centos8 backup]#gzip -d all-2019-11-27.sql.gz
[root@centos8 ~]#mysql
MariaDB [(none)]> set sql_log_bin=off;
MariaDB [(none)]> source /backup/all-2019-11-27.sql
MariaDB [(none)]> set sql_log_bin=on;

5.2.3.5 实战案例:利用二进制日志,还原数据库最新状态

#二进制日志独立存放
[mysqld]
log-bin=/data/mysql/mysql-bin

#完全备份,并记录备份的二进制位置
mysqldump -uroot -pmagedu -A -F --default-character-set=utf8 --singletransaction --master-data=2 | gzip > /backup/all_`date +%F`.sql.gz

#修改数据库
insert students (name,age,gender)value('mage',20,'M');
insert students (name,age,gender)value('wang',22,'M');

#损坏数据库
rm -rf /var/lib/mysql/*

#还原
cd /backup
gzip -d all_2019-11-25.sql.gz

#CentOS 8 需要事先生成数据库相关文件,CentOS7 不需要执行此步
mysql_install_db --user=mysql
systemctl restart mariadb
MariaDB [(none)]> show master logs;
+------------------+-----------+
| Log_name 		   | File_size |
+------------------+-----------+
| mysql-bin.000001 | 	   998 |
| mysql-bin.000002 | 	 28090 |
| mysql-bin.000003 | 	   342 |
+------------------+-----------+
3 rows in set (0.000 sec)

MariaDB [(none)]>set sql_log_bin=0;
MariaDB [(none)]>source /data/all_2019-11-25.sql

[root@centos8 ~]#grep '^-- CHANGE MASTER TO' /data/all_2019-11-25.sql
-- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=328;

#二进制日志的备份
[root@centos8 mysql]#mysqlbinlog mysql-bin.000001 --start-position=328 > /backup/inc.sql
[root@centos8 mysql]#mysqlbinlog mysql-bin.000002 >> /backup/inc.sql

MariaDB [(none)]>set sql_log_bin=0;
MariaDB [(none)]>source /backup/inc.sql
MariaDB [(none)]>set sql_log_bin=1;

5.2.3.6 实战案例:mysqldump 和二进制日志结合实现增量备份

[root@centos8 ~]#mysqldump -uroot -p -A -F --single-transaction --master-data=2 |gzip > /backup/all-`date +%F`.sql.gz

#观察备份文件中的二进制文件和位置,将之后的二进制日志进行复制备份
[root@centos8 ~]#cp /var/lib/mysql/mariadb-bin.000003 /backup
[root@centos8 ~]#mysqlbinlog --start-position=389 /backup/mariadb-bin.000003 > /backup/inc.sql

5.2.3.7 实战案例:恢复误删除的表

案例说明:每天2:30做完全备份,早上10:00误删除students,10:10才发现故障,现需要将数据库还原到10:10的状态,且恢复被删除的students表

#完全备份
[root@centos8 ~]#mysqldump -uroot -p -A -F --single-transaction --master-data=2 > /backup/allbackup_`date +%F_%T`.sql
[root@centos8 ~]#ll /backup/
total 2992
-rw-r--r-- 1 root root 3060921 Nov 27 10:20 allbackup_2019-11-27_10:20:08.sql

#完全备份后数据更新
MariaDB [testdb]> insert students (name,age,gender) values('rose',20,'f');
Query OK, 1 row affected (0.001 sec)

MariaDB [testdb]> insert students (name,age,gender) values('jack',22,'M');
Query OK, 1 row affected (0.001 sec)

#10:00误删除了一个重要的表
MariaDB [testdb]> drop table students;
Query OK, 0 rows affected (0.021 sec)

#后续其它表继续更新
MariaDB [testdb]> use hellodb;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
MariaDB [hellodb]> insert teachers (name,age,gender)values('wang',30,'M');
Query OK, 1 row affected (0.002 sec)

MariaDB [hellodb]> insert teachers (name,age,gender)values('mage',28,'M');
Query OK, 1 row affected (0.002 sec)

MariaDB [hellodb]> 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 | wang          |  30 | M      |
|   6 | mage          |  28 | M      |
+-----+---------------+-----+--------+
6 rows in set (0.000 sec)

#10:10发现表删除,进行还原
#停止数据库访问

#从完全备份中,找到二进制位置
[root@centos8 ~]#grep '\-\- CHANGE MASTER TO' /backup/allbackup_2019-11-
27_10\:20\:08.sql
-- CHANGE MASTER TO MASTER_LOG_FILE='mariadb-bin.000003', MASTER_LOG_POS=389;

#备份从完全备份后的二进制日志
[root@centos8 ~]#mysqlbinlog --start-position=389 /var/lib/mysql/mariadb-bin.000003 > /backup/inc.sql

#找到误删除的语句,从备份中删除此语句
[root@centos8 ~]#vim /data/inc.sql
#DROP TABLE `student_info` /* generated by server */
#如果文件过大,可以使用sed实现
[root@centos8 ~]#sed -i.bak '/^DROP TABLE/d' /data/inc.sql

#利用完全备份和修改过的二进制日志进行还原
[root@centos8 ~]#mysql -uroot -p
MariaDB [hellodb]> set sql_log_bin=0;
MariaDB [hellodb]> source /backup/allbackup_2019-11-27_10:20:08.sql;
MariaDB [hellodb]> source /backup/inc.sql
MariaDB [hellodb]> set sql_log_bin=1;

5.3 xtrabackup备份工具

5.3.1 xtrabackup工具介绍

Percona 公司

官网:www.percona.com
percona-server
InnoDB --> XtraDB

Xtrabackup备份工具

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

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

下载: https://www.percona.com/downloads/

MYSQL数据库(八)数据库备份和恢复_第4张图片
MYSQL数据库(八)数据库备份和恢复_第5张图片

xtrabackup 特点:

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

xtrabackup工具文件组成

Xtrabackup2.2 版之前包括4个可执行文件:
innobackupex: Perl 脚本
xtrabackup:   C/C++,编译的二进制程序
xbcrypt: 	  加解密
xbstream: 	  支持并发写的流文件格式

xtrabackup 是用来备份 InnoDB 表的,不能备份非 InnoDB 表,和 MySQL Server 没有交互

innobackupex 脚本用来备份非 InnoDB 表,同时会调用 xtrabackup 命令来备份 InnoDB 表,还会和MySQL Server 发送命令进行交互,如加全局读锁(FTWRL)、获取位点(SHOW SLAVE STATUS)等。即innobackupex是在 xtrabackup 之上做了一层封装实现的

xtrabackup的新版变化

xtrabackup版本升级到2.4后,相比之前的2.1有了比较大的变化:innobackupex 功能全部集成到xtrabackup 里面,只有一个 binary程序,另外为了兼容考虑,innobackupex作为 xtrabackup 的软链接,即xtrabackup现在支持非Innodb表备份,并且 Innobackupex 在下一版本中移除,建议通过xtrabackup替换innobackupex

xtrabackup备份过程

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-V0f3QTW5-1592137481711)(C:\Users\cui\AppData\Roaming\Typora\typora-user-images\image-20200613203126622.png)]

备份生成的相关文件

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

  • xtrabackup_info:文本文件,innobackupex工具执行时的相关信息,包括版本,备份选项,备份时长,备份LSN(log sequence number日志序列号),BINLOG的位置

  • xtrabackup_checkpoints:文本文件,备份类型(如完全或增量)、备份状态(如是否已经为prepared状态)和LSN范围信息,每个InnoDB页(通常为16k大小)都会包含一个日志序列号LSN。LSN是整个数据库系统的系统版本号,每个页面相关的LSN能够表明此页面最近是如何发生改变的

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

  • backup-my.cnf:文本文件,备份命令用到的配置选项信息
    xtrabackup_logfile:备份生成的二进制日志文件

范例:相关文件

[root@centos8 ~]#ll /usr/bin/innobackupex 
lrwxrwxrwx 1 root root 10 Apr 11 04:10 /usr/bin/innobackupex -> xtrabackup
[root@centos8 ~]#ll /usr/bin/xtrabackup 
-rwxr-xr-x 1 root root 21303696 Apr 11 04:10 /usr/bin/xtrabackup

[root@centos8 ~]#ll /backup/
total 12340
-rw-r----- 1 root root      487 Jun 13 22:10 backup-my.cnf
drwxr-x--- 2 root root      272 Jun 13 22:10 hellodb
-rw-r----- 1 root root      425 Jun 13 22:10 ib_buffer_pool
-rw-r----- 1 root root 12582912 Jun 13 22:10 ibdata1
drwxr-x--- 2 root root     4096 Jun 13 22:10 mysql
drwxr-x--- 2 root root     8192 Jun 13 22:10 performance_schema
drwxr-x--- 2 root root     8192 Jun 13 22:10 sys
-rw-r----- 1 root root       25 Jun 13 22:10 xtrabackup_binlog_info
-rw-r----- 1 root root      135 Jun 13 22:10 xtrabackup_checkpoints
-rw-r----- 1 root root      479 Jun 13 22:10 xtrabackup_info
-rw-r----- 1 root root     2560 Jun 13 22:10 xtrabackup_logfile

[root@centos8 ~]#cat /backup/xtrabackup_checkpoints 
backup_type = full-backuped
from_lsn = 0
to_lsn = 2682522
last_lsn = 2682531
compact = 0
recover_binlog_info = 0
flushed_lsn = 2682531

[root@centos8 ~]#cat /backup/xtrabackup_info 
uuid = 9ea8b2fb-ad7f-11ea-9cd4-000c2930800a
name = 
tool_name = xtrabackup
tool_command = -uroot -pmagedu --backup --target-dir=/backup/
tool_version = 2.4.20
ibbackup_version = 2.4.20
server_version = 5.7.29-log
start_time = 2020-06-13 22:10:20
end_time = 2020-06-13 22:10:22
lock_time = 1
binlog_pos = filename 'centos8-bin.000002', position '10185'
innodb_from_lsn = 0
innodb_to_lsn = 2682522
partial = N
incremental = N
format = file
compact = N
compressed = N
encrypted = N

[root@centos8 ~]#ll /backup/xtrabackup_binlog_info
-rw-r----- 1 root root 25 Jun 13 22:10 /backup/xtrabackup_binlog_info
[root@centos8 ~]#cat /backup/xtrabackup_binlog_info 
centos8-bin.000002	10185
mysql> show master logs;
+--------------------+-----------+
| Log_name           | File_size |
+--------------------+-----------+
| centos8-bin.000001 |       177 |
| centos8-bin.000002 |     10185 |
+--------------------+-----------+
2 rows in set (0.00 sec)

[root@centos8 ~]#file /backup/xtrabackup_logfile
/backup/xtrabackup_logfile: data

[root@centos8 ~]#cat /backup/backup-my.cnf
# This MySQL options file was generated by innobackupex.

# The MySQL server
[mysqld]
innodb_checksum_algorithm=crc32
innodb_log_checksum_algorithm=strict_crc32
innodb_data_file_path=ibdata1:12M:autoextend
innodb_log_files_in_group=2
innodb_log_file_size=50331648
innodb_fast_checksum=false
innodb_page_size=16384
innodb_log_block_size=512
innodb_undo_directory=./
innodb_undo_tablespaces=0
server_id=1
redo_log_version=1
server_uuid=64f21c70-ad78-11ea-80fc-000c2930800a
master_key_id=0
5.3.2 xtrabackup安装

yum install percona-xtrabackup 在EPEL源中
最新版本下载安装:
https://www.percona.com/downloads/XtraBackup/LATEST/

5.3.3 xtrabackup用法

xtrabackup工具备份和还原,需要三步实现

  1. 备份:对数据库做完全或增量备份
  2. 预准备: 还原前,先对备份的数据,整理至一个临时目录,
  3. 还原:将整理好的数据,复制回数据库目录中

xtrabackup 选项参考

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

备份

innobackupex [option] BACKUP-ROOT-DIR

选项说明:

--user:			#该选项表示备份账号
--password:		#该选项表示备份的密码
--host:			#该选项表示备份数据库的地址
--databases:	#该选项接受的参数为数据库名,如果要指定多个数据库,彼此间需要以空格隔开;
如:"xtra_test dba_test",同时,在指定某数据库时,也可以只指定其中的某张表。
如:"mydatabase.mytable"。该选项对innodb引擎表无效,还是会备份所有innodb--defaults-file:#该选项指定从哪个文件读取MySQL配置,必须放在命令行第一个选项位置
--incremental:  #该选项表示创建一个增量备份,需要指定--incremental-basedir
--incremental-basedir:#该选项指定为前一次全备份或增量备份的目录,与--incremental同时使用
--incremental-dir:    #该选项表示还原时增量备份的目录
--include=name:    	  #指定表名,格式:databasename.tablename

Prepare预准备

innobackupex --apply-log [option] BACKUP-DIR

选项说明:

--apply-log:#一般情况下,在备份完成后,数据尚且不能用于恢复操作,因为备份的数据中可能会包含尚未提交的事务或已经提交但尚未同步至数据文件中的事务。因此,此时数据文件仍处理不一致状态。此选项作用是通过回滚未提交的事务及同步已经提交的事务至数据文件使数据文件处于一致性状态
--use-memory:#和--apply-log选项一起使用,当prepare 备份时,做crash recovery分配的内存大小,单位字节,也可1MB,1M,1G,1GB等,推荐1G
--export:#表示开启可导出单独的表之后再导入其他Mysql中
--redo-only:#此选项在prepare base full backup,往其中合并增量备份时候使用,但不包括对最后一个增量备份的合并

还原

innobackupex --copy-back [选项] BACKUP-DIR
innobackupex --move-back [选项] [--defaults-group=GROUP-NAME] BACKUP-DIR

选项说明:

--copy-back:#做数据恢复时将备份数据文件拷贝到MySQL服务器的datadir
--move-back:#这个选项与--copy-back相似,唯一的区别是它不拷贝文件,而是移动文件到目的地。这个选项移除backup文件,用时候必须小心。使用场景:没有足够的磁盘空间同事保留数据文件和Backup副本
--force-non-empty-directories #指定该参数时候,使得innobackupex --copy-back或--moveback选项转移文件到非空目录,已存在的文件不会被覆盖。如果--copy-back和--move-back文件需要从备份目录拷贝一个在datadir已经存在的文件,会报错失败

还原注意事项

  1. datadir 目录必须为空。除非指定innobackupex --force-non-empty-directorires选项指定,否则–copy-back选项不会覆盖
  2. 在restore之前,必须shutdown MySQL实例,不能将一个运行中的实例restore到datadir目录中
  3. 由于文件属性会被保留,大部分情况下需要在启动实例之前将文件的属主改为mysql,这些文件将属于创建备份的用户, 执行chown -R mysql:mysql /data/mysql,以上需要在用户调用innobackupex之前完成
5.3.4 实战案例:利用xtrabackup实现完全备份及还原

注意:目前percona-xtrabackup-24-2.4.18-1.el8.x86_64.rpm不支持CentOS8上的mariadb-10.3版本

案例1:新版xtrabackup完全备份及还原

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-X0q7I94C-1592137481715)(C:\Users\cui\AppData\Roaming\Typora\typora-user-images\image-20200613220552254.png)]

1 在原主机做完全备份到/backup
#/backup目录不需事先创建
xtrabackup -uroot -pmagedu --backup --target-dir=/backup/
scp -r /backup/* 目标主机:/backup

2 在目标主机上还原
1)预准备:确保数据一致,提交完成的事务,回滚未完成的事务
	xtrabackup --prepare --target-dir=/backup/
2)复制到数据库目录
	注意:数据库目录必须为空,MySQL服务不能启动
	xtrabackup --copy-back --target-dir=/backup/
3)还原属性
	chown -R mysql:mysql /var/lib/mysql
4)启动服务
	systemctl start mariadb

案例2:旧版xtrabackup完全备份及还原

1 在源主机备份

innobackupex --user=root /backup
scp -r /backup/2018-02-23_11-55-57/ 	目标主机:/data/

2 在目标主机预准备并还原

#预准备
innobackupex --apply-log /data/2018-02-23_11-55-57/

#还原过程
systemctl stop mariadb
rm -rf /var/lib/mysql/*
innobackupex --copy-back /data/2018-02-23_11-55-57/
chown -R mysql.mysql /var/lib/mysql/
systemctl start mariadb

5.3.5 实战案例:利用xtrabackup完全,增量备份及还原

案例1:新版xtrabackup完全,增量备份及还原
MYSQL数据库(八)数据库备份和恢复_第6张图片

1 备份过程
1)完全备份:
mkdir /backup/
xtrabackup -uroot -pmagedu --backup --target-dir=/backup/base
2)第一次修改数据
3)第一次增量备份  #增量备份是基于前一个备份
xtrabackup -uroot -pmagedu --backup --target-dir=/backup/inc1 --incremental-basedir=/backup/base
4)第二次修改数据
5)第二次增量
xtrabackup -uroot -pmagedu --backup --target-dir=/backup/inc2 --incremental-basedir=/backup/inc1
6)scp -r /backup/* 目标主机:/backup/
#备份过程生成三个备份目录
/backup/{base,inc1,inc2}

2还原过程 (想象成扎口袋)
1)预准备完成备份,此选项--apply-log-only 阻止回滚未完成的事务
xtrabackup --prepare --apply-log-only --target-dir=/backup/base
2)合并第1次增量备份到完全备份,
xtrabackup --prepare --apply-log-only --target-dir=/backup/base --incremental-dir=/backup/inc1
3)合并第2次增量备份到完全备份:最后一次还原不需要加选项--apply-log-only
xtrabackup --prepare --target-dir=/backup/base --incremental-dir=/backup/inc2

4)复制到数据库目录,注意数据库目录必须为空,MySQL服务不能启动
xtrabackup --copy-back --target-dir=/backup/base
5)还原属性:chown -R mysql:mysql /data/mysql
6)启动服务:systemctl start mariadb

案例2:旧版xtrabackup完全,增量备份及还原

1 在源主机备份

innobackupex /backup
mkdir /backup/inc{1,2}
#修改数据库内容
innobackupex --incremental /backup/inc1 --incremental-basedir=/backup/2018-02-23_14-21-42(完全备份生成的路径)
#再次修改数据库内容
innobackupex --incremental /backup/inc2 --incremental-basedir=/backup/inc1/2018-02-23_14-26-17 (上次增量备份生成的路径)
scp -r /backup/* 目标主机:/data/

2 在目标主机还原

#预准备过程
innobackupex --apply-log --redo-only /data/2018-02-23_14-21-42/
innobackupex --apply-log --redo-only /data/2018-02-23_14-21-42/ --incremental-dir=/data/inc1/2018-02-23_14-26-17
innobackupex --apply-log /data/2018-02-23_14-21-42/ --incremental-dir=/data/inc2/2018-02-23_14-28-29/

#还原过程
不启动mariadb
systemctl stop mariadb
rm -rf /var/lib/mysql/*
innobackupex --copy-back /data/2018-02-23_14-21-42/
chown -R mysql.mysql /var/lib/mysql/
systemctl start mariadb
5.3.6 实战案例:xtrabackup单表导出和导入
#导出
1 单表备份
innobackupex -uroot -pmagedu --include='hellodb.students' /backup
2备份表结构
mysql -e 'show create table hellodb.students' > student.sql
3删除表
mysql -e 'drop table hellodb.students‘
#导出
4 innobackupex --apply-log --export /backups/2018-02-23_15-03-23/

5 创建表
	mysql>CREATE TABLE `students` (
		`StuID` int(10) unsigned NOT NULL AUTO_INCREMENT,
		`Name` varchar(50) NOT NULL,
		`Age` tinyint(3) unsigned NOT NULL,
		`Gender` enum('F','M') NOT NULL,
		`ClassID` tinyint(3) unsigned DEFAULT NULL,
		`TeacherID` int(10) unsigned DEFAULT NULL,
		PRIMARY KEY (`StuID`)
) ENGINE=InnoDB AUTO_INCREMENT=26 DEFAULT CHARSET=utf8
6 删除表空间
alter table students discard tablespace;
7 cp /backups/2018-02-23_15-03-23/hellodb/students.{cfg,exp,ibd}
/var/lib/mysql/hellodb/
8 chown -R mysql.mysql /var/lib/mysql/hellodb/
9 mysql>alter table students import tablespace;

你可能感兴趣的:(MySQL)