您的位置:首页 > 数据库 > MySQL

mysql备份与恢复方法总结与比较

2012-08-28 12:07 507 查看
这两天把mysql的各类备份方式总结了一下,部分是摘录其他人的内容。

这些一些是综合了许多文章得出的结论,一些是自己试验的结果。

可能是不十分正确,如果各位发现错误,请指正!

MYISAM引擎的备份与恢复
1、直接备份文件(cp、tar)
方法:关闭mysql或者锁顶定表,避免写操作。将数据文件全部复制到备份路径即可。
锁表方法:FLUSH TABLES WITH READ LOCK(锁所有库所有表)
LOCK TABLES tbl_name (锁某一表) (此种锁定之前最好执行一下flush tables)

解锁方法:unlock tables
恢复:直接将数据复制到mysql数据目录下即可
优点:简单、方便、效率高
缺点:需要锁表或关闭数据库。不具有可移植性!数据易出错
2、mysqldump备份
mysqldump客户端可用来转储数据库或搜集数据库进行备份或将数据转移到另一个SQL服务器(不一定是一个MySQL服务器)。
如果你在服务器上进行备份,并且表均为MyISAM表,应考虑使用mysqlhotcopy,因为可以更快地进行备份和恢复。
方法:常用语句:
shell> mysqldump -uuser -ppass --default-character-set=utf8 --opt --extended-insert=false /

--triggers -R --hex-blob -x db_name > db_name.sql(注意参数顺序)

恢复:shell>mysqldump –uuser –ppass dn_name<db_name.sql
mysqldump 常用参数意义见下
优点:备份出来的数据比较小,基本是纯数据,可跨平台
缺点:不支持增量备份。会锁表,如果数据量大,锁表时间会很长。
3、 mysqlhotcopy备份
mysqlhotcopy是一个Perl脚本,最初由Tim Bunce编写并提供。它使用LOCK TABLES、FLUSH TABLES和cp或scp来快速备份数据库。它是备份数据库或单个表的最快的途径,但它只能运行在数据库目录所在的机器上。mysqlhotcopy只用于备份MyISAM。它运行在Unix和NetWare中。使用之前,主机需安装perl-DBD-MySQL和perl-DBI rpm包
方法:格式
Shell> mysqlhotcopy –uuser –ppass db_name /path/to/bakdir

常用选项:
--addtodest 不重命名目标文件(如果存在),合并它们(增量备份)
--checkpoint=db_name.tbl_name 在指定的db_name.tbl_name插入检查点条目,记录mysqlhotcopy操作记录
--method 备份方法使用cp或者scp,默认使用cp
--allowold 如果目标存在不放弃(加上一个_old后缀重新命名它)。
[align=left]--noindices 备份中不包括全部索引文件。这样使备份更小、更快。可以在以后用myisamchk -rq重新构建索引。[/align]
[align=left]--regexp=expr 复制所有数据库名匹配给出的正则表达式的数据库。[/align]
[align=left]恢复:将备份出的数据复制(覆盖)到mysql数据目录(注意权限)[/align]
优点:支持一次性拷贝多个数据库,同时还支持正则表达。支持增量备份,备份速度快
缺点:只适用myisam引擎;只能在mysql数据目录所在的主机上执行;
4、sql语法备份
BACKUP TABLE 语法其实和 mysqlhotcopy 的工作原理差不多,都是锁表,然后拷贝数据文件。它能实现在线备份,但是效果不理想,因此不推荐使用。它只拷贝表结构文件(*.frm)和数据文件(*.myd),不同时拷贝索引文件,因此恢复时比较慢。只使用myisam引擎
语法:mysq>backup table tbl_name to ‘/path/to/backup/dir/’ (备份目录mysql用户要有写的权限)

SELECT INTO OUTFILE 则是把数据导出来成为普通的文本文件,可以自定义字段间隔的方式,方便处理这些数据。
[align=left] SELECT...INTO OUTFILE 'file_name'形式的SELECT可以把被选择的行写入一个文件中。该文件被创建到服务器主机上,因此您必须拥有FILE权限,才能使用此语法。file_name必须是一个新文件,而不能是一个已经存在的文件。[/align]
SELECT...INTO OUTFILE语句的主要作用是让您可以非常快速地把一个表转储到服务器机器上。如果您想要在服务器主机之外的部分客户主机上创建结果文件,您不能使用SELECT...INTO OUTFILE。在这种情况下,您应该在客户主机上使用比如“mysql –e "SELECT ..." > file_name”的命令,来生成文件。
5、binlog日志备份
二进制日志记录了所有的 DDL 和 DML 的语句, 但不包括查询语句, 语句以事件方式保存。如果MySQL服务器启用了二进制日志,你可以使用mysqlbinlog工具来恢复从指定的时间点开始 (例如,从你最后一次备份)直到现在或另一个指定的时间点的数据。而坏处是日志文件增长速度快,很快占会占满磁盘空间,而且二进制日志会使服务器性能大约慢1%.
如下情况时,二进制日志会更换到新的文件:
(1)服务器重启
(2)服务器被更新
(3)日志达到最大日志长度 max_binlog_size
(4)在 MySQL 命令终端 FLUSH LOGS
开启方法:修改my.cnf,在[mysqld]下开启binkog日志
log-bin=mysql-bin

