MySQL_备份
阅读原文时间:2023年07月11日阅读:3

Mysql 的备份

三种级别的备份与恢复数据:

1、表级别备份:
mysqldump [OPTIONS] database [tables]
mysqldump -p密码 库名 表名 > 保存的路径
例子:
# mysqldump -p123 db01 emp > /tmp/mysqlbak/emp.sql 备份单个表
# mysqldump -p123 db01 emp dept > /tmp/mysqlbak/emp.sql 备份多个表

表级别的恢复:
终端命令行中 mysql -p 密码 要把表恢复到的库的库名 < 备份的路径 或者在mysql数据库内使用source命令来执行外部的sql文件 mysql> source 备份的路径

2、库级别的备份:mysqldump [OPTIONS] --databases [OPTIONS] DB1 [DB2 DB3…]

# mysqldump --databases 库名 -p密码 > 备份到的路径 备份单个库
# mysqldump --databases 库名1 库名2 -p密码 > 备份到的路径 备份多个库

库恢复:
# mysql -p < 备份的路径 mysql> source 备份的路径


3、全库备份:mysqldump [OPTIONS] --all-databases [OPTIONS]
考虑到数据库里有innodb,也有其他类型的表,那么就只能锁表备份
# mysqldump -p --lock-tables --all-databases > 备份到的路径

全库恢复: 注意mysqldump的恢复速度较慢,所以数据太大需要的时间较长

全库恢复步骤:

0. 杀死进程,删除socket文件
[root@db01 data]# cd ../
[root@db01 mysql]# rm -f mysql.sock
[root@db01 mysql]# pkill -9 mysqld
1. 初始化
[root@db01 mysql]# scripts/mysql_install_db --user=mysql --defaults-file=/etc/my.cnf
2. 把数据库先启起来
[root@db01 mysql]# service mysql start
Starting MySQL. SUCCESS!
3. 恢复
[root@db01 mysql]# mysql show databases;
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)


说明:
如果备份对象下的数据库绝大多数都是myisam类型表,为了保证数据的一致性,备份时需要锁定表。
如果备份的数据库里的表与其他库没有关系的话,那么只需要锁定该库下的表就可以了,如:
--lock-tables
如果备份的数据库里的表与其他库有关系的话,那么需要锁定整个mysql数据库的所有库下的所有表;如:
--lock-all-tables
如果是针对innodb的表进行备份由于innodb是事务型的引擎,会话与会话之间是隔离的,所以备份的时候不影响数据库的正常使用,无需锁表。

常用参数:
--flush-logs, -F   开始备份前刷新日志
--flush-privileges 备份包含mysql数据库时刷新授权表
--lock-all-tables, -x   MyISAM一致性,服务可用性(针对所有库所有表)
--lock-tables, -l       备份前锁表(针对要备份的库)
--master-data=1|2      该选项将会记录binlog的日志位置与文件名并追加到文件中
详细说明:
1. 该选项等于2表示将二进制日志的位置和文件名写入到备份文件,并在dump文件中注释掉这一行;
2. 该选项等于1表示将二进制日志的位置和文件名写入到备份文件,不在dump文件中注释掉这一行;
3. 恢复时会执行,默认是1
4. This option requires the RELOAD privilege and the binary log must be enabled.
5. 这个选项会自动打开--lock-all-tables,关闭--lock-tables;除非同时设置了
--single-transaction(这种情况下,全局读锁只会在开始dump的时候加上一小段时间)
6. 在任何情况下,所有日志中的操作都会发生在导出的准确时刻。

--single-transaction   适用InnoDB引擎,保证一致性,服务可用性
详细说明:
1. 将导出操作封装在一个事务内来使得导出的数据是一个一致性快照,进而保证数据的一致性。目前只支持InnoDB存储引擎,其他引擎不能保证导出是一致的。
2. 当导出开启了--single-transaction选项时,要确保导出文件有效(正确的表数据和二进制日志位置),就要保证没有其他连接会执行如下语句:ALTER TABLE, DROP TABLE, RENAME TABLE, TRUNCATE TABLE,这会导致一致性快照失效。这个选项开启后会自动关闭lock-tables。

1、逻辑备份

Mysqldump 实现完全备份+增量备份(binlog)

# 使用场景
- 适用于中小型数据库;通过结合二进制日志文件,把数据库恢复到最新的状态
- 二进制日志文件默认会记录下所有对数据库数据变化的操作
- 二进制日志文件中会记录某个操作的详细sql语句,还有执行的时候环境、时间、以及该记录在二进制日志文件的起始和结束点pos值

几个日志的解释

- error log  记录mysql服务端在运行时产生的错误信息,以及mysql启动和关闭时的日志信息(排错)  
- slow log &nbsp; 慢查询时间阀值,以秒为单位,如果超过这个阀值就是慢查询  (调优)  
- bin log   记录对数据库增、删、改的SQL操作,可以使用这个日志做增量备份  (备份)  
- Relay log  中继日志(主从复制日志)  从机器上从主机器复制过来日志,根据日志来同步数据(复制)  


