备份恢复

备份恢复

1. 运维人员在备份恢复工作职责

a. 备份、恢复策略定制
b. 备份巡检
c. 定期恢复演练
d. 出现数据损坏,快速、准确恢复
e. 升级、迁移

2. MySQL 备份工具

2.1 逻辑 :(SQL语句)

mysqldump (自带)
mydumper (第三方工具)
into outfile/load data infile/mysqlimport
mysqlbinlog(官方自带)
binlog2sql 
主从复制

2.2 物理 :

xtrabackup 

3. mysqldump的应用

3.1 介绍

自带的客户端工具。
逻辑备份工具,备份出来的是SQL语句(Create database 、create table 、insert into),文本文件。
可读性比较强。
可以有较高的压缩比。
支持本地和远程备份。

3.2 mysqldump 备份参数

a. 连接参数

-u 用户名
-p 密码
-h 远程地址
-P 指顶端口
-S 指定本地socket文件

b. 备份参数

-A 全库 备份 :

[root@db01 ~]# mkdir -p /data/backup/mdp
[root@db01 ~]# mysqldump  -uroot -p123 -A > /data/backup/mdp/full.sql
注:如果备份成功了vim /data/backup/mdp/full.sql 头部是注释信息(版本信息)、建表语句。。。。

-B 单库或多库备份:

#指定备份world库和test库(中间用空格隔开)
[root@db01 mdp]# mysqldump  -uroot -p123 -B world test > /data/backup/mdp/db.sql

单表或多表备份

#备份单库单表(库名 表名)
[root@db01 mdp]# mysqldump -uroot -p123 world city  >/data/backup/mdp/tab1.sql
#备份单库多表 (库名  表1 表2)
[root@db01 mdp]# mysqldump -uroot -p123 world city country >/data/backup/mdp/tab.sql

--master-data=2

a. 备份开始时,自动记录binlog 文件名+位置号。
b. 自动锁表,自动解锁
c. 配合--single-transaction可以减少锁表

