细聊MySQL的备份与恢复

备份对于数据库来说是相当重要的工作。如果数据库在使用过程中出现了问题,比如系统崩溃、硬件故障或错误的删除了数据。这时,如果我们进行了数据备份,就能比较方便的使数据库恢复工作,并使我们的数据损失到最小。下面,我从备份类型、备份方法及一些常用的例子来和大家详细探讨下数据库的备份与恢复。

一、备份类别

1、物理备份与逻辑备份

物理备份用人话来形容就是复制数据库的数据文件。如果我们需要备份名为test的数据库,则我们可以将数据目录下的test目录复制到备份设备中。如果我们需要备份test库下名为user的表,则可以根据不同的存储引擎选取不同的数据文件来复制。如user是myisam,则可以复制user.frm,user.MYD,user.MYI文件。如user是innodb,则可以复制user.frm,user.ibd。其中.frm是包含数据结构的文件。.MYD是myisam引擎中包含具体数据的文件。.MYI是myisam引擎中包含索引内容的文件。.ibd是innodb引擎中包含具体数据的文件。

逻辑备份是将数据库的结构对象及数据对象(所有的事件、触发器、存储过程等)转化为SQL语句后再保存到备份文件中。所以逻辑备份与具体的操作平台无关。

物理备份的特征:

1、它是直接复制二进制数据文件的,所以我们在恢复数据时只能原样恢复,不能自定义修改数据文件再恢复。

2、物理备份比逻辑备份速度更快,因为没有转化SQL这一过程。

3、物理备份不支持细粒度的备份,如果你只是想备份某个表中的某一范围的行,可能会难以办到。

4、物理备份可能会丢失最新写入到数据库的数据。因为在物理备份时,可能会有新增的数据还驻留在内存中,没有写入硬盘。

5、物理备份对平台有一定的要求,如果两个操作系统的文件系统不一样,有可能会不能恢复数据。所以要求尽可能在相同的操作系统及文件系统上实现数据的备份与恢复。

6、最好在服务器停止运行时执行物理备份,否则可能需要正确的加锁策略来确保数据一致。

逻辑备份的特征:

1、通过将需备份的数据转换成SQL来完成备份,所以在恢复数据时,我们可以通过修改SQL的方式来自定义恢复的内容,有更大的灵活性。

2、因为特征1的原因,所以在速度方面会比物理备份慢,因此不太适合大量数据的备份。

3、备份力度方面比物理备份更细,可以到行级。

4、不依赖具体的操作系统平台。

5、备份时无需停止服务器。

2、在线备份与离线备份

在线备份是通过远程客户端连到服务器进行备份,如在客户端使用导出工具导出SQL备份文件。在备份时应该在SQL上加合适的锁防止数据不一致的情况。比如写数据时应加写锁以防止导出数据集时发生数据不一致。

离线备份是在服务器停运的状态下进行备份,因为此时不会有数据操作,所以它在实现上更简单。

3、完全备份与增量备份

完全备份就是备份到目前为止的所有数据。增量备份只备份自上一次完全备份或增量备份到至今,期间有所变化的数据。实现完全备份的方法有很多,如使用逻辑备份或者物理备份都可以实现完全备份。完全备份在恢复时是最方便的,但在备份时通常需要耗费很长的时间,所以如果数据库的数据量非常大,每天都执行完全备份是不现实的。应采用完全备份与增量备份相结合的策略。如在每个星期天执行一次完全备份,礼拜一到礼拜五实行增量备份。增量备份的特性与完全备份刚好相反,在备份时会非常的快捷方便,但在还原时会比较繁琐。而且要实现增量备份,我们必须在服务器运行时开启二进制日志。这样我们在恢复时才能根据二进制日志来进行实时恢复。

二、备份方法

物理备份方法通常是用专门的MySQL备份工具或操作系统的相关指令进行的,这里强调一点,就是在进行物理复制的时候,在执行复制之前应给需要备份的表加读锁,并且需要将驻留在内存的索引信息写入I/O,具体命令为FLUSH TABLES WITH READ LOCK。下面我主要介绍下MySQL普通版本下的备份方法。

使用mysqldump实现数据库的逻辑备份。

mysqldump命令在mysql安装目录的bin目录下。主要作用是导出SQL文件。具体语法格式如下:

mysqldump [options] db_name [tbl_name ...] 
mysqldump [options] --databases db_name ...
mysqldump [options] --all-databases

常用的可选参数如下:

参数 描述 适用 废弃
--add-drop-database 在每个 CREATE DATABASE 声明前加上DROP DATABASE 声明
--add-drop-table 在每个 CREATE TABLE  声明前加上DROP TABLE 声明
--add-drop-trigger 在每个 CREATE TRIGGER  声明前加上DROP TRIGGER 声明
--add-locks 在备份时所表
--all-databases 备份所有数据库里的所有表
--allow-keywords 将表名作为列名的前缀
--apply-slave-statements 将STOP SLAVE放在CHANGE MASTER声明前,并将START SLAVE放在结尾
--comments 增加注释到备份文件
--compact 生成更加紧凑的输出
--compatible=name[,name,...] 生成更加兼容的格式
--complete-insert 使用完整的 INSERT 声明
--create-options 在CREATE TABLE声明里包含所有的MySQL指定选项
--databases 备份指定的数据库
--delete-master-logs 在执行dump操作后删除master节点的binlog
--disable-keys 对于每一个表的INSERT声明前加上/*!40000 ALTER TABLE
           tbl_name DISABLE KEYS
           */; 和/*!40000 ALTER TABLE
           tbl_name ENABLE KEYS
           */,这样可以更快的载入dump文件,但仅仅对具有非唯一索引的MyISAM表有效。
--dump-date 包含dump时间
--extended-insert 使用批量插入语法
--flush-logs 在开始导出前刷新MYSQL server日志文件
--flush-privileges 在导出后刷新权限
--hex-blob 使用16进制导出二进制列
--ignore-error=error[,error]... 跳过指定的错误 5.7.1
--ignore-table=db_name.tbl_name 不导出指定的表
--insert-ignore 写INSERT IGNORE 声明,而不是 INSERT 声明
--lock-all-tables 锁所有的数据库表
--lock-tables 导出前所数据库内的表
--login-path=name 同mysql命令
--max_allowed_packet=value 同mysql命令
--net_buffer_length=value 同mysql命令
--no-autocommit 添加 SET autocommit = 0 和COMMIT 声明在每个  INSERT 声明前
--no-create-db 不创建 CREATE DATABASE 声明
--no-data 不导出表的数据
--no-defaults 同mysql命令
--no-set-names 不设置字符集
--no-tablespaces 不写任何 CREATE LOGFILE GROUP 或 CREATE TABLESPACE 声明
--opt --add-drop-table --add-locks --create-options --disable-keys
--extended-insert --lock-tables --quick --set-charset的缩写
--order-by-primary 按逐渐或唯一索引排序导出数据行
--quote-names 添加引用标识
--replace 用 REPLACE 声明代替 INSERT 声明
--result-file=file 输出文件到指定位置
--secure-auth 同mysql命令 5.7.4 5.7.5
--set-charset 设置字符集
--set-gtid-purged=value 增加 SET @@GLOBAL.GTID_PURGED 
--shared-memory-base-name=name 同mysql命令
--single-transaction 在导出前写 BEGIN SQL 声明
--skip-add-drop-table add-drop-table 反向操作
--skip-add-locks add-locks 反向操作
--skip-comments comments 反向操作
--skip-compact compact 反向操作
--skip-disable-keys disable-keys 反向操作
--skip-extended-insert extended-insert 反向操作
--skip-opt 关闭 --opt 选项
--skip-quick quick 反向操作
--skip-quote-names quote-names 反向操作
--skip-set-charset 不设置字符集
--skip-triggers 不导出触发器
--skip-tz-utc 关闭 tz-utc 选项
--tab=path 生成一个用tab隔开的数据文件。
--tables 覆盖 --databases 选项
--triggers 导出触发器
--tz-utc 针对列中的TIMESTAMP字段,增加SET TIME_ZONE=‘+00:00‘到导出文件中
--where=‘where_condition‘ 导出符合where条件的行
--xml 生成XML输出

以下是一个简单的备份例子,如下所示:

/usr/local/mysql/bin/mysql -uroot -p123456 -h127.0.0.1 -e"flush tables with read lock” #将驻留在内存中的数据写入表中并给所有表添加读锁
/usr/local/mysql/bin/mysqldump -uroot -p123456 -h127.0.0.1  --databases test --add-drop-database --add-drop-table --extended-insert --create-options > /usr/local/mysql/backup/backup.sql
#备份test库到backup.sql文件。加了—databases后,会在备份文件里
生成创建数据库CREATE DATABASE test;的声明。否则,如果直接使用
mysqldump test > backup.sql命令则不会生成create database语句。
具体参数的运用可以参考上表,如果数据较大,我们可以使用—opt选项进行备份。
/usr/local/mysql/bin/mysql -uroot -p123456 -h127.0.0.1 -e"unlock tables”
#解除读锁

