MySql数据库备份与还原的几种方法

一、物理备份对比逻辑备份

物理备份是指直接复制包含数据的文件夹和文件。这种类型的备份适用于大数据量且非常重要,遇到问题需要快速回复的数据库。

逻辑备份保存能够代表数据库信息的逻辑结构(CREATE DATABASE, CREATE TABLEs等)和内容(INSERT …,或者分隔符分割的文本文件),这种类型的备份适合小数据量备份。可以通过备份文件进行库结构,表机构或者数据的修改。

物理备份主要有以下特点:

  • 备份文件包含所有的数据库文件夹和文件,即是mysql数据文件夹下的全部(所有数据库实例)或者部分(单个或多个数据库实例)。
  • 物理备份相较于逻辑备份快,它只涉及文件的拷贝而无需转换。
  • 备份文件较逻辑备份紧凑。
  • 备份速度及压缩性是备份的重要因素,尤其对业务繁忙且比较重要的数据库。因此Mqsql企业级的备份使用物理备份。.
  • 备份和恢复的力度包括整个数据文件级别、单个文件级别,根据数据库引擎的不同可能提供表级别的力度。例如,Innodb引擎可以使用单表单文件存储。MyISAM表包含一系列相关文件。.
  • 除了基本的数据库文件,备份还可以包含其它一些如日志、配置等相关的文件。
  • MEMORY 引擎类型表很难使用这种类型备份,因为它的数据存储在内存中。.
  • 备份的跨平台性要求设备间具有相似的硬件特性设备间进行。
  • 备份一般在mysql服务器停止的时候进行,如果需要运行中执行备份,则需要对特定表进行锁操作,放置备份期间,表数据变化。
  • 物理备份工具包括mysql的 mysqlbackup及文件系统级别的命令,如, scptarrsync
  • 恢复:
    • MySQL Enterprise Backup 可以恢复它所备份的备份。
    • ndb_restore 用于恢NDB 表。
    • 文件复制方式的复制,只需要将备份文件放到他们原始的位置即可。

逻辑备份有以下特点:

  • 备份是以查询mysql服务器方式来获取数据库结构及内容信息。
  • 备份速度比物理备份慢,因为它需要首先访问数据库获取数据,然后再转化为相应的逻辑格式。如果备份实在客户端,那么服务器还需要将备份发送到客户端。
  • 备份文件比物理备份的文件大,尤其是以文本方式存储的时候。
  • 备份和恢复粒度包括服务器级别、数据库级别、表级别。与存储引擎无关。
  • 备份不包括日志和配置文件,及其它任何数据库相关的非数据文件。
  • 备份以逻辑格式存储,与机器无关,可以跨平台使用。
  • 逻辑备份需要mysql服务器在运行状态。
  • 备份工具包括 mysqldump 及 SELECT ... INTO OUTFILE 语句,其实这些工具使用于任何引擎。即使是MEMORY。
  • 恢复,对于SQL-format dump 文件可以使用 mysql 客户端。对于分隔符分割的文本类型文件,可以使用LOAD DATA INFILE 语句或者mysqlimport 客户端。

在线备份 vs 线下备份

在线备份,即备份时,可以实时服务器信息。线下备份,即,在服务器停止的时候执行备份。相应的备份文件也可以称为热备或者冷备。还一种可以称之为温备,即备份的时候,服务器运行,但是不允许进行数据修改。

在线备份特点:

  • 对于其它客户端,备份是非侵入性的。不影响其它客户端进行时特定允许的数据操作。
  • 注意备份期间数据锁的使用。

线下备份特点:

  • 对客户端的影响是不可逆的。因此,一般备份采取在备机上进行备份。
  • 备份过程很简单,客户端无法进行干预。

备份的线上和线下区别基本相似。但是,线上恢复的时候,因为需要进行较多的锁操作,所以受的影响比较大。恢复期间不要进行数据访问操作。

本地备份 vs 远程备份

本地备份即备份操作和数据库服务器在同一台服务器上。远程则相反。对于一些类型的备份,备份命令可以远程触发,本地写备份。

  • mysqldump 可以连接本地或者远端服务器。生成本地或者远端备份。分隔符分割的文本存储在服务器所在服务器产生。
  • SELECT ... INTO OUTFILE 本地或者远程触发。输出在服务器端。
  • 物理备份基本上都是本地执行。虽然备份可能会需要发送到其它服务器。

快照备份

一些文件系统支持快照。可以保存特定时间点的一份逻辑备份。而不需要复制整个文件系统。Mysql本身不提供这种功能,需要地方放工具如Veritas, LVM, or ZFS提供。

全量备份 vs 增量备份

全量备份即备份mysql管理的所有数据。增量备份即备份改变的数据。全量备份可以通过以上讲述的一些备份方法进行备份。增量备份则需要通过启用服务器二进制日志(记录数据变化)来使用。