mysqlbinlog 查看二进制日志文件内容
--start-datetime=name 开始的时间
--stop-datetime=name 结束的时间
--start-position=# 开始的位置(POS)
--stop-position=# 结束的位置

# 操作步骤:
demo1:先做全量备份,然后更新数据库并误操作, binlog进行数据恢复

# 举例的操作步骤:
1、全库备份
[root@db01 data]# mysqldump -p --flush-logs --master-data=2 --all-databases > /backup/all.sql
Enter password:

--flush-logs //备份时先将内存中日志写回磁盘,然后截断二进制日志,并产生新的日志文件
初始状态:
mysql> select * from t1;
+------+---------+----------+
| id   | name    | sal      |
+------+---------+----------+
|    1 | harry   | 12000.33 |
|    2 | tom     | 15000.00 |
|    3 | harryyy |     NULL |
+------+---------+----------+

# 查看完整备份文件中的字段
vim /tmp/all.sql
-- CHANGE MASTER TO MASTER_LOG_FILE='mysqld-bin.000003', MASTER_LOG_POS=120;

2. 更新相关数据
注释:更新的db02库中的t1表
mysql> insert into t1 values (4,'jack',2000);
Query OK, 1 row affected (0.01 sec)
mysql> delete from t1 where id=3;
Query OK, 1 row affected (0.01 sec)

mysql> select * from t1;
+------+-------+----------+
| id   | name  | sal      |
+------+-------+----------+
|    1 | harry | 12000.33 |
|    2 | tom   | 15000.00 |
|    4 | jack  |  2000.00 |
+------+-------+----------+
3 rows in set (0.00 sec)

3. 模拟故障
进入到数据库中,将3个业务库全部删掉
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| db01               |
| db02               |
| myblog             |
| mysql              |
| performance_schema |
| test               |
+--------------------+
7 rows in set (0.00 sec)

mysql> drop database db01;
Query OK, 7 rows affected (0.04 sec)

mysql> drop database db02;
Query OK, 1 row affected (0.01 sec)

mysql> drop database myblog;
Query OK, 12 rows affected (1.62 sec)

4.还原
1)全库恢复
[root@db01 data]# mysql -p < /backup/all.sql 结果:当前数据库恢复到了11:05分的状态 ​ 2)增量恢复 # 查看(读懂)二进制日志文件 # at 120 起始位置 #181012 19:06:00 server id 1 end_log_pos 199 CRC32 0xc4a7306e Query   thread_id=9     exec_time=0     error_code=0 SET TIMESTAMP=1539342360/*!*/; SET @@session.pseudo_thread_id=9/*!*/; SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/; SET @@session.sql_mode=1075838976/*!*/; SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/; /*!\C utf8 *//*!*/; SET @@session.character_set_client=33,@@session.collation_connection=33,@@session.collation_server=8/*!*/; SET @@session.lc_time_names=0/*!*/; # at 199 #181012 19:06:00 server id 1 end_log_pos 310 CRC32 0x764ea2b3 Query   thread_id=9     exec_time=0     error_code=0 use `db02`/*!*/; SET TIMESTAMP=1539342360/*!*/; insert into t1 values (4,'jack',2000) 正常的更新数据,需要恢复 /*!*/; # at 310 #181012 19:06:00 server id 1 end_log_pos 341 CRC32 0xa5a0cfe4 Xid = 1103 COMMIT/*!*/; # at 341 //insert语句的结束位置 #181012 19:06:32 server id 1 end_log_pos 420 CRC32 0xc2c81cd3 Query   thread_id=9     exec_time=0     error_code=0 SET TIMESTAMP=1539342392/*!*/; BEGIN /*!*/; # at 420 #181012 19:06:32 server id 1 end_log_pos 519 CRC32 0x7b3404e2 Query   thread_id=9     exec_time=0     error_code=0 SET TIMESTAMP=1539342392/*!*/; delete from t1 where id=3 误操作的数据,不需要恢复 /*!*/; # at 519 #181012 19:06:32 server id 1 end_log_pos 550 CRC32 0x5bbc4007 Xid = 1105 COMMIT/*!*/; ​ # 使用二进制日志文件恢复到我想要的状态 mysqlbinlog --start-position=120 --stop-position=341 mybinlog.000004|mysql -p Enter password: ​ # 在此时注意:这里是开始恢复数据库,指定起止的时间,时间要确定好,在查看二进制日志的时候看清楚要恢复的是那些操作的步骤,COMMIT/*!*/;才算是之前的操作被二进制日志记录下来了,要找这个标志下面的那个 # at 数字,此时这个数字才是自己想要恢复的数据的截止时间。 ​ # 验证: mysql> use db02;
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> select * from t1;
+------+---------+----------+
| id   | name    | sal      |
+------+---------+----------+
|    1 | harry   | 12000.33 |
|    2 | tom     | 15000.00 |
|    3 | harryyy |     NULL |
|    4 | jack    |  2000.00 |//第4条记录产生说明恢复成功
+------+---------+----------+
4 rows in set (0.00 sec)