三、数据恢复方法

1、mysqldump恢复法

使用mysqldump备份的数据,通常在一个.sql文件中。要恢复数据,只用利用mysql客户端执行备份文件即可。如:

/usr/local/mysql/bin/mysql -uroot -p123456 -h127.0.0.1 < /usr/local/mysql/backup/backup.sql

即可

2、二进制日志恢复法

使用此方法的前提是你的服务器是以—log-bin参数运行的,这样服务器才会生成二进制日志。使用二进制日志恢复法需使用mysqlbinlog命令,此命令也在mysql安装目录的bin目录下。恢复命令如下:

/usr/local/mysql/bin/mysqlbinlog xxx-bin.000001 | /usr/local/mysql/bin/mysql -uroot -p123456 -h127.0.0.1

诸如此类xxx-bin.000001的格式均为二进制日志文件。xxx-bin.000001里是以二进制存储的对数据库的所有操作,所以此命令执行后会将历史上对数据库的操作进行重做,以此达到恢复数据的目的。值得注意的是,如果你有多个二进制日志文件,如有xxx-bin.000001和xxx-bin.000002这两个文件,如果按以下方式进行恢复将是不安全的:

/usr/local/mysql/bin/mysqlbinlog xxx-bin.000001 | /usr/local/mysql/bin/mysql -uroot -p123456 -h127.0.0.1
/usr/local/mysql/bin/mysqlbinlog xxx-bin.000002 | /usr/local/mysql/bin/mysql -uroot -p123456 -h127.0.0.1

这样利用两次客户端连线去恢复数据是不安全的,如果在xxx-bin.000001内有一个生成临时表的声明,而在xxx-bin.000002内需要使用这个临时表,则这样操作将出现问题,执行mysqlbinlog xxx-bin.000002时将会找不到这个临时表。所以正确的做法应该是:

/usr/local/mysql/bin/mysqlbinlog xxx-bin.000001 xxx-bin.000002 | /usr/local/mysql/bin/mysql -uroot -p123456 -h127.0.0.1

mysqlbinlog恢复数据的方法很灵活,可以通过时间点与位置点进行恢复如:

/usr/local/mysql/bin/mysqlbinlog —start-datetime=‘2014-01-20 8:00:00’—stop-datetime=‘2014-01-22 19:00:00‘ xxx-bin.000001| /usr/local/mysql/bin/mysql -uroot -p123456 -h127.0.0.1
#表示重做xxx-bin.000001文件里从2014-01-20 8:00:00到
2014-01-22 19:00:00这个时间范围内的操作。
/usr/local/mysql/bin/mysqlbinlog --start-position=368315xxx-bin.000001 | /usr/local/mysql/bin/mysql-uroot -p123456 -h127.0.0.1
#表示重做xxx-bin.000001文件内从位置368315开始直到文件末尾的操作。

关于备份与恢复,一般采用完全备份和增量备份结合的方法。这样可以在保证备份效率的基础上达到实时恢复要求。比如让服务器以—log-bin参数运行,然后每个礼拜天进行一次mysqldump。这样,比如2014年12月7号23点59分完成的备份,2014年12月9日7点需要进行恢复。则首先运行mysql < backup.2014-12-7.sql,恢复到2014年12月7日23点59分前的数据。然后利用mysqlbinlog hostname-bin.000001 —start-datetime=‘2014-12-8 00:00:00’ | mysql 命令恢复之后的数据。

时间: 2024-10-10 03:58:38

细聊MySQL的备份与恢复的相关文章

细聊MySQL之常用工具及基本操作(二)

接细聊MySQL之常用工具及基本操作(一) 四.客户端管理工具mysqlcheck的使用.mysqlcheck是客户端表维护工具,可以检查.修复.优化或分析表. 如 shell> mysqlcheck databasename tablename [options] databasename为数据库名 tablename为表名 如果你只指定databasename,通常会检查databasename下所有的表.如果你既不指定databasename,也不指定tablename,那么一定要添加参数

细聊MySQL的Innodb存储引擎(完)

细聊MySQL的Innodb存储引擎(一) 细聊MySQL的Innodb存储引擎(二) 细聊MySQL的Innodb存储引擎(完) 上篇主要和大家探讨了Innodb引擎中出现幻读的处理方法与死锁的探测及避免死锁的一些注意事项.此篇,我们来研究下Innodb的索引. Innodb里涉及到的索引主要有四种,分别为聚簇索引(Clustered Index).次级索引(Secondary Index).全文索引(FULLTEXT Index).哈希索引(Hash Index). 聚簇索引与次级索引 每一