全量恢复 vs 增量恢复

全量恢复及恢复备份中所有的数据,是数据库恢复到备份时数据库状态。如果全量恢复的状态不够实时,可以接着使用增量恢复,恢复全量备份到这一刻所有的数据变化,是数据库状态保持最新。

增量恢复即恢复一个时间段内的数据变化。基于二进制日志,作为全量备份的补充。二进制文件中存储数据改变命令操作,通过重新执行相应的操作,使得数据库恢复到特定的状态.

备份规划、压缩和加密

...

 

二、数据库备份方法

使用mysqldump 备份

mysqldump 可以备份所有类型的表。对于 InnoDB 类型的表,可以通过--single-transaction 选项使用在线无锁备份。

通过复制表数据文件备份

对于那些使用独立文件存储表的引擎,备份可以通过复制表文件进行。例如,MyISAM 表存储文件(.frm:表结构*.MYD:表数据, and *.MYI:表索引)。为了保持数据的一致性,备份时需要关闭服务器或者锁定相应的数据表:

FLUSH TABLES tbl_list WITH READ LOCK;

备份只需要读锁,这样备份的同时不影响其它客户端进行数据检索。Flush操作是为了确保所有活跃的索引页都已经写盘。

也可以通过拷贝表文件来创建二进制备份,但,前提是在此期间不能进行任何的数据更新操作。 (对于包含Innodb类型表的数据库不能采取此方法,因为即使不进行任何更新操作,Innodb仍然可能有更改的数据缓存在内存中)。

分隔符文本类型备份

操作命令: SELECT * INTO OUTFILE 'file_name' FROM tbl_name.。备份文件生成在mysql服务器上。执行此语句需要确保输出文件不存在,服务器不允许文件覆盖操作,避免由此产生安全隐患。这一方法适用于任何类型数据文件,但是只能保存表记录,无法保存表结构。

另一种创建文本类型备份(包含 CREATE TABLE 语句)的方法是使用 mysqldump 附带--tab 选。加载文本类型本分可以使用 LOAD DATA INFILE 或者 mysqlimport.

二进制文件增量备份

MySQL支持增量备份。启动服务器时附带 --log-bin 选项启用二进制日志功能。二进制文件记载了自某一次备份以来所有的数据更新操作。生成一份增量备份时, 需要使用FLUSH LOGS或者mysqldump --flush-logs 生成一份新的日志文件,执行完成之后,将自某一次备份之后到最新的二进制日志文件复制到备份位置,即增量备份文件。恢复时,重新执行这些增量备份文件。

shell> mysqlbinlog binlog_files | mysql -u root -p

使用备机执行备份

备份一定程度上影响服务器的性能,因此通常我们选择在备机上进行备份。

备机备份时,首先需要备份主机信息及中继日志(relay log)。因为备份备机数据时,无论选用哪种备份方法,当重新使用备份数据恢复后,都需要重新将备份的主机信息及中继日志进行复制。 当备机执行LOAD DATA INFILE 语句时,需要备份相应的SQL_LOAD-* 使用的文件夹。备机需要在LOAD DATA INFILE崩溃时使用这些文件进行恢复。文件夹位置: --slave-load-tmpdir 。如果服务器启动时并未指定此选项,则使用系统tmpdir 变量信息。

恢复崩溃表

恢复 MyISAM 表时,首先使用 REPAIR TABLE 或者 myisamchk -r 尝试恢复,这通常能解决99.9% 以上的问题。

使用文件系统快照备份

Veritas文件系统下备份步骤如下:

  1. 首先客户端执行 FLUSH TABLES WITH READ LOCK.
  2. 另起shell,执行 mount vxfs snapshot
  3. 在之前的客户端执行 UNLOCK TABLES. .
  4. 拷贝快照文件.
  5. Unmount snapshot.

LVM及ZFS文件系统执行备份过程类似。

 

三、mysqldump 备份

使用mysqldump 备份及恢复,

dump文件作用:

  • 数据备份,灾难恢复
  • 建立备机数据。
  • 实验数据:
    • 数据副本
    • 升级测试

mysqldump 根据配置不同,提供两种输出格式

  • 不附带--tabmysqldump将sql语句写到标准输出,包括CREATE 语句和插入语句。输出可以保存为文件以备后续重新载入使用。可以通过配置选择需要备份的对象。
  • 使用--tabmysqldump 每个表生成两个文件对象。一个tab分隔符的文本文件tbl_name.txt,另一个包含 CREATE TABLE 语句的文件tbl_name.sql 。

使用mysqldump生成SQL格式备份

默认情况下mysqldump 输出到标准输出。使用以下命令输出到文件:

shell> mysqldump [arguments] > file_name