# 最新状态,没有回复delete误操作

2、物理备份

xtrabackup备份

#xtrabackup备份
优点:
1. 备份过程快速、可靠(因为是物理备份);
2. 支持增量备份,更为灵活
3. 备份过程不会打断正在执行的事务;
4. 能够基于压缩等功能节约磁盘空间和流量;
5. 自动实现备份检验;
6. 还原速度快;

缺点:
1. 只能对innodb表增量备份,myisam表增量备份时是全备
2. innobackupex备份MyISAM表之前要对全库进行加READ LOCK,阻塞写操作,若备份是在从库上进行的话会 影响主从同步,造成延迟。对InnoDB表备份不会阻塞读写。

innobackupex全备原理:
1. innobackupex首先会启动一个xtrabackup_log后台检测的进程,实时检测mysql的redo log的变化,一旦发现 redo有新的日志写入,立刻将日志写入到日志文件xtrabackup_log中
2. 物理拷贝innodb的数据文件和系统表空间文件idbdata1到对应的以默认时间戳为备份目录的地方
3. 复制结束后,执行flush table with read lock操作进行全库锁表准备备份非InnoDB文件
4. 复制.frm .myd .myi等非InnoDB引擎文件
5. 查看binary log 的位置
6. 解锁unlock tables
7. 停止xtrabackup_log进程

# 实例1:使用innobackupex+binlog实现增量备份并恢复演练
# 思路:
1.inobackupex全备
2.inobackupex预备
3.修改数据,备份binlog日志 (增量备份)
4.删除数据(模拟故障)
5.全备恢复
6.恢复binlog 增量备份

[root@mysql01 xtrabackup]# ls
libev-4.15-3.el7.x86_64.rpm  percona-xtrabackup-24-2.4.7-1.el7.x86_64.rpm

安装innobackupex工具
[root@mysql01 xtrabackup]# yum -y install libev-4.15-3.el7.x86_64.rpm
[root@mysql01 xtrabackup]# yum -y install percona-xtrabackup-24-2.4.7-1.el7.x86_64.rpm
# 查看带来的文件列表
[root@mysql01 xtrabackup]# rpm -ql percona-xtrabackup-24
/usr/bin/innobackupex
/usr/bin/xbcloud
/usr/bin/xbcloud_osenv
/usr/bin/xbcrypt
/usr/bin/xbstream
/usr/bin/xtrabackup
/usr/share/doc/percona-xtrabackup-24-2.4.7
/usr/share/doc/percona-xtrabackup-24-2.4.7/COPYING
/usr/share/man/man1/innobackupex.1.gz
/usr/share/man/man1/xbcrypt.1.gz
/usr/share/man/man1/xbstream.1.gz
/usr/share/man/man1/xtrabackup.1.gz

# 具体步骤:
建立myisam 存储引擎和Innodb存储引擎的表测试:
开启bin-log日志

mysql> create database db01;
ERROR 1007 (HY000): Can't create database 'db01'; database exists
mysql> create database db001;     创建库
Query OK, 1 row affected (0.00 sec)
mysql> use db001;
Database changed
mysql> show tables;
Empty set (0.00 sec)

mysql> create table t1(id int,name varchar(10)) engine=myisam; 指定存储引擎为myisam.
mysql> insert into t1 values (1,'mona');
Query OK, 1 row affected (0.00 sec)

mysql> create table t2 (id int,name vachar(10)) engine=innodb;   指定存储引擎为innodb
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'vachar(10)) engine=innodb' at line 1
mysql> create table t2 (id int,name varchar(10)) engine=innodb;
Query OK, 0 rows affected (0.00 sec)

mysql> insert into t2 values (2,'tom');
Query OK, 1 row affected (0.00 sec)

创建一个备份用户admin并授予相应的权限。
mysql>grant reload,process,lock tables,replication client on *.* to 'admin'@'localhost' identified by '123';
创建一个admin用户并给他以reload,process,lock
tables,replication的权限 给定密码。

刷新权限
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)

注意:如果不使用root账号备份 需要的权限: 连接到服务是为了执行备份,需要在/backup上有read,write和execute权限。

在数据库中需要以下权限:
RELOAD和LOCK TABLES权限:为了执行FLUSH TABLES WITH READ LOCK REPLICATION CLIENT权限:为了获取binary log位置 PROCESS权限:显示有关在服务器中执行的线程的信息(即有关会话执行的语句的信息),允许使用SHOW ENGINE

