准备环境:
Mysql 安装在 lv01上,后续我们使用lvm快照卷对其进行恢复
Mysql的二进制文件在/bakup/bin_log下以及另外一个远程主机
默认使用InnoDB存储引擎,使用单表单文件
在my.cnf添加或者修改如下行
1
2
3
4
|
[mysqld]
default_storage_engine = INNODB
innodb_file_per_table = 1
log-bin= /backup/bin_log/mysql-bin
|
我们默认有一个数据库叫hellodb,里面存放着各路种江湖豪杰的数据
我们再介绍一些命令
Mysqlbinlog 可以查看mysql的二进制文件,二进制文件里面记录了mysql数据库创建新型,各种增删改查等有效信息,里面还有偏移量信息记录当前位置
SET TIMESTAMP=1378552435/*!*/;
insert into help_relation(help_topic_id,help_keyword_id) values (471,466)
/*!*/;
# at 1061269
#130907 19:13:55 server id 1end_log_pos 1061339Querythread_id=1exec_time=0error_code=0
end_log_position 记录了当前的偏移量,很大一部分依靠二进制进行恢复的工作都靠。
使用重定向可以备份文件到其他位置,里面缺少不了的参数有如下几个
--start-position= 定义起始偏移量
--stop-position= 定义结束偏移量
1
|
mysqlbinlog --start-position=1061131 --stop-position=1061339 > /tmp/a .sql
|
这样子,我们就把偏移量起始位置为1061131结束位置1061339的二进制文件复制到其他地方了
使用mysqldump进行备份
进行备份之前,先要弄明白一件事情,如果备份当时还有人在往数据库中写数据,当你备份第一张表时是第一时刻,接下来是第二张表,但是在你备份第一张表的时候第二张表就被修改过了,你却备份了,接下来完蛋了,满足不了ACID,数据不统一了。那你该怎么办,如果能在备份的时候把所有的表锁住就好了,或者启动一个大事物,这样问题就解决了。
对于InnoDB我们使用如下命令
1
|
mysqldump -uroot -pmypass --single-transaction -E --master-data=2 --all-databases > /bakup/all_db_ `
date +%F`.sql
|
这句命令对mysql所有的数据进行完全备份,当然我们还是可以使用增量或者差异备份,一下的参数或许对你来说很有用
-u 用户名
-p 密码
-h 主机
-B �Cdatabases db1db2 指定要备份的数据库,可以有多个
--single-transaction启动一个大事物
-E �Cevents 同时备份时间调度器代码
-A �Call-databases备份所有的数据库文件,
--master-data ,此选项有2个值,默认为2,但是必须得写上―master-data才表示启用,等于2是.当前使用的哪个二进制,偏移量在哪个位置,输出信息如下:
-- CHANGE MASTERTO MASTER_LOG_FILE='mysql-bin.000003', MASTER_LOG_POS=8696;
-R �Croutines 备份存储过程和存储函数
我们在hellodb 中添加一张表叫kongfu,然后再进行破坏工作,删掉/mydata/data下的所有文件以模拟故障,看还能不能恢复到以前的状态。
1
2
|
mysql> use hellodb;
mysql> create table kongfu(ID int,Name Char(20));
|
加一些数据进去,降龙十八掌和九阴真经吧
1
|
INSERT INTO kongfu VALUES (1, 'XLSBZ' ),(2, 'JYZJ' );
|
搞破坏之前,我们先看看当前的偏移量,使用命令
1
|
Mysql>show master status;
|
看到我们现在的偏移量为9015,其实这个9015对我们这次演示是是没有什么作用的,但是还是拿出来,这个命令确实很重要
查看用mysqldump备份的文件中MATER-DATA输出的信息,备份当时的偏移量是8696
于是我们用mysqlbinlog 导出
1
|
# mysqlbinlog --start-position=8696 > /bakup/bak_bin /1.sql
|
该到搞破坏的时候了,我们删除/mysql/data下的所有文件
然后恢复
首先要重新初始化mysql
恢复步骤,首先使用
mysql < /bakup/all_db_2013-09-07.sql
查看hellodb,发现没有我们以前建立的kongfu,于是我们再次使用刚刚导出的1.sql恢复,这样就能看到kongfu了.
1
|
[root@dns1 bak_bin] # mysql < 1.sql mysql < /bakup/bak_bin/1.sql
|
我们再次检查查看kongfu 已经在里面了,我们成功了
使用LVM进行备份
LVM 使用逻辑卷的snapshot进行物理备份,snapshot常用的技术为copy onwirte,原始数据发生改变时才写数据到快照里面,这样可以使得创建快照卷十分快速,当误删数据库的时候,snapshot所创建的快照卷其实已经保存了你创建的信息,所以我们就不用担心数据的丢失了。
为了保证任何事物提交都能立刻保存在存储引擎中,我们增加参数,让每次提交事物立刻同步到二进制文件中,在/etc/my.cnf的[mysqld]添加如下
1
|
sync_binlog = 1
|
创建快照卷之前一定要锁住所有的表,不要让用户往数据库里面去写信息,我们使用如下命令
1
|
mysql> FLUSH TABLES WITH READ LOCK;
|
这个过程可能需要很久,因为当前数据中可能还有未提交的事物,等待用户提交后这条命令才可以执行成功
执行成功立即创建逻辑卷,我这里只给力1G,你可以更具情况来大点,
1
|
lvcreate -L 1G -s -p r -n mybak /dev/vg01/lv01
|
挂载到/mydata/snap下,看到和/mydata/data下同样的内容
1
|
mount /dev/vg01/mybak /mydata/snap/
|
创建快照卷后挂载就可以看到和当前数据一样的一组数据了
记得要释放所有锁
1
|
mysql> UNLOCK TABLES;
|
我们加一些数据进去,在kongfu里面添加打狗棒法和蛤蟆功吧
1
|
mysql> INSERT INTO kongfu VALUES (3, 'DGBF' ),(4, 'HMG' );
|
按照上面方法,我们备份新增的二进制文件
1
|
mysqlbinlog --start-position=390 mysql-bin.000014 > .. /bak_bin/2 .sql
|
我们再次制造灾难
[root@dns1 data]# rm -rf *
删除了/mydata/data下所有的数据
OK,别急,我们来恢复,我们将保存在snapshot里面的数据复制回来,别忘了修改权限
1
2
|
[root@dns1 snap] # cp -R ../snap/* ../data/
[root@dns1 mydata] # chown -R mysql:mysql data/
|
启动mysql 查看kongfu表,发现没有 ID=3 和ID=4的数据
使用刚才备份的2.sql恢复
1
|
[root@dns1 bak_bin] # mysql <2.sql
|
这样子就看到了新增的3和4了
总体来说 LVM是一个不错的选择,对于没有足够资金去购买专业备份工具中小企业是个不错的选择
Xtrabackup
Xtrabakckup是percona提供给我们的专业的备份工具,功能异常强大,支持增量备份(不用手都去备份啦)
我们去安装xtrabackup
首先我们需要安装两个与其相关的开发包
1
2
3
|
yum
install perl-Time-HiRes
yum
install perl-DBD-MySQL
rpm -ivh percona-xtrabackup-2.1.4-656.rhel6.x86_64.rpm
|
安装好就直接可以使用了
我们给一个最小权限创建备份
1
2
3
4
|
mysql> CREATE USER
'bkuser' @ 'localhost' IDENTIFIED BY 'mypass' ;
mysql> REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'bkuser' @ 'localhost' ;
GRANT RELOAD ,LOCK TABLES, REPLICATION CLIENT ON *.* TO 'bkuser' @ 'localhost' ;
mysql> FLUSH PRIVILEGES;
|
xtrabackup使用innobackupex命令来备份,我们来解释一些参数
我们对当前数据进行一个完全备份
1
|
# innobackupex --user=bkuser --password=mypass /bakup/
|
这样我们一次完全备份就完成了,但是我们得想一个问题,备份当时如果还有没有提交的事物,事物已经提交了,但是没有写入磁盘的数据怎么办
因此我们需要做一些“准备“工作
如果想进行完全备份,让已提交但是为写入磁盘的事物写入磁盘。
1
|
innobackupex --user=bkuser --password=mypass --apply-log --redo-only /bakup/2013-09-08_12-29-33/
|
我们在kongfu里面添加以种功夫,ID=6的功夫叫
1
|
mysql> INSERT INTO kongfu VALUES (6, 'ZQ' )
|
我们进行增量备份,
1
|
innobackupex --user=bkuser --password=mypass --incremental /bakup/
--incremental-basedir= /bakup/2013-09-08_12-29-33/
|
使用―incremental 选项说明这是一次增量备份,--incremental-basedir说明这是基于那一次进行增量备份
我们来做”准备”工作
1
|
innobackupex --user=bkuser --password=mypass --apply-log --redo-only /bakup/2013-09-08_12-29-33/
--incremental- dir = /bakup/2013-09-08_12-33-43/
|
这样子我们就把第一次做完全备份未提交的事物在第一次增量备份中写到磁盘中了,以后也是这样的思路,而最后一次的未提交的事物则依靠INNODB存储引擎来实现,事物的回滚。
备份好了,我们搞破坏,然后修复它。
记住删除之后不要初始化,使用下面的命令恢复
1
|
# innobackupex --copy-back /bakup/2013-09-08_12-29-33/
|
这样子就恢复到上次做增量备份的位置了,然后在使用二进制文件恢复上次增量备份到现在的文件,我们在/bakup/2013-09-08_12-29-33/中可以查看
cat xtrabackup_binlog_info
mysql-bin.0000151734
然后我们在使用mysqlbinlog对二进制进行备份,恢复就可以得到原先的数据了。
总结,这三个工具都是最常用的备份工具,其中xtrabackup是最快的,mysqldump使用的最多,对于开源节流的企业LVM也是不错的选择。
本文出自 “思博系统” 博客http://sysbo.blog.51cto.com/823152/1291889