备份所有数据库 --all-databases

shell> mysqldump --all-databases > dump.sql

备份部分数据库则在--databases 选项后添加数据库名称:

shell> mysqldump --databases db1 db2 db3 > dump.sql

--databases 选项标识后面命令行的指令都为数据库名,如果没有这个选项,则第一个为数据库名,后续为表名。

 --all-databases 和 --databases,选项,使得mysqldump 创建的备份文件包括 CREATE DATABASE 及 USE 语句。这样在恢复时,就可以针对特定的数据库进行恢复,不至于造成所有的恢复都恢复到默认数据库里。如果需要备份文件包含drop数据库语句,则使用 --add-drop-database 选项。这样就会在CREATE DATABASE语句之前添加DROP DATABASE  语句。

备份单个数据库:

shell> mysqldump --databases test > dump.sql

备份单个数据库时可以不使用 –database选项:

shell> mysqldump test > dump.sql

不使用--databases选项,备份文件不包含CREATE DATABASE 和 USE 语句:

  • 恢复时需要指定数据库。
  • 如果指定的数据库不存在,则需要首先创建。
  • 不包含 DROP DATABASE 语句。

备份指定的表:

    shell> mysqldump test t1 t3 t7 > dump.sql

SQL-Format 备份文件加载

生成时包含 --all-databases 或者 --databases 选项的,备份文件包含CREATE DATABASE 和 USE 语句,不需要再指定数据库:

shell> mysql < dump.sql

sql命令行,使用source:

mysql> source dump.sql

备份不包含数据库创建语句,确保指定恢复的数据库存在:

shell> mysqladmin create db1

指定数据库:

shell> mysql db1 < dump.sql

sql命令行执行:

mysql> CREATE DATABASE IF NOT EXISTS db1;

mysql> USE db1;

mysql> source dump.sql

文本分隔符格式备份

 mysqldump  --tab=dir_name ,生成tbl.sql, tbl.txt文件到指定的输出文件夹爱。.sql 文件包含CREATE TABLE 语句,.txt文件包含表数据,一个文件行对应一条表记录。

如下备份数据库d1到 /tmp 目录:

shell> mysqldump --tab=/tmp db1

 .txt 包含服务器写入的表数据。服务器使用SELECT ... INTO OUTFILE 语句写文件,所以必须确保具有 FILE 访问权。如果需要生成的文件已存在则会报错。

The server sends the CREATE definitions for dumped tables to mysqldump, which writes them to .sql files. These files therefore are owned by the user who executes mysqldump.

 --tab 最好本地使用,如果远程使用,则必须确保服务器和客户端都存在此目录。这样.txt 文件会写到远程客户端文件夹,.sql文件会本地写。

mysqldump --tab.txt 文件,每行一条表记录,tab符分割,列值没有修饰符,换行符分割行。

  • --fields-terminated-by=str

分割符设置,默认为tab

  • --fields-enclosed-by=char

列值修饰符,默认无

  • --fields-optionally-enclosed-by=char

非数字列值修饰符,默认无

  • --fields-escaped-by=char

特殊字符列值修饰符,默认无

  • --lines-terminated-by=str

行分隔符,默认换行

如下,双引号修饰符

--fields-enclosed-by='"'

16进制双引号修饰符:

--fields-enclosed-by=0x22

修饰符综合使用:

shell> mysqldump --tab=/tmp --fields-terminated-by=,
         --fields-enclosed-by='"' --lines-terminated-by=0x0d0a db1

文本分割符备份文件载入

Shell命令:

  shell> mysql db1 < t1.sql

  shell> mysqlimport db1 t1.txt

mysql命令:

  mysql> USE db1;

  mysql> LOAD DATA INFILE 't1.txt' INTO TABLE t1;

If you used any data-formatting options with mysqldump 使用了任何数据格式化选项,则mysqlimport 或者 LOAD DATA INFILE 也不需使用相应的配置:

shell> mysqlimport --fields-terminated-by=,

           --fields-enclosed-by='"' --lines-terminated-by=0x0d0a db1 t1.txt

或者:

复制代码

mysql> USE db1;

  mysql> LOAD DATA INFILE 't1.txt' INTO TABLE t1

         FIELDS TERMINATED BY ',' FIELDS ENCLOSED BY '"'

         LINES TERMINATED BY '\r\n';

复制代码

mysqldump 提示

数据库复制

shell> mysqldump db1 > dump.sql
shell> mysqladmin create db2
shell> mysql db2 < dump.sql

不要添加 --databases 选项,避免备份文件包含USE 语句。

服务器之间数据库复制

服务器1:

shell> mysqldump --databases db1 > dump.sql

将备份文件复制到服务器2:

服务器2执行:

shell> mysql < dump.sql