实例1:
完全备份:
1、创建一个备份目录(自己指定备份的目录)
[root@mysql01 backup]# mkdir full_xtrabak

2、执行完全备份
[root@mysql01 backup]# innobackupex --user=admin --password=123 /backup/full_xtrabak/
查看备份结果:
[root@mysql01 2018-10-12_19-54-30]# pwd
/backup/full_xtrabak/2018-10-12_19-54-30

注意:备份完后的备份集是不能用于恢复的,所以还需要将备份开始到备份结束的之间数据库发生的改变应用到备份集中。

[root@mysql01 2018-10-12_19-54-30]# ls
backup-my.cnf db1     mysql               xtrabackup_binlog_info xtrabackup_logfile
db001         ibdata1 performance_schema xtrabackup_checkpoints
db01           myblog   test               xtrabackup_info

了解如下文件: xtrabackup_checkpoints:
备份类型(如完全或增量)、备份状态(如是否已经为prepared状态)和LSN(日志序列号)范围信息;每个InnoDB页 (通常为16k大小)都会包含一个日志序列号,即LSN。
LSN是整个数据库系统的系统版本号,每个页面相关的LSN能够表明此页面近是如何发生改变的。
xtrabackup_binlog_info: mysql服务器当前正在使用的二进制日志文件及至备份这一刻为止二进制日志事件的位置。
xtrabackup_info: xtrabackup工具在备份时记录的使用工具及数据库信息 backup-my.cnf:备份命令用到的配置选项信息 xtrabackup_logfile:xtrabackup记录innodb事物日志的信息

准备完全备份(预备):

一般情况下,在备份完成后,数据尚且不能用于恢复操作,因为备份的数据中可能会包含尚未提交的事务或已经提交但 尚未同步至数据文件中的事务。 因此,此时数据文件仍处于不一致状态。“准备”的主要作用正是通过回滚未提交的事务及同步已经提交的事务至数据文 件也使得数据文件处于一致性状态。

在何时备份时,无论全量还是增量备份,在需要恢复数据时,只应用前滚,不应用回滚,怕的是在这备份期间有用户在提交数据,保证不了数据的一致性,直至知道用户的这个sql语句操作应用完毕,才去执行回滚,这样数据就能保证一致性。

注意:全量和增量备份完毕后,最后统一应用日志到全量备份集中

预备增量备份:
预备增量备份需要的2个步骤:
1、需要先预备完全备份,但只是前滚

应用日志到全量备份集
[root@mysql01 2018-10-12_19-54-30]# innobackupex --user=admin --password=123 --apply-log /backup/full_xtrabak/2018-10-12_19-54-30/

准备完全备份成功后提示信息:
InnoDB: Starting shutdown… InnoDB: Shutdown completed; log sequence number 2613288 170713 23:45:16 completed OK!
说明:
在实现“准备”的过程中,innobackupex通常还可以使用--use-memory选项来指定其可以使用的内存的大小,默认通常 为100M。如果有足够的内存可用,可以多划分一些内存给prepare的过程,以提高其完成速度。

对完全备份的数据库更改,进行二进制日志增量备份:
1、查看完全备份日志的位置
[root@mysql01 2018-10-12_19-54-30]# cat xtrabackup_binlog_info
mybinlog.000004 1366   这个是备份完二进制文件的一个二进制文件的编号为000004 在这个文件里面的3536表示从数据库开始所有的sql语句,截止到3536这个position,这个position后面的为增量备份的内容

2、更改数据库信息
mysql> select * from t2;
+------+------+
| id   | name |
+------+------+
|   2 | tom |
+------+------+
1 row in set (0.00 sec)

mysql> insert into t2 values (1,'harry');
Query OK, 1 row affected (0.00 sec)

mysql> insert into t2 values (3,'jack');
Query OK, 1 row affected (0.01 sec)
mysql> select * from t2;
+------+-------+
| id   | name |
+------+-------+
|   2 | tom   |
|   1 | harry |
|   3 | jack |
+------+-------+
3 rows in set (0.00 sec)

3、增量备份二进制日志
[root@mysql01 data]# pwd
/usr/local/mysql/data
[root@mysql01 data]# mysqlbinlog --start-position= mybinlog.000004 > /backup/full_xtrabak/`date +%F`.sql

注意:innobackupex工具是物理拷贝文件,所以在恢复时不需要连接数据库,这样就不需要初始化数据库并启动服务。

通过备份进行还原:
1、还原完全备份
[root@mysql01 data]# innobackupex --defaults-file=/etc/my.cnf --copy-back /backup/full_xtrabak/2018-10-12_19-54-30/

# chown mysql. -R /usr/local/mysql/
# service mysql start

注:datadir必须是为空的,innobackupex –copy-back不会覆盖已存在的文件,除非指定--force-non-empty-directories参数;
还要注意,还原时需要先关闭服务,如果服务是启动的,那么就不能还原到datadir

