Linux下mysql服务器的备份与还原

一,基于LVM的mysql数据库物理备份与还原:

这种情况要求,我们的msyql数据库必须安装在逻辑卷上。一下方法可以实现几乎热备份(之所以这么说是因为当我们创建快照的时候不能往数据库中写数据),要通过LVM的快照来实现。

1,完全备份

进入数据库对所有表施加读锁,此时数据库中的数据只能读不能写。

mysql> flush tables with read lock;

我们通过滚动日志的方式(即再创建一个新的二进制日志)来实现即时点恢复:

mysql> flush logs;

查看当前二进制日志的名字和position,以便实现即时点恢复:

mysql> show master status;

+------------------+----------+--------------+------------------+

| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |

+------------------+----------+--------------+------------------+

| mysql-bin.000005 |      107 |              |                  |

+------------------+----------+--------------+------------------+

mysql>\q

我们的mysql数据文件存放在/dev/myvg/lv_mydata这个逻辑卷上,我们要创建这个逻辑卷的快照,以便备份。执行这个步骤的时候不能有写操作,这就是我们在数据库中加读锁的原因:

#lvcreate �CL 100M �Cn data-snap �Cs �Cp r /dev/myvg/lv_mydata 

进入mysql数据库对解锁,我们的数据库可以正常被访问了(而在此之后影响数据库的所有操作都将被记录进二进制日志中,所有:完全备份+二进制日志=我们所有的数据):

mysql>unlock tables;

如下操作备份数据库:

#mkdir /snap

#mount /dev/myvg/data-snap /snap

#tar jcf /tmp/all_data-`date +%F-%H-%M-%S`.tar.bz2 /snap/

这就生成了我们的备份文件:all_data-2012-03-18-09-39-06.tar.bz2

#umount /snap

#rm -rf /snap

#lvremove /dev/myvg/data-snap

好了,我们的数据库文件备份成功了。

1,备份还原

当数据库产生故障,我们可以用如下方法把备份还原。

为了模拟故障,我删除了一个数据库。

mysql< drop database jiaowu;

我们可以通过以上的备份进行恢复:

对完整备份的还原必须停止mysql服务器:

#service mysqld stop

把我们备份时新建的二进制日志文件复制走,我们需要用其进行即时点恢复:

#cp /mydata/data/mysql-bin.000005 /tmp

#cd /tmp

#tar xf all_data-2012-03-18-09-39-06.tar.bz2 

把我们的原数据库文件移走:

#mv /mydata/data /mydata/data.bak

把我们备份的数据库放在/mydata目录:

#mv snap/data /mydata

如果属组属主改变,则更改属主属组为mysql:

#cd /mydata

#chown mysql:mysql /mydata/data

#chown mysql:mysql /mydata/data/*

重启服务,我们的完全备份以恢复:

#service mysqld start

即使点的恢复:

#mysqlbinlog /tmp/mysql-bin.000005

如下所示,最后显示的为:

# at 97404

#120318 10:07:13 server id 1  end_log_pos 97489 Query thread_id=454 exec_time=0 error_code=0

SET TIMESTAMP=1332036433/*!*/;

drop database jiaowu

/*!*/;

# at 97489

#120318 10:07:36 server id 1  end_log_pos 97508 Stop

DELIMITER ;

# End of log file

ROLLBACK /* added by mysqlbinlog */;

/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;

因为到97404这个点以后我做的是删除数据库jiaowu操作,也就是我自己模拟的故障,不能让其恢复,故要定义终止点97404:

#mysqlbinlog -�Cstop-position=97404 /tmp/mysql-bin.000005 > /tmp/jiaowu.sql

先临时关闭二进制文件,避免下面执行的恢复即时点操作被记录进二进制日志:

mysql> set sql_log_bin=0;

加载这个文件,使恢复到即时点:

mysql> source /tmp/jiaowu.sql

二,使用Xtrabackup进行MySQL备份

一、安装

1、简介

Xtrabackup是由percona提供的mysql数据库备份工具,据官方介绍,这也是世界上惟一一款开源的能够对innodb和xtradb数据库进行热备的工具。特点:

(1)备份过程快速、可靠;

(2)备份过程不会打断正在执行的事务;

(3)能够基于压缩等功能节约磁盘空间和流量;

(4)自动实现备份检验;

(5)还原速度快;

2、安装

其最新版的软件可从 http://www.percona.com/software/percona-xtrabackup/ 获得。本文基于RHEL5.4的系统,因此,直接下载相应版本的rpm包安装即可,这里不再演示其过程。

二、完全备份的实现及恢复

1、完全备份

我们首先建立一个目录,用于存放备份的数据:

#mkdir /backup

完全备份:

# innobackupex --user=DBUSER --password=DBUSERPASS /backup

# ls /backup (会生成一个时间戳的目录,里面就是备份的数据文件)

2012-03-18_12-51-23 

如果要使用一个最小权限的用户进行备份,则可基于如下命令创建此类用户:

mysql> CREATE USER ’bkpuser’@’localhost’ IDENTIFIED BY ’s3cret’;

mysql> REVOKE ALL PRIVILEGES, GRANT OPTION FROM ’bkpuser’;

mysql> GRANT RELOAD, LOCK TABLES, REPLICATION CLIENT ON *.* TO ’bkpuser’@’localhost’;

mysql> FLUSH PRIVILEGES;