[root@db01 ~ 23:27:58]# mysqldump --help (获取帮助)
 --master-data[=#]  (查看=1、2、3 的用法)
[root@db01 mdp]# mysqldump  -uroot -p123 -A --master-data=2 > /data/backup/mdp/full.sql
#在备份文件中会产生如下这句话 vim /data/backup/mdp/full.sql
-- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000003', MASTER_LOG_POS=454;

--single-transaction(仅支持InnoDB表)

备份InnoDB表时,开启一个独立事务,调整隔离级别RR,开启快照备份。不能出现DDL操作,会产生阻塞,有可能会导致备份失败。加以上两个参数时,对Innodb表进行不加锁备份 、对MyISAM表加锁备份的

[root@db01 ~ 23:27:58]# mysqldump --help (获取帮助)               
[root@db01 mdp]# mysqldump  -uroot -p123 -A --master-data=2 --single-transaction > /data/backup/mdp/full.sql                      

彩蛋: 备份流程说明

 1. 备份元数据(create database  ,create table )---> show ,information_schema ---> FTWRL ,global read lock
 2. 备份MyISAM表数据,锁表备份 ,select --转换-> full.sql 
 3. 备份InnoDB表数据,调整隔离级别,解锁表,开启独立事务,生成快照, select 快照---->full.sql
#将所用表锁定,不能对原数据进行修改(DDL、DML都不能发生)
mysql>flush table with read lock;

具体备份流程可以参照:

#打开备份流程参照日志(一般不开,调试的时候才会打开)
mysql> set global general_log=on;
#查看备份日志是否打开
mysql> show variables like '%general%';
+------------------+--------------------------+
| Variable_name    | Value                    |
+------------------+--------------------------+
| general_log      | OFF                      |
| general_log_file | /data/3306/data/db01.log |
+------------------+--------------------------+
查看日志 /data/3306/data/db01.log

-R(存储过程和函数) --triggers(触发器) -E(事件) 特殊对象备份

 mysqldump  -uroot -p123 -A --master-data=2 --single-transaction -R  --triggers  -E > /data/backup/mdp/full.sql 

max_allowed_packet 数据包大小 (一般64或者128就够了)

mysqldump  -uroot -p123 -A --master-data=2 --single-transaction -R  --triggers  -E  --max_allowed_packet=64M > /data/backup/mdp/full.sql    

压缩备份+时间戳

mysqldump -uroot -p123 -A  -R  --triggers   -E --master-data=2  --single-transaction   --max_allowed_packet=64M |gzip > /backup/full_$(date +%F).sql.gz

3.3 MDP+binlog 故障恢复演练

备份策略:
1. 每天晚上23:00进行MDP的全备+binlog
2. 每天中午12:30,进行binlog备份

模拟故障:
周二上午10点 数据库损坏了,binlog和mdp备份都是好的。

3.3.1 模拟环境

a. 原始数据

mysql> create database mdp charset utf8mb4;
mysql> use mdp;
mysql> create table t1(id int);
mysql> insert into t1 values(1),(2),(3);
mysql> commit;

b. 模拟周一晚上23:00,mdp全备

[root@db01 mdp]# mysqldump -uroot -p123 -A  -R  --triggers   -E --master-data=2  --single-transaction   --max_allowed_packet=64M |gzip > /data/backup/mdp/full_$(date +%F).sql.gz
#进行解压检查
[root@db01 mdp]# gunzip full_2020-07-10.sql.gz 
[root@db01 mdp]# vim full_2020-07-10.sql 

c. 模拟周二白天数据变化

mysql> create table t2(id int);
mysql> insert into t2 values(1),(2),(3);
mysql> commit;

d. 模拟周二10点的数据故障

mysql> drop database mdp;

3.3.2 恢复演练

a. 检查备份

vim full_2020-07-10.sql
SET @@GLOBAL.GTID_PURGED='4d98ed45-c0e9-11ea-8dd7-000c295bb94f:1-7';
CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000003', MASTER_LOG_POS=1047;
#查看全备,我们可以得到一个点(起点)

b.检查日志

[root@db01 mdp]# cd /data/3306/binlog/
[root@db01 binlog]# ll
total 16
-rw-r----- 1 mysql mysql  357 Jul 10 09:03 mysql-bin.000001
-rw-r----- 1 mysql mysql  541 Jul 10 09:26 mysql-bin.000002
-rw-r----- 1 mysql mysql 1622 Jul 10 11:50 mysql-bin.000003
-rw-r----- 1 mysql mysql  105 Jul 10 09:26 mysql-bin.index

c. 截取binlog

#我们可以从全备文件中找到起点vim full_2020-07-10.sql
起点: 'mysql-bin.000003', MASTER_LOG_POS=1047  
#登录数据库mysql>show binlog events in 'mysql-bin.000003'; 可以得到终点
终点: | mysql-bin.000003 | 1533 | Query          |         6 |        1622 | drop database mdp   
#截取误删除日志并导入到一个文件中
[root@db01 binlog]# mysqlbinlog --skip-gtids --start-position=1047 --stop-position=1533 mysql-bin.000003 >/tmp/bin.sql

或者:
[root@db01 binlog]# mysqlbinlog --skip-gtids --include-gtids='4d98ed45-c0e9-11ea-8dd7-000c295bb94f:8-9' mysql-bin.000003 >/tmp/bin1.sql

c. 恢复数据

[root@db01 binlog]# cd /data/backup/mdp/
mysql> set sql_log_bin=0;
mysql> source /data/backup/mdp/full_2020-07-10.sql
mysql> set sql_log_bin=0;
mysql> source /tmp/bin.sql
mysql> set sql_log_bin=1;

=========================================
彩蛋:扩展案例
备份策略: mdp全备+binlog ,数据量200G(备份时间大概1~2小时,全备的话是5倍)
故障场景: 误删除了核心表oldguo表,10M小表。
需求:快速恢复
=========================================
预备环境:
原始环境:

mysql> create database mdb charset utf8mb4;
Query OK, 1 row affected (0.00 sec)
mysql> use mdb;
mysql> create table oldguo (id int);
mysql> insert into oldguo values(1),(2),(3);

全备:

 mysqldump -uroot -p123 -A  -R  --triggers   -E --master-data=2  --single-transaction   --max_allowed_packet=64M  > /data/backup/mdp/full.sql

追加新数据:

mysql> insert into oldguo values(4),(5),(6);
mysql> commit;
mysql> use test;
mysql> delete from t1 where id>10;
Query OK, 4 rows affected (0.00 sec)
mysql> commit;

搞破坏:误删除oldguo表

mysql> drop table mdb.oldguo;

如何快速恢复?

a. 全备截取单表备份:

[root@db01 ~ 00:07:15]# sed -e'/./{H;$!d;}' -e 'x;/CREATE TABLE `oldguo`/!d;q'  /data/backup/mdp/full.sql>/data/createtable.sql
[root@db01 ~ 00:07:15]# grep -i 'INSERT INTO `oldguo`'   /data/backup/mdp/full.sql >/data/data.sql 

b. binlog2sql 截取binlog单表的日志:

功能

  1. 友好的展示或管理binlog
  2. 快速DML闪回(通过日志翻转方式)。

安装配置binlog2sql

参考文章:https://github.com/danfengcao/binlog2sql.git
git clone https://github.com/danfengcao/binlog2sql.git && cd binlog2sql
###安装phython3环境
[root@db01 ~ 01:30:09]# yum install python3
[root@db01 ~ 01:30:09]# pip3 install -r requirements.txt  #用phython3读一下它所需要的包
[root@db01 ~ 01:30:09]# pip3 show pymysql  #查看当前版本(0.7有点低)
[root@db01 ~ 01:30:09]# pip3 install --upgrade PyMySQL #更新到高版本

解析日志事件SQL

[root@db01 /data/app/binlog2sql-master 01:58:33]# grep "\--\ CHANGE MASTER TO" /data/backup/mdp/full.sql
-- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=21793896;
[root@db01 binlog2sql]# python3 binlog2sql.py  -h 10.0.0.51 -P3306 -uroot -p123 -d mdb -t oldguo --start-file='mysql-bin.000001' >/tmp/bin/sql
#起始点
[root@db01 /data/app/binlog2sql-master 01:58:33]# grep "\--\ CHANGE MASTER TO" /data/backup/mdp/full.sql
-- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=21793896;
#终止点 (找到drop)
mysql> show binlog events in 'mysql-bin.000001'
#然后再修改/tmp/bin/sql
#恢复数据
mysql>source   /data/createtable.sql   #恢复建表语句
mysql>source   /data/data.sql              #恢复数据

只解析delete类型操作

[root@db01 binlog2sql]# python3 binlog2sql.py  -h 10.0.0.51 -P3306 -uroot -p123 -d test -t t1  --start-file='mysql-bin.000003'   --sql-type=delete

生成指定事件回滚语句

[root@db01 binlog2sql]# python3 binlog2sql.py  -h 10.0.0.51 -P3306 -uroot -p123 -d test -t t1  --start-file='mysql-bin.000003'   --sql-type=delete --start-position=932 --stop-position=1198 -B

[root@db01 binlog2sql]# python3 binlog2sql.py  -h 10.0.0.51 -P3306 -uroot -p123 -d test -t t1  --start-file='mysql-bin.000003'   --sql-type=delete --start-position=932 --stop-position=1198 -B>/tmp/flashback.sql

4. Xtrabackup 物理备份工具

4.1 介绍

Percona 公司的产品。可以兼容 MySQL 各个版本。
物理备份工具。相当于“CP”文件。
MySQL 8.0之前的版本,PXB需要使用2.4.x版本。
MySQL 8.0+版本,PXB需要使用8.0版本。

4.2 安装pxb

wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
yum -y install perl perl-devel libaio libaio-devel perl-Time-HiRes perl-DBD-MySQL libev

wget https://www.percona.com/downloads/XtraBackup/Percona-XtraBackup-2.4.12/binary/redhat/7/x86_64/percona-xtrabackup-24-2.4.12-1.el7.x86_64.rpm
yum install -y percona-xtrabackup-24-2.4.12-1.el7.x86_64.rpm 

[root@db01 app]# innobackupex --version
xtrabackup: recognized server arguments: --server-id=6 --log_bin=/data/3306/binlog/mysql-bin --datadir=/data/3306/data --innodb_data_file_path=ibdata1:100M;ibdata2:100M;ibdata3:100M:autoextend --innodb_undo_tablespaces=3 --innodb_undo_directory=/data/3306/undologs --innodb_log_file_size=100M --innodb_log_files_in_group=3 --innodb_buffer_pool_size=256M --innodb_log_buffer_size=33554432 
innobackupex version 2.4.12 Linux (x86_64) (revision id: 170eb8c)

4.3 PXB备份逻辑

a. InnoDB
ibddata1 ibd...,采用热备方式。并且可以将备份过程中的redo进行备份。

b. 非InnoDB数据
FTWRL(全局锁) : frm myd myi ...

c. 针对InnoDB数据,原生态支持增量备份。
针对上次备份时的checkpoint_lsn,之后发生的数据页修改。

4.4 应用

4.4.1 前提

备份时,需要数据库实例启动。备份期间,会自动读取my.cnf信息,datadir ,socket。
    vim /etc/my.cnf
    [client]
    socket=/tmp/mysql.sock

4.4.2 全备

#--no-timestamp 没有这个参数的话,生成的备份文件是以时间戳为名字的,上产环境中建议添加这个参数
[root@db01 ~ 02:54:22]#  mkdir -p /data/backup/pxb/
[root@db01 backup]# innobackupex --user=root --password 123  --no-timestamp /data/backup/pxb/full

文件功能介绍:
xtrabackup_binlog_info : binlog位置点
xtrabackup_checkpoints : checkpoint lsn,为了下次增量
xtrabackup_info : 总览
xtrabackup_logfile : 部分redo

4.4.3 全备恢复

a. prepare 准备备份过程
--apply-log : 模拟了InnoDB CR的过程,应用redo前滚和undo回滚。让数据达到一致状态方可恢复。

[root@db01 undologs]# innobackupex  --apply-log  /data/backup/pxb/full/

b. 数据恢复(也可以用cp命令= innobackupex)

[root@db01 full]# pkill mysqld
[root@db01 full]# rm -rf /data/3306/data/*   /data/3306/undologs/*
[root@db01 undologs]# innobackupex --copy-back /data/backup/pxb/full/
[root@db01 undologs]# chown -R mysql.mysql /data/*

c. 启动数据库

[root@db01 undologs]# /etc/init.d/mysqld start

4.4.4 inc备份

a . 准备基础环境 
mysql> create database pxb charset utf8mb4;
mysql> use pxb
mysql> create table t1 (id int);
mysql> insert into t1 values(1);
mysql> commit;
b. 模拟周日23:00 全备 
[root@db01 pxb]# innobackupex --user=root --password=123 --no-timestamp /data/backup/pxb/full
c. 模拟周一白天的数据变化 
mysql> use pxb
mysql> insert into t1 values(11),(21);
mysql> commit;
d. 模拟周一晚上23:00增量备份 (增量备份 --incremental-basedir=/data/backup/pxb/full/ )
[root@db01 inc1]# innobackupex --user=root --password=123 --no-timestamp --incremental /data/backup/pxb/inc1 --incremental-basedir=/data/backup/pxb/full/ 
e. 模拟周二白天的数据变化 
use pxb
insert into t1 values(22),(33);
commit;
f. 模拟周二增量
innobackupex --user=root --password=123 --no-timestamp --incremental /data/backup/pxb/inc2 --incremental-basedir=/data/backup/pxb/inc1
g. 模拟周三白天的数据变化 
use pxb
insert into t1 values(122),(133);
commit;
h. 判断
[root@db01 pxb]# cat full/xtrabackup_checkpoints 
backup_type = full-backuped
from_lsn = 0
to_lsn = 250975799
last_lsn = 250975808
compact = 0
recover_binlog_info = 0
[root@db01 pxb]# cat inc1/xtrabackup_checkpoints 
backup_type = incremental
from_lsn = 250975799
to_lsn = 250977706
last_lsn = 250977715
compact = 0
recover_binlog_info = 0
[root@db01 pxb]# cat inc2/xtrabackup_checkpoints 
backup_type = incremental
from_lsn = 250977706
to_lsn = 250979620
last_lsn = 250979629
compact = 0
recover_binlog_info = 0
[root@db01 pxb]# 

4.4.5 搞破坏,并恢复

a. 周三上午10点发生故障
[root@db01 pxb]# pkill mysqld 
[root@db01 pxb]# rm -rf /data/3306/data/* /data/3306/undologs/*

b. 准备备份。
1. 基础全备的prepare 
[root@db01 pxb]# innobackupex --apply-log --redo-only /data/backup/pxb/full/

 --redo-only         This option should be used when preparing the base full
                      backup and when merging all incrementals except the last
                      one. This forces xtrabackup to skip the "rollback" phase
                      and do a "redo" only. This is necessary if the backup
                      will have incremental changes applied to it later. See
                      the xtrabackup documentation for details.


2. inc1 合并至full中并prepare
[root@db01 ~ 09:03:50]# innobackupex --apply-log --redo-only --incremental-dir=/data/backup/pxb/inc1/ /data/backup/pxb/full/

3. inc2 合并至full中并prepare
[root@db01 ~ 09:03:50]# innobackupex --apply-log --incremental-dir=/data/backup/pxb/inc2/ /data/backup/pxb/full/


c. 恢复全备
[root@db01 pxb]# innobackupex --copy-back /data/backup/pxb/full/ 
[root@db01 pxb]# chown -R mysql.mysql /data/*

d. 截取并恢复binlog
[root@db01 inc2]# cat xtrabackup_binlog_info 
mysql-bin.000009    1290    4d98ed45-c0e9-11ea-8dd7-000c295bb94f:1-233,
b6c782f4-c4af-11ea-b173-000c295bb94f:1-5
[root@db01 inc2]# 
[root@db01 inc2]# mysqlbinlog --skip-gtids --start-position=1290 /data/3306/binlog/mysql-bin.000009 >/tmp/bin.sql

作业: 500G的全备,周三白天:误删除的是一张200M的表?

你可能感兴趣的:(备份恢复)