mysql> select * from t2;
+------+------+
| id   | name |
+------+------+
|   2 | tom |
+------+------+
1 row in set (0.00 sec)

2、还原增量备份(结合二进制日志文件进行数据的恢复)
mysql> source /xtrabak/2017-07-13_23-05-10/2017-07-14.sql
mysql> select * from t2;
+------+-------+
| id   | name |
+------+-------+
|   2 | tom   |
|   1 | harry |
|   3 | jack |
+------+-------+



实例2:通过innobackupex实现增量备份
说明:
需要注意的是,增量备份仅能应用于InnoDB或XtraDB表,对于MyISAM表而言,执行增量备份时其实进行的是完全备份。
语法:
innobackupex --incremental /data/backups --incremental-basedir=BASEDIR
注意:
1、BASEDIR指的是完全备份所在的目录,此命令执行结束后,innobackupex命令会在/data/backups目录中创建一个新的以时间命名的目录以存放所有的增量备份数据。
2、在执行过增量备份之后再一次进行增量备份时,其--incremental-basedir应该指向上一次的增量备份所在的目录。

全量备份:
最开始数据:
mysql> select * from t1;
+------+------+
| id   | name |
+------+------+
|   1 | mona |
+------+------+
1 row in set (0.00 sec)

mysql> select * from t2;
+------+-------+
| id   | name |
+------+-------+
|   2 | tom   |
|   1 | harry |
|   3 | jack |
+------+-------+
3 rows in set (0.10 sec)

[root@db01 ~]# innobackupex --user=admin --password=123 /full_xtrabackup

[root@db01 2018-10-14_17-31-17]# cat xtrabackup_checkpoints
backup_type = full-backuped
from_lsn = 0
to_lsn = 2700237
last_lsn = 2700237
compact = 0
recover_binlog_info = 0

修改:
mysql> update t2 set name='lisi' where id=2;
mysql> insert into t2 values(4,'sarsh');
mysql> insert into t1 values(2,'fire');

mysql> select * from t1;
+------+------+
| id   | name |
+------+------+
|   1 | mona |
|   2 | fire |
+------+------+
2 rows in set (0.00 sec)

mysql> select * from t2;
+------+-------+
| id   | name |
+------+-------+
|   2 | lisi |
|   1 | harry |
|   3 | jack |
|   4 | sarsh |
+------+-------+
4 rows in set (0.00 sec)

增量备份1:

[root@db01 ~]# innobackupex --user=admin --password=123 --incremental /incremental1_backup --incremental-basedir=/full_xtrabackup/2018-10-14_17-31-17/

180804 14:49:44 [00] Writing xtrabackup_info
180804 14:49:44 [00]       …done
xtrabackup: Transaction log of lsn (2183726) to (2183726) was copied.
180804 14:49:44 completed OK!


[root@db01 2018-10-14_17-36-35]# cat xtrabackup_checkpoints
backup_type = incremental 增量备份
from_lsn = 2700237
to_lsn = 2701750
last_lsn = 2701750
compact = 0
recover_binlog_info = 0

[root@db01 2018-10-14_17-36-35]# cat xtrabackup_binlog_info
mybinlog.000003 820

再次修改数据:
mysql> delete from t2 where id>3;
mysql> insert into t1 values(3,'jack');
mysql> create table t3 select * from t1;

mysql> select * from t1;
+------+------+
| id   | name |
+------+------+
|   1 | mona |
|   2 | fire |
|   3 | jack |
+------+------+
3 rows in set (0.00 sec)

mysql> select * from t2;
+------+-------+
| id   | name |
+------+-------+
|   2 | lisi |
|   1 | harry |
|   3 | jack |
+------+-------+
3 rows in set (0.00 sec)
mysql> show tables;
+----------------+
| Tables_in_db01 |
+----------------+
| t1             |
| t2             |
| t3             |
+----------------+
3 rows in set (0.00 sec)

增量备份2:
[root@db01 incremental1_backup]# innobackupex --user=admin --password=123 --incremental /incremental1_backup --incremental-basedir=/incremental1_backup/2018-10-14_17-36-35

查看当前二进制日志文件信息:
[root@db01 2018-10-14_17-41-36]# cat xtrabackup_binlog_info
mybinlog.000003 1399

说明:
/incremental1_backup/ 保存增量备份集目录
/incremental1_backup/2018-10-14_17-36-35 第一次增备的目录
/incremental1_backup/2018-10-14_17-41-36 第二次增备的目录

再次更改数据库:
mysql> create table t4 (id int(10));
Query OK, 0 rows affected (0.12 sec)

mysql> insert into t4 values(1);
Query OK, 1 row affected (0.02 sec)

mysql> select * from t4;
+------+
| id   |
+------+
|   1 |
+------+
1 row in set (0.00 sec)

