MySQL 备份与恢复

一、逻辑备份和恢复
确定要备份的表的存储引擎是事务型还是非事务性,两种不同的存储引擎备份方式在处理数据一致性方面是不太一样的。
在MySQL 里面,逻辑备份的最大优点是对于各种存储引擎,都可以用同样的方法来备份;而物理备份则不同,不同的存储引擎有着不同的备份方法。
在MySQL 中,使用mysqldump 工具来完成逻辑备份。有以下3 种方法来调用mysqldump:
[root@CentOS 3306]# mysqldump -help
Usage: mysqldump [OPTIONS] database [tables]        ##备份指定的数据库,或者此数据库中某些表。
OR     mysqldump [OPTIONS] --databases [OPTIONS] DB1 [DB2 DB3...]   ##备份指定的一个或多个数据库。
OR     mysqldump [OPTIONS] --all-databases [OPTIONS]   ##备份所有数据库。
For more options, use mysqldump --help

以下给出一些使用mysqldump 工具进行备份的例子。
(1)备份所有数据库:mysqldump -uroot -p --all-database > all.sql
(2)备份数据库test:mysqldump -uroot -p test > test.sql
(3)备份数据库test 下的表emp:mysqldump -uroot -p test emp > emp.sql
(4)备份数据库test 下的表emp 和dept:mysqldump -uroot -p test emp dept > emp_dept.sql
(5)备份数据库test 下的emp表为逗号分割的文本,备份到/tmp:mysqldump -uroot -T /tmp test emp --fields-terminated-by ','
     # mysqldump -uroot  -h 127.0.0.1 -P3306 -T /tmp test t2 --fields-terminated-by ','

需要强调的是,为了保证数据备份的一致性,MyISAM 存储引擎在备份的时候需要加上-l 参数,表示将所有表加上读锁,在备份期间,所有表将只能读而不能进行数据更新。但是对于事务存储引擎(InnoDB 和BDB)来说,可以采用更好的选项--single-transaction,此选项将使得InnoDB 存储引擎得到一个快照(Snapshot),使得备份的数据能够保证一致性。

##完全恢复
(1)上午9 点,备份数据库:mysqldump -uroot –p –l –F test >test.dmp
     ##其中-l 参数表示给所有表加读锁,-F 表示生成一个新的日志文件。
     # mysqldump -uroot -h 127.0.0.1 -P3306 -l -F test >test.dmp
(2)9 点半备份完毕,然后,插入新的数据:insert into t2 values(5,'z5');
(3)10 点,数据库突然故障,数据无法访问。需要恢复备份:mysql -uroot -p test < test.dmp
     # mysql -uroot -h 127.0.0.1 -P3306 test < test.dmp
(4)使用mysqlbinlog 恢复自mysqldump 备份以来的BINLOG。
     # mysqlbinlog mysql_redo.000002 | mysql -uroot -h 127.0.0.1 -P3306 test

##基于时间点恢复
(1)如果上午10 点发生了误操作,可以用以下语句用备份和BINLOG 将数据恢复到故障前:
mysqlbinlog --stop-datetime="2005-04-20 9:59:59" mysql_redo.000001 | mysql -uroot -h 127.0.0.1 -P3306 test
(2)跳过故障时的时间点,继续执行后面的BINLOG,完成恢复。
mysqlbinlog --start-datetime="2005-04-20 10:01:00" mysql_redo.000001 | mysql -uroot -h 127.0.0.1 -P3306 test

##基于位置恢复
(1)在shell 下执行如下命令:
mysqlbinlog --start-datetime="2015-12-03 00:45:53" --stop-datetime="2015-12-03 00:46:16" mysql_redo.000001 > mysql_restore.sql
[root@CentOS 3306]# vi mysql_restore.sql
# at 867       <<<--------------------- 位置号
#151203  0:53:05 server id 1  end_log_pos 946 CRC32 0x1e3c1821  Query   thread_id=2     exec_time=0     error_code=0
SET TIMESTAMP=1449075185/*!*/;
BEGIN
/*!*/;
# at 946       <<<--------------------- 位置号
#151203  0:53:05 server id 1  end_log_pos 1033 CRC32 0xd95d264e         Query   thread_id=2     exec_time=0     error_code=0
SET TIMESTAMP=1449075185/*!*/;
delete from t
/*!*/;
# at 1033      <<<--------------------- 位置号
#151203  0:53:05 server id 1  end_log_pos 1064 CRC32 0x0ab01cc0         Xid = 1492
COMMIT/*!*/;
##该命令将在目录创建小的文本文件,编辑此文件,找到出错语句前后的位置号,例如前后位置号分别是867和1033。
(2)恢复了以前的备份文件后,应从命令行输入下面内容:
mysqlbinlog --stop-position="867" mysql_redo.000001 | mysql -uroot -h 127.0.0.1 -P3306 test
mysqlbinlog --start-position="1033" mysql_redo.000001 | mysql -uroot -h 127.0.0.1 -P3306 test

二、物理备份和恢复
##冷备份
进行备份的操作如下:停掉MySQL 服务,在操作系统级别备份MySQL 的数据文件和日志文件到备份目录。
进行恢复的操作如下:首先停掉MySQL 服务,在操作系统级别恢复MySQL 的数据文件;然后重启MySQL 服务,使用mysqlbinlog 工具恢复自备份以来的所有BINLOG。