使用innobakupex备份时,其会调用xtrabackup备份所有的InnoDB表,复制所有关于表结构定义的相关文件(.frm)、以及MyISAM、MERGE、CSV和ARCHIVE表的相关文件,同时还会备份触发器和数据库配置信息相关的文件。这些文件会被保存至一个以时间命令的目录中。

在备份的同时,innobackupex还会在备份目录中创建如下文件:

(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 ―― 备份命令用到的配置选项信息;

在使用innobackupex进行备份时,还可以使用--no-timestamp选项来阻止命令自动创建一个以时间命名的目录;如此一来,innobackupex命令将会创建一个BACKUP-DIR目录来存储备份数据。

2、如果要恢复数据,则需要准备(prepare)一个完全备份

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

innobakupex命令的--apply-log选项可用于实现上述功能。如下面的命令:

# innobackupex --apply-log /backup/2012-03-18_12-51-23

如果执行正确,其最后输出的几行信息通常和如下类似:

120318 12:52:12  innobackupex: completed OK!

在实现“准备”的过程中,innobackupex通常还可以使用--use-memory选项来指定其可以使用的内存的大小,默认通常为100M。如果有足够的内存可用,可以多划分一些内存给prepare的过程,以提高其完成速度。

3、从一个准备好的完全备份中恢复数据

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

#service mysqld stop

做即时点恢复:

#cd /backup/2012-03-18_12-51-23/

找到我们做好完全备份时的二进制日志的终止点,这个可以作为我们恢复即时点的起始点:

# cat xtrabackup_binlog_info 

mysql-bin.000001 153681

生成一个sql脚本:

#mysqlbinlog --start-position=153681 /mydata/data/mysql-bin.000001 > /tmp/data.sql

注意要想恢复,则存放数据库数据的目录必须为空,我的为/mydata/data:

# rm -rf /mydata/data/*

# innobackupex --copy-back /backup/2012-03-18_12-51-23/

如果执行正确,其输出信息的最后几行通常如下:

120318 12:39:12  innobackupex: completed OK!

请确保如上信息的最行一行出现“innobackupex: completed OK!”。

当数据恢复至DATADIR目录以后,还需要确保所有数据文件的属主和属组均为正确的用户,如mysql,否则,在启动mysqld之前还需要事先修改数据文件的属主和属组。如:

# chown -R  mysql:mysql  /mydata/data/

让服务上线:

#service mysqld start

mysql> set sql_log_bin=0;

加载这个文件,使恢复到即时点:

mysql> source /tmp/data.sql

三,使用innobackupex进行增量备份

1,先进行完全备份:

新建我们要存放备份数据的目录:

#mkdir /backup

完全备份:

# innobackupex --user=DBUSER --password=DBUSERPASS  /backup

查看生成的备份文件:

# ls /backup/

2012-03-18_12-58-31

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

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

# innobackupex --incremental /backup/ --incremental-basedir=/backup/2012-03-18_12-58-31/

查看生成的备份的文件:

# ls /backup/

2012-03-18_12-58-31  2012-03-18_13-00-00

第二次增量备份:

# innobackupex --incremental /backup/ --incremental-basedir=/backup/2012-03-18_13-00-00/  

查看生成的备份的文件:

# ls /backup/

2012-03-18_12-58-31  2012-03-18_13-00-00  2012-03-18_13-00-50

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

需要注意的是,增量备份仅能应用于InnoDB或XtraDB表,对于MyISAM表而言,执行增量备份时其实进行的是完全备份。

3,还原数据的时候,做准备工作

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

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

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

于是,操作就变成了:

# innobackupex --apply-log --redo-only /backup/2012-03-18_12-58-31/  (完全备份的目录)

redo-only的作用是:让已经提交的事物同步到数据文件中,没有提交的事物不做回滚;

接着执行:

# innobackupex --apply-log --redo-only /backup/2012-03-18_12-58-31 --incremental-dir=/backup/2012-03-18_13-00-00/

--incremental-dir指的是第一次增量备份的目录

而后是第二个增量:

# innobackupex --apply-log --redo-only /backup/2012-03-18_12-58-31 --incremental-dir=/backup/2012-03-18_13-00-50/

--incremental-dir指的是第二次增量备份的目录,其它依次类推,即如果有多次增量备份,每一次都要执行如上操作;

这些操作做完之后,就把所有增量备份中的数据合并到了完全备份的数据中了,这些增量备份的数据文件就可以删除了,恢复的时候直接恢复完全备份数据即可。

4,数据的恢复:

即时点恢复:

#cd /mydata/data

查找我们最后一次做增量备份的终止点:

# cd 2012-03-18_13-00-50/

# cat xtrabackup_binlog_info 

mysql-bin.000001 2275   (说明我们的增量备份的终止点是2275,我们做即时点恢复的时候从这个点开始就好了)

生成一个sql文件,用于即时点恢复:

#mysqlbinlog --start-position=2275 /mydata/data/mysql-bin.000001 > /tmp/data.sql

#service mysqld stop

模拟破坏

#rm -rf /mydata/data/*

从完全备份的数据文件恢复:

# innobackupex --copy-back /backup/2012-03-18_12-58-31

#chown -R mysql:mysql  /mydata/data

#service mysqld start

临时设置二进制文件关闭:

mysql> set sql_log_bin=0;

加载这个文件,使恢复到即时点:

mysql> source /tmp/data.sql

你可能感兴趣的:(数据库,服务器,tables)