MySQL-lesson07-备份恢复

1、备份类型

热备
在数据库正常业务时,备份数据,并且能够一致性恢复

冷备
关闭数据库业务,数据库没有任何变更的情况下,进行备份数据

温备
锁表备份,只能查询不能恢复

2、备份方式

2.1 逻辑备份

基于SQL语句进行备份
常用工具:mysqldump,mysqlbinlog

2.2 物理备份

基于磁盘文件备份
常用工具:xtrabackup

3、备份策略

全备:全库备份
增量:备份变化的数据
备份周期:定期备份

4、逻辑备份工具

4.1 mysqldump

1、mysqldump适合小于100G以下的数据量
2、mysqldump原生态不支持增量,必须配合binlog实
现增量
3、对于大数据量的数据库备份,从架构上拆分,分别进行备份

mysqldump优点:
1.备份可读性强
2.文本形式备份,压缩比较高
缺点:恢复时间长

1) 通用参数
-u -p -S -h -p

2) 备份专用参数
* -A 全备参数
mysqldump -uroot -p -A > /backup/full.sql

* -B 指定备份多个单库,系统相关的库不用备,只备份生产相关库;适合于跨版本迁移
mysqldump -uroot -p -B oldboy world student >/backup/bak.sql

* 针对表的备份;备份world库下的city,country表
mysqldump -uroot -p world city country >/backup/bak1.sql

* 加-B与不加-B参数的区别:是加-B多出创建语句和use语句;不加-B则没有,这种备份恢复时,必须库事先存在,并且use进库,才能source恢复

3) 特殊参数使用
-R      备份存储过程及函数
--triggers    备份触发器
-E       备份事件
mysqldump -uroot -p -A -R --triggers >/backup/full.sql
-F 刷新的binlog日志;有多少个生产库,就会刷新多少个新的binlog日志;备份时加入 -F参数,滚动新的binlog日志,新的binlog的起点,就是下次备份起点;非必须

--master-data=2     以注释的形式,保存备份时时间点的binlog的状态信息(binlog文件名和位置点)
-- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000035', MASTER_LOG_POS=194;

--single-transaction 支持innodb存储引擎热备功能,此参数自动判断:在不加--single-transaction ,启动所有表的温备份,所有表都锁定
对innodb可以不锁表热备,对非innodb表可以实现自动锁表功能。

--max-allowed-packet=64M           //设置备份包允许的最大数据量大小,非必须

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

例句1:mysqldump -uroot -p -A -R --triggers --master-data=2 --single-transaction >/backup/full.sql
功能:
(1) 以注释的形式,保存备份开始时间点的binlog的状态信息
(2)对innodb可以不锁表热备
(3)对非innodb表可以实现自动锁表功能

例句2:mysqldump -uroot -p -A -R --triggers --master-data=2 --single-transaction |gzip >/backup/all_$(date +%F-%T).sql.gz
适合多引擎混合备份命令;

恢复:
gunzip /backup/all_2020-02-03-16:34:13.sql.gz
进入数据库
drop database world;
set sql_log_bin=0;
source /backup/all_2020-02-03-16:34:13.sql
注意:尽量不要在生产库直接进行恢复们可以先找一个测试库,验证没问题,把问题数据导出并导入生产库。

报错:mysqldump 备份时,报错socket文件路径错误
解决办法:做软连接
ln -s 源文件 目标文件

数据量级大问题,gzip最大包为4M,超过4M报错;
解决方法:服务端参数只进不出,修改没有用;加上允许数据包的大小参数:--max_allowed_packet=128M。
mysqldump -uroot -p -A -R --triggers --master-data=2 --single-transaction --max_allowed_packet=128M |gzip >/backup/all_$(date +%F-%T).sql.gz

4.2 面试题

  1. 你们公司数据量多大?
    小数据量:30G-50G都可以。
    互联网公司 数据量不要超过100G。
    zabbix除外,数据量较大。

  2. 备份多长时间?
    mysqldump 5分钟25G
    10分钟、20分钟、半个小时;备份时长的主要因素是IO,sata磁盘IO速度在80M左右,固态盘更块。
    备份多时间,恢复大概也要多长时间。

  3. 什么工具备份?
    mysqldump
    可以简单说一下备份策略,每天全备,每小时增备。
    xtrabackup备份时间快于mysqldump

4.3 备份恢复案例

正在运行的网站系统,mysql数据库,数据量25G,日业务增量10-15M。
备份方式:每天23:00,计划任务调用mysqldump执行全备脚本。
故障时间:上午10点,误删除一个表。

恢复思路:

  1. 挂出维护界面
  2. 找测试库
  3. 恢复全备到测试库
  4. 截取二进制日志到误删除时间点,恢复到测试库
    起点:master-data=2,找备份文件,获取到日志名字和位置号
    终点:分析最后一个binlog,找到误删除事件位置点
  5. 验证数据,将故障表导出,导入会产生库
  6. 开启业务