备份存储程序(存储过程、函数、触发器、事件)

  • --events:事件
  • --routines:储过程、函数
  • --triggers:触发器(默认包含)

显式剔除:--skip-events--skip-routines, or --skip-triggers.

 

分别备份表定义及数据

shell> mysqldump --no-data test > dump-defs.sql     //备份定义
shell> mysqldump --no-create-info test > dump-data.sql //备份数据
shell> mysqldump --no-data --routines --events test > dump-defs.sql

使用mysqldump测试升级

生产服务器备份:

shell> mysqldump --all-databases --no-data --routines --events > dump-defs.sql

另外的升级服务器:

shell> mysql < dump-defs.sql

因为备份文件不包含数据,所以可以很快执行,这样可以很快发现问题。

恢复数据:

生产服务器:

shell> mysqldump --all-databases --no-create-info > dump-data.sql

另外的升级服务器:

shell> mysql < dump-data.sql

四、二进制文件增量恢复

作为全全量备份的补充,用于将服务器更新到最新状态。

规则:

  • 服务器启动时必须附带 --log-bin 选项以启动二进制日志功能。恢复时需要指明二进制文件路径和名称,默认为数据文件路径,可以通过 --log-bin 配置。

查看二进制文件命令:

mysql> SHOW BINARY LOGS;

查看当前主二进制文件名称:

mysql> SHOW MASTER STATUS;
  • mysqlbinlog 将二进制日志转化为文本格式,以便于阅读和执行其中的指令,根据时间及位置定位日志中的事件。
  • 使用 mysql 客户端执行 mysqlbinlog 命令如下:
  • 使用 mysqlbinlog 查看二进制日志内容
shell> mysqlbinlog binlog_files | mysql -u root -p
shell> mysqlbinlog binlog_files | more

将二进制文件保存为文本类型文件:

shell> mysqlbinlog binlog_files > tmpfile
shell> ... edit tmpfile ...
  • 可以对生成的文本类型日志进行编辑,然后再做执行:
shell> mysql -u root -p < tmpfile

一个连接执行一个二进制日志会存在问题,下面是一个反面示例:

shell> mysqlbinlog binlog.000001 | mysql -u root -p # DANGER!!
shell> mysqlbinlog binlog.000002 | mysql -u root -p # DANGER!!

使用一个连接执行所有的二进制日志文件:

shell> mysqlbinlog binlog.000001 binlog.000002 | mysql -u root -p

或者将所有的人日志写入一个文件执行:

shell> mysqlbinlog binlog.000001 >  /tmp/statements.sql
shell> mysqlbinlog binlog.000002 >> /tmp/statements.sql
shell> mysql -u root -p -e "source /tmp/statements.sql"

对于包含全局事物ID事件执行:

shell> mysqlbinlog --skip-gtids binlog.000001 >  /tmp/dump.sql
shell> mysqlbinlog --skip-gtids binlog.000002 >> /tmp/dump.sql
shell> mysql -u root -p -e "source /tmp/dump.sql" 

基于时间的增量恢复

mysqlbinlog使用 --start-datetime 和 --stop-datetime 选项确定执行的日志事件范围。例如,10点的时候删除了一张表,如果要恢复,就需要分别执行10点之前和之后的日志,如下:

复制代码

shell> mysqlbinlog --stop-datetime="2005-04-20 9:59:59" \

         /var/log/mysql/bin.123456 | mysql -u root -p

shell> mysqlbinlog --start-datetime="2005-04-20 10:01:00" \

         /var/log/mysql/bin.123456 | mysql -u root -p

复制代码

查看而不执行:

shell> mysqlbinlog /var/log/mysql/bin.123456 > /tmp/mysql_restore.sql

mysqlbinlog不能很好的处理对于多个事件作为一个事件执行的日志。

 

基于日志位置的增量恢复

mysqlbinlog  --start-position || --stop-position 精确到行号基于位置恢复。能够很好的解决处理同时发生的多个事务的情景。为了确定精确的位置,首先使用 mysqlbinlog 获取特定事务时间点前后一定范围的日志,将其存储到文本文件:

shell> mysqlbinlog --start-datetime="2005-04-20 9:55:00" \

         --stop-datetime="2005-04-20 10:05:00" \

         /var/log/mysql/bin.123456 > /tmp/mysql_restore.sql

找到位置后,就可以执行基于位置的增量恢复:

复制代码

shell> mysqlbinlog --stop-position=368312 /var/log/mysql/bin.123456 \

         | mysql -u root -p

shell> mysqlbinlog --start-position=368315 /var/log/mysql/bin.123456 \

         | mysql -u root -p

复制代码

二进制日志各sql语句之前包含SET TIMESTAMP 语,重新执行的日志产生的日志会反映当时执行的时间戳。

 

你可能感兴趣的:(数据库)