MySQL备份--mysqldump_xtrabackup备份

本博客为整理原创,欢迎大家多多指正错误。转载请注明出处

学习心得

1.解除思想的禁锢,学习找方法

2.不要把简单的问题复杂化

生产环境中最重要的就是数据、数据、数据。因为其他都可以重新来过,但数据没了就…

数据丢失的几大因素:硬件故障 、软件故障、自然灾害、黑客攻击、误操作 (占比最大)

需要思考的三大问题:能够容忍丢失多少数据

                                    恢复数据需要多长时间

                                    需要恢复哪一些数据

如果数据量较小,且业务量不大或数据库可以短租暂停业务,可以通过直接复制数据文件+二进制日志的方式实现备份,也可以通过mysqldump工具进行数据库完全备份+二进制日志的方式实现备份

如果数据量很大,且不能过分影响业务运行。可以通过lvm快照的方式实现备份,也可以通过xtrabackup的方式实现备份

1.直接复制数据文件的方式就不说了,操作简单,恢复方便,但需要暂停服务。

2.mysqldump的原理是生成一个创建原始数据库和表的sql语句。mysqldump支持所有的存储引擎,对InnoDB引擎支持热备。mysqldump因为是执行的逻辑备份,所以备份过程和恢复过程都比较慢,只适合业务量不大数据库备份。

3.实际生产环境中,大多是不能过分影响业务的运行的,所说本文重点介绍xtrabackup的方式,lvm快照的方式后期再测试总结。

https://www.cnblogs.com/kerrycode/p/6610874.html 二进制日志参考文档

mysqldump工具简单介绍

官方使用说明:https://dev.mysql.com/doc/refman/5.7/en/mysqldump.html

mysql> FLUSH TABLES WITH READ LOCK;                        #给所有表加读锁

备份所有数据  恢复不需要建数据库

#mysqldump -u用户名 -p密码 --all-databases > /保存路径/文件名.sql 

#mysqldump -uroot -p --all-databases >/home/backup/all.sql

备份一个或多个库  恢复不需要建数据库

#mysqldump -u用户名 -p密码 --databases 数据库1 数据库2... >文件名.sql

备份某个库的某个表   恢复需要先建数据库

#mysqldump [options] db_name [tbl_name ...]

mysqldump备份恢复

mysql>source  备份的文件名.sql

实例

在test数据库上新增一个customers表

create table customers(

c_id int primary key auto_increment,

c_name varchar(20),

c_age tinyint unsigned,

c_sex enum("M","F"),

c_city varchar(20),

c_salary float(12,2)

);

插入一条测试数据

insert into customers values
(1,"Zhangsan",25,"M","Beijing",8000),
(2,"Lisi",30,"F","Shanghai",10000),
(3,"Wangwu",27,"M","Shenzhen",3000);

查看如下图

 

锁表备份全库

mysql>flush tables with read lock;  #所有表添加读锁

#mysqldump -uroot -p --all-databases >backup.sql   #备份所有库

删除test库,然后用backup.sql来恢复

mysql>drop database test;

恢复数据

mysql>source /home/backup/backup.sql       #如下图,部分截图过程

 

mysql>select * from test.customers;

完成

上诉方法是备份后完整的恢复数据,是实现了备份的目的,那么如果备份后有了重新增删改操作呢?备份的数据就是不完整的。那么就要通过二进制日志来恢复了。

执行备份前后刷新一下日志

mysql>flush logs;  #刷新日志后会生成一个新的二进制日志,譬如当前是mysql-bin.000001刷新后就生成mysql-bin.000002日志。

备份后通过已经生成的二进制日志来实现数据还原。备份前刷新日志,就是为了方便识别上次备份的截止记录。如上次锁表备份时,二进制日志是mysql-bin.000001.那么就代表从mysql-bin.000002开始是没有备份的内容,还原数据就是还原原先的备份+mysql-bin.000002日志。

实例2:

接上面实例1

再创建一个orders表

create table orders(

o_id int,

o_name varchar(30),

o_price float(12,2),

foreign key(o_id) references customers(c_id)

on delete cascade     

on update cascade);

插入一条测试数据

insert into orders values
(1,"iphone",5288),
(1,"ipad",3299),
(3,"mate9",3688),
(2,"iwatch",2222),
(2,"r11",4400);

然后假设数据库宕机,重新恢复数据。

恢复思路,我们做的备份中,已经包含了customers表,而后又新增了orders表,那么要恢复的内容就是备份数据+mysql-bin.000002日志文件(因为创建orders表时使用的二进制日志文件是mysql-bin.000002)

mysql>source  /home/backup/backup.sql              #恢复备份数据

#mysqlbinlog  --no-defaults /opt/mysqldata/data/mysql-bin.000002 >/home/abc.sql       #通过mysqlbinlog命令 读取mysql-bin.000002日志内容输出到abc.sql文件中

mysql>source  /home/abc.sql                #恢复二进制数据

扩展:假设我们只要恢复二进制日志中的部分数据呢。那么就要通过position来确定需要恢复的数据

如:

#/usr/bin/mysqlbinlog --no-defaults --start-position=4 --stop-position=838 mysql-bin.000003 | mysql -uroot –p                #通过--start-position= 和--stop-position= 来实现部分日志记录恢复

#mysqlbinlog  --no-defaults --start-datetime='2019-04-10 02:03:00'  --stop-datetime="2019-04-10 02:07:00"  /opt/mysqlData/data/mysql-bin.000009 | mysql -uroot –p    #通过起始时间和结束时间来恢复

mysqlbinlog参数解释

