专职DBA-MySQL备份恢复

专职DBA-MySQL备份恢复

DBA在数据库备份恢复工作职责:设计备份策略
(1).数据量:小于100G、100G-1TB、大于1TB
(2).备份工具
mysqldump (MDP)
xtrabackup(XBK)
MEB
select ... from ... into outfile ...
(3).备份时间:23:00  23:59
(4).周期频率:每天、每周、每月
(5).备份方式
全备 (full) : 某个时刻总的数据量。
增量 (inc) : 总是针对前一天的变化备份。
差异 (dif) : 总是针对最近一次全备变化备份

inc和dif的优缺点:
inc
优点:备份数据量少,快。
缺点:恢复时,需要依赖所有过程备份。

dif
优点:恢复时,全备+1个差异。
缺点:备份数据量较大,较慢。
(6).备份对象:数据库、表、binlog日志
(7).备份脚本
(8).备份检查
备份存在性:日志,文件,备份集
备份空间够用否
备份可用性:文件内容,备份集完整性。
(9).定期在测试库恢复演练:一季度、半年。
(10).数据故障恢复
物理故障:磁盘,raid,FS,数据文件,rm,dd等等。
逻辑故障:drop,delete,truncate,update等等。
通过现有备份,能够将数据库恢复到故障之前的时间点。
(11).迁移:停机时间、回退方案
同构:低版本-->高版本
异构:
windows ----> Linux
Oracle  ----> MySQL
MySQL   ----> MongoDB
MySQL         上云
Oracle        自愈,自治


备份类型
1.热备:InnoDB支持,在业务不停止的时候备份,几乎不锁表,对业务影响较小。
2.温备:锁表备份,只能查询不能做变更(MyISAM),影响到写入操作。
3.冷备:停业务备份,所有查询变更都做不了。


备份方式及工具介绍
1.逻辑备份工具
mysqldump(MDP) : full+binlog
mysqlbinlog
mydumper

2.物理备份工具
基于磁盘数据文件备份
xtrabackup(XBK) : Percona第三方 : full+inc+binlog,full+binlog
MySQL Enterprise Backup(MEB) : MySQL官方


逻辑备份和物理备份的比较
mysqldump
优点:
1.不需要下载安装。
2.备份出来的是SQL,文本格式,可读性高,便于备份处理。
3.压缩比较高,节省备份的磁盘空间。

缺点:
1.依赖于数据库引擎,需要从磁盘把数据读出。然后转换成SQL进行转储,比较耗费资源,数据量大的话效率极低。
建议:100G以内的数据量级,可以使用mysqldump
超过TB以上,我们也可能选择的是mysqldump,配合分布式的系统
1EB=1024PB=1000000TB

xtrabackup
优点:
1.类似于直接cp数据文件,不需要管逻辑结构,相对来说性能较高。
缺点:
1.可读性差.
2.压缩比低,需要更多磁盘空间。
建议:>100G<TB


备份策略
备份方式:
全备:全库备份,备份所有数据。
增量:备份变化的数据。
逻辑备份:mysqldump+mysqlbinlog
物理备份:xtrabackup_full+xtrabackup_incr+binlog
          或者xtrabackup_full+binlog
备份周期:根据数据量设计备份周期。比如:周日全备,周1-周6增量。


[root@db01 ~]# mysqld --defaults-file=/data/mysql/3306/my.cnf &
[root@db01 ~]# ps -ef | grep mysql
[root@db01 ~]# netstat -lnp | grep mysql
[root@db01 ~]# mkdir -p /backup

备份工具使用-mysqldump
mysqldump逻辑备份的客户端工具,备份的是SQL语句。
备份过程:将数据--调取到临时表--转换--SQL语句--转存到bak.sql文件。
客户端通用连接参数:-u  -p   -S   -h  -P
本地备份:mysqldump -uroot -p -S /data/mysql/3306/mysql.sock
远程备份:mysqldump -uroot -p -h10.0.0.11 -P3306

备份专用基本参数
(1).-A  --all-databases 全备参数
[root@db01 ~]# mysqldump -S /data/mysql/3306/mysql.sock -p -A >/backup/full.sql