模拟故障:
1、模拟全备
mysqldump -uroot -p -A -R --triggers --master-data=2 --single-transaction >/backup/all.sql

2、模拟业务
create database baidu charset utf8;
use baidu;
create table t1(id int);
insert into t1 values(1),(2),(3);
insert into t1 values(11),(12),(13);
update t1 set id=10 where id=1;

3、模拟10点数据误删除
drop database world;
drop database baidu;

4、准备恢复
查看备份文件:
-- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000013', MASTER_LOG_POS=819739;

截取二进制日志:

# 查看当前binlog文件
show master status;

# 找到drop之前的位置点
show binlog events in 'mysql-bin.000013';
| mysql-bin.000013 | 820513 | Xid         |         6 |      820544 | COMMIT /* xid=770 */ 
| mysql-bin.000013 | 820544 | Query       |         6 |      820639 | drop database world 
| mysql-bin.000013 | 820639 | Query       |         6 |      820734 | drop database baidu 

# 生产中查看最后10行方法:
show binlog events in 'mysql-bin.000013' limit 14,10;

5、截取binlog日志
mysqlbinlog --start-position=819739 --stop-position=820544 /data/mysql/mysql-bin.000013 >/backup/binlog.sql

6、开始恢复
关闭binlog日志记录
set sql_log_bin=0;
恢复全备
soure /backup/all.sql
恢复增备
source /backup/binlog.sql
恢复记录
set sql_log_bin=1;

5 物理备份工具

XBK(Percona Xtrabackup)
MEB(MySQL Enterprise Backup)

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

5.1 安装

  1. 安装依赖包
    yum -y install perl perl-devel libaio libaio-devel perl-Time-HiRes perl-DBD-MySQL libev

  2. 下载并安装
    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

wget https://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

yum -y install percona-xtrabackup-24-2.4.4-1.el6.x86_64.rpm

5.2 备份实现原理

  1. 对于非innodb引擎,锁定表,直接拷贝表的数据文件
  2. 对于innodb引擎,立即触发checkpoint动作,将内存数据页刷写到磁盘的动作;拷贝此时的数据文件(LSN=1000),在此过程中产生的日志文件(to_lsn=1000 redo last_lsn=1020 和 undo)也进行备份

热备:备份某时间点的数据地同时,将redo和undo也一并备份走了(备份过程中产生的变化也也备份),将来恢复的时候会应用redo和undo,实现一致性地恢复,前提是支持事务地存储引擎。

5.3 全备

只有全备和增备,没有指定库、表备份
innobackupex --user=root --password=123 /backup

1、备份内容介绍
xtrabackup_binlog_info //备份时间点二进制日志的信息

xtrabackup_checkpoints //记录备份信息
cat xtrabackup_checkpoints
backup_type = full-backuped //全备
from_lsn = 0 //从哪开始
to_lsn = 4600060 //结束
last_lsn = 4600060
compact = 0
recover_binlog_info = 0

xtrabackup_info //详细显示

xtrabackup_logfile //redo的日志文件,二进制格式

2、备份到指定目录
--no-timestamp //取消时间戳

  • 备份到指定目录full
    innobackupex --user=root --password=123 --no-timestamp /backup/full

5.4 恢复全备

