数据库的备份和恢复
一 (理论篇)、数据库备份与恢复基础
1、数据库的备份与恢复
- 备份:存储的数据副本;
原始数据:持续改变;
-
恢复:把副本应用到线上系统;
仅能恢复至备份操作时刻的数据状态;
时间点恢复:
binary logs;
2、为什么备份?
原始数据:持续改变;
恢复:把副本应用到线上系统;
仅能恢复至备份操作时刻的数据状态;
时间点恢复:
binary logs;
灾难恢复: 硬件故障(冗余)、软件故障(bug)、自然灾害、黑客攻击、误操作、… 测试;
3.备份时应该注意事项:
- 能容忍最多丢失多少数据;
- 恢复数据需要在多长时间内完成;
- 需要恢复哪些数据;
做恢复演练:
测试备份的可用性;
增强恢复操作效率;
...
4. 备份类型:
备份的数据的及范围:
完全备份和部分备份
完全备份:整个数据集;
部分备份:数据集的一部分,比如部分表;
完全备份、增量备份、差异备份区别
完全备份
增量备份:仅备份自上一次完全备份或 增量备份以来变量的那部数据;
差异备份:仅备份自上一次完全备份以来变量的那部数据;
物理备份、逻辑备份:
物理备份:复制数据文件进行备份;
逻辑备份:从数据库导出数据另存在一个或多个文件中;
根据数据服务是否在线:
热备:读写操作均可进行的状态下所做的备份;
温备:可读但不可写状态下进行的备份;
冷备:读写操作均不可进行的状态下所做的备份;
MyISAM:温备,不能热备
Innodb:热备
5、备份需要考虑因素:
锁定资源多长时间?
备份过程的时长?
备份时的服务器负载?
恢复过程的时长?
6、备份策略:
完全+差异
完全+增量
7、备份手段:物理、逻辑
9、备份什么?
数据
二进制日志、InnoDB的事务日志;
代码(存储过程、存储函数、触发器、事件调度器)
服务器的配置文件
10、备份工具:
mysqldump:mysql服务自带的备份工具;逻辑备份工具;
完全、部分备份;
InnoDB:热备;
MyISAM:温备;
cp/tar等复制归档工具:物理备份工具,适用于所有存储引擎;冷备;完全备份
lvm2:快照(请求一个全局锁),之后立即释放锁,达到几乎热备的效果;物理备份;借助于文件系统的管理工具
注意:不能仅备份数据文件;要同时备份事务日志;
前提:要求数据文件和事务日志位于同一个逻辑卷;
xtrabackup:
由Percona提供,开源工具,支持对InnoDB做热备,物理备份工具;
完全备份、部分备份;
完全备份、增量备份;
完全备份、差异备份;
mysqlhotcopy:几乎冷备;仅适用于MyISM存储引擎
select:
备份:SELECT cluase INTO OUTFILE 'FILENAME';
恢复:CREATE TABLE
导入:LOAD DATA
二、实战篇
(一)、备份工具的选择:
1、 mysqldump+复制binlog:这种可以远程备份
mysqldump:做完全备份
复制binlog中指定范围的event:增量备份;
2、lvm2快照+复制binlog:
使用cp或tar做物理备份;完全备份;
复制binlog中指定范围的event:增量备份;
3、xtrabackup(innodb)+binlog:
由Percona提供的支持对InnoDB做热备(物理备份)的工具;
完全备份、增量备份!
(二)准备工作
首先查看二进制日志是否开启
]> show global variables like '%log%';
如果没开启
可以用 set global log_bin=ON;
要是不行就改配置文件 mysql.conf*
,加上log_bin
查看二进制日志文件
]> show master logs;
实战(1)mysqldump:
逻辑备份、完全备份、部分备份;
二次封装工具:
- mydumper
- phpMyAdmin
这是一个巨大的SQL语句、单个巨大的备份工具。
这是个客户端命令工具,通过mysql协议连接至mysql服务器。这个备份相当于查询库中所有的数据并用插入的方式存储在另一个文件中。
用法:
-
mysqldump [OPTIONS] db_name [tbl_name ...]
这种不会创建备份的这个数据库!! -
mysqldump [options] --databases db_name ...
这种即便备份库中的一个表也会创建这个库。 -
mysqldump [OPTIONS] --all-databases [OPTIONS]
自动创建数据库!
MyISAM存储引擎:支持温备,备份时要锁定表;
-x, --lock-all-tables:锁定所有库的所有表,读锁;
-l, --lock-tables:锁定指定库所有表;
InnoDB存储引擎:支持温备和热备;
--single-transaction:创建一个事务,基于此快照执行备份;
其它选项:
-R, --routines:备份所有存储过程和存储函数;
--triggers:备份表相关的触发器此为默认选项可以不加
-E, --events :备份指定数据库相关的event scheduler(调度程序)
--master-data[=#]
此语句用于在二进制文件中记录备份时间点标记
1:记录为CHANGE MASTER TO语句,此语句不被注释;
2:记录为CHANGE MASTER TO语句,此语句被注释;
以下就是=2时备份文件中出现的内容
-- CHANGE MASTER TO MASTER_LOG_FILE='mariadb-bin.000003', MASTER_LOG_POS=15335;
表示指明那个二进制文件,和保存时处于什么位置
--flush-logs:锁定表完成后,即进行日志刷新操作(只能滚动二进制日志);
mysqldump备份使用方法
备份数据库
~]# mysqldump -uroot -h127.0.0.1 -p --databases hellodb > /tmp/hellodb.sql
备份多个数据库
~]# mysqldump -uroot -h127.0.0.1 -p --databases hellodb mysql > /tmp/hellodb_mydb.sql
备份与还原
备份,完全备份
~]# mysqldump -uroot -hlocalhost --all-databases --lock-all-tables --master-data=2 > /root/all.sql
还原完全备份的文件+binlog
(1)还原完全备份
1、关闭二进制日志功能;
set sql_log_bin=OFF;
2、启动数据库
3、导入之前备份的文件并导入
~]# mysql < all.sql 或者 > source /tmp/all.sql
(2)还原至时间点
1、首先查看备份时的二进制文件位置
2、由二进制日志文件导出还原点之前的二进制日志
~]# mysqlbinlog --start-position=16842 ./mariadb-bin.000003 > binlog1.sql
3、把此文件导入mysql
~]# mysql < binlog1.sql
(3)打开二进制日志功能并刷新日志
1、开启日志功能
2、刷新日志文件
> flush logs;
注意:
1、二进制日志文件不应该与数据文件放在同一磁盘上
2、如果数据不大最少应该每周做一次完全备份,每天或着每6个小时来刷新日志(flush logs),复制二进制日志文件做增量备份
实战(2)基于lvm2的备份:
前提:数据目录位于逻辑卷,包含了数据文件和事务日志;
(1) 请求锁定所有表;
mysql> FLUSH TABLES WITH READ LOCK;
(2) 记录二进制文件事件位置;
mysql> FLUSH LOGS;
mysql> SHOW MASTER STATUS;
mysql -e 'SHOW MASTER STATUS;' >> /PATH/TO/SOME_POS_FILE
(3) 创建快照卷
lvcreate -L # -s -p r - SNAM-NAME /dev/VG-NAME/LV-NAME
(4) 释放锁
mysql> UNLOCK TABLES
(5) 挂载快照卷,并执行备份;
(6) 周期性备份二进制日志,通过原卷备份二进制日志;
实战(3)Xtrabackup:
MyISAM:温备,不支持增量备份;
InnoDB:热备,增量;
物理备份,速率快、可靠;备份完成后自动校验备份结果集是否可用;还原速度快;
Usage: [innobackupex [--defaults-file=#] --backup | innobackupex [--defaults-file=#] --prepare] [OPTIONS]
完全+binlog(总结):
预备:要确认innodb_file_per_table=ON
(1)准备工作
从官方找到对应版本的rpm包并下载
https://www.percona.com/downloads/XtraBackup/LATEST/
这里我下载的是 percona-xtrabackup-2.3.2-1.el7.x86_64.rpm
1、创建用户并授权能访问
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;
全库备份:
1、物理上的数据文件备份
innobackupex --user --password= --host= /PATH/TO/BACKUP_DIR
2、把此生成的文件保存下来
恢复(期间mysql是关闭状态):
1、删除原有的数据保存目录下(/var/lib/mysql/*)所有文件
2、整理事务日志中的已提交的事务数据:
innobackupex --apply-log /PATH/TO/BACKUP_DIR
3、执行数据的复制操作
innobackupex --copy-back /PATH/TO/BACKUP_DIR
4、把数据保存目录下的所有文件改属主属组。
chown -R mysql.mysql /var/lib/mysql/*
5、这里还是会启动不了可以,删除这里的事务日志,因为与默认的不相符,或者按下边日志上说的做
注意:–copy-back需要在mysqld主机本地进行,mysqld服务不能启动;
innodb_log_file_size可能要重新设定;
增量备份
1.执行增量备份
innobackupex --user --password='' --host='' --incremental=BBB --incremental-basedir=/AAA
表示相对于/AAA 这个备份目录做备份操作,备份后的保存位置/BBB
2.恢复:
“准备”(prepare)增量备份与整理完全备份有着一些不同,尤其要注意的是:
(1)需要在每个备份(包括完全和各个增量备份)上,将已经提交的事务进行“重放”。“重放”之后,所有的备份数据将合并到完全备份上。
(2)基于所有的备份将未提交的事务进行“回滚”。
1.于是,操作就变成了(整理完全备份并应用事务日志):
# innobackupex --apply-log --redo-only BASE-DIR
2.接着执行整理第一个增量备份:
# innobackupex --apply-log --redo-only BASE-DIR --incremental-dir=INCREMENTAL-DIR-1
3.而后是第二个增量:
# innobackupex --apply-log --redo-only BASE-DIR --incremental-dir=INCREMENTAL-DIR-2
4.执行恢复操作
innobackupex --copy-back BASEDIR
改下属主属组,然后确保事务日志是否为默认大小,或者删了也行
5.最后应用二进制日志文件
mysqlbinlog --start-position=1714 ./mariadb-bin.000002 > binlog1.sql
~]# mysql < binlog1.sql
启动就OK!
备份单库:
--databases
总结:完全+增量+binlog
备份:完全+增量+增量+…
完全+差异
使用Xtrabackup进行MySQL备份:
一、安装
1、简介
Xtrabackup是由percona提供的mysql数据库备份工具,据官方介绍,这也是世界上惟一一款开源的能够对innodb和xtradb数据库进行热备的工具。特点:
(1)备份过程快速、可靠;
(2)备份过程不会打断正在执行的事务;
(3)能够基于压缩等功能节约磁盘空间和流量;
(4)自动实现备份检验;
(5)还原速度快;
2、安装
其最新版的软件可从 http://www.percona.com/software/percona-xtrabackup/ 获得。本文基于RHEL5.8的系统,因此,直接下载相应版本的rpm包安装即可,这里不再演示其过程。
二、备份的实现
1、完全备份
# innobackupex --user=DBUSER --password=DBUSERPASS /path/to/BACKUP-DIR/
如果要使用一个最小权限的用户进行备份,则可基于如下命令创建此类用户:
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 /path/to/BACKUP-DIR
如果执行正确,其最后输出的几行信息通常如下:
xtrabackup: starting shutdown with innodb_fast_shutdown = 1
120407 9:01:36 InnoDB: Starting shutdown...
120407 9:01:40 InnoDB: Shutdown completed; log sequence number 92036620
120407 09:01:40 innobackupex: completed OK!
在实现“准备”的过程中,innobackupex通常还可以使用–use-memory选项来指定其可以使用的内存的大小,默认通常为100M。如果有足够的内存可用,可以多划分一些内存给prepare的过程,以提高其完成速度。
3、从一个完全备份中恢复数据
注意:恢复不用启动MySQL
innobackupex命令的–copy-back选项用于执行恢复操作,其通过复制所有数据相关的文件至mysql服务器DATADIR目录中来执行恢复过程。innobackupex通过backup-my.cnf来获取DATADIR目录的相关信息。
innobackupex --copy-back /path/to/BACKUP-DIR
如果执行正确,其输出信息的最后几行通常如下:
innobackupex: Starting to copy InnoDB log files
innobackupex: in '/backup/2012-04-07_08-17-03'
innobackupex: back to original InnoDB log directory '/mydata/data'
innobackupex: Finished copying back files.
120407 09:36:10 innobackupex: completed OK!
请确保如上信息的最行一行出现“innobackupex: completed OK!”。
当数据恢复至DATADIR目录以后,还需要确保所有数据文件的属主和属组均为正确的用户,如mysql,否则,在启动mysqld之前还需要事先修改数据文件的属主和属组。如:
chown -R mysql:mysql /mydata/data/
4、使用innobackupex进行增量备份
每个InnoDB的页面都会包含一个LSN信息,每当相关的数据发生改变,相关的页面的LSN就会自动增长。这正是InnoDB表可以进行增量备份的基础,即innobackupex通过备份上次完全备份之后发生改变的页面来实现。
要实现第一次增量备份,可以使用下面的命令进行:
innobackupex --incremental /backup --incremental-basedir=BASEDIR
其中,BASEDIR指的是完全备份所在的目录,此命令执行结束后,innobackupex命令会在/backup目录中创建一个新的以时间命名的目录以存放所有的增量备份数据。另外,在执行过增量备份之后再一次进行增量备份时,其–incremental-basedir应该指向上一次的增量备份所在的目录。
需要注意的是,增量备份仅能应用于InnoDB或XtraDB表,对于MyISAM表而言,执行增量备份时其实进行的是完全备份。
“准备”(prepare)增量备份与整理完全备份有着一些不同,尤其要注意的是:
(1)需要在每个备份(包括完全和各个增量备份)上,将已经提交的事务进行“重放”。“重放”之后,所有的备份数据将合并到完全备份上。
(2)基于所有的备份将未提交的事务进行“回滚”。
于是,操作就变成了:
# innobackupex --apply-log --redo-only BASE-DIR
接着执行:
# innobackupex --apply-log --redo-only BASE-DIR --incremental-dir=INCREMENTAL-DIR-1
而后是第二个增量:
# innobackupex --apply-log --redo-only BASE-DIR --incremental-dir=INCREMENTAL-DIR-2
其中BASE-DIR指的是完全备份所在的目录,而INCREMENTAL-DIR-1指的是第一次增量备份的目录,INCREMENTAL-DIR-2指的是第二次增量备份的目录,其它依次类推,即如果有多次增量备份,每一次都要执行如上操作;
5、Xtrabackup的“流”及“备份压缩”功能
Xtrabackup对备份的数据文件支持“流”功能,即可以将备份的数据通过STDOUT传输给tar程序进行归档,而不是默认的直接保存至某备份目录中。
要使用此功能,仅需要使用–stream选项即可。如:
# innobackupex --stream=tar /backup | gzip > /backup/`date +%F_%H-%M-%S`.tar.gz
甚至也可以使用类似如下命令将数据备份至其它服务器:
# innobackupex --stream=tar /backup | ssh user@www.magedu.com "cat - > /backups/`date +%F_%H-%M-%S`.tar"
此外,在执行本地备份时,还可以使用–parallel选项对多个文件进行并行复制。此选项用于指定在复制时启动的线程数目。当然,在实际进行备份时要利用此功能的便利性,也需要启用innodb_file_per_table选项或共享的表空间通过innodb_data_file_path选项存储在多个ibdata文件中。
对某一数据库的多个文件的复制无法利用到此功能。其简单使用方法如下:
# innobackupex --parallel /path/to/backup
同时,innobackupex备份的数据文件也可以存储至远程主机,这可以使用–remote-host选项来实现:
# innobackupex --remote-host=root@www.magedu.com /path/IN/REMOTE/HOST/to/backup
6、导入或导出单张表
默认情况下,InnoDB表不能通过直接复制表文件的方式在mysql服务器之间进行移植,即便使用了innodb_file_per_table选项。而使用Xtrabackup工具可以实现此种功能,不过,此时需要“导出”表的mysql服务器启用了innodb_file_per_table选项(严格来说,是要“导出”的表在其创建之前,mysql服务器就启用了innodb_file_per_table选项),并且“导入”表的服务器同时启用了innodb_file_per_table和innodb_expand_import选项。
(1)“导出”表
导出表是在备份的prepare阶段进行的,因此,一旦完全备份完成,就可以在prepare过程中通过–export选项将某表导出了:
# innobackupex --apply-log --export /path/to/backup
此命令表示对 /path/to/backup 这个完全备份的目录进行导出操作
此命令会为每个innodb表的表空间创建一个以.exp结尾的文件,这些以.exp结尾的文件则可以用于导入至其它服务器。
(2)“导入”表
要在mysql服务器上导入来自于其它服务器的某innodb表,需要先在当前服务器上创建一个跟原表表结构一致的表,而后才能实现将表导入:
mysql> CREATE TABLE mytable (...) ENGINE=InnoDB;
此命令表示创建一个对应文件名的表可以先用 · show create table hellodb.students;· 来查看那张表的表空间
然后将此表的表空间删除:
mysql> ALTER TABLE mydatabase.mytable DISCARD TABLESPACE;
更改属主属组
chown mysql.mysql ...
接下来,将来自于“导出”表的服务器的mytable表的mytable.ibd和mytable.exp文件复制到当前服务器的数据目录,然后使用如下命令将其“导入”:
mysql> ALTER TABLE mydatabase.mytable IMPORT TABLESPACE;
7、使用Xtrabackup对数据库进行部分备份
Xtrabackup也可以实现部分备份,即只备份某个或某些指定的数据库或某数据库中的某个或某些表。但要使用此功能,必须启用innodb_file_per_table选项,即每张表保存为一个独立的文件。同时,其也不支持–stream选项,即不支持将数据通过管道传输给其它程序进行处理。
此外,还原部分备份跟还原全部数据的备份也有所不同,即你不能通过简单地将prepared的部分备份使用–copy-back选项直接复制回数据目录,而是要通过导入表的方向来实现还原。当然,有些情况下,部分备份也可以直接通过–copy-back进行还原,但这种方式还原而来的数据多数会产生数据不一致的问题,因此,无论如何不推荐使用这种方式。
(1)创建部分备份
创建部分备份的方式有三种:正则表达式(–include), 枚举表文件(–tables-file)和列出要备份的数据库(–databases)。
(a)使用–include
使用–include时,要求为其指定要备份的表的完整名称,即形如databasename.tablename,如:
# innobackupex --include='^mageedu[.]tb1' /path/to/backup
(b)使用–tables-file
此选项的参数需要是一个文件名,此文件中每行包含一个要备份的表的完整名称;如:
# echo -e 'mageedu.tb1\nmageedu.tb2' > /tmp/tables.txt
# innobackupex --tables-file=/tmp/tables.txt /path/to/backup
(c)使用–databases
此选项接受的参数为数据名,如果要指定多个数据库,彼此间需要以空格隔开;同时,在指定某数据库时,也可以只指定其中的某张表。此外,此选项也可以接受一个文件为参数,文件中每一行为一个要备份的对象。如:
# innobackupex --databases="mageedu testdb" /path/to/backup
(2)整理(preparing)部分备份
prepare部分备份的过程类似于导出表的过程,要使用–export选项进行:
# innobackupex --apply-log --export /pat/to/partial/backup
此命令执行过程中,innobackupex会调用xtrabackup命令从数据字典中移除缺失的表,因此,会显示出许多关于“表不存在”类的警告信息。同时,也会显示出为备份文件中存在的表创建.exp文件的相关信息。
(3)还原部分备份
还原部分备份的过程跟导入表的过程相同。当然,也可以通过直接复制prepared状态的备份直接至数据目录中实现还原,不要此时要求数据目录处于一致状态。
原创文章,作者:qzx,如若转载,请注明出处:http://www.178linux.com/60400