补充:
1.常规备份是要加--set-gtid-purged=OFF解决备份时的警告
[root@db01 ~]# mysqldump -S /data/mysql/3306/mysql.sock -p -A --set-gtid-purged=OFF >/backup/full.sql
2.构建主从时,做的备份,不需要加这个参数。
[root@db01 ~]# mysqldump -S /data/mysql/3306/mysql.sock -p -A --set-gtid-purged=ON >/backup/full.sql
在构建主从复制是,千万不要OFF。在日常备份时,可以OFF。
--set-gtid-purged=AUTO,ON,OFF
1.--set-gtid-purged=OFF可以使用在日常备份参数中。
2.--set-gtid-purged=ON在构建主从复制环境时需要的参数配置。


(2)-B备份多个单库db1 db2 db3,增加创建数据库语句 和 use连接数据库的语句。
说明:生产中需要备份业务相关的库和MySQL库。
[root@db01 ~]# mysqldump -S /data/mysql/3306/mysql.sock -p -B world school --set-gtid-purged=OFF >/backup/a.sql


备份单个或多个表
world数据库下的city,country表
[root@db01 ~]# mysqldump -S /data/mysql/3306/mysql.sock -p world city country --set-gtid-purged=OFF >/backup/a.sql
以上备份恢复时,必须库事先存在。并且ues才能source恢复。


(3).高级参数应用
-R --routines           备份存储过程及函数
--triggers  备份触发器
-E --events             备份事件
[root@db01 ~]# mysqldump -S /data/mysql/3306/mysql.sock -p -A --master-data=2 --single-transaction --routines --events --triggers --set-gtid-purged=OFF >/backup/a.sql

-F 在备份开始时,刷新一个新binlog日志
[root@db01 ~]# mysqldump -S /data/mysql/3306/mysql.sock -p -F -A --master-data=2 --single-transaction --routines --events --triggers --set-gtid-purged=OFF >/backup/a.sql


--master-data=2
在备份时,自动记录二进制日志的文件和位置号。可以自动加锁和解锁。
以注释的形式,保存备份开始时间点的binlog的状态信息。
加了--single-transaction可以减少锁表时间。
-- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000008', MASTER_LOG_POS=194;
功能:
(1).在备份时,会自动记录,二进制日志文件名和位置号。
0 默认值
1 以change master to命令形式,可以用作主从复制
2 以注释的形式记录,备份时刻的文件名+postion号
(1).自动锁表
(3).如果配合--single-transaction,只对非InnoDB表进行锁表备份,InnoDB表进行热备,实际上是实现快照备份。


--single-transaction
innodb 存储引擎开启热备(快照备份)功能。
在对于InnoDB表备份时,开启一个单独事务,备份所有表的一致性快照数据。
--master-data可以自动加锁。
(1).在不加--single-transaction ,启动所有表的温备份,所有表都锁定。
(2).加上--single-transaction,对innodb进行快照备份,对非innodb表可以实现自动锁表功能。
(1)开启单独事务备份
(2)对于InnoDB表一致性快照备份
(3)减少整体锁表的时间
备份必加参数
[root@db01 ~]# mysqldump -S /data/mysql/3306/mysql.sock -p -F -A --master-data=2 --single-transaction --routines --events --triggers --set-gtid-purged=OFF >/backup/full.sql




--max-allowed-packet 最大的数据包大小
1153 - Got a packet bigger than 'max_allowed_packet' bytes
The maximum packet length to send to or receive from server.
[root@db01 ~]# mysqldump -S /data/mysql/3306/mysql.sock -p -F -A --master-data=2 --single-transaction --routines --events --triggers --set-gtid-purged=OFF --max-allowed-packet=128M >/backup/full.sql


压缩备份并添加时间戳
mysqldump -S /data/mysql/3306/mysql.sock -p -F -A --master-data=2 --single-transaction --routines --events --triggers --set-gtid-purged=OFF|gzip >/backup/full_$(date +"%F_%T").sql.gz


