https://blog.csdn.net/flyfish778/article/details/52451738
https://www.cnblogs.com/tongxiaoda/p/8507688.html
Mysqldump
用来生成MySQL的逻辑备份文件,其文件内容就是构成数据库对象和数据内容的可重复执行的SQL语句。
mysqldump[OPTIONS]database[tables]mysqldump[OPTIONS]--databases[OPTIONS]DB1[DB2 DB3...]mysqldump[OPTIONS]--all-databases[OPTIONS]
options的关键参数:
-h,--host=name 要导出的目标数据库所在主机,默认是localhost-u,--user=name 链接目标数据库的数据库用户名-p,--password[=name] 链接目标数据库的数据库密码-P,--port=# 链接目标数据库的端口--add-drop-database 在使用--databases或--all-databases参数时在每个create database命令前都加上drop database命令--add-drop-table 在每个create table命令前加上drop table命令--default-character-set=name 指定默认的字符集,默认是UTF8--replace 使用该命令插入数据而不是使用insert命令--set-charset 将set names default_character_set命令写入到导出备份文件中,默认是开启状态--dump-slave[=#] 表示从复制的slave从库导出备份,且其中包含了change master 通语句。value参数如果不写或=-1的情况下,则change master to语句写入dump文件中,设置为2则表示也写入dump文件中,只是会注释掉--master-data[=#] 表示从复制的主库上导出备份。value参数与--dump-slave相同。使用该参数会自动打开lock-all-table参数,除非同时使用--single-transaction参数-T,--tab=name 表示将备份文件以文本文件的方式生成,并指定存放文件路径,每个表会生成两个文件,一个是.sql文件保存表结构,一个是.txt文件保存表数据信息-A,--all-databases 导出所有数据库里的所有表-B,--databases 导出指定的一个或多个数据库--ignore-table=name 代表导出过程中忽略某个指定表的导出,如果要忽略多个表则这个参数使用多次-d,--no-data 代表只导出表结构-R,--routines 代表导出时也要把存储过程和函数也导出来--triggers 代表导出时也将触发器导出来-w,--where=name 代表导出符合条件的数据-x,--lock-all-tables 代表在导出过程中对每个数据库的每个表加上一个只读锁--no-autocommit 代表对每个表的数据导出内容用set autocommit=0和commit两个语句包裹--single-transaction 代表将事务隔离级别设置为可重复读并在导出开始执行start transaction开启一个新事务,在dump执行过程中也不会阻止任何读写操作
例子:
导出一个数据库[root@localhost ~]# mysqldump -uroot -p -P3306 --databases course > backup.sql导出多个数据库[root@localhost ~]# mysqldump -uroot -p -P3306 --databases course test > course.sql[root@localhost ~]# mysqldump -uroot -p -P3306 -B course test > course.sql导出所有数据库[root@localhost ~]# mysqldump -uroot -p -P3306 --all-databases > all.sql仅导出course数据库的数据,不包括表结构[root@localhost ~]# mysqldump -uroot -p -P3306 --no-create-info course > course.sql仅导出course数据库中的students和students_myisam两个表[root@localhost ~]# mysqldump -uroot -p -P3306 --no-create-info course students students_myisam > students.sql仅导出course数据库的表结构[root@localhost ~]# mysqldump -uroot -p -P3306 --no-data course > course.sql导出course数据库中除了teacher和score两个表的其他表结构和数据[root@localhost ~]# mysqldump -uroot -p -P3306 --ignore-table=course.teacher --ignore-table=course.score course > course.sql导出course数据库的表和存储过程和触发器[root@localhost ~]# mysqldump -uroot -p -P3306 --routines --triggers course > course.sql导出course数据库中符合条件的数据[root@localhost ~]# mysqldump -uroot -p -P3306 --where="sid in (1,2)" course students students_myisam > course.sql远程导出course数据库[root@localhost ~]# mysqldump -uroot -p -P3306 -h192.168.1.178 cmdb_v2 students_myisam > students.sql在主库备份[root@codis-178~]# mysqldump -uroot -p -P3306 --master-data=2 --single-transctions course > course.sql(在备份开始之初,在所有表上加一个只读锁(flush table withreadlock),当成功获取该锁并开始备份之后,此锁就会立即释放,后续dump过程不会影响其他的读写操作)在从库备份[root@codis-178~]# mysqldump -uroot -p -P3306 --dump-slave --single-transctions test > test.sql
这里注意,导出时报以下错误:
[root@codis-178~]# mysqldump -uroot -p -P3306 -h192.168.1.68 course > course.sqlEnter password: mysqldump: Couldn't execute 'SET OPTION SQL_QUOTE_SHOW_CREATE=1': 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 'OPTION SQL_QUOTE_SHOW_CREATE=1' at line 1 (1064)
这是由于mysqldump版本低导致,也就是5.5版本不能导出5.7版本
如何解决?
用5.7或更高版本的mysqldump覆盖或者指定目录运行即可?
使用mysqldump命令导出文本文件,通过指定--tab=dir_name参数来指定文件路径
添加配置secure-file-priv=/tmp/[root@localhost ~]# mysqldump -uroot -p -P3306 --tab=/tmp course[root@localhost ~]# ll /tmp/course.sql-rw-r--r--1root root1544Mar513:28/tmp/course.sql
还可指定文件格式
--fields-teminated-by=str
指定每个字段值之间的间隔符,默认是tab
--fields-enclosed-by=char
指定每个字段值使用什么字符括起来,默认是没有
--fields-optionsally-enclosed-by=char
指定对每个非数字类型的字段使用什么字符括起来,默认没有
--lines-terminated-by=str
指定行之间的结束符,默认是newline
[root@localhost ~]# mysqldump -uroot -p -P3306 --tab=/tmp course --fields-terminated-by=, --fields-enclosed-by="'" --lines-terminated-by="\n" courseEnter password: [root@localhost ~]# cat /tmp/course.txt '1','math','3''2','english','2''3','chinese','4''4','history','1''5','biology','5'
(3)select... into outfile
用来导出表中符合条件的数据到文本文件,不导出表结构
mysql> select * from students_myisam into outfile'/tmp/students_myisam_test.txt'fields terminatedby','enclosedby"'"lines teerminatedby'\r\n';Query OK,3rows affected (0.00sec)[root@localhost ~]# cat /tmp/students_myisam_test.txt '1','a','1','1''2','b','2','2''3','c','3','3'mysql> select * from students_myisam where sidin(1,2) into outfile'/tmp/students_myisam_test2.txt'fields terminatedby','encllosedby"'"lines terminatedby'\r\n';Query OK,2rows affected (0.01sec)[root@localhost ~]# cat /tmp/students_myisam_test2.txt '1','a','1','1''2','b','2','2'
参数说明:
terminated by
字段以什么字符分隔
enclosed by
字段以什么字符括起来
escaped by
转义字符,默认是反斜杠
lines
每条记录的分隔符,默认是换行符
local
指定从客户主机读文件,没有指定则文件必须在服务器上
replace
新行将代替有相同的唯一值的现有行
ignore
跳过有唯一键的现有行的重复行的输入,不指定时当遇到重复行会报错
恢复
(1)普通恢复
导入一个备份文件mysql-uroot-pcourse
(2)恢复文本文件
先导入表结构
再导入数据文件
数据文件导入使用mysqlimport或是loaddatainfilemysqlimport -uroot -p--fields-terminated-by=, --fields-enclosed-by="'" --lines-terminated-by="\n" course /tmp/course.txtusecourse;loaddatainfile'/tmp/course.txt'intotablestudentsfieldsterminatedby','enclosedby"'"linesterminatedby'\r\n';
(3)全量恢复
将备份文件中的所有数据进行恢复,恢复完成后的数据就是生成备份的那一刻的数据状态。
(4)基于时间点的恢复
将数据库恢复到指定的某个时间点的状态,通常需要依赖二进制日志将指定时间点前的所有数据库操作都重新操作一遍。
步骤:
1.通过全量备份将数据库恢复到上一个全量恢复的时间点
2.利用二进制日志恢复到指定时间点
开启二进制日志
log-bin=mysql-binbinlog_format=ROWexpire_logs_days=10
测试实验:
mysql> alter table students add tstamp timestamp;QueryOK,0rows affected (0.92sec)Records:0Duplicates:0Warnings:0mysql> flush logs;QueryOK,0rows affected (0.30sec)mysql> insert into students(sid,sname,gender,dept_id,tstamp) values(9,'Mix',1,2,now()),(10,'Tom',0,1,now());QueryOK,2rows affected (0.09sec)Records:2Duplicates:0Warnings:0mysql> flush logs;QueryOK,0rows affected (0.24sec)mysql> insert into students(sid,sname,gender,dept_id,tstamp) values(11,'Luis',-1,2,now()),(12,'Sun',0,3,now());QueryOK,2rows affected (0.09sec)Records:2Duplicates:0Warnings:0mysql> insert into students(sid,sname,gender,dept_id,tstamp) values(13,'Martis',-1,1,now()),(14,'Oifer',1,3,now());QueryOK,2rows affected (0.07sec)Records:2Duplicates:0Warnings:0mysql> flush logs;QueryOK,0rows affected (0.24sec)mysql> select * from students;+-----+--------+--------+---------+---------------------+| sid | sname | gender | dept_id | tstamp |+-----+--------+--------+---------+---------------------+|1| abc |1|1|2018-03-0514:46:41||2|Andy|-1|1|2018-03-0514:46:41||3|Bob|-1|1|2018-03-0514:46:41||4|Ruth|-1|2|2018-03-0514:46:41||5|Mike|-1|2|2018-03-0514:46:41||6|John|0|3|2018-03-0514:46:41||7|Cindy|1|3|2018-03-0514:46:41||8|Susan|1|3|2018-03-0514:46:41||9|Mix|1|2|2018-03-0514:50:04||10|Tom|0|1|2018-03-0514:50:04||11|Luis|-1|2|2018-03-0514:51:48||12|Sun|0|3|2018-03-0514:51:48||13|Martis|-1|1|2018-03-0514:52:27||14|Oifer|1|3|2018-03-0514:52:27|+-----+--------+--------+---------+---------------------+14rows in set (0.00sec)mysql> truncate table students;QueryOK,0rows affected (0.21sec)mysql> select * from students;Emptyset (0.00sec)首先恢复students表的全量备份mysql> source backup.sql;mysql> select * from students;+-----+-------+--------+---------+---------------------+| sid | sname | gender | dept_id | tstamp |+-----+-------+--------+---------+---------------------+|1| abc |1|1|2018-03-0514:46:41||2|Andy|-1|1|2018-03-0514:46:41||3|Bob|-1|1|2018-03-0514:46:41||4|Ruth|-1|2|2018-03-0514:46:41||5|Mike|-1|2|2018-03-0514:46:41||6|John|0|3|2018-03-0514:46:41||7|Cindy|1|3|2018-03-0514:46:41||8|Susan|1|3|2018-03-0514:46:41|+-----+-------+--------+---------+---------------------+8rows in set (0.01sec)恢复某个时间点数据[root@localhost data]# mysqlbinlog mysql-bin.000002| mysql -uroot -pEnterpassword: mysql> select * from students;+-----+-------+--------+---------+---------------------+| sid | sname | gender | dept_id | tstamp |+-----+-------+--------+---------+---------------------+|1| abc |1|1|2018-03-0514:46:41||2|Andy|-1|1|2018-03-0514:46:41||3|Bob|-1|1|2018-03-0514:46:41||4|Ruth|-1|2|2018-03-0514:46:41||5|Mike|-1|2|2018-03-0514:46:41||6|John|0|3|2018-03-0514:46:41||7|Cindy|1|3|2018-03-0514:46:41||8|Susan|1|3|2018-03-0514:46:41||9|Mix|1|2|2018-03-0514:50:04||10|Tom|0|1|2018-03-0514:50:04|+-----+-------+--------+---------+---------------------+10rows in set (0.00sec)[root@localhost data]# mysqlbinlog mysql-bin.000003| mysql -uroot -pEnterpassword: mysql> select * from students;+-----+--------+--------+---------+---------------------+| sid | sname | gender | dept_id | tstamp |+-----+--------+--------+---------+---------------------+|1| abc |1|1|2018-03-0514:46:41||2|Andy|-1|1|2018-03-0514:46:41||3|Bob|-1|1|2018-03-0514:46:41||4|Ruth|-1|2|2018-03-0514:46:41||5|Mike|-1|2|2018-03-0514:46:41||6|John|0|3|2018-03-0514:46:41||7|Cindy|1|3|2018-03-0514:46:41||8|Susan|1|3|2018-03-0514:46:41||9|Mix|1|2|2018-03-0514:50:04||10|Tom|0|1|2018-03-0514:50:04||11|Luis|-1|2|2018-03-0514:51:48||12|Sun|0|3|2018-03-0514:51:48||13|Martis|-1|1|2018-03-0514:52:27||14|Oifer|1|3|2018-03-0514:52:27|+-----+--------+--------+---------+---------------------+
如果恢复某个日志文件中的一部分内容,可以通过指定--start-datetime或是--stop-datetime参数来确定开始恢复和停止的时间。
mysqlbinlog --start-datetime="2018-02-05 10:23:41"/data1/mysql/data/mysql-bin.000001| mysql -uroot -pmysqlbinlog --stop-datetime="2018-03-05 15:00:00"/data1/mysql/data/mysql-bin.000001| mysql -uroot -p
六、Xtrabackup
Xtrabackup是一个对MySQL做数据备份的工具,支持在线热备份(备份时不影响数据读写)。
特点:
备份过程快、可靠
备份过程不会打断正在执行的事务
能够基于压缩等功能节约磁盘空间和流量
自动实现备份检验
还原速度快
[root@localhost ~]# wget https://www.percona.com/downloads/XtraBackup/Percona-XtraBackup-2.4.9/binary/tarball/percona-xtrabackup-2.4.9-Linux-x86_64.tar.gz[root@localhost ~]# tar -zxvf percona-xtrabackup-2.4.9-Linux-x86_64.tar.gz[root@localhost ~]# cp percona-xtrabackup-2.4.9-Linux-x86_64/bin/* /usr/bin/全量备份[root@localhost data1]# mkdir backup[root@localhost backup]# xtrabackup --backup --target-dir=/data1/backup/ -uroot -p'MY@)!&sql2017' -P3306 --host=127.0.0.1.........xtrabackup: Transactionlogof lsn (11460068) to (11460077) was copied.18030515:14:34completed OK!恢复[root@localhost mysql]# mv data data_bak[root@localhost mysql]# lsdata_bak[root@localhost mysql]# mkdir data[root@localhost mysql]# chown -R mysql:mysql data首先执行prepare,将所有的数据文件都准备到同一时间点,因为在备份过程中所有数据文件都在不同的时间点,如果直接恢复会导致冲突[root@localhost mysql]# xtrabackup --prepare --target-dir=/data1/backup/.........InnoDB: Shutdown completed;logsequence number1146147918030515:16:48completed OK!全量恢复[root@localhost mysql]# xtrabackup --copy-back --target-dir=/data1/backup/ --datadir=/data1/mysql/data.........18030515:20:17[01] Copying ./test1/app01.ibd to /data1/mysql/data/test1/app01.ibd18030515:20:17[01] ...done18030515:20:17completed OK![root@localhost mysql]# chown -R mysql:mysql data
增量备份[root@localhost backup]# mkdir base[root@localhost backup]# chown -R mysql:mysql base[root@localhost backup]# xtrabackup --backup --traget-dir=/data1/backup/base -uroot -p'MY@)!&sql2017' -P3306 --host=127.0.0.1mysql> insert into studentsvalues(15,'aa',1,1,now());Query OK,1row affected (0.07sec)mysql> insert into studentsvalues(16,'bb',1,2,now());Query OK,1row affected (0.09 sec)[root@localhost ~]# xtrabackup --backup --target-dir=/data1/backup/inc1 --incremental-basedir=/data1/backup/base -uroot -p'MY@)!&sql2017' -P3306 --host=127.0.0.1mysql> insert into studentsvalues(17,'cc',0,3,now());Query OK,1row affected (0.19sec)mysql> insert into studentsvalues(18,'dd',-1,3,now());Query OK,1row affected (0.22sec)[root@localhost ~]# mkdir -p /data1/backup/inc2[root@localhost ~]# chown -R mysql:mysql /data1/backup/inc2[root@localhost ~]# xtrabackup --backup --target-dir=/data1/backup/inc2 --incremental-basedir=/data1/backup/inc1 -uroot -p'MY@)!&sql2017' -P3306 --host=127.0.0.1增量恢复[root@localhost mysql]# xtrabackup --prepare --apply=log-only --target-dir=/data1/backup/base --datadir=/data1/mysql/data[root@localhost mysql]# xtrabackup --prepare --apply-log-only --target-dir=/data1/backup/base --incremental-datadir=/data1/backup/inc1 --datadir=/data1/mysql/data[root@localhost mysql]# xtrabackup --prepare --target-dir=/data1/backup/base --incremental-datadir=/data1/backup/inc2 --datadir=/data1/mysql/data[root@localhost mysql]# xtrabackup --copy-back --target-dir=/data1/backup/base/ --datadir=/data1/mysql/datamysql>select* from students;+-----+--------+--------+---------+---------------------+| sid | sname | gender | dept_id | tstamp |+-----+--------+--------+---------+---------------------+|1| abc |1|1|2018-03-0514:46:41||2| Andy | -1|1|2018-03-0514:46:41||3| Bob | -1|1|2018-03-0514:46:41||4| Ruth | -1|2|2018-03-0514:46:41||5| Mike | -1|2|2018-03-0514:46:41||6| John |0|3|2018-03-0514:46:41||7| Cindy |1|3|2018-03-0514:46:41||8| Susan |1|3|2018-03-0514:46:41||9| Mix |1|2|2018-03-0514:50:04||10| Tom |0|1|2018-03-0514:50:04||11| Luis | -1|2|2018-03-0514:51:48||12| Sun |0|3|2018-03-0514:51:48||13| Martis | -1|1|2018-03-0514:52:27||14| Oifer |1|3|2018-03-0514:52:27||15| aa |1|1|2018-03-0515:34:55||16| bb |1|2|2018-03-0515:35:55||17| cc |0|3|2018-03-0515:42:14||18| dd | -1|3|2018-03-0515:42:23|+-----+--------+--------+---------+---------------------+18rows in set (0.00sec)
1.利用mysqldump实现从逻辑角度完全备份mysql,配合二进制日志备份实现增量备份
2.利用lvs快照从物理角度实现几乎热备的完全备份,配合二进制日志备份实现增量备份
3.利用percona公司的xrabackup实现完全热备份与增量热备份
实验环境:RHEL5.8 ,SElinux关闭,MySQL是tar包初始化安装版本5.5.28
一.测试环境准备
1.1 mysql的安装就不说了,见http://laoguang.blog.51cto.com/6013350/1039208
1.2 编缉/etc/my.cnf把二进制日志存放目录改到其它非数据目录,innodb每表一文件
建立一目录用于存放二进制日志
mkdir /mybinlog
chown mysql:mysql /mybinlog
修改my.cnf
vim /etc/my.cnf
log-bin=/mybinlog/mysql-bin ##二进制日志目录及文件名前缀
innodb_file_per_table=1##启用InnoDB表每表一文件,默认所有库使用一个表空间
启动mysqld
service mysqld start
1.3 创建一个测试库与测试表
mysql>create database laoguang;
mysql>use laoguang;
mysql>create table linux (id tinyint auto_increment primary key,name char(10));
mysql>insert into linux (name) values ('apache'),('nginx'),('php');
1.4 创建用于存放备份的目录
mkdir /myback
chown -R mysql:mysql /myback
二,用mysqldump实现备份
2.1 mysqldump用来温备,所以我们得为所有库加读锁,并且滚动一下二进制日志,并记录当前二进制文件位置
mysqldump --all-databases --lock-all-tables --routines --triggers--master-data=2\
--flush-logs>/myback/2012-12-3.19-23.full.sql
--all-databases 备份所有库
--lock-all-tables 为所有表加读锁
--routines 存储过程与函数
--triggers 触发器
--master-data=2在备份文件中记录当前二进制日志的位置,并且为注释的,1是不注释掉在主从复制中才有意义
--flush-logs 日志滚动一次
查看有没有备份成功,有没有启用新二进制的日志,查看备份的文件中有没有记录完整备份后二进制的位置
备份二进制日志
cp /mybinlog/mysql-bin.000001 /myback/2012-12-3.19-23.full.00001
2.2 模拟数据库意外损坏,测试完整恢复
rm -rf /data/mydata/*
rm -rf
/mybinlog/*
初始化mysql并启动mysql
cd /usr/local/mysql
./scripts/mysql_install_db--user=mysql--datadir=/data/mydata
rm -rf /mybinlog/* ##因为我们不是全新初始化的,可能会有报错的二进制日志,我们不需要
service mysqld start ##启动时会重新生成新的二进制日志的
恢复到备份状态,备份前先关闭对恢复过程的二进制日志记录,因为记录恢复语句是毫无意义的
mysql>set globalsql_log_bin=0;
mysql
打开记录并查看恢复状况
mysql>set globalsql_log_bin=1;
mysql>show databases;
打开二进制记录并查看恢复状况
mysql>set globalsql_log_bin=1;
mysql>show databases;
2.3 模拟一种场景,我往linux表中新添加了数据,然后不小心将这个表删了,我们要恢复到删除之前的状态,并且新加的数据还存在。
2.3.1 新增数据
mysql>use laoguang;
mysql>insert into linux (name) values ('haddop'), ('mysql');
mysql>drop table linux;
mysql>show master status; ##查看当前所在二进制日志中的位置
+------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000001 | 9005 | | |
+------------------+----------+--------------+------------------+
我们先恢复完整数据,再恢复完整备份后到删除之前的数据,对应二进制日志就是完整备份后的二进制日志位置到删除表之前的位置
2.3.2 先恢复完整备份,同样恢复过程不要记录日志
mysql>set globalsql_log_bin=0;
mysql
2.3.3 查看删除表时的记录位置
mysqlbinlog /mybinlog/mysql-bin.000001
# at 8893
#121202 14:14:07 server id 1 end_log_pos 9005 Querythread_id=5exec_time=0error_code=0
SETTIMESTAMP=1354428847/*!*/;
DROP TABLE `linux` /* generated by server */
/*!*/;
DELIMITER ;
# End of log file
2.3.4 由上图可知删除是在8893时做的,将二进制文件中完整备份到删除表之前的记录导出
mysqlbinlog--stop-position=8893/mybinlog/mysql-bin.000001>/tmp/change.sql
--start-position 指定从哪开始导出二进制日志
--stop-position 指定到哪结束
--start-datetime 从哪个时间开始格式如"2005-12-25 11:25:56"
--stop-datetime 到哪个时间结束
由于这个二进制日志是我们完整恢复后才启用的,所以我们直接从头开始即可,如果你的二进制日志很多,请查看完整备份中记录的备份时的位置,从那开始到删除之前即可
将这段二进制记录应用到mysql的库中
mysql
进入数据库查看数据有没有恢复
mysql>select * from linux;
基于mysqldump通常我们就是完整备份+二进制日志来进行恢复的。
三,利用lvm的快照来备份MySQL
要求你的MySQL的数据目录必须在lvm卷上,下面来演示过程
3.1 建立lvm卷组,挂载到/data/mydata下,这个我就不演示了
3.2 初始化MySQL时将数据目录指向/data/mydata,安装过程见上链接
3.3 同样如第一步那样准备环境
3.4 在MySQL中为所有表加读锁,不要关闭终端,否则锁将失效,滚动日志
mysql>flush tables with read lock;
mysql>flush logs;
mysql>show master status;
+------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000002 | 107 | | |
+------------------+----------+--------------+------------------+
3.5 另开一终端速度建立快照,我的那个卷组是/dev/myvg/mydata
lvcreate -L 200M -n mysql-snap -s -p r /dev/myvg/mydata
3.4 速度释放读锁
mysql>unlock tables;
3.5 挂载快照,拷备出来,卸载快照,删除快照
mount /dev/myvg/mysql-snap /mnt
mkdir /myback/lvm
cp -pR /mnt/* /myback/lvm
umount /mnt
lvremove /dev/myvg/mysql-snap
3.6 就这样一次完整备份就完成了,下面来测试能否正常使用
servivce mysqld stop
rm -R /data/mydata/*
cp -Rp /myback/lvm/* /data/mydata
service mysqld start ##如果能正常启动代表没有问题,起不来请看数据目录权限
3.7 如果在完整备份后MySQL出现故障,与mysqldump一样,先恢复上次的完整备份,再利用二进制日志恢复,二进制恢复再啰嗦一遍,找到完整备份时的二进制位置,把从那时到故障前的日志用mysqlbinlog导出来,然后批处理方式导入到MySQL中。这个同mysqldump中实验一致就不重复了。
用lvm的快照来备份速度是非常快的,而且几乎热备,恢复也很快速,操作也简单,完整恢复后再将相应二进制恢复即可。
四:基于xtrabackup来完全备份,增量备份,热备份MySQL
下载地址:http://www.percona.com/software/percona-xtrabackup
4.1 下载安装xtrabackup,我用的是percona-xtrabackup-2.0.3-470.rhel5.i386.rpm
yum install perl-DBD-MySQL
rpm -ivh percona-xtrabackup-2.0.3-470.rhel5.i386.rpm
4.2 MySQL基本环境与第一步的一致
4.3 为备份建立一个只有备份权限的用户
mysql>create user 'percona'@'localhost' identified by 'redhat';
mysql>revoke all privileges,grant option from 'percona'@'localhost';
mysql>grant reload,lock tables,replication client on *.* to 'percona'@'localhost';
mysql>flush privileges;
4.4 完整备份一次MySQL
innobackupex--host=locahost --user=percona --password=redhat --defaults-file=/usr/local/mysql/my.cnf /myback/
数据会完整备份到/myback/中目录名字为当前的日期,extrabackup会备份所有的InnoDB表,MyISAM表只是复制表结构文件、以及MyISAM、MERGE、CSV和ARCHIVE表的相关文件,同时还会备份触发器和数据库配置信息相关的文件。除了保存数据外还生成了一些extrabackup需要的数据文件
1)xtrabackup_checkpoints 备份类型(如完全或增量)、备份状态(如是否已经为prepared状态)和LSN(日志序列号)范围信息;每个InnoDB页(通常为16k大小)都会包含一个日志序列号,即LSN。LSN是整个数据库系统的系统版本号,每个页面相关的LSN能够表明此页面最近是如何发生改变的。
2)xtrabackup_binlog_info mysql服务器当前正在使用的二进制日志文件及至备份这一刻为止二进制日志事件的位置。
3)xtrabackup_binlog_pos_innodb 二进制日志文件及用于InnoDB或XtraDB表的二进制日志文件的当前position。
4)xtrabackup_binary 备份中用到的xtrabackup的可执行文件;
5)backup-my.cnf 备份命令用到的配置选项信息;
4.4 测试恢复MySQL,用extrabackup来完整恢复
service mysqld stop
rm -Rf /data/mydata
innobackupex --apply-log /myback/2012-12-02_20-06-12/
--apply-log 的意义在于把备份时没commit的事务撤销,已经commit的但还在事务日志中的应用到数据库
innobackupex --copy-back /myback/2012-12-02_20-06-12/
--copy-back数据库恢复,后面跟上备份目录的位置
chown -R mysql:mysql /data/mydata
service mysqld start ##如果能启动代表恢复正常
4.5 我们来实验一下增量备份
4.5.1 在表中新增一些数据
mysql>insert into linux (name) values ('tomcat'), ('memcache'), ('varnish');
4.5.2 增量备份
innobackupex--user=percona--password=redhat--incremental \
--incremental-basedir=/myback/2012-12-02_20-06-12/ /myback/
--incremental 指定是增量备份
--incremental-basedir 指定基于哪个备份做增量备份,最后是增量备份保存的目录
增量备份只能对InnoDB引擎做增量备份,对MyISAM的表是完全复制
4.6 测试增量备份恢复
service mysqld stop
rm -Rf /data/mydata/*
innobackupex --apply-log --redo-only /myback/2012-12-02_20-06-12/
--redo-only 指的是把备份时commit的但还在事务日志中的应用到时数据,但是还没提交的不撤消,
因为这个事务可能在增量备份中提交,假如的撤消了增量备份中就提交不,因为事务已经不完整
将增量备份全并到完整备份中去
innobackupex --apply-log /myback/2012-12-02_20-06-12/ \
--incremental-dir=/myback/2012-12-02_20-28-49/
/myback/2012-12-02_20-06-12/ 这个是完整备份的目录
--incremental-dir 后跟的是增量备份的目录
这个会使增量备份中的的数据合并到完整备份中,如果还有增量备份,继续合并,恢复时恢复完整备份即可
恢复数据,并起动MySQL
innobackupex --copy-back /myback/2012-12-02_20-06-12/
chown -R mysql:mysql /data/mydata
service mysqld start