MySQL 备份恢复
================================================================================
概述:
================================================================================
1.介绍
★备份:存储的数据副本;
原始数据:持续改变;(考虑问题)
★恢复:把副本应用到线上系统;
仅能恢复至备份操作时刻的数据状态;
★时间点恢复:
binary logs; (二进制日志)
★为什么备份?
灾难恢复:硬件故障(冗余)、软件故障(bug)、自然灾害、黑客攻击、误操作、...
测试;
★备份时应该注意事项:
能容忍最多丢失多少数据;
恢复数据需要在多长时间内完成;
需要恢复哪些数据;
☉做恢复演练:
测试备份的可用性;
增强恢复操作效率;
...
2.备份类型
★备份的数据的集范围:
☉完全备份和部分备份
完全备份:整个数据集;
部分备份:数据集的一部分,比如部分表;
★完全备份、增量备份、差异备份:
完全备份
增量备份:仅备份自上一次完全备份或增量备份以来变量的那部分数据;
差异备份:仅备份自上一次完全备份以来变量的那部数据;
★物理备份、逻辑备份:
物理备份:复制数据文件进行备份;
逻辑备份:从数据库导出数据另存在一个或多个文件中;
★根据数据服务是否在线:
热备:读写操作均可进行的状态下所做的备份;
温备:可读但不可写状态下进行的备份;
冷备:读写操作均不可进行的状态下所做的备份;
3.备份需要考虑的因素、备份策略及备份内容
★备份需要考虑因素:
锁定资源多长时间?
备份过程的时长?
备份时的服务器负载?
恢复过程的时长?
★备份策略:
完全+差异+时间点还原(二进制日志binlog)
完全+增量+时间点还原 (二进制日志binlog)
注意:事务日志和二进制日志应该放在有冗余能力的磁盘上,RAID10最好
★备份手段:
物理
逻辑
★备份什么?
数据
二进制日志、InnoDB的事务日志;
代码(存储过程、存储函数、触发器、事件调度器)
服务器的配置文件
★备份,多久一次?
数据变化量;
可用的备份存储空间;
4.备份工具:
★mysqldump:mysql服务自带的备份工具;逻辑备份工具;
完全、部分备份;
InnoDB:热备;
MyISAM:温备;
★cp/tar
lvm2:快照(请求一个全局锁),之后立即释放锁,达到几乎热备的效果;物理备份;
注意:不能仅备份数据文件;要同时备份事务日志;
前提:要求数据文件和事务日志位于同一个逻辑卷;
★xtrabackup:
由Percona提供,开源工具,支持对InnoDB做热备,物理备份工具;
完全备份、部分备份;
完全备份、增量备份;
完全备份、差异备份;
★mysqlhotcopy
★select:
备份:SELECT cluase INTO OUTFILE ‘FILENAME‘;
恢复:CREATE TABLE
导入:LOAD DATA
★作用:
逻辑备份、完全备份、部分备份;
★二次封装工具:
mydumper //能够实现并行备份
phpMyAdmin
★Usage:
mysqldump [OPTIONS] database [tables]
//只备份指定库中的所有表,没有create database语句
mysqldump [OPTIONS] --databases [OPTIONS] DB1 [DB2 DB3...]
//可以备份多个数据库,也可以指定备份哪个数据库
mysqldump [OPTIONS] --all-databases [OPTIONS]
//备份所有数据库
★MyISAM存储引擎:支持温备,备份时要锁定表;
-x, --lock-all-tables:锁定所有库的所有表,读锁;
-l, --lock-tables:锁定指定库所有表;
★InnoDB存储引擎:支持温备和热备;
--single-transaction:创建一个事务,基于此快照执行备份;
注意:一定要备份时间点一致的数据
★其它选项:
-R, --routines:存储过程和存储函数;
--triggers //触发器
-E, --events //时间调度器
--master-data[=#]
记录备份那一刻开始时binlog处于哪一个文件的哪一个位置
1:记录为CHANGE MASTER TO语句,此语句不被注释;
2:记录为CHANGE MASTER TO语句,此语句被注释;
--flush-logs:锁定表完成后,即进行日志刷新操作(使二进制日志滚动一下);
★使用备份脚本实现自动化备份
注意:
数据备份时要保留备份时的时间戳作为备份文件名的一部分;
备份好的文件要做异地另存;
演示:
1.备份hellodb数据库的所有表,操作如下:
[root@centos7 ~]# mkdir mysql.bak # 这里我先创建一个专门存放备份的目录 # 使用mysqldump 指明用户账户,要备份的数据库和重定向的位置即可 [root@centos7 ~]# mysqldump -uroot -hlocalhost -ptaoxiu hellodb > ./mysql.bak/hellodb.sql.1 [root@centos7 ~]# ls ./mysql.bak/ hellodb.sql.1 # 查看备份的hellodb数据库,可以看到表头显示的版本信息,数据库名称等 [root@centos7 ~]# cat mysql.bak/hellodb.sql.1 -- MySQL dump 10.14 Distrib 5.5.44-MariaDB, for Linux (x86_64) -- -- Host: localhost Database: hellodb -- ------------------------------------------------------ -- Server version 5.5.44-MariaDB /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; /*!40101 SET NAMES utf8 */; /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; /*!40103 SET TIME_ZONE=‘+00:00‘ */; /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE=‘NO_AUTO_VALUE_ON_ZERO‘ */; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
2.如上题,因为我们仅是备份指定数据库的所有表,所以没有create database语句,现在我们添加
--databases选项来备份,可以指明要备份的单个或者多个数据库,这样的话就create database语句了;
[root@centos7 ~]# mysqldump -uroot -hlocalhost -ptaoxiu --databases hellodb > ./mysql.bak/hellodb.sql.2 [root@centos7 ~]# ll -h mysql.bak total 16K -rw-r--r-- 1 root root 7.6K Dec 2 18:27 hellodb.sql.1 -rw-r--r-- 1 root root 7.8K Dec 2 18:41 hellodb.sql.2 [root@centos7 ~]# cat mysql.bak/hellodb.sql.2 -- MySQL dump 10.14 Distrib 5.5.44-MariaDB, for Linux (x86_64) -- -- Host: localhost Database: hellodb -- ------------------------------------------------------ -- Server version 5.5.44-MariaDB /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; /*!40101 SET NAMES utf8 */; /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; /*!40103 SET TIME_ZONE=‘+00:00‘ */; /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE=‘NO_AUTO_VALUE_ON_ZERO‘ */; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; -- -- Current Database: `hellodb` -- # 存在创建数据库的语句 CREATE DATABASE /*!32312 IF NOT EXISTS*/ `hellodb` /*!40100 DEFAULT CHARACTER SET utf8 */; USE `hellodb`;
3.备份整个数据库,使用--all-databases选项
[root@centos7 ~]# mysqldump -uroot -hlocalhost -ptaoxiu --all-databases > ./mysql.bak/data.sql.3 [root@centos7 ~]# ll -h mysql.bak total 15M -rw-r--r-- 1 root root 15M Dec 2 18:45 data.sql.3 # 备份的所有数据库,明显文件大很多 -rw-r--r-- 1 root root 7.6K Dec 2 18:27 hellodb.sql.1 -rw-r--r-- 1 root root 7.8K Dec 2 18:41 hellodb.sql.2
4.假如我们的备份策略为完全+增量+binlog备份,要使用binlog二进制日志重读,就要确定从备份那一刻开始,binlog的起始文件位置,这时就要使用--master-data=[#]选项,(确保二进制日志是开启的)
[root@centos7 ~]# mysqldump -uroot -hlocalhost -ptaoxiu --master-data=2 --databases hellodb > ./mysql.bak/hellodb.sql.2 [root@centos7 ~]# cat mysql.bak/hellodb.sql.2 -- MySQL dump 10.14 Distrib 5.5.44-MariaDB, for Linux (x86_64) -- -- Host: localhost Database: hellodb -- ------------------------------------------------------ -- Server version 5.5.44-MariaDB-log /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; /*!40101 SET NAMES utf8 */; /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; /*!40103 SET TIME_ZONE=‘+00:00‘ */; /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE=‘NO_AUTO_VALUE_ON_ZERO‘ */; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; -- -- Position to start replication or point-in-time recovery from -- # 可以看到在备份的那一刻,二进制日志处在master-log.000004,POS为245 -- CHANGE MASTER TO MASTER_LOG_FILE=‘master-log.000003‘, MASTER_LOG_POS=245; -- -- Current Database: `hellodb` -- CREATE DATABASE /*!32312 IF NOT EXISTS*/ `hellodb` /*!40100 DEFAULT CHARACTER SET utf8 */; USE `hellodb`;
-----------------------------------------------------------------------
基于备份做时间点恢复数据库:
如上,我们已经备份好了hellodb的数据库,假如在备份之后,用户又修改了hellodb数据库的内容,之后hellodb数据库因为某些原因挂了,这时,我们除了借助于备份的数据库之外,还要借助于二进制日志文件binlog才能把数据库恢复到崩溃前的时间点。
1.为了演示效果这里我首先修改一下hellodb数据库,模拟在hellodb数据库数据备份之后,崩溃之前,用户增加,修改的hellodb数据库中的内容,如下:
MariaDB [hellodb]> SELECT * FROM courses; # 修改之前的hellodb数据库courses表 +----------+----------------+ | CourseID | Course | +----------+----------------+ | 1 | Hamo Gong | | 2 | Kuihua Baodian | | 3 | Jinshe Jianfa | | 4 | Taijiquan | | 5 | Daiyu Zanghua | | 6 | Weituo Zhang | | 7 | Dagou Bangfa | | 14 | Zabbix | +----------+----------------+ 8 rows in set (0.00 sec) MariaDB [hellodb]> INSERT INTO courses (Course) VALUES (‘Puppet‘),(‘Ansible‘); Query OK, 2 rows affected (0.01 sec) Records: 2 Duplicates: 0 Warnings: 0 MariaDB [hellodb]> DELETE FROM courses WHERE CourseID=2; Query OK, 1 row affected (0.07 sec) MariaDB [hellodb]> SELECT * FROM courses; # 修改之后的hellodb数据库courses表 +----------+---------------+ | CourseID | Course | +----------+---------------+ | 1 | Hamo Gong | | 3 | Jinshe Jianfa | | 4 | Taijiquan | | 5 | Daiyu Zanghua | | 6 | Weituo Zhang | | 7 | Dagou Bangfa | | 14 | Zabbix | | 15 | Puppet | | 16 | Ansible | +----------+---------------+ 9 rows in set (0.00 sec) MariaDB [(none)]> drop database hellodb; # 删除hellodb数据库,模拟数据库崩溃 Query OK, 7 rows affected (0.08 sec)
2.如上hellodb数据库已经崩溃,现在要做恢复,就要准备好备份的数据库文件hellodb.sql和要做时间点恢复的二进制日志文件,如下:
1)首先准备要做时间点恢复的二进制日志文件
# 首先准备二进制日志文件 [root@centos7 ~]# ls /var/lib/mysql/ aria_log.00000001 centos7.log ibdata1 ib_logfile1 master-log.000002 master-log.000004 mydb mysql.sock Syslog testdb zabbix aria_log_control centos7-slow.log ib_logfile0 master-log.000001 master-log.000003 master-log.index mysql performance_schema test ultrax # 因为我最后执行的那个DELETE删除hellodb数据库的命令也会被记录在二进制日志文件中,所以, # 要把最后的那个position截取掉,这里我重定向到/tmp/如下: [root@centos7 ~]# mysqlbinlog --stop-position=7996 /var/lib/mysql/master-log.000004 > /tmp/mylog.sql
2)准备好备份好的hellodb数据库的备份文件hellodb.sql
[root@centos7 ~]# ls mysql.bak data.sql.3 hellodb.sql.1 hellodb.sql.2 hellodb.sql.4 [root@centos7 ~]# cp mysql.bak/hellodb.sql.2 /tmp/hellodb.sql # 假设在/tmp目录下 [root@centos7 ~]# ls /tmp/
3.测试,登录数据库,因为在恢复数据时会执行大量的写操作,但没有必要记录在二进制日志文件中,所以,可以关闭当前会话的二进制日志文件;然后倒入hellodb.sql脚本,可以发现hellodb数据库正常恢复到备份的时间点的数据,如下:
[root@centos7 ~]# mysql -ptaoxiu Welcome to the MariaDB monitor. Commands end with ; or \g. MariaDB [(none)]> SET sql_log_bin=OFF; # 关闭当前会话的二进制日志文件 Query OK, 0 rows affected (0.00 sec) MariaDB [(none)]> \. /tmp/hellodb.sql # 倒入hellodb.sql脚本文件 Query OK, 0 rows affected (0.00 sec) Query OK, 0 rows affected (0.00 sec) Query OK, 0 rows affected (0.00 sec) Query OK, 0 rows affected (0.00 sec) Query OK, 0 rows affected (0.00 sec) Query OK, 0 rows affected (0.00 sec) Query OK, 0 rows affected (0.00 sec) Query OK, 0 rows affected (0.00 sec) Query OK, 0 rows affected (0.00 sec) Query OK, 0 rows affected (0.00 sec) ... MariaDB [hellodb]> select * from courses; # 查询发现数据已经恢复到备份时间点的数据 +----------+----------------+ | CourseID | Course | +----------+----------------+ | 1 | Hamo Gong | | 2 | Kuihua Baodian | | 3 | Jinshe Jianfa | | 4 | Taijiquan | | 5 | Daiyu Zanghua | | 6 | Weituo Zhang | | 7 | Dagou Bangfa | | 14 | Zabbix | +----------+----------------+ 8 rows in set (0.00 sec)
4.接下来,我们要想恢复到数据库崩溃之前的时间点,就要借助于二进制日志文件来恢复,如下:
MariaDB [(none)]> \. /tmp/mylog.sql # 导入二进制日志文件的sql脚本 Query OK, 0 rows affected (0.00 sec) Query OK, 0 rows affected (0.00 sec) Query OK, 0 rows affected (0.00 sec) Query OK, 0 rows affected (0.00 sec) Query OK, 0 rows affected (0.00 sec) Query OK, 0 rows affected (0.00 sec) ... MariaDB [hellodb]> select * from courses; # 查看数据可以发现,hellodb库的courses表恢复到了崩溃前我们修改的数据状态了 +----------+---------------+ | CourseID | Course | +----------+---------------+ | 1 | Hamo Gong | | 3 | Jinshe Jianfa | | 4 | Taijiquan | | 5 | Daiyu Zanghua | | 6 | Weituo Zhang | | 7 | Dagou Bangfa | | 14 | Zabbix | | 15 | Puppet | | 16 | Ansible | +----------+---------------+ 9 rows in set (0.00 sec) MariaDB [(none)]> SET sql_log_bin=ON; # 开启记录二进制日志的文件 Query OK, 0 rows affected (0.00 sec)
★备份过程如下:
★
本文出自 “逐梦小涛” 博客,请务必保留此出处http://1992tao.blog.51cto.com/11606804/1879047
原文地址:http://1992tao.blog.51cto.com/11606804/1879047