实现所有表的单独备份
提示:
information_schema.tables
SELECT CONCAT("mysqldump -S /data/mysql/3306/mysql.sock -p123 ",table_schema," ",table_name," -F --master-data=2 --single-transaction --routines --events --triggers --set-gtid-purged=OFF >/backup/",table_schema,"_",table_name,".sql")
FROM information_schema.tables
WHERE table_schema NOT IN('mysql','sys','information_schema','performance_schema');


模拟故障案例并恢复
(1).每天全备
(2).binlog日志是完整
(3).模拟白天的数据变化
(4).模拟下午两点误删除数据库


需求:利用全备+binlog恢复数据库误删除之前。
故障模拟及恢复:
1.模拟周一23:00的全备
[root@db01 ~]# mysqldump -S /data/mysql/3306/mysql.sock -p -F -A --master-data=2 --single-transaction --routines --events --triggers --set-gtid-purged=OFF >/backup/full.sql

2.模拟白天的数据变化
[root@db01 ~]# mysql -S /data/mysql/3306/mysql.sock -p
mysql> set global read_only=off;
mysql> set global supper_read_only=off;
mysql> create database day01 charset=utf8mb4;
mysql> use day01;
mysql> create table t1(id int);
mysql> insert into t1 values(1),(2),(3);
mysql> commit;
mysql> insert into t1 values(4),(5),(6);
mysql> commit;
mysql> shutdown;

模拟磁盘损坏:
[root@db01 ~]# cd /data/mysql/3306/
[root@db01 /data/mysql/3306]# mv data data_rm1
[root@db01 ~]# mv /data/mysql/3306/logs/* /backup/binlog/

[root@db01 /data/mysql/3306]# mkdir data
[root@db01 /data/mysql/3306]# chown mysql.mysql data

恢复故障思路
(1).检查备份可用性
(2).从备份中获取二进制日志位置
(3).根据日志位置截取需要的二进制日志
(4).初始化数据库并启动
(5).恢复全备
(6).恢复二进制日志

[root@db01 ~]# cd /data/mysql/3306/
[root@db01 /data/mysql/3306]# rm -rf data/* error.log logs/* slow.log tmp/*

[root@db01 /data/mysql/3306]# mysqld --defaults-file=/data/mysql/3306/my.cnf --initialize-insecure
[root@db01 ~]# mysqld --defaults-file=/data/mysql/3306/my.cnf &
[root@db01 ~]# ps -ef | grep mysql
[root@db01 ~]# netstat -lnp | grep mysql
[root@db01 ~]# mysql -S /data/mysql/3306/mysql.sock
mysql> set global read_only=off;
mysql> set global super_read_only=off;
mysql> set sql_log_bin=off;
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000002 |      154 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

mysql> source /backup/full.sql;
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| binlog             |
| mysql              |
| performance_schema |
| school             |
| sys                |
| world              |
+--------------------+
7 rows in set (0.00 sec)
全备的数据已将回来,先不要退出会话。

[root@db01 ~]# cd /backup/
[root@db01 /backup]# sed -n '22p' full.sql
-- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000007', MASTER_LOG_POS=194;

[root@db01 /backup]# cd /backup/binlog/
[root@db01 /backup/binlog]# mysqlbinlog --skip-gtids --start-position=194 mysql-bin.000007 >/tmp/bin.sql

mysql> source /tmp/bin.sql;
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| binlog             |
| day01              |
| mysql              |
| performance_schema |
| school             |
| sys                |
| world              |
+--------------------+
8 rows in set (0.00 sec)

mysql> select * from day01.t1;
+------+
| id   |
+------+
|    1 |
|    2 |
|    3 |
|    4 |
|    5 |
|    6 |
+------+
6 rows in set (0.00 sec)

mysql> set sql_log_bin=on;
数据已经恢复完成


mysqldump备份的恢复方式(在生产中恢复要谨慎,恢复会删除重复的表)
注意:
mysqldump在备份和恢复时都需要mysql实例启动为前提。
一般数据量级100G以内,大约15-45分钟可以恢复。
mysqldump是覆盖形式恢复的方法。