binlog-do-db=db_test(指定开启binlog的数据库,如不知道,默认是全部数据库)

binlog-do-db=db_test2

expire_logs_day=3(设置日志的过期天数,过了指定的天数,会自动删除,如不设置,默认永久保存)
重新启动数据库
恢复方法:
(1)、mysqlbinlog -stop-date=“2012-08-24 9:59:59” /var/log/mysql/mysql-bin.[0-9]* | mysql -u root –ppass (读取日志最开始至2012-08-24的所有日志并恢复)

(2)、mysqlbinlog -stop-date=“2012-08-24 9:59:59” /var/log/mysql/mysql-bin.[0-9]* | mysql -u root –ppass --one-database db_name (只按时间恢复某一数据库得信息)

(3)、mysqlbinlog -stop-date=“2012-08-24 9:59:59” /var/log/mysql/mysql-bin.[0-9]*>file.sql

(将日志转换成sql文件,可直接导入到mysql内)
Mysqlbinlog 常用参数:
--start-position=N 从二进制日志中第1个位置等于N参量时的事件开始读
--stop-position=N 从二进制日志中第1个位置等于和大于N参量时的事件起停止读。
--start-datetime=datetime 从二进制日志中第1个日期时间等于或晚于datetime参量的事件开始读取。datetime值相对于运行mysqlbinlog的机器上的本地时区
---database=db_name,-d db_name 只列出该数据库的条目(只用本地日志)。
-h host_name 获取给定主机上的MySQL服务器的二进制日志。
--to-last-logs,-t 在MySQL服务器中请求的二进制日志的结尾处不停止,而是继续打印直到最后一个二进制日志的结尾。如果将输出发送给同一台MySQL服务器,会导致无限循环。该选项要求--read-from-remote-server。
--disable-logs-bin,-D 禁用二进制日志。如果使用--to-last-logs选项将输出发送给同一台MySQL服务器,可以避免无限循环。该选项在崩溃恢复时也很有用,可以避免复制已经记录的语句。注释:该选项要求有SUPER权限。
6、mysql主从复制
MySQL支持单向、异步复制,复制过程中一个服务器充当主服务器,而一个或多个其它服务器充当从服务器。(这与同步复制可以进行对比,同步复制是MySQL簇的一个特征)。主服务器将更新写入二进制日志文件,并维护文件的一个索引以跟踪日志循环。这些日志可以记录发送到从服务器的更新。当一个从服务器连接主服务器时,它通知主服务器从服务器在日志中读取的最后一次成功更新的位置。从服务器接收从那时起发生的任何更新,然后封锁并等待主服务器通知新的更新。
主从复制严格来说不算一种备份方式,它只是将主mysql上所有的写操作在从的重新执行了一遍。这样写操作在主库上,在从库上可以读数据库,从而实现读写分离,降低了主库的压力,提高了查询速度。而在从库上执行上面的备份方法,可以大胆的锁表或关闭数据库,提高mysql的高可用性。
[具体配置方法见附录]
7、软件备份XtarBackup(innobackupex
Xtrabackup下的innobackupex 支持myisam的备份。备份时也会锁表(不支持增量备份)
[align=left]备份[/align]
shell>innobackupex –defaults-file=/etc/my.cnf –user=username –password=passwd --databases=”databases1 databases2” /bak/path/to/dir
[align=left]恢复:[/align]
Shell>innobackupex –apply-log –defaults-file=/etc/my.cnf –user=username –password=passwd /path/to/bak/dir/data
[align=left]因为innobackupex存在bug,所以执行完上面的命令后,需要手动将备份出的(.frm .MYD .MYI)文件覆盖的mysql的数据目录![/align]

Innodb引擎的备份与恢复
1、Mysqldump
Shell> mysqldump -uuser -ppass --default-character-set=utf8 --opt --extended-insert=false /

--triggers -R --hex-blob --single-transaction db_name > db_name.sql

恢复:shell>mysqldump –uuser –ppass dn_name<db_name.sql
2、 软件备份XtarBackup(xtrabackup)
xtrabackup
优点:支持热备,支持增量备份。

xtrabackup缺点:备份是物理拷贝+逻辑备份的方式备份数据库,会发生物理磁盘的读操作,但是物理备份的速度会比较快。

总的来看xtrabackup会比mysqldump优秀很多,因为他支持热备和增量备份。但是这个也是根据数据库情况而定,如果是在slave上做备份,不用太多的考虑表锁问题,mysqldump也是很不错的。还有就是如果数据量不大,小于5G,数据基本都是update语句较多的情况下,不太适合使用xtrabackup做全备和增量备份策略,因为xtrabackup增量备份的原理是通过lsn(日志序号)来操作的,如果你的数据库更新太频繁,每天新的lsn太多,那增量备份还没有全备来的快,还有就是xtrabackup全备的时候会备份ib_logfile*和ibdata*,就算你使用的独享表空间也会备份这些文件,所以每次全备的size会比较大,磁盘空间和系统资源的占用也比较多。

Xtrabackup中包含两个工具:
xtrabackup 只能备份InnoDB和XtraDB两种数据表,支持在线热备份,可以在不加锁的情况下备份Innodb数据表,不过此工具不能操作Myisam引擎表
innobackupex 是一个脚本封装,封装了xtrabackup,能同时处理Innodb和Myisam,但在处理Myisam时需要加一个读锁。
方法:
(1) 普通备份(全量备份)

Xtrabackup –defaulets-file=/etc/my.cnf –backup –target-dir=/path/to/backdir/

注意:xtrabackup只备份数据文件,并不备份数据表结构(.frm),所以这里要手动备份一下,以便xtrabackup恢复的时候使用。
(2) 增量备份 xtrabackup –default-file=/etc/my.cnf –backup –target-dir=/path/to/backdir –incremental-basedir=/path/to/base/backdir

补充:
myisamchk
myisamchk可以获得有关数据库表的信息或检查、修复、优化他们。
myisamchk适用MyISAM表。
当你运行myisamchk时,必须确保其它程序不使用表。
使用之前先执行“FLUSH TABLES” 强制清空仍然在内存中的任何表修改,同时确保myisamchk执行过程中其他程序不使用表。否则会报错“warning: clients are using or haven't closed the table properly”

避免此问题出现的最简单方法是用check table命令来检查表,用法“sql>check table dbname.tabname”

mysqldump
mysqldump支持下面的选项:
--add-drop--database 在每个CREATE DATABASE语句前添加DROP DATABASE语句。

---database,-B 转储几个数据库。通常情况,mysqldump将命令行中的第1个名字参量看作数据库名,后面的名看作表名。使用该选项,它将所有名字参量看作数据库名。CREATE DATABASE IF NOT EXISTS db_name和USE db_name语句包含在每个新数据库前的输出中。
--tables 覆盖---database或-B选项。选项后面的所有参量被看作表名。
--default-character-set=charset 使用charsetas默认字符集。如果没有指定,mysqldump使用utf8。如果数据表不是采用默认的 latin1 字符集的话,那么导出时必须指定该选项,否则再次导入数据后将产生乱码问题。

--delayed-insert 使用INSERT DELAYED语句插入行。

--delete-master-logs 在主复制服务器上,完成转储操作后删除二进制日志。该选项自动启用--master-data。
--disable-keys,-K 对于每个表,用/*!40000 ALTER TABLE tbl_name DISABLE KEYS */;和/*!40000 ALTER TABLE tbl_name ENABLE KEYS */;语句引用INSERT语句。这样可以更快地装载转储文件,因为在插入所有行后创建索引。该选项只适合MyISAM表。

--extended-insert,-e 使用包括几个VALUES列表的多行INSERT语法。这样使转储文件更小,重载文件时可以加速插入。
--flush-logs,-F 开始转储前刷新MySQL服务器日志文件。该选项要求RELOAD权限。请注意如果结合--all--database(或-A)选项使用该选项,根据每个转储的数据库刷新日志。例外情况是当使用--lock-all-tables或--master-data的时候:在这种情况下,日志只刷新一次,在所有 表被锁定后刷新。如果你想要同时转储和刷新日志,应使用--flush-logs连同--lock-all-tables或--master-data。

--force,-f 在表转储过程中,即使出现SQL错误也继续。
--host=host_name,-h host_name 从给定主机的MySQL服务器转储数据。默认主机是localhost。

--hex-blob 使用十六进制格式导出二进制字符串字段。如果有二进制数据就必须使用本选项。影响到的字段类型有 BINARY、VARBINARY、BLOB。
--lock-all-tables,-x 所有数据库中的所有表加锁。在整体转储过程中通过全局读锁定来实现。该选项自动关闭--single-transaction和--lock-tables。
--lock-tables,-l 开始转储前锁定所有表。用READ LOCAL锁定表以允许并行插入MyISAM表。对于事务表例如InnoDB和BDB,--single-transaction是一个更好的选项,因为它不根本需要锁定表。请注意当转储多个数据库时,--lock-tables分别为每个数据库锁定表。因此,该选项不能保证转储文件中的表在数据库之间的逻辑一致性。不同数据库表的转储状态可以完全不同。
--master-data[=value] 该选项将二进制日志的位置和文件名写入到输出中。该选项要求有RELOAD权限,并且必须启用二进制日志。如果该选项值等于1,位置和文件名被写入CHANGE MASTER语句形式的转储输出,如果你使用该SQL转储主服务器以设置从服务器,从服务器从主服务器二进制日志的正确位置开始。如果选项值等于2,CHANGE MASTER语句被写成SQL注释。如果value被省略,这是默认动作。
--master-data 选项启用--lock-all-tables,除非还指定--single-transaction(在这种情况下,只在刚开始转储时短时间获得全局读锁定。又见--single-transaction。)在任何一种情况下,日志相关动作发生在转储时。该选项自动关闭--lock-tables。
--single-transaction 该选项从服务器转储数据之前发出一个BEGIN SQL语句。它只适用于事务表,例如InnoDB和BDB,因为然后它将在发出BEGIN而没有阻塞任何应用程序时转储一致的数据库状态。当使用该选项时,应记住只有InnoDB表能以一致的状态被转储。例如,使用该选项时任何转储的MyISAM或HEAP表仍然可以更改状态。--single-transaction选项和--lock-tables选项是互斥的,因为LOCK TABLES会使任何挂起的事务隐含提交。要想转储大的表,应结合--quick使用该选项。

--no-data,-d 不写表的任何行信息。如果你只想转储表的结构这很有用。
--opt 该选项是速记;等同于指定 --add-drop-tables--add-locking --create-option --disable-keys--extended-insert --lock-tables --quick --set-charset。它可以给出很快的转储操作并产生一个可以很快装入MySQL服务器的转储文件。该选项默认开启,但可以用--skip-opt禁用。要想只禁用确信用-opt启用的选项,使用--skip形式;例如,--skip-add-drop-tables或--skip-quick。
--quick,-q 该选项用于转储大的表。它强制mysqldump从服务器一次一行地检索表中的行而不是检索所有行并在输出前将它缓存到内存中。
--routines,-R 在转储的数据库中转储存储程序(函数和程序)。使用---routines产生的输出包含CREATE PROCEDURE和CREATE FUNCTION语句以重新创建子程序。但是,这些语句不包括属性,例如子程序定义者或创建和修改时间戳。这说明当重载子程序时,对它们进行创建时定义者应设置为重载用户,时间戳等于重载时间。如果你需要创建的子程序使用原来的定义者和时间戳属性,不使用--routines。相反,使用一个具有mysql数据库相应权限的MySQL账户直接转储和重载mysql.proc表的内容。
--triggers 为每个转储的表转储触发器。该选项默认启用;用--skip-triggers禁用它。
MySQL表级锁的锁模式

MySQL的表级锁有两种模式:表共享读锁(Table Read Lock)和表独占写锁(Table Write

Lock)。MyISAM在执行查询语句(SELECT)前,会自动给涉及的所有表加读锁,在执行更新操作(UPDATE、DELETE、INSERT等)前,会自动给涉及的表加写锁。

所以对MyISAM表进行操作,会有以下情况:

a、对MyISAM表的读操作(加读锁),不会阻塞其他进程对同一表的读请求,但会阻塞对同一表的写请求。只有当读锁释放后,才会执行其它进程的写操作。

b、对MyISAM表的写操作(加写锁),会阻塞其他进程对同一表的读和写操作,只有当写锁释放后,才会执行其它进程的读写操作。

锁表方法
FLUSH TABLES WITH READ LOCK;
这个命令是全局读锁定,执行了命令之后所有库所有表都被锁定只读。一般都是用在数据库联机备份,这个时候数据库的写操作将被阻塞,读操作顺利进行。
解锁的语句也是unlock tables。

LOCK TABLES tab_name
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息