预备增量备份:
预备增量备份需要2个步骤:
1.需要先预备全备,但是只重做已提交事务,不回滚未提交事务,然后应用到全备,也是只重做已提交事务,不回滚未提交事务
2.最后回滚未提交事务
注意:如果已经回滚了未提交事务,那么就无法再应用增量备份。

If you replay the committed transactions and rollback the uncommitted ones onthe base backup,  
you will not be able to add the incremental ones. If you do this on an incremental one, you won't be able to add data from that moment  and the remaining increments.
Having  this  in  mind,  the  procedure  is  very  straight-forward  using  the --redo-only option, starting with the base
backup:
innobackupex --apply-log --redo-only BASE-DIR

注意:全量和增量都备份完毕后,最后统一应用日志到全量备份集中!!!!!!!

应用全备日志到备份集(全备):
[root@db01 ~]# innobackupex --user=admin --password=123 --apply-log --redo-only /full_xtrabackup/2018-10-14_17-31-17/

应用增量备份1:
[root@db01 ~]# innobackupex --user=admin --password=123 --apply-log --redo-only /full_xtrabackup/2018-10-14_17-31-17/ --incremental-dir=/incremental1_backup/2018-10-14_17-36-35

应用增量备份2:
[root@db01 ~]# innobackupex --user=admin --password=123 --apply-log /full_xtrabackup/2018-10-14_17-31-17/ --incremental-dir=/incremental1_backup/2018-10-14_17-41-36

NOTE:
         --redo-only should be used when merging all  incrementals  except  the  last
         one.  That's why the previous line doesn't contain the --redo-only option.
         Even if the --redo-only was used on the last step,  backup  would  still  be
         consistent but in that case server would perform the rollback phase.

# 注:
1、--redo-only除了最后一个不用加之外,其他的增量应用都要加,最后一个应用的时候可以直接进入回滚未提交事务阶段。
如果加了也没事,服务启动的时候会进入recovery过程,来回滚
2、应用增量备份的时候只能按照备份的顺序来应用。如果应用顺序错误,那么备份就不可用。如果无法确定顺序,可以使用xtrabackup-checkpoints来确定顺序。

# 回滚未提交事务【可选项】:
[root@server ~]# innobackupex --apply-log /xtrabak/2017-07-15_07-46-49/ (完全备份的备份集)
InnoDB: Shutdown completed; log sequence number 2627131
170715 08:26:03 completed OK!

# 删除所有数据后进行恢复:
备份好二进制日志文件:
[root@db01 2018-10-14_17-41-36]# cat xtrabackup_binlog_info
mybinlog.0000031399
[root@db01 data]# cp mybinlog.000003 /opt/