一般我们认为,在同数据量级,物理备份要比逻辑备份速度快。
逻辑备份的优势:
1.可读性强
2.压缩比很高


企业故障恢复案例
背景环境:中小型网站架构,MySQL5.7.20,数据量200G,日业务增量10-15M。
备份策略:每周mysqldump全备,每天binlog增量,binlog15天过期。
年底故障演练:周三上午10点,模拟误删数据库,并进行恢复。
恢复方案:
(1).停业务,挂维护页,避免数据的二次伤害。
(2).找一个临时库,恢复上一次全备。
(3).截取上一次全备到周三上午10点误删除之间的所有binlog
(4).恢复binlog到临时库,导出故障表,恢复至生产。
(5).测试可用性和完整性。
方法一:直接使用临时库顶替原生产库,前端应用割接到新库。
方法二:将误删除的表导出,导入到原生产库。
(6).开启业务
处理结果:经过20分钟的处理,最终业务恢复正常。


故障模拟演练
准备数据
[root@db01 ~]# mysql -S /data/mysql/3306/mysql.sock
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;
[root@db01 ~]# rm -rf /backup/*


周二23:00全备
[root@db01 ~]# mysqldump -S /data/mysql/3306/mysql.sock -p -F -A --master-data=2 --single-transaction --routines --events --triggers --set-gtid-purged=OFF|gzip >/backup/full_$(date +"%F_%T").sql.gz


模拟周二23:00到周三10点之间数据变化
mysql> use mdp;
mysql> insert into t1 values(4),(5),(6);
mysql> commit;

模拟故障,删除表(只是模拟,不代表生产操作)
mysql> drop database mdp;


恢复过程
准备临时数据库(多实例3307)
mkdir -p /data/mysql/3307/{data,logs,tmp}
cp /data/mysql/3306/my.cnf /data/mysql/3307/
tree /data/mysql/3307/
sed -i 's/3306/3307/g' /data/mysql/3307/my.cnf
chown -R mysql:mysql /data/mysql/3307
mysqld --defaults-file=/data/mysql/3307/my.cnf --initialize-insecure
cat /data/mysql/3307/error.log
mysqld --defaults-file=/data/mysql/3307/my.cnf &
ps -ef | grep mysql
netstat -lnp | grep mysql
mysql -S /data/mysql/3307/mysql.sock

准备备份
[root@db01 /backup]# gunzip -d full_2019-09-15_01\:59\:21.sql.gz
mysql> show master status;
mysql> show binlog events in 'mysql-bin.000005';
[root@db01 ~]# mysqlbinlog --skip-gtids --include-gtids='0cfb4a27-d714-11e9-9150-000c29ca1344:1-5' --exclude-gtids='0cfb4a27-d714-11e9-9150-000c29ca1344:5' /data/mysql/3306/logs/mysql-bin.000005 >/tmp/bin.sql


恢复备份到临时库
[root@db01 ~]# mysql -S /data/mysql/3307/mysql.sock
mysql> set global read_only=off;
mysql> set global super_read_only=off;
mysql> set sql_log_bin=off;
mysql> source /backup/full_2019-09-15_01:59:21.sql;
mysql> source /tmp/bin.sql;
mysql> select * from mdp.t1;
+------+
| id   |
+------+
|    1 |
|    2 |
|    3 |
|    4 |
|    5 |
|    6 |
+------+
6 rows in set (0.00 sec)

mysql> set sql_log_bin=on;

将故障表导出并恢复到生产
[root@db01 ~]# mysqldump -S /data/mysql/3307/mysql.sock -B mdp --set-gtid-purged=OFF >/backup/mdp.sql

[root@db01 ~]# mysql -S /data/mysql/3306/mysql.sock
mysql> set sql_log_bin=off;
mysql> source /backup/mdp.sql;
mysql> select * from mdp.t1;
+------+
| id   |
+------+
|    1 |
|    2 |
|    3 |
|    4 |
|    5 |
|    6 |
+------+
6 rows in set (0.00 sec)

mysql> set sql_log_bin=on;