注意:恢复的路径必须是空的,mysql不需要启动

  1. 停数据库
    pkill mysqld

  2. 删数据库
    rm -rf /application/mysql/data/*

  3. 准备恢复,使用redo前滚,使用undo回滚,保证数据一致性;
    innobackupex --apply-log /backup/full/

  4. 恢复数据
    第一种:将full目录里的文件拷贝到 /application/mysql/data/
    cp -a * /application/mysql/data/

第二种:innobackupex --copy-back /backup/full/

  1. 修改权限
    chown -R mysql. /application/mysql/data/*

  2. 启动数据库

5.5 增量备份

  1. 增量备份介绍
    基于上一次备份的增量备份,XBK需要将增量合并到全备中才能恢复。
    优点:是节约空间和时间
    缺点:依赖全备和上一次备份

  2. 增量备份策略设计及实现

# 全备
innobackupex --user=root --password=123 --no-timestamp /backup/full

# 周一模拟数据
create database full charset utf8;
use full
create table t1(id int);
insert into t1 values(1),(2),(3);
commit;

# 周一增量备份
innobackupex --user=root --password=123 --no-timestamp --incremental-basedir=/backup/full --incremental /backup/inc1

--incremental-basedir=/backup/full    //上次备份的路径
--incremental      //打开增量备份的功能

# 周二数据模拟
create database inc1 charset utf8;
use inc1
create table t2(id int);
insert into t2 values(4),(5),(6);
commit;

# 周二增量备份
innobackupex --user=root --password=123 --no-timestamp --incremental-basedir=/backup/inc1 --incremental /backup/inc2

# 查看三个备份的记录信息
cat /backup/full/xtrabackup_checkpoints /backup/inc1/xtrabackup_checkpoints /backup/inc2/xtrabackup_checkpoints
==================================
backup_type = full-prepared
from_lsn = 0                   //起点
to_lsn = 4600060        
last_lsn = 4600060     //终点
compact = 0
recover_binlog_info = 0
==================================
backup_type = incremental
from_lsn = 4600060      //起点
to_lsn = 4615842    
last_lsn = 4615842       //终点
compact = 0
recover_binlog_info = 0
=================================
backup_type = incremental
from_lsn = 4615842     //起点
to_lsn = 4636357
last_lsn = 4636357    /终点
compact = 0
recover_binlog_info = 0
  1. 恢复准备
    --apply-log //redo和undo都应用,检查
    --redo-only //只应用redo;最后一次增量不加,其它都要加 redo-only

恢复准备:
innobackupex --apply-log --redo-only /backup/full
第一次增量合并并准备,full的终点与inc1的终点一致
innobackupex --apply-log --redo-only --incremental-dir=/backup/inc1 /backup/full
第二次增量合并并准备,full的终点与inc2的终点一致
innobackupex --apply-log --incremental-dir=/backup/inc2 /backup/full
全备再次准备
innobackupex --apply-log /backup/full/

  1. 恢复数据
    pkill mysqld //停数据库
    cd /application/mysql/data/
    rm -rf * //删除数据
    innobackupex --copy-back /backup/full/ //拷贝回数据

5.6 故障案例

  1. 背景:
    某大型网站,mysql数据库,数据量500G,每日更新量100M-200M
    备份策略:xtrabackup,每周日23:00进行全备,周一到周六23:00进行增量备份。
    故障场景:
    周三下午2点出现数据库意外删除表操作。

  2. 思路
    1、周日全备+周一增备+周二增备
    2、进行备份准备
    3、找到测试库,使用备份恢复数据,目前数据状态:周二晚上23:00时间点
    4、截取周二备份时间点到周三误删除时间点之前的二进制日志
    起点:备份中会记录
    终点:分析日志文件事件
    5、恢复二进制日志,导出故障表,导入回生产库。

  3. 恢复准备
    (1) 全备:
    rm -rf /backup/*
    innobackupex --user=root --password=123 --no-timestamp /backup/full
    (2) 模拟周一数据
    create database day1 charset utf8;
    use day1
    create table t1(id int);
    insert into t1 values(1),(2),(3);
    commit;
    (3) 周一的增量备份
    innobackupex --user=root --password=123 --no-timestamp --incremental-basedir=/backup/full --incremental /backup/inc1
    (4) 模拟周二数据
    create database day2 charset utf8;
    use day2
    create table t2(id int);
    insert into t2 values(1),(2),(3);
    commit;
    (5) 周二的增量备份
    innobackupex --user=root --password=123 --no-timestamp --incremental-basedir=/backup/inc1 --incremental /backup/inc2
    (6) 周三的数据变化
    create database day3 charset utf8;
    use day3
    create table t3(id int);
    insert into t3 values(1),(2),(3);
    commit;
    (7) 模拟下午2点的故障
    drop table t1;

  4. 恢复数据

思考问题:
如果误删除表只有1M,以上方案是否合适?
找到建表语句,将数据导回;建个空表,将空表的ibd文件删除,把备份的ibd改个权限,import进去。

# 恢复单独表
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.7 面试题

1、介绍以下逻辑备份和物理备份的不同点?它是怎么实现的?
逻辑备份:基于SQL语句的备份
物理备份:基于磁盘的数据文件的备份

2、mysqldump 和 xtrabackup 热备是怎么实现的?
mysqldump:对于innodb表,开启一个专门的备份事务,基于时间点的快照进行热备。

xtrabackup:备份某时间点的数据的同时,将redo和undo也一并备份走了(备份过程中产生的变化也也备份),在恢复时模拟CSR过程,将数据和日志恢复到一致状态,即可恢复状态。前提是支持事务地存储引擎。

3、备份参数的使用

4、DBA运维人员在备份、恢复的职责
2.1设计备份、容灾策略
2.2 定期的备份、容灾检查
2.3 定期的故障恢复演练
2.4 数据损坏时的快速且准确恢复
2.5 数据迁移工作

5、以下两个命令的备份结果区别 ?
mysqldump -uroot -p123 -B world >/data/backup/db1.sql
-B 库备份,备份时把库的建库语句以及use库的语句加进去

mysqldump -uroot -p123 world >/data/backup/db2.sql
不加-B针对表级别备份,备份库下所有表,不包含建库语句
应用时,如果world库不存在,需要手工创建,并且use到world库下再恢复。

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