上一章我们已经实现了全量备份,对于一些重要的数据,的确有必要使用全量备份,但是如果数据量太大,比如说100G,全量备份下来就会占用不少时间和精力,甚至都没有资金买磁盘了,这时候我们可以使用增量备份,大大的缩减了时间,和磁盘占用率。
当然,为了更有效的保证数据的完整性和安全性,我们可以使用全备和增备结合,既不会占用太大的磁盘空间,有保证了数据的有效性和安全行。
解决方案:周日全备,周一到周六做增量
- 周日全备:
坑:一定要写成/backup/full ,千万别写成/backup/full/,一个斜杠的区别真要人命,否则成为了隐藏文件,甚至比隐藏文件更可恶,亲测了。mkdir -p /backup/full innobackupex --defaults-file=/application/mysql/my.cnf --user=root --password=123456 --no-timestamp /backup/full
- 模拟数据变化 数据库fxw(周一数据变化)
mysql> use fxw; 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 mysql> show tables; +---------------+ | Tables_in_fxw | +---------------+ | t1 | +---------------+ 1 row in set (0.00 sec) mysql> commit; Query OK, 0 rows affected (0.00 sec) mysql> insert t1 values(16,'111111'); Query OK, 1 row affected (0.01 sec) mysql> insert t1 values(17,'7777777'); Query OK, 1 row affected (0.00 sec) mysql> insert t1 values(18,'888888'); Query OK, 1 row affected (0.00 sec)
- 第一增量(周一晚上增量):
innobackupex --defaults-file=/application/mysql/my.cnf --user=root --password=123456 --incremental --no-timestamp --incremental-basedir=/backup/full/ /backup/inc1
# --incremental 增量备份 (不加该参数表示默认全量备份)
# --no-timestamp 不设置时间戳
# --incremental-basedir 基于谁做增量备份(这里是基于周一的全量备份)
# /backup/inc1 设置增量备份的文件夹 -
模拟数据变化(周二数据变化)
mysql> insert t1 values(19,'99999999999'); Query OK, 1 row affected (0.02 sec) mysql> insert t1 values(20,'20202020'); Query OK, 1 row affected (0.00 sec) mysql> insert t1 values(20,'2020202'); Query OK, 1 row affected (0.00 sec) mysql> insert t1 values(21,'21212121'); Query OK, 1 row affected (0.01 sec) mysql> insert t1 values(22,'2222222'); Query OK, 1 row affected (0.00 sec) mysql> commit; Query OK, 0 rows affected (0.00 sec)
-
第二次增量(周二晚上增量):
# 请注意:--incremental-basedir=/backup/inc1/ /backup/inc2[root@db01 full]# innobackupex --defaults-file=/application/mysql/my.cnf --user=root --password=123456 --incremental --no-timestamp --incremental-basedir=/backup/inc1/ /backup/inc2 190817 11:14:26 innobackupex: Starting the backup operation IMPORTANT: Please check that the backup run completes successfully. At the end of a successful backup run innobackupex prints "completed OK!". . . 省略部分 . . 190817 11:17:46 Executing UNLOCK TABLES 190817 11:17:46 All tables unlocked 190817 11:17:46 Backup created in directory '/backup/inc2' MySQL binlog position: filename 'mysql-bin.000001', position '1708' 190817 11:17:46 [00] Writing backup-my.cnf 190817 11:17:46 [00] ...done 190817 11:17:46 [00] Writing xtrabackup_info 190817 11:17:46 [00] ...done xtrabackup: Transaction log of lsn (3901839) to (3901839) was copied. 190817 11:17:46 completed OK! [root@db01 full]#
第二次的增量是基于第一次(周一的)数据,因此--incremental-basedir应该只想周一的数据
- 模拟数据损坏
mysql> select * from t1; +------+-------------------------+ | id | name | +------+-------------------------+ | 1 | zhang3 | | 2 | li4 | | 3 | wang5 | | 4 | zhang33 | | 5 | li44 | | 6 | wang54 | | 11 | weidaorisun | | 12 | wddfafdeidaorisun | | 13 | wd为道日损n | | 14 | 为道日损 | | 15 | 为ddddddddddd道日损 | | 16 | 111111 | | 17 | 7777777 | | 18 | 888888 | | 19 | 99999999999 | | 20 | 20202020 | | 20 | 2020202 | | 21 | 21212121 | | 22 | 2222222 | +------+-------------------------+ 19 rows in set (0.02 sec) mysql> drop table t1; Query OK, 0 rows affected (0.01 sec)
-
恢复数据的准备
innobackupex --apply-log --redo-only /backup/full #只将已commit的部分合并到全备中,最后一次(即inc2)不适用--redo-only innobackupex --apply-log --redo-only --incremental-dir=/backup/inc1 /backup/full #将增量备份inc1合并到全备中 innobackupex --apply-log --incremental-dir=/backup/inc2 /backup/full #将增量备份inc2合并到全备中 innobackupex --apply-log /backup/full
-
恢复数据
(1)关闭MySQL服务[root@db01 full]# service mysqld stop Shutting down MySQL.... SUCCESS!
(2)删除/application/mysql/data/下的所有数据
[root@db01 full]# cd /application/mysql/data/ [root@db01 data]# rm -rf ./* [root@db01 data]# ll total 0
(3)恢复数据
[root@db01 data]#innobackupex --defaults-file=/application/mysql/my.cnf --copy-back /backup/full innobackupex version 2.4.4 based on MySQL server 5.7.13 Linux (x86_64) (revision id: df58cf2) 190817 11:34:32 [01] Copying ib_logfile0 to /application/mysql/data/ib_logfile0 190817 11:34:32 [01] ...done 190817 11:34:33 [01] Copying ib_logfile1 to /application/mysql/data/ib_logfile1 190817 11:34:33 [01] ...done 190817 11:34:34 [01] Copying ibdata1 to /application/mysql/data/ibdata1 190817 11:34:35 [01] ...done . . 省略部分 . . 190817 11:34:38 [01] Copying ./fxw/db.opt to /application/mysql/data/fxw/db.opt 190817 11:34:38 [01] ...done 190817 11:34:38 [01] Copying ./table01/t1.frm to /application/mysql/data/table01/t1.frm 190817 11:34:38 [01] ...done 190817 11:34:38 [01] Copying ./table01/t1.ibd to /application/mysql/data/table01/t1.ibd 190817 11:34:38 [01] ...done 190817 11:34:38 [01] Copying ./table01/db.opt to /application/mysql/data/table01/db.opt 190817 11:34:38 [01] ...done 190817 11:34:38 [01] Copying ./test/db.opt to /application/mysql/data/test/db.opt 190817 11:34:38 [01] ...done 190817 11:34:38 completed OK!
(4)修改权限
[root@db01 data]# mkdir binlog #我的binlog在data下,所以需要创建 [root@db01 data]# chown -R mysql.mysql /application/mysql/data/
(5)启动MySQL并测试
[root@db01 data]# service mysqld start Starting MySQL.. SUCCESS! [root@db01 data]# mysql -uroot -p123456 -e "select * from fxw.t1"; Warning: Using a password on the command line interface can be insecure. +------+-------------------------+ | id | name | +------+-------------------------+ | 1 | zhang3 | | 2 | li4 | | 3 | wang5 | | 4 | zhang33 | | 5 | li44 | | 6 | wang54 | | 11 | weidaorisun | | 12 | wddfafdeidaorisun | | 13 | wd为道日损n | | 14 | 为道日损 | | 15 | 为ddddddddddd道日损 | | 16 | 111111 | | 17 | 7777777 | | 18 | 888888 | | 19 | 99999999999 | | 20 | 20202020 | | 20 | 2020202 | | 21 | 21212121 | | 22 | 2222222 | +------+-------------------------+ [root@db01 data]#
生产恢复案例:
背景:
1、xtrabackup备份策略每周日,full全备
2、xtrabackup周一到周六,inc1-inic6
3、总数据量200G
4、周三上午10点误删除表t1,数据量1G左右
5、周二晚上inc2备份完成之后到周三上午10点又做了很多操作
如何将数据库恢复到t1表误删除之前状态?
思路:
1、停业务,挂维护页
2、找备用库
3、合并full+inc1+inc2
4、截取周二晚上inc2备份后到周三上午10点,t1表删除之前的binlog日志
5、将合并后的full+截取的binlog恢复到备用库
6、验证数据可用性和完整性
7、使用备用库替代生产库使用或者将t1表导出并导入回生产库
8、业务恢复
-----------------
思考:以上恢复策略是否可以优化?
为了恢复1G表,需要将整个全备恢复,有必要吗?有什么好的解决办法?
解决方案:(单独拷贝所需恢复表的idb文件)
drop table t1; #删除表
#开始恢复
create table t1 (id int,name varchar(20));
alter table t1 discard tablespace; #在数据库内部删除t1.idb文件,不能去文件夹中rm
cd /application/mysql/data/fxw
cp /backup/full/fxw/t1.ibd ./ #copy备份的idb文件到数据库文件夹下
chown -R mysql.mysql * #修改权限
alter table t1 import tablespace; #导入表空间