课下作业:
练习:
1.创建一个数据库app01
2.在app01下创建一张表t1
3.插入5行任意数据
4.全备
5.插入两行数据,任意修改3行数据,删除1行数据。
6.删除所有数据
7.再t1中又插入5行新数据,修改3行数据。
需求,跳过第六步恢复表数据。
写备份脚本和策略
2.分库分表并发备份

备份时优化参数:
(1).max_allowed_packet  最大的数据包大小
mysql> select @@max_allowed_packet;
(2).增加key_buffer_size    (临时表有关)
mysql> select @@key_buffer_size;



MySQL物理备份工具-xtrabackup(XBK、PBK、Xbackup)
Percona 公司的产品,Perl语言开发。
安装依赖包:
yum -y install perl perl-devel libaio libaio-devel perl-Time-HiRes perl-DBD-MySQL libev perl-Digest perl-Digest-MD5

可以一直yum -y,用腾讯镜像站。。。
[root@db01 ~]# yum -y install https://mirrors.cloud.tencent.com/percona/centos/7Server/RPMS/x86_64/percona-xtrabackup-24-2.4.15-1.el7.x86_64.rpm

[root@db01 ~]# rm -rf /etc/my.cnf.rpmnew
[root@db01 ~]# rm -rf /etc/my.cnf.d

[root@db01 ~]# ls -l `which innobackupex`
lrwxrwxrwx 1 root root 10 Sep 17 04:54 /usr/bin/innobackupex -> xtrabackup


备份方式:物理备份
(1).自动判断表的类型。
(2).flush table with read lock; (FTWRL)
(2).对于非InnoDB表(不支持事务的),进行锁表,然后cp数据文件,属于一种温备份。
(3).对于InnoDB的表(支持事务的),立即CKPT,不锁表,将提交的脏页进行刷新到磁盘,进行cp数据页,最终以数据文件的方式保存下来,cp同时将过程中产生的redo和undo一块备份走。属于热备方式。


恢复:
1.非InnoDB,直接恢复即可。
2.InnoDB表,需要XBK处理备份后,再进行恢复。
处理备份(Prepare)?
模仿了,自动故障恢复的流程:先redo前滚,再undo回滚。


面试题:XBK在innodb表备份恢复的流程。
(1).XBK备份执行的瞬间,立即触发ckpt,已提交的数据脏页,从内存刷写到磁盘,并记录此时的LSN号。
(2).备份时,拷贝磁盘数据页,并且记录备份过程中产生的redo和undo一起拷贝走,也就是checkpoint LSN之后的日志。
(3).在恢复之前,模拟Innodb“自动故障恢复”的过程,将redo(前滚)与undo(回滚)进行应用。
(4).恢复过程是cp备份到原来数据目录下。


innobackupex使用
全备
[root@db01 ~]# innobackupex --defaults-file=/data/mysql/3306/my.cnf -uroot -p123 -S /data/mysql/3306/mysql.sock /backup/full

[root@db01 ~]# ls -l /backup/full/
total 0
drwxr-x--- 11 root root 304 Sep 17 06:14 2019-09-17_06-14-16

[root@db01 ~]# du -sh /backup/full/2019-09-17_06-14-16
179M    /backup/full/2019-09-17_06-14-16

[root@db01 ~]# rm -rf /backup/*


自主定制备份路径名
[root@db01 ~]# innobackupex --defaults-file=/data/mysql/3306/my.cnf -uroot -p123 -S /data/mysql/3306/mysql.sock --no-timestamp /backup/full