# 停止数据库:
service mysql stop
# 删除所有数据文件:
rm -rf /usr/local/mysql/data/*

# 在准备步骤完成后,还原时只需要还原完全备份即可
[root@db01 data]# innobackupex --defaults-file=/etc/my.cnf --copy-back /full_xtrabackup/2018-10-14_17-31-17/

[root@db01 data]# chown -R mysql. /usr/local/mysql/data/

mysql> select * from t1;
+------+------+
| id   | name |
+------+------+
|    1 | mona |
|    2 | fire |
|    3 | jack |
+------+------+
3 rows in set (0.00 sec)

mysql> select * from t2;
+------+-------+
| id   | name  |
+------+-------+
|    2 | mona  |
|    1 | harry |
|    3 | jack  |
+------+-------+
3 rows in set (0.00 sec)

mysql> select * from t3;
+------+------+
| id   | name |
+------+------+
|    1 | mona |
|    2 | fire |
|    3 | jack |
+------+------+
3 rows in set (0.00 sec)

mysql>

# 最后一步:结合二进制日志文件将数据库恢复到最新状态
[root@db01 data]# mysqlbinlog /opt/mybinlog.000003 |less
[root@db01 data]# mysqlbinlog --start-position=1399 /opt/mybinlog.000003 |mysql -p
Enter password:

xtrabackup总结

1.如果数据库在第2次增量备份后发生故障,那么数据恢复时只能够使用xtrabackup全量备份+xtrabackup增量备份恢复到第2次增量的点
2.如果要将数据库恢复到最新状态,需要结合binlog日志恢复
3.以上全量和增量的备份集是不能用的,需要将xtrabackup_log应用到全量的备份集中才有效
4. 应用所有日志到全量备份集中时,需注意:
1). 除了最后一次增量备份应用日志可以不加--redo-only外,其他都要加;
  只应用已经提交的事务,不回滚未提交的事务!!!
2). 应用日志到全量备份集中时一定要严格按照时间顺序执行,否则无效

3、lvm—snapshot备份

lvm-snapshot 备份
优点:
几乎是热备(创建快照前把表上锁,创建后立即释放)
支持所有存储引擎
备份速度快
无需使用昂贵的商业软件(它是操作系统级别的)

缺点:
可能需要跨部门协调(使用操作系统级别的命令,DBA一般没权限)
数据如果分步在多个逻辑卷上比较麻烦(针对存储级别而言)

# 环境准备:
centos 6.5 系统:
正常安装MySQL:
1. 安装系统
2. 准备LVM,例如 /dev/vg_back/lv-mysql,mount /usr/local/mysql
3. 源码安装MySQL到 /usr/local/mysql

可选操作: 将现在的数据迁移到LVM
1. 准备lvm及文件系统
# lvcreate -L 2G -n lv-mysql vg_back
# mkfs.ext4 /dev/vg_back/lv-mysql

2. 将数据迁移到LVM
# service mysqld stop
# mount /dev/vg_back/lv-mysql /u01/             //临时挂载点
# rsync -va /usr/local/mysql/ /u01/                       //将MySQL原数据镜像到临时挂载点

# umount /u01/
# mount /dev/vg_back/lv-mysql /usr/local/mysql       //加入fstab开机挂载
# df -Th
/dev/mapper/vg_back-lv-mysql ext4  2.0G  274M  1.7G  15% /usr/local/mysql
# service mysqld start


lvextend xxx
resize2fs xxx centos 6
xfs_growfs

xfs  ext4

1.2手动基于LVM快照实现备份:
1. 加锁
mysql> flush table with read lock;

2.创建快照
# lvcreate -L 500M -s -n lv-mysql-snap /dev/vg_back/lv-mysql
# mysql -uroot -p123 -e 'show master status' > /backup/`date +%F`_position.txt
或者
mysql> show master status;
+-------------------+----------+--------------+------------------+-------------------+
| File              | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+-------------------+----------+--------------+------------------+-------------------+
| mysqld-bin.00003 |     135 |              |                  |               |
+-------------------+----------+--------------+------------------+-------------------+

3. 释放锁
mysql> unlock tables;

4. 从快照中备份
# mount -o ro /dev/vg_back/lv-mysql-snap /u01/
# mkdir /backup/`date +%F`
# rsync -a /u01/ /backup/2015-07-02/

5. 移除快照
# umount /u01/
# lvremove -f /dev/vg_back/lv-mysql-snap

脚本  + Cron完成:
#!/bin/bash
#LVM backmysql…
back_dir=/backup/`date +%F`

[ -d $back_dir ] || mkdir -p $back_dir

mysql -uroot -p123 -e 'flush table with read lock'
lvcreate -L 500M -s -n lv-mysql-snap /dev/vg_back/lv-mysql
mysql -uroot -p123 -e 'show master status' |grep mysql > $back_dir/position.txt
mysql -uroot -p123 -e 'flush logs'
mysql -uroot -p123 -e 'unlock tables'

mount -o ro /dev/vg_back/lv-mysql-snap /u01

rsync -a /u01/ $back_dir

if [ $? -eq 0 ];then
        umount /u01/
        lvremove -f /dev/vg_back/lv-mysql-snap
fi

1.3 mysqllvmbackup 工具基于LVM自动备份
功能:利用LVM快照实现物理备份,即LVM快照备份的自动版

安装perl模块
1. 在线安装
http://www.lenzg.net/mylvmbackup
它依赖于perl 模块,可用以下命令安装
perl  -MCPAN  -e  'install Config::IniFiles'
   
2. 离线安装
# rpm -ivh mylvmbackup-0.16-0.noarch.rpm
warning: mylvmbackup-0.16-0.noarch.rpm: Header V4 DSA/SHA1 Signature, key ID b27291f2: NOKEY
error: Failed dependencies:
perl(Config::IniFiles) is needed by mylvmbackup-0.16-0.noarch
perl(Date::Format) is needed by mylvmbackup-0.16-0.noarch
perl(File::Copy::Recursive) is needed by mylvmbackup-0.16-0.noarch

解决:
# yum -y localinstall atrpms-77-1.noarch.rpm perl-File-Copy-Recursive-0.38-1.el6.rfx.noarch.rpm perl-IO-stringy-2.110-1.2.el6.rfx.noarch.rpm perl-Config-IniFiles-2.56-1.el6.rf.noarch.rpm

安装mylvmbackup软件包
# yum -y install mylvmbackup-0.15-0.noarch.rpm 解决依赖关系perl-TimeDate
   
备份方法一:  
# mylvmbackup --user=root --password=123 --host=localhost --mycnf=/etc/my.cnf --vgname=vg_back --lvname=lv-mysql --backuptype=tar   --lvsize=100M --backupdir=/backup
   
# tar xf backup-20140903_000236_mysql.tar.gz
# ls
backup                               backup-cnf-20150702_000236_mysql
backup-20150702_000236_mysql.tar.gz  backup-pos

# 备份方法二:  
vim /etc/mylvmbackup.conf
[mysql]                     #连接数据库配置
   user=root
   password=123456
   host=localhost
   port=3306
   socket=/tmp/mysql.sock
   mycnf=/etc/my.cnf
  [lvm]                           #LVM逻辑卷的配置
   vgname=vg_server        #卷组名称
   lvname=lv_mysql         #逻辑卷名称
   backuplv=mysql_snap     #快照卷名称
   lvsize=500M
  [fs]                            #文件系统配置
   xfs=0
   mountdir=/var/tmp/mylvmbackup/mnt/          #挂载目录
   backupdir=/backup       #备份目录,也可以备份到行程主机
  [misc]                          #定义备份选项
   backuptype=tar            #定义备份的类型
   backupretention=0
   prefix=backup              #定义备份文件名前缀
   suffix=_mysql               #定义备份文件名后缀
   tararg=cvf                   #定义tar参数,默认为cvf
   tarfilesuffix=.tar.gz       #定义备份文件后缀名格式
   datefmt=%Y%m%d_%H%M%S  #定义备份文件名时间戳格式
   keep_snapshot=0        #是否保留snaphot
   keep_mount=0           #是否卸载snaphot
   quiet=0                     #定义记录日志类型
  注释:其他配置保持输入即可,然后直接执行mylvmbackup即可

二、如何备份线上mysql数据库

1、数据量的大小
2、之前有没有备份,备份策略是什么
3、安装路径和数据路径(本地硬盘还是逻辑卷)
4、数据库的业务情况
5、数据库的架构(单机|主从等)

1、备份周期(一个礼拜) 建议:一周全备两次,其余增量备份
2、备份方法
3、备份工具
4、脚本+执行计划

Mysql 主从复制搭建(MS架构)

# 环境准备及要求:
1、关闭防火墙个selinux
2、hosts文件中两台服务器主机名和ip地址一一对应起来
3、系统时间需要同步
1)搭建时间同步服务器
yum -y install xinetd
cd /etc/xinetd.d/
vim time-dgram
vim time-stream
把这两个配置文件中的disabled= NO 禁用=NO

# 思路:
1. master端必须开启二进制日志;slave端必须开启relaylog日志
2. master端和slave端的server_id号必须不能一致
3. 告诉slave需要同步的master主机的IP、user、password等..

# 具体步骤:
1、修改配置文件(master和slave)
master端:
master端必须开启二进制日志   log_bin 开启
servce_id=20

slave端:
slave端必须开启relaylog日志 relay_log=自己指定路径
server_id=10

2、初始化数据使两边的数据一致(以Master为主)
 1)检查两边的服务器上是否有mysql用户
 #id mysql   没有的话创建它 #useradd -r -s /sbin/nologin mysql   -r表示创建系统用户 -s表示指定的解释器
 
master数据库已经有业务数据,需要停服务拷贝到slave服务器。
注意:slave是一个干净系统,没有安装mysql数据库,所以需要将所有的安装目录和数据目录一起拷贝

3、
1)停止master的数据库服务
#service mysql stop
ERROR! MySQL server PID file could not be found!
2)删除socket文件,这个文件只有在启动数据库的时候才会产生
# rm -f /usr/local/mysql/mysql.sock
3)同步mysql下的所有文件到slave服务器那边的/usr/local/mysql/ 下
rsync -av /usr/local/mysql/ 192.168.5.5:/usr/local/mysql/

# 注意:
同步完毕数据后,记得删除master和slave数据目录下的auto.cnf文件,里面保存的是当前数据库的UUID
删除Master和slave两边的auto.cnf文件 rm -f /usr/local/mysql/data/auto.cnf

4、启动Master和slave上的数据库

5、Master端创建授权用户
mysql> grant replication slave on *.* to 'slave'@'10.1.1.%' identified by '123';
Query OK, 0 rows affected (0.00 sec)
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)

6、查看Master服务器那边的正在写的二进制文件名和位置
mysql> flush tables with read lock; 先加锁,不一致;如果业务还未上线,这个就没有必要了
Query OK, 0 rows affected (0.00 sec)  

# 查看日志写到什么位置
mysql> show master status;
+-----------------+----------+--------------+------------------+-------------------+
| File            | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+-----------------+----------+--------------+------------------+-------------------+
| mybinlog.000002 |      405 |              |                  |                   |
+-----------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

7、slave端设定复制信息
mysql> change master to
   -> master_host='192.168.5.4',  
   -> master_user='slave',
   -> master_password='123',
   -> master_port=3307,
   -> master_log_file='mybinlog.000002',
   -> master_log_pos=405;
Query OK, 0 rows affected, 2 warnings (0.01 sec)

8、启动复制线程 开始同步
mysql> start slave;
mysql> show slave status \G;

            Slave_IO_Running: Yes 代表成功连接到master并且下载日志
           Slave_SQL_Running: Yes 代表成功执行日志中的SQL语句          
9、测试验证
master写————> slave可以看到
slave写—————>master看不到