MySQL备份与恢复
MySQL备份与恢复
数据备份的重要性
在生产环境中,数据的安全性至关重要
任何数据的丢失都可能产生严重的后果
造成数据丢失的原因
程序错误
人为操作错误
运算错误
磁盘故障
灾难(如火灾,地震)和盗窃
数据库备份的分类
从物理与逻辑的角度,备份可分为
物理备份:
对数据库操作系统的物理文件(如数据文件,日志文件等)的备份
物理备份方法:
冷备份(脱机备份):是在关闭数据库的时候进行的
热备份(联机备份):数据库处于运行状态,依赖于数据库的日志文件
温备份:数据库锁定表格(不可写入但可读)的状态下进行备份操作
逻辑备份:
对数据库逻辑组件(如:表等数据库对象)的备份
从数据库的备份策略角度,备份可分为
完全备份:
每次对数据库进行完整的备份
差异备份:
备份自从上次完全备份之后被修改过的文件
增量备份:
只有在上次完全备份或者增量备份后被修改的文件才会被备份(无重复备份)
常见的备份方法
物理冷备
备份时数据库处于关闭状态,直接打包数据库文件
备份速度快,恢复时也是最简单的
专业备份工具mysqldump或mysqlhotcopy
mysqldump常用的逻辑备份工具
mysqlhotcopy仅拥有备份MyISAM和ARCHIVE表
启用二进制日志进行增量备份
进行增量备份,需要刷新二进制日志
第三方工具备份
免费的MySQL热备份软件Percona XtraBackup
MySQL完全备份与恢复
MySQL完全备份介绍
是对整个数据库、数据库结构和文件结构的备份
保存的是备份完成时刻的数据库
是差异备份与增量备份的基础
每次对数据进行完整的备份,完全备份是增量备份的基础,完全备份保存的是备份完成时刻的数据库
优点
备份与恢复操作简单方便
缺点
数据存在大量的重复
占用大量的备份空间
备份与恢复时间长
数据库完全备份分类
物理冷备份与恢复
关闭MySQL数据库
使用tar命令直接打包数据库文件夹
直接替换现有MySQL目录即可
mysqldump备份与恢复
MySQL自带的备份工具,可方便实现对MySQL的备份
可以将指定的库、表导出为SQL脚本(.sql结尾)
使用命令MySQL导入备份的数据
物理冷备份与恢复步骤
先备份数据库中的数据打包,模拟数据丢失,损坏,利用备份打包恢复数据
物理冷备份
先关闭数据库,之后打包备份
恢复数据库
恢复数据库,采用将备份数据mv成线上库文件夹的方式
物理冷备份其实就是将数据库下的文件复制出来,然后当文件坏掉在复制回去。
create database aa;
use aa;
create table aa(id int(5), name varchar(64), age int(5));
insert into bbb values(1,'zhangsan',11),(2,'lisi',12);
关闭数据库服务,打包备份
ystemctl stop mysqld.service
mkdir /beifen
tar zcvf /beifen/mysql_all-$(date +%F).tar.gz /usr/local/mysql/data/
cd /beifen
ll
模拟数据损坏
systemctl start mysqld.service
mysql
drop database aa;
show databases;
恢复数据
tar xf /beifen/mysql_all-2020-12-28.tar.gz
mv /beifen/usr/local/mysql/data/ /usr/local/mysql/
systemctl start mysqld.service
show databases;
mysqldump备份和恢复
mysqldump命令对单个库进行完全备份
mysqldump -u 用户名 -p [密码] [选项] [数据库名] > /备份路径/备份文件名
mysqldump命令对多个库进行完全备份
mysqldump -u 用户名 -P [密码] [选项] --databases 库名1 [库名2]... >/备份路径/备份文件名
对所有库进行完全备份
mysqldump -u 用户名-p [密码] [选项] -all-databases > /备份路径/备份文件名
实例
show databases;
use aa;
insert into a values(1);
insert into a values(2);
select * from a;
show databases;
mysqldump -uroot -p aa > /beifen/a-$(date +%F).sql
ll /beifen
登录数据库,删除aa库,并创建一个b库(bb库用于还原aa库)
drop database aa;
create database bb;
将aa库的数据,还原到bb库上面
mysql -u root -p bb < /beifen/a-2020-12-28.sql
方法二
方法二和方法一的区别在于,一个是在mysql外面执行命令,一个在mysql里面执行命令;第一步不变,将第三步在mysql里面执行
登录mysql,创建一个cc用于还原aa
source /beifen/a-2020-12-28.sql;
MySQL增量备份与恢复
MySQL增量备份
使用mysqldump进行完全备份存在的问题
备份数据中有重复数据
备份时间与恢复时间过长
MySQL增量备份是自上一次备份后增加/变化的文件或者内容
特点
没有重复数据,备份量不大,时间短
恢复需要上次完全备份及完全备份之后所有的增量备份才能恢复,而且要对所有增量备份进行逐个反推恢复
MySQL没有提供直接的增量备份方法
可通过MySQL提供的二进制日志间接实现增量备份
MySQL二进制日志对备份的意义
二进制日志保存了所有更新或者可能更新数据库的操作
二进制日志在启动MySQL服务器后开始记录,并在文件达到max_binlog_size所设置的大小或者接收到flush logs命令后重新创建新的日志文件
只需定时执行flush logs方法重新创建新的日志,生成二进制文件序列,并及时把这些日志保存到安全的地方就完成了一个时间段的增量备份
MySQL数据库增量恢复
一般恢复
将所有备份的二进制日志内容全部恢复
断点恢复
基于位置恢复
数据库在某一时间点可能既有错误的操作也有正确的操作
可以基于精准的位置跳过错误的操作
基于时间点恢复
跳过某个发生错误的时间点实现数据恢复
增量恢复的方法
一般恢复
mysqlbinlog [–no-defaults] 增量备份文件 | mysql -u 用户名 -p
基于位置的恢复
恢复数据到指定位置(到错误操作前的最后一次正确操作)
mysqlbinlog --stop-position=‘操作id’ 二进制日志 | mysql -u 用户名 -p密码
从指定的位置开始恢复数据(跳过错误操作后的第一次正确操作)
mysqlbinlog --start-position=‘操作id’ 二进制日志 | mysql -u 用户名 -p密码
基于时间点恢复
跳过某个发生错误的时间点实现数据恢复
恢复数据到指定时间(停止错误操作的时间)
mysqlbinlog --stop-datetime=‘错误时间’ 二进制日志 | mysql -u 用户名 -p密码
从指定的位置开始恢复数据(跳过错误操作后的第一次正确操作)
mysqlbinlog --start-datetime=‘正确操作时间’ 二进制日志 | mysql -u 用户名 -p密码
实例:
开启二进制日志文件
vi /etc/my.cnf
添加log_bin=/usr/local/mysql/data/mysql_bin
systemctl restart mysqld
ll /usr/local/mysql/data/
mysqlbinlog --no-defaults --base64-output=decode-rows -v /usr/local/mysql/data/mysql_bin.000001
–no-defaults:解决utf-8报错
–base64-output=decode-rows:解决乱码问题
-v:输出文件指向
mysql
show databases;
use cc;
insert into a values(3);
insert into a values(4);
delete from a where id='1';
mysqlbinlog --no-defaults --base64-output=decode-rows -v /usr/local/mysql/data/mysql_bin.000002
mysqlbinlog --no-defaults --stop-datetime='2020-12-28 11:07:42' /usr/local/mysql/data/mysql_bin.000003 | mysql -u root -p
mysqlbinlog --no-defaults --start-datetime='2020-12-28 11:07:45' /usr/local/mysql/data/mysql_bin.000003 | mysql -u root -p
基于位置点恢复
mysql> delete from a where id='3';
Query OK, 1 row affected (0.00 sec)
mysql> delete from a where id='4';
Query OK, 1 row affected (0.00 sec)
mysql> delete from a where id='5';
Query OK, 3 rows affected (0.00 sec)
mysqlbinlog --no-defaults --base64-output=decode-rows -v /usr/local/mysql/data/mysql_bin.000003
mysqlbinlog --no-defaults --stop-position='2019' /usr/local/mysql/data/mysql_bin.000003 | mysql -uroot -p
mysqlbinlog --no-defaults --start-position='2267' /usr/local/mysql/data/mysql_bin.000003 | mysql -uroot -p