[root@db01 ~]# ls -l /backup/full/
total 102456
-rw-r----- 1 root root       537 Sep 17 06:20 backup-my.cnf
drwxr-x--- 2 root root        48 Sep 17 06:20 binlog
drwxr-x--- 2 root root        48 Sep 17 06:20 day01
-rw-r----- 1 root root      7050 Sep 17 06:20 ib_buffer_pool
-rw-r----- 1 root root 104857600 Sep 17 06:20 ibdata1
drwxr-x--- 2 root root        48 Sep 17 06:20 mdp
drwxr-x--- 2 root root      4096 Sep 17 06:20 mysql
drwxr-x--- 2 root root      8192 Sep 17 06:20 performance_schema
drwxr-x--- 2 root root       176 Sep 17 06:20 school
drwxr-x--- 2 root root        54 Sep 17 06:20 shenzhen
drwxr-x--- 2 root root      8192 Sep 17 06:20 sys
drwxr-x--- 2 root root       144 Sep 17 06:20 world
-rw-r----- 1 root root        68 Sep 17 06:20 xtrabackup_binlog_info
-rw-r----- 1 root root       141 Sep 17 06:20 xtrabackup_checkpoints
-rw-r----- 1 root root       618 Sep 17 06:20 xtrabackup_info
-rw-r----- 1 root root      2560 Sep 17 06:20 xtrabackup_logfile


备份集中多出来的文件:
xtrabackup_binlog_info:备份时的binlog的位置点信息,截取binlog的起点信息。
[root@db01 ~]# cat /backup/full/xtrabackup_binlog_info
mysql-bin.000007        194     0cfb4a27-d714-11e9-9150-000c29ca1344:1-1000021
记录的是备份时刻,binlog的文件名字和当时的结束的position,可以用来作为截取binlog时的起点。

xtrabackup_checkpoints:
[root@db01 ~]# cat /backup/full/xtrabackup_checkpoints
backup_type = full-backuped #备份类型和状态
from_lsn = 0 #整个备份,起始的LSN(上次所到达的LSN号,对于全备就是从0开始,对于增量有别的显示方法)
to_lsn = 313412276 #CKPT的LSN(备份开始时间ckpt点数据页的LSN)
last_lsn = 313412285 #备份结束的LSN(备份结束后,redo日志最终的LSN)
compact = 0
recover_binlog_info = 0
flushed_lsn = 313412285
(1).备份时刻,立即将已经commit过的,内存中的数据页刷新到磁盘(CKPT),开始备份数据,数据文件的LSN会停留在to_lsn位置。
(2).备份时刻有可能会有其他的数据写入,已备走的数据文件就不会再发生变化了。
(3).在备份过程中,备份软件会一直监控着redo的undo,如果一旦有变化会将日志也一并备走,并记录LSN到last_lsn。
从to_lsn---》last_lsn 就是,备份过程中产生的数据变化。


xtrabackup_info:备份信息的总览
[root@db01 ~]# cat /backup/full/xtrabackup_info
uuid = 392658e9-d8d0-11e9-bde5-000c29ca1344
name = 
tool_name = innobackupex
tool_command = --defaults-file=/data/mysql/3306/my.cnf -uroot -p123 -S /data/mysql/3306/mysql.sock --no-timestamp /backup/full
tool_version = 2.4.15
ibbackup_version = 2.4.15
server_version = 5.7.26-log
start_time = 2019-09-17 06:20:41
end_time = 2019-09-17 06:20:43
lock_time = 0
binlog_pos = filename 'mysql-bin.000007', position '194', GTID of the last change '0cfb4a27-d714-11e9-9150-000c29ca1344:1-1000021'
innodb_from_lsn = 0
innodb_to_lsn = 313412276
partial = N
incremental = N
format = file
compact = N
compressed = N
encrypted = N


xtrabackup_logfile:记录备份过程中产生的redo
[root@db01 ~]# cat /backup/full/xtrabackup_logfile


搞破坏
[root@db01 ~]# mysqladmin -S /data/mysql/3306/mysql.sock -p shutdown
[root@db01 ~]# cd /data/mysql/3306/
[root@db01 /data/mysql/3306]# mv data data_rm2


重做回滚准备的备份
将redo进行重做,已提交的写到数据文件,未提交的使用undo回滚掉。模拟了CSR的过程。
[root@db01 ~]# innobackupex --apply-log /backup/full/


开始恢复
(1).被恢复的目录是空。
(2).被恢复的数据库的实例是关闭。
[root@db01 ~]# mkdir -p /data/mysql/3306/data
[root@db01 ~]# cp -a /backup/full/* /data/mysql/3306/data/
[root@db01 ~]# chown -R mysql:mysql /data/mysql/3306/data
[root@db01 ~]# tail -f /data/mysql/3306/error.log
[root@db01 ~]# mysqld --defaults-file=/data/mysql/3306/my.cnf &