细聊MySQL的Innodb存储引擎(二)

细聊MySQL的Innodb存储引擎(一) 上一篇主要和大家探讨了下Innodb的锁机制与隔离机制.本篇来和大家一起研究下在使用Innodb是会出现的问题以及如何解决它们. Innodb是如何解决幻读问题的 什么是幻读?听起来似乎很高端,但实际上它只是反映了事务中的一种数据不一致的情况.下面看我来描述这样一个场景,通过这个场景,大家就能很清楚的知道幻读到底是什么意思. 打开两个客户端,设为A和B A客户端 mysql> start transaction; (步骤一) Query OK, 0 r

细聊MySQL之常用工具及基本操作(三)

细聊MySQL之常用工具及基本操作(一) 细聊MySQL之常用工具及基本操作(二) 七.使用mysqlshow工具查看数据库.表和列的信息.具体语法: shell> mysqlshow [options] [db_name [tbl_name [col_name]]] 注:如果没有数据库给定,列出数据库列表 如果没有表给定,列出所有数据库的表 如果没有列给定,列出表内所有的列 详细参数如下: 参数 描述 适用 弃用 --bind-address=ip_address 同mysql命令 --com

细聊MySQL的分区功能

此篇主要介绍下MySQL的分区功能.我们分别从分区的概念.分区对于MySQL应用的优点.分区的类别及设置来和大家一起探讨下MySQL的分区. 什么是分区? MySQL在未启用分区功能时,数据库的单个表内容是以单个文件的形式存放在文件系统上的.当启用分区功能后,MySQL将按用户指定的规则将单个表内容分割成几个文件存放在文件系统上.分区分为水平分区和垂直分区,水平分区是将表的数据按行分割成不同的数据文件,而垂直分区则是将表的数据按列分割成不同的数据文件.分片要遵循完备性原则.可重构性原则与不相交原

细聊MySQL的安全机制

MySQL作为系统的数据库,在安全性方面有非常高的要求.如果一个系统的数据库被非法进入或窃听,则系统的数据将受到非常严重的威胁,轻则数据.密码被盗,重则导致整个系统瘫痪.所以数据库的安全对于系统来说是非常重要的. 本文将从MySQL的服务器启动与客户端访问.操作及链路三方面来阐述MySQL的安全机制. 一.MySQL的服务器启动与客户端访问.        1.服务器启动,启动服务器在安全方面的影响主要是启动它的用户.默认情况下,MySQL不允许使用root账号启动.我们应该建立一个只能操作My

细聊MySQL的Innodb存储引擎(一)

从MySQL5.5开始,Innodb就成为MySQL的默认存储引擎了.可想而知,Innodb已经成为MySQL的主要生产方式.那Innodb到底有什么本事能够击败其它几位存储引擎而荣登宝座呢?下面,我就来和大家一起探讨探讨牛逼的Innodb引擎.Innodb涉及到的知识点比较多,所以我会分几篇来叙述,此篇主要介绍Innodb的基本概念和架构. 要了解Innodb,首先需要了解MySQL的ACID模型.何为ACID?ACID指的是事务的原子性(A).一致性(C).隔离性(I).持久性(D). 原子

细聊MySQL之基本安装与启动

由于MySQL的生产环境通常会部署在Linux上,所以这里只说下Linux上的安装与启动. 一.版本识别 MYSQL的版本说明:如mysql-5.7.1-m1 第一个数字5代表主版本号和描述文件格式.所有的MYSQL 5发布版本有一样的文件格式. 第二个数字7代表发布等级.主版本号5和发布登记合起来组成发布序列号. 第三个号码1代表发布次数.每次有新的发布,发布次数号增加1. m+数字代表一个里程碑号,MYSQL开发使用一个里程碑模型管理. rc代表一个发布候选.发布候选版本通常是稳定的.通过了

细聊MySQL之常用工具及基本操作(一)

一.对于MySQL用户来说,使用MySQL的第一步就是启动它.要启动MySQL,我们需要mysqld或mysqld_safe命令.默认情况下,直接执行mysqld或mysqld_safe即可.如 shell> mysqld & 或 shell> mysqld_safe &.当然不是所有事情都那么顺利,如果启动不了,请指定相关的参数.服务器运行的前提是你已经执行了mysql_install_db脚本.当然,如果就这样启动,将有很多功能启动不了.如没有binlog,当某一天你不小心