##热备份
MySQL 中,对于不同的存储引擎热备份方法也有所不同,下面主要介绍MyISAM 和InnoDB两种最常用的存储引擎的热备份方法。

##MyISAM 存储引擎热备份
MyISAM 存储引擎的热备份有很多方法,本质其实就是将要备份的表加读锁,然后再cp 数据文件到备份目录。
方法1:使用mysqlhotcopy 工具
mysqlhotcopy 是MySQL 自带的一个热备份工具,使用方法很简单:mysqlhotcopy db_name [/path/to/new_directory]
方法2:手工锁表copy
在mysqlhotcopy 使用不正常的情况下,可以手工来做热备份,操作步骤如下:
首先数据库中所有表加读锁:flush tables for read ;
然后cp 数据文件到备份目录即可。

##InnoDB 存储引擎热备份
ibbackup 是Innobase 公司(www.innodb.com)的一个热备份工具,专门对InnoDB 存储引擎进行物理热备份,此工具是收费的,但可以免费使用1 个月。Innobase 公司已经于2005 年被Oracle 公司所收购。
Xtrabackup是Percona公司开发的一款基于InnoDB的在线热备工具,具有开源、免费、支持在线热备、备份恢复速度快、占用磁盘空间小等热点。

三、表的导入导出
1、导出
在某些情况下,为了一些特定的目的,经常需要将表里的数据导出为某些符号分割的纯数据文本,而不是SQL 语句。
方法1:使用SELECT ...INTO OUTFILE ...命令来导出数据,具体语法如下。
mysql> SELECT * FROM tablename INTO OUTFILE 'target_file' [option];
其中option 参数可以是以下选项:
FIELDS TERMINATED BY 'string' (字段分隔符,默认为制表符’\t’);
FIELDS [OPTIONALLY] ENCLOSED BY 'char'(字段引用符,如果加OPTIONALLY 选项则只用在char、varchar 和text 等字符型字段上。默认不使用引用符);
FIELDS ESCAPED BY 'char' (转义字符,默认为’\’);
LINES STARTING BY 'string' (每行前都加此字符串,默认'');
LINES TERMINATED BY 'string'(行结束符,默认为’\n’);
其中char 表示此符号只能是单个字符,string 表示可以是字符串。

例子:
mysql> select * from t into outfile '/tmp/t.txt' FIELDS TERMINATED BY '|';
[root@CentOS tmp]# cat t.txt 
1|a
2|b
3|c
4|d
5|d
6|d

方法2:用mysqldump 导出数据为文本。
mysqldump –u username –T target_dir dbname tablename [option]
其中option 参数可以是以下选项:
? --fields-terminated-by=name(字段分隔符);
? --fields-enclosed-by=name(字段引用符);
? --fields-optionally-enclosed-by=name(字段引用符,只用在char、varchar 和text 等字符型字段上);
? --fields-escaped-by=name(转义字符);
? --lines-terminated-by=name(记录结束符)。

例子:
# mysqldump -uroot -h 127.0.0.1 -P3306 -T /tmp test t --fields-terminated-by ','
除了生成数据文件t.txt 之外,还生成一个t.sql 文件,里面记录了t 表的创建脚本

2、导入
方法1:使用“LOAD DATA INFILE…”命令。
mysql > LOAD DATA [LOCAL] INFILE ‘filename’ INTO TABLE tablename [option]
##LOAD DATA 默认读的是服务器上的文件,但是加上LOCAL 参数后,就可以将本地具有访问权限的文件加载到数据库中。
##可以用--local-infile=0 选项启动mysqld 从服务器端禁用所有LOAD DATA LOCAL命令。
option 可以是以下选项:
? FIELDS TERMINATED BY 'string'(字段分隔符,默认为制表符'\t');
? FIELDS [OPTIONALLY] ENCLOSED BY 'char'(字段引用符,如果加OPTIONALLY 选项则只用在char、varchar 和text 等字符型字段上。默认不使用引用符);
? FIELDS ESCAPED BY 'char'(转义字符,默认为'\');
? LINES STARTING BY 'string'(每行前都加此字符串,默认'');
? LINES TERMINATED BY 'string'(行结束符,默认为'\n');
? IGNORE number LINES(忽略输入文件中的前n 行数据);
? (col_name_or_user_var,...) (按照列出的字段顺序和字段数量加载数据);
? SET col_name = expr,... 将列做一定的数值转换后再加载。
其中char 表示此符号只能是单个字符,string 表示可以是字符串。

例子:
mysql> load data infile '/tmp/t.txt' into table t fields terminated by '|';
mysql> load data infile '/tmp/t.txt' into table t fields terminated by '|' set id=id+100;

方法2:用mysqlimport 来实现,具体命令如下。
shell>mysqlimport –u root –p*** [--LOCAL] dbname order_tab.txt [option]
其中option 参数可以是以下选项:
? --fields-terminated-by=name(字段分隔符);
? --fields-enclosed-by=name(字段引用符);
? --fields-optionally-enclosed-by=name(字段引用符,只用在char、varchar 和text 等字符型字段上);
? --fields-escaped-by=name(转义字符);
? --lines-terminated-by=name(记录结束符);
? -- ignore-lines=number(或略前几行)

例子:
# mysql -uroot -h 127.0.0.1 -P3306 test < t.sql
# mysqlimport -uroot -h 127.0.0.1 -P3306 test /tmp/t.txt --fields-terminated-by ','

你可能感兴趣的:(MySQL 备份与恢复)