[root@db01 ~]# ps -ef | grep mysql
[root@db01 ~]# netstat -lnp | grep mysql

如果你不想cp也可以用
innobackupex --defaults-file=/data/mysql/3306/my.cnf --copy-back --rsync /backup/full/


innobackupex 增量备份(incremental)
(1).增量备份的方式,是基于上一次备份进行增量。
(2).增量备份无法单独恢复。必须基于全备进行恢复。
(3).所有增量必须要按顺序合并到全备中。


全备+增量备份
故障案例说明:
1.背景:某大型网站,MySQL 5.7.20,数据量800G
2.备份策略:Xtrabackup,full(周日23:30)+incN(周一到周六23:30)+binlog(每天中午12:30)
3.故障:周三上午10点,数据库"瘫了"。


故障案例模拟:
[root@db01 ~]# mysql -S /data/mysql/3306/mysql.sock -p
mysql [(none)]> set global read_only=off;
mysql [(none)]> set global super_read_only=off;

1.模拟初始数据
mysql [(none)]> create database xbk charset=utf8mb4;
mysql [(none)]> use xbk;
mysql [xbk]> create table t1(id int) engine=innodb charset=utf8mb4;
mysql [xbk]> insert into t1 values(1),(2),(3);
mysql [xbk]> commit;

2.模拟周日的全备
[root@db01 ~]# rm -rf /backup/*
[root@db01 ~]# innobackupex --defaults-file=/data/mysql/3306/my.cnf -uroot -p123 -S /data/mysql/3306/mysql.sock --no-timestamp /backup/full

3.模拟周一白天数据变化
mysql [xbk]> insert into t1 values(11),(22),(33);
mysql [xbk]> commit;

4.模拟周一晚上增量备份
[root@db01 ~]# innobackupex --defaults-file=/data/mysql/3306/my.cnf -uroot -p123 -S /data/mysql/3306/mysql.sock --no-timestamp --incremental --incremental-basedir=/backup/full /backup/inc1

5.模拟周二白天数据变化
mysql [xbk]> insert into t1 values(111),(222),(333);
mysql [xbk]> commit;

6.模拟周二晚上增量备份
[root@db01 ~]# innobackupex --defaults-file=/data/mysql/3306/my.cnf -uroot -p123 -S /data/mysql/3306/mysql.sock --no-timestamp --incremental --incremental-basedir=/backup/inc1 /backup/inc2

7.模拟周三白天的数据变化
mysql [xbk]> insert into t1 values(1111),(2222),(3333);
mysql [xbk]> commit;

8.搞破坏
mysql [xbk]> shutdown;
[root@db01 ~]# cd /data/mysql/3306/
[root@db01 /data/mysql/3306]# mv data data_rm3

9.恢复模拟
检查备份
full+inc1+inc2+binlog

full进行处理备份
[root@db01 ~]# innobackupex --apply-log --redo-only /backup/full/

合并inc1到full中,处理备份
[root@db01 ~]# innobackupex --apply-log --redo-only --incremental-dir=/backup/inc1 /backup/full/

合并inc2到full中,处理备份
[root@db01 ~]# innobackupex --apply-log --incremental-dir=/backup/inc2 /backup/full/

最后一次整理备份
[root@db01 ~]# innobackupex --apply-log /backup/full/  

开始恢复
[root@db01 ~]# mkdir -p /data/mysql/3306/data
[root@db01 ~]# cp -a /backup/full/* /data/mysql/3306/data/
[root@db01 ~]# chown -R mysql:mysql /data/mysql/3306/data
[root@db01 ~]# tail -f /data/mysql/3306/error.log
[root@db01 ~]# mysqld --defaults-file=/data/mysql/3306/my.cnf &

