MySQL备份与恢复
一、前言
1.1 是什么?
MySQL的备份你可以理解为将原始数据复制或者做了一个副本,而恢复即指把副本应用到线上系统。但由于原始数据在持续的变化,而我们的备份操作却不能一直进行,所以这时候副本就不会包括原始数据库的所有信息,所以仅能恢复到备份时刻的数据状态。而如果我们想要做更为复杂的时间点恢复,就需要二进制日志的帮助。
1.2 为很么备份与恢复?
我们不能保证服务器成为永动机,所以我们就必须要做备份,尤其是数据库服务器。而且数据的重要性不言而喻,数据是最重要的资源之一。造成服务器故障的原因有很多,其中包括但不限于这些故障:硬件故障,软件故障,自然灾害,******,管理员从删库到跑路等等。硬件故障我们可以通过冗余解决,软件故障那我们就需要修复BUG,自然灾害就需要通过异地灾备解决了,******那就需要做好安全工作,而删库到跑路那就只能祈祷了。每一个程序猿都不容易,请善待每一个程序猿。那在服务器出现故障的之后,我们凭什么使服务正常运行,其中的重要一环就是数据恢复了。
1.3 如何做备份与恢复?
1.3.1 备份的类型
根据备份的数据范围可以分为全部备份和部分备份。全部备份即指备份整个数据集,一般耗时极长;部分备份即指只备份数据集的一部分,比如部分库,部分表。
根据数据的备份量可以分为全量备份、增量备份、差异备份。全量备份即指全部数据都备份;增量备份即指备份上一次全量备份或者增量备份以来变化的所有数据;差异备份即指仅备份上一次全量备份以来变化的所有的数据。
备份还可以分为物理备份和逻辑备份。物理备份即指复制数据文件进行备份;逻辑备份即指从数据库导出数据另存在一个或多个文件中。
根据数据库服务器是否在线可以分为热备、温备、冷备。热备指服务器读写状态下所做的备份;温备指服务器只读不可写状态下所做的备份;冷备指服务器读写均不可操作的状态下所做的备份。
1.3.2 备份时考虑的因素?
什么时候备份?
备份与恢复数据过程的时长?
需要备份和恢复那些数据?
备份时服务器的负载?
能容忍最多丢失多少数据?
这些问题没有标准答案,应该结合自己公司实际的生产环境规划。
1.3.3 备份策略
全量备份+差异备份+二进制日志备份
全量备份+增量备份+二进制日志备份
1.3.4 备份什么?
我们可以备份数据、二进制日志、InnoDB的事务日志、代码(存储过程、存储函数、触发器、时间调度器、服务器的配置文件)等等。
1.3.5 备份工具
1 Mysqldump
MySQL自带的逻辑备份工具。支持全量备份和部分备份;InnoDB支持热备,MyISAM引擎仅支持温备。
2 cp/tar
LVM快照的备份方式。快照请求一个全局锁,之后立即释放锁,能达到几乎热备的效果,属于物理备份。用这种备份有个前提:即要求数据文件和事务日志位于同一个逻辑卷,数据文件和事务日志都要进行备份。
3 Xtrabackup
由开源组织Percona提供的一款开源的物理备份工具,支持InnoDB热备。是目前比较流行的备份工具。
二、Mysqldump备份与恢复
2.1 思路
Mysqldump是逻辑备份工具,可以进行全量备份和增量备份。
Mysqldump命令的工作原理十分简单,它先查出需要备份的表的结构,再生成CREATE语句和INSERT语句。在恢复数据的时候,这些语句就发挥作用了。恢复的过程是这样的,首先使用CREATE语句创建表,然后使用INSERT语句插入数据使数据恢复。Mysqldump可以备份整个数据库抑或部分数据库,单个表抑或多个表,表中的行,存储过程,存储函数,触发器以及二进制日志文件。如果要增量备份的话,必须要开启二进制日志的功能。MyISAM存储引擎支持温备,备份的时候要锁定表;而InnoDB存储引擎则支持温备和热备。
2.2 Mysqldump命令的用法
Mysqldump有三种常用的用法格式,而mysqldump的选项很多,因此不便一一介绍,我会结合具体用法介绍选项的作用。
Usage: mysqldump [OPTIONS] database [tables] mysqldump [OPTIONS] --databases [OPTIONS] DB1 [DB2 DB3...] mysqldump [OPTIONS] --all-databases [OPTIONS]
2.3 备份策略
Mysqldump全备+二进制日志增备
实现过程如下:
1)Mysqldump全备
mysqldump -uroot -p123456 --lock-all-tables --master-data=2 --events --routines --all-databases > /apps/data_backup/database_`date +%F`.sql
解释: --lock-all-tables 锁定所有库的所有表,施加读锁 --master-data=2 表示在备份文件中记录当前二进制日志的位置 --events 备份时间调度器的代码 --routines 备份存储过程和存储函数 --all-databases 备份所有库
2)查看备份文件
less /apps/data_backup/database_2017-07-31.sql -- Position to start replication or point-in-time recovery from -- #下行表示备份的数据保存在log-bin.000001,二进制日志位置为:245 -- CHANGE MASTER TO MASTER_LOG_FILE='log-bin.000001', MASTER_LOG_POS=245; -- -- Current Database: `NEW` --
3)二进制全备
方法:滚动日志复制文件
#滚动日志 mariadb root@localhost:(none)> FLUSH LOGS; Query OK, 0 rows affected Time: 0.008s [root@mysql2 mysql]# pwd /var/lib/mysql #复制导出文件 [root@mysql2 mysql]# cp log-bin.000001 /apps/data_backup/log-bin.000001
4)二进制增备
#先创建一张表 CREATE DATABASE newdb; use newdb; mariadb root@localhost:new_db> CREATE TABLE tb1(id int not null); MariaDB [newdb]> SHOW MASTER STATUS; #查看目前的二进制日志位置 mariadb root@localhost:new_db> SHOW MASTER STATUS; +----------------+------------+----------------+--------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | |----------------+------------+----------------+--------------------| | log-bin.000002 | 430 | | | +----------------+------------+----------------+--------------------+
#二进制备份 mysqlbinlog --start-position=245 --stop-position=430 log-bin.000001 > /apps/data_backup/binlog_`date +%F_%H`.sql
解释: #上次备份的二进制日志位置 --start-position=245 #目前的二进制日志位置 --stop-position=430
5)模拟日志损坏,实现恢复工作
DROP DATABASE new_db;
恢复的时候是离线的,备份的时候是在线的!
恢复的时候是离线的,备份的时候是在线的!
重要的事情说两遍!
#首先导入全量备份
mysql -u root -p123456 < /apps/data_backup/database_2017-07-31.sql
#导入增量备份
mysql -u root -p123456 < /apps/data_backup/binlog_2017-07-31_12.sql
#登陆查看,确认是否恢复
mysql -u root -p123456
三、Xtrabackup备份与恢复
4.1 全量备份与恢复
Xtrabackup备份与恢复三步走:备份、预处理、恢复
#创建备份目录
mkdir /innobackup cd /innobackup
#备份
[root@mysql2 innobackup]# innobackupex --user=root --password=123456 . xtrabackup: Transaction log of lsn (3764389) to (3764389) was copied. 170731 12:56:38 completed OK! #表示成功
#预处理,将未提交的事务进行回滚
innobackupex --apply-log /innobackup/2017-07-31_12-56-34/ InnoDB: Shutdown completed; log sequence number 3764785 170731 13:00:53 completed OK!
#模拟故障
[root@mysql2 ~]# systemctl stop mariadb [root@mysql2 ~]# cd /var/lib/mysql/ rm -rf *
#恢复
innobackupex --copy-back /innobackup/2017-07-31_12-56-34/ 170731 13:04:19 [01] Copying ./ibtmp1 to /var/lib/mysql/ibtmp1 170731 13:04:19 [01] ...done 170731 13:04:20 completed OK!
#改变属组
chown -R mysql:mysql /var/lib/mysql/
#启动并查看是否恢复
[root@mysql2 ~]# systemctl start mariadb [root@mysql2 ~]# [root@mysql2 ~]# mysql -u root -p123456 MariaDB [(none)]> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | NEW | | dbtest | | hellodb | | hidb | | mydb | | mysql | | mytest | | performance_schema | | test | | testdb | | vsftpd | | wordpress | +--------------------+
#立即进行一次全量备份
innobackupex --user=root --password=123456 /innobackup/
4.2 增量备份
#新建一个表
mariadb root@localhost:hidb> CREATE TABLE tb1 (id INT NOT NULL,name VARCHAR(15)); Query OK, 0 rows affected Time: 0.038s
#插入数据
mariadb root@localhost:hidb> INSERT INTO tb1 VALUES(1,'michael'); Query OK, 1 row affected Time: 0.003s
#增量备份
innobackupex --user=root --password=123456 --incremental /innobackup/ --incremental-basedir=/innobackup/2017-07-31_13-08-28/ xtrabackup: Transaction log of lsn (3768140) to (3768140) was copied. 170731 13:28:22 completed OK! #备份成功
#再次插入数据
mariadb root@localhost:hidb> INSERT INTO tb1 VALUES(2,'neo'); Query OK, 1 row affected Time: 0.003s
#查看数据
mariadb root@localhost:hidb> SELECT * from tb1; +------+---------+ | id | name | |------+---------| | 1 | michael | | 2 | neo | +------+---------+
#基于上一次增量备份做增量备份
innobackupex --user=root --password=123456 --incremental /innobackup/ --incremental-basedir=/innobackup/2017-07-31_13-28-17/ xtrabackup: Transaction log of lsn (3768449) to (3768449) was copied. 170731 13:32:17 completed OK!