常用选项
  --start-position=953                   起始pos点
  --stop-position=1437                   结束pos点
  --start-datetime="2013-11-29 13:18:54" 起始时间点
  --stop-datetime="2013-11-29 13:21:53"  结束时间点
  --database=zyyshop                     指定只恢复zyyshop数据库(一台主机上往往有多个数据库,只限本地log日志)            
不常用选项:    
-u --user=name  Connect to the remote server as username.连接到远程主机的用户名
-p –password  [=name]Password to connect to remote server.连接到远程主机的密码
-h --host=name         Get the binlog from server.从远程主机上获取binlog日志
--read-from-remote-server   Read binary logs from a MySQL server.从某个MySQL服务器上读取binlog日志
小结:实际是将读出的binlog日志内容,通过管道符传递给mysql命令。这些命令、文件尽量写成绝对路径;

下面介绍xtrabackup备份工具

innobackupex 是一个脚本,封装xtrabackup的几个命令行二进制工具,使得命令行使用非常简单

sync_binlog =1  备份时建议设置为1 。可以在备份时实现安全的写入,不会因为备份导致二进制日志损坏。

一般建议创建一个专门备份的用户,可以给一个最小的权限。最小权限是指reload,lock tables,replication client 三个权限

Mysql> create user 'bkpuser'@'localhost' identified by '123456';

Mysql>REVOKE  ALL PRIVILETES,GRANT OPTION FROM ‘bkpuser’;

Mysql> grant reload,lock tables,replication client on *.* to 'bkpuser'@'localhost';

Mysql>flush privileges;

Xtrabackup 执行一个完整备份,如下

#innobackupex --user=root --password=123456 /home     #完整备份

备份完如下图,生成2019-04-10_18-16-05目录

 

Xtrabackup_info记录了备份时间,备份工具,备份命令,备份server版本,备份开始时间,备份结束时间等等

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

innobackupex命令的—apply-log选项可用于实现上述功能,完成后就可以用于恢复了

#innobackupex --apply-log /home/2019-04-10_18-16-05/ 

通常模拟数据丢失是清空数据目录

#service  mysql stop

#rm –rf /opt/mysqldata/data/*

恢复数据

恢复数据不需要启动数据库

Innobackupex命令的—copy-back选项用于执行恢复操作,其通过复制所有数据相关的文件至mysql服务器DATADIR目录中来执行恢复过程。Innobackupex通过backup-my.cnf来获取DATADIR目录相关信息。

#innobackupex  --copy-back   /home/ 2019-04-10_18-16-05 #恢复数据到mysql,如下图示,显示complete OK;恢复正确。

恢复之后重启数据库。

查看错误日志,如下

查看下恢复的数据文件的属组

#chown  -R mysql:mysql /opt/mysqldata/data/*   #更改数据文件属主

#service mysql start

扩展:清空数据后如果要直接启动mysql,需要初始化数据库

################初始化mysql################

#find / -name mysql_install_db

#/usr/bin/mysql_install_db  --user=mysql –datadir=/opt/mysqldata/data

# service mysql start

Xtrabackp+二进制日志,实现数据完整恢复。

如已经恢复了完全备份。完全备份后产生的更新读写操作都在二进制日志mysql-bin.000002里。那么flush log一下。把mysql-bin.000002日志重新导入到数据库里。

#mysqlbinlog  --no-defaults /opt/mysqldata/data/mysql-bin.000002 >/home/abc.sql

Mysql>use test;

Mysql>source /home/new.sql

注意:xtrabackupInnoDB引擎支持增量备份,对MyISAM不支持增量备份。遇到MyISAM引擎时,xtrabackup做的是完全备份

Xtrabackup 实现增量备份

每个InnoDB页面都会包含一个LSN信息,每当相关的数据发生改变,相关的页面的LSN就会自动增长,这正是InnoDB表可以进行增量备份的基础,即innobackupex通过备份上次完全备份之后发生改变的页面来实现。

要实现第一次增量备份,可以使用下面的命令进行。

#innobackupex  --incremental  /backup  --incremental-basedir=BASERDIR

# innobackupex --incremental --user=root --password=123456 /home/backup --incremental-basedir=/home/2019-04-11_00-12-50/  #如第一条报权限错误,那么就执行第二条

其中,BASERDIR指的是完全备份所在的目录,此命令执行结束后,innobackupex命令会在/backup目录中创建一个新的以时间命名的目录以存放所有的增量备份数据。另外,在执行过增量备份之后再一次进行增量备份时,其—incremental-basedir应该指向上一次的增量备份所在的目录。

准备”(prepare)增量备份与整理完全备份有着一些不同,尤其要注意的是:

(1)   需要在每个备份(包括完全和各个增量备份上),将已经提交的事务进行“重放”。‘重放’之后,所有的备份数据将合并到完全备份上。

(2)   基于所有的备份将未提交的事务进行”回滚”

增量备份后怎么使备份生效呢,增量备份后要把增量备份和完全备份合并?

#innobackupex --apply-log --redo-only ../2019-04-11_00-12-50/

#innobackupex --apply-log  --redo-only ../2019-04-11_00-12-50/  --incremental-dir=2019-04-11_00-37-24/

#innobackupex --apply-log  --redo-only ../ 2019-04-11_00-37-24/  --incremental-dir=2019-04-11_0049-36

备注:50是完全备份,24是第一次增量备份。 36是第二次增量备份

每一次还原之后,都要重新做一次完全备份。再在完全备份的基础上做一次增量备份。

未完待续

每一次的总结都是一次提高的过程,让家人过上更好的生活。努力吧,骚年!!!

猜你喜欢

转载自www.cnblogs.com/smallmint/p/10688252.html