[root@db01 ~]# ps -ef | grep mysql
[root@db01 ~]# netstat -lnp | grep mysql
[root@db01 ~]# mysql -S /data/mysql/3306/mysql.sock -p
mysql [xbk]> set global read_only=off;
mysql [xbk]> set global super_read_only=off;
mysql [(none)]> use xbk;
mysql [xbk]> select * from t1;
+------+
| id   |
+------+
|    1 |
|    2 |
|    3 |
|   11 |
|   22 |
|   33 |
|  111 |
|  222 |
|  333 |
+------+
9 rows in set (0.00 sec)

[root@db01 ~]# cat /backup/inc2/xtrabackup_binlog_info
mysql-bin.000008        2156    0cfb4a27-d714-11e9-9150-000c29ca1344:1-1000021,
ccd8a5da-d8d2-11e9-8419-000c29ca1344:1-9

截取binlog和安装传统方式或gtid
[root@db01 ~]# mysqlbinlog --skip-gtids --start-position=2156 /data/mysql/3306/logs/mysql-bin.000008 > /tmp/bin.sql
mysql [xbk]> set sql_log_bin=off;
mysql [xbk]> source /tmp/bin.sql;
mysql [xbk]> select * from t1;
+------+
| id   |
+------+
|    1 |
|    2 |
|    3 |
|   11 |
|   22 |
|   33 |
|  111 |
|  222 |
|  333 |
| 1111 |
| 2222 |
| 3333 |
+------+
12 rows in set (0.00 sec)

恢复到周三误drop之前的数据状态
恢复思路:
(1).挂出维护页,停止当天的自动备份脚本。
(2).检查备份:周日full+周一inc1+周二inc2,周三的完整二进制日志。
(3).进行备份整理(细节),截取关键的二进制日志(从备份--误删除之前)。
(4).测试库进行备份恢复及日志恢复。
(5).应用进行测试无误,开启业务。
(6).此次工作的总结。


自己扩展
(1).MySQL8.0的XBK
(2).从全备中恢复单表。
(3).远程备份
innobackupex --defaults-file=/etc/my.cnf --no-lock --user 'root' --password 'password123' --stream=tar ./ | ssh [email protected] \ "cat - > /home/backup/database/`date +%Y%m%d`/`date +%H-%M`-backup.tar"
echo `date +%Y%m%d-%H%M`:备份结束 >> backup_db.log


作业1
Xtrabackup企业级增量恢复实战
背景:
某大型网站,mysql数据库,数据量500G,每日更新量20M-30M
备份策略:
xtrabackup,每周日0:00进行全备,周一到周六00:00进行增量备份。
故障场景:
周三下午2点出现数据库意外删除表操作。
如何恢复?


作业2
练习:mysqldump备份恢复例子。
1.创建一个数据库 oldboy
2.在oldboy下创建一张表t1
3.插入5行任意数据。
4.全备。
5.插入两行数据,任意修改3行数据,删除1行数据。
6.删除所有数据。
7.再t1中又插入5行新数据,修改3行数据。
需求,跳过第六步恢复表数据。


作业3
分别写备份脚本和策略。


作业4:备份集中单独恢复表。
思考:在之前的项目案例中,如果误删除的表只有10M,而备份有500G,该如何快速恢复误删除表?
提示:
drop table city;
create table city like city_bak;
alter table city discard tablespace;
cp /backup/full/world/city.ibd  /application/mysql/data/world/
chown -R mysql.mysql  /application/mysql/data/world/city.ibd 
alter table city import  tablespace;


作业5:从mysqldump全备中获取库和表的备份。
1.获得表结构。
# sed -e'/./{H;$!d;}' -e 'x;/CREATE TABLE `city`/!d;q'  full.sql>createtable.sql
2.获得INSERT INTO 语句,用于数据的恢复。
# grep -i 'INSERT INTO `city`'  full.sqll >data.sql &
3.获取单库的备份。
# sed -n '/^-- Current Database: `world`/,/^-- Current Database: `/p' all.sql >world.sql


批量的分库分表备份
(1).shell脚本for循环
(2).用元数据查询拼接concat()  information_schema.tables

猜你喜欢

转载自www.cnblogs.com/zhouwanchun/p/11530948.html