专职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 root@192.168.2.100 \ "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