文章目录
- 前言
- 一、数据备份的重要性
- 二、数据库备份的分类
- 1.物理备份
- 2.逻辑备份
- 2.1 完全备份
- 2.2 差异备份
- 2.3 增量备份
- 2.4备份方式比较
- 3.如何选择逻辑备份策略(频率)
- 三、常见的备份方法
- 1.物理备份
- 2.专用备份工具 mysqldump 或 mysqlhotcopy
- 3.启用二进制日志进行增量备份
- 4.第三方工具备份
- 四、MySQL完全备份介绍
- 1、物理备份与恢复(冷备)
- 1.1环境准备
- 1.2实验物理备份与恢复(冷备)
- 五、mysqldump 备份与恢复(温备份)
- 1.完全备份一个或多个完整的库 (包括其中所有的表)
- 2.完全备份 MySQL 服务器中所有的库
- 3.完全备份指定库中的部分表
- 4.查看备份文件
- 六、完全恢复
- 七,增量备份
- 一,增量备份的特点
- 二,增备备份的三种恢复方式
- 三、增量备份实验
- 1.开启二进制日志功能g
- 1.1 二进制日志(binlog)3种不同的记录格式
- STATEMENT(基于SQL语句)
- ROW(基于行)
- MIXED 推荐使用
- 1.2 二进制日志对备份的意义如下
- 2.进行完全备份
- 3.可每天进行增量备份操作
- 4.插入新数据,以模拟数据的增加或变更
- 5.生成新的二进制文件并查看其内容
- 6.模拟丢失所有数据的用二进制文件恢复步骤
- 四、MySQL增量恢复
- 1.一般恢复
- 1.1 模拟丢失更改的数据的恢复步骤(直接使用恢复即可)
- 2.断点恢复
- 2.1 基于位置恢复
- 2.2 基于时间点恢复
前言
备份的主要目的是灾难恢复,备份还可以测试应用、回滚数据修改、查询历史数据、审计等。而备份、恢复中,日志起到了很重要的作用
一、数据备份的重要性
1.备份的主要目的是灾难恢复
2.在生产环境中,数据的安全性至关重要
3.任何数据的丢失都可能产生严重的后果
4.造成数据丢失的原因
①程序错误
②人为操作错误
③运算错误
④磁盘故障
⑤灾难 (如火灾、地震) 和盗窃
二、数据库备份的分类
1.物理备份
- 数据库备份可以分为物理备份和逻辑备份
- 物理备份是对数据库操作系统的物理文件(如数据文件、日志文件等)的备份。这种类型的备份适用于在出现问题的时候需要快速恢复的大型重要数据库
- 物理备份又可以成为冷备份(脱机备份)、热备份(连接备份)和温备份
①冷备份 (脱机备份) :是在关闭数据库的时候进行的(tar)
②热备份 (联机备份) :数据库处于运行状态,依赖于数据库的日志文件(mysqlhotcopy mysqlbackup)
③ 温备份 :数据库锁定表格(不可写入但可读)的状态下进行备份操作(mysqldump)
2.逻辑备份
- 逻辑备份是备份sql语句,在恢复的时候执行备份的sql语句实现数据库数据的重视
- 逻辑备份时对数据库逻辑组件的备份表示为逻辑数据库结构
- 这种类型的备份适用于可以编辑数据值或表结构
- 从数据库的备份策略角度来看,备份又可分为完全备份,差异备份和增量备份
2.1 完全备份
- 每次对数据进行完整备份,即对整个数据库,数据库结构和文件结构备份,保存的是备份完成时刻的数据库,是差异备份与增量备份的基础完全备份的备份与恢复操作都非常简单方便,但是数据存在大量的重复并且会占用大量的磁盘空间,备份的时间也很长
- 简述:每次都进行完全备份,会导致备份文件占用空间巨大,并且有大量重复数据
- 恢复时,直接使用用完全备份的文件即可
2.2 差异备份
- 备份那些自从上次完全备份之后被修改的所有文件,备份的时间节点是从上一次完全备份起,备份数据量会越来越大,数据恢复时只需要恢复上次的完全备份与最佳的一次差异备份
- 简述:每次差异备份,都会备份上一次备份之后的数据,可能会出现重复数据
- 恢复时,先恢复完全备份的数据,在恢复差异备份的数据
2.3 增量备份
- 只有那些在上次完全备份或者增量备份后被修改的文件才会被备份以上次完整备份或上次增量备份的时间为时间点,仅备份期间内的数据变化,因而备份的数据量小,占用空间小,备份速度快
- 但恢复时,需要上一次的完整备份开始到最后一次增量备份之间的所有增量依次恢复,如中间某次的备份数据损坏,将导致数据的丢失
- 每次增量备份都是备份在上一次完全备份或者增量备份之后的数据,不会出现重复数据的情况,也不会占用额外的磁盘空间
- 恢复数据,需要按照次序恢复完全备份和增量备份的数据
2.4备份方式比较
备份方式 | 完全备份 | 差异备份 | 增量备份 |
完全备份时的状态 | 表1、表2 | 表1、表2 | 表1、表2 |
第1次添加内容 | 创建表3 | 创建表3 | 创建表3 |
备份内容 | 表1、表2、表3 | 表3 | 表3 |
第2次添加内容 | 创建表4 | 创建表4 | 创建表4 |
备份内容 | 表1、表2、表3、表4 | 表3、表4 | 表4 |
3.如何选择逻辑备份策略(频率)
- 一周一次的全备,全备的时间需要在不提供业务的时间区间进行 PM 10点 AM 5:00之间进行全备
- 增量:3天/2天/1天一次增量备份
- 差异:选择特定的场景进行备份
- 一个处理(NFS)提供额外空间给与mysql 服务器用
三、常见的备份方法
1.物理备份
- 备份时数据库处于关闭状态,直接打包数据库文件(tar)
- 备份速度快,恢复时也是最简单的
2.专用备份工具 mysqldump 或 mysqlhotcopy
- mysqldump 常用的逻辑备份工具
- mysqlhotcopy 仅拥有备份 MyISAM 和 ARCHIVE 表
3.启用二进制日志进行增量备份
- 进行增量备份,需要刷新二进制日志
- MySQL支持增量备份,进行增量备份时必须启用二进制日志。二进制日志文件为用户提供复制,对执行备份点后进行的数据库更改所需的信息进行恢复
- 如果进行增量备份(包含自上次完全备份或增量备份以来发生的数据修改),需要刷新二进制日志
4.第三方工具备份
- 免费的MySQL 热备份软件 Percona XtraBackup mysqlbackup
以上小结
- 是从数据库的备份策略角度,备份可以氛围完全备份,差异备份和增量备份
- 从物理和逻辑角度,备份可以分为物理备份(冷、热备份)、逻辑备份
- 备份可以针对整库,某些库或某些表来进行
四、MySQL完全备份介绍
- 是对整个数据库、数据库结构和文件结构的备份
- 保存的是备份完成时刻的数据库
- 是差异备份与增量备份的基础
- 优点:
备份与恢复操作简单方便 - 缺点:
数据存在大量的重复
占用大量的备份空间
备份与恢复时间长
1、物理备份与恢复(冷备)
- 关闭MySQL数据库
- 使用tar命令直接打包数据库文件夹
- 直接替换现有MySQL目录即可
1.1环境准备
mysql> create database test;
Query OK, 1 row affected (0.00 sec)
mysql> use test;
mysql> create table if not exists test (id int(4) not null auto_increment,name varchar(10) not null,age char(10) not null,hobby varchar(50),primary key (id));
Query OK, 0 rows affected (0.01 sec)
mysql> insert into test values(1,'A',12,'wan');
Query OK, 1 row affected (0.00 sec)
mysql> insert into test values(2,'B',13,'nao');
Query OK, 1 row affected (0.00 sec)
mysql> select *from test;
+----+------+-----+-------+
| id | name | age | hobby |
+----+------+-----+-------+
| 1 | A | 12 | wan |
| 2 | B | 13 | nao |
+----+------+-----+-------+
2 rows in set (0.00 sec)
1.2实验物理备份与恢复(冷备)
mysql> use test;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> select * from test; ##查看原有数据
+----+------+-----+-------+
| id | name | age | hobby |
+----+------+-----+-------+
| 1 | A | 12 | wan |
| 2 | B | 13 | nao |
+----+------+-----+-------+
2 rows in set (0.00 sec)
[root@localhost ~]# systemctl stop mysqld
#关闭服务
[root@localhost ~]# tar -zcvf /opt/mysql_all$(date +%F).tar.gz /usr/local/mysql/data
#压缩备份
[root@localhost ~]# mkdir /opt/mysql_bak
[root@localhost ~]# mv /usr/local/mysql/data/* /opt/mysql_bak
#模拟删除数据库
#解压备份恢复
[root@localhost ~]# cd /
[root@localhost /]# tar -xf mysql_all2022-08-10.tar.gz -C ./
五、mysqldump 备份与恢复(温备份)
- MySQL自带的备份工具,可方便实现对MySQL的备份
- 可以将指定的库、表导出为SQL 脚本
- 使用命令mysq|导入备份的数据
- 冷备份使用tar打包,需要先关闭数据库是因为数据库仍在持续写入,不关闭会导致数据丢失
1.完全备份一个或多个完整的库 (包括其中所有的表)
##格式 mysqldump -u root -p[密码] --databases 库名1 [库名2] ... > /备份路径/备份文件名.sql #导出的就是数据库脚本文件
#例:
[root@nginx1 ~]# mysqldump -uroot -p --databases test > /opt/test.sql ##备份一个test 库
Enter password: ##要输入密码
[root@nginx1 opt]# mysqldump -uroot -p --databases qwe asd > /opt/qwe-asd.sql #备份qwe 和 asd 两个库
Enter password:
2.完全备份 MySQL 服务器中所有的库
##格式 mysqldump -u root -p[密码] --all-databases > /备份路径/备份文件名.sql
##例:
[root@nginx1 opt]# mysqldump -uroot -p --all-databases > /opt/all.sql
Enter password:
3.完全备份指定库中的部分表
##格式 mysqldump -u root -p[密码] 库名 [表名1] [表名2] ... > /备份路径/备份文件名.sql
#例:
[root@nginx1 opt]# mysqldump -uroot -p qwe qwe1 > /opt/qwe-qwe1.sql
Enter password:
#使用“-d”选项,说明只保存数据库的表结构
#不使用“-d"选项,说明表数据也进行备份
#做为一个表结构模板
4.查看备份文件
[root@nginx1 opt]# grep -v "^--" /opt/qwe-qwe1.sql | grep -v "^/" |grep -v "^$"
六、完全恢复
- 方法一:使用source恢复数据库的步骤
1.登录到MySQL数据库
2.执行source备份sql脚本的路径
mysql> use qwe;
mysql> select * from test;
+----+------+-----+-------+
| id | name | age | hobby |
+----+------+-----+-------+
| 1 | A | 12 | wan |
| 2 | B | 13 | nao |
+----+------+-----+-------+
2 rows in set (0.00 sec)
mysql> delete from test;
Query OK, 2 rows affected (0.00 sec)
mysql> source /opt/test.sql
mysql> select * from test;
+----+------+-----+-------+
| id | name | age | hobby |
+----+------+-----+-------+
| 1 | A | 12 | wan |
| 2 | B | 13 | nao |
+----+------+-----+-------+
2 rows in set (0.00 sec)
- 方法二:使用mysql命令,无须登录MySQL数据库
使用 -e 删除数据表,执行mysql备份sql脚本的路径
[root@nginx1 opt]# mysqldump -uroot -p test > /opt/test.sql
[root@nginx1 opt]# mysql -uroot -p -e 'drop table test.test;'
[root@nginx1 opt]# mysql -uroot -p -e 'show tables from test;'
[root@nginx1 opt]# mysql -uroot -p test < /opt/test.sql
[root@nginx1 opt]# mysql -uroot -p -e 'show tables from test'
上述小总结
- 冷备份 (脱机备份) :是在关闭数据库的时候进行的(tar)
- 温备份 :数据库锁定表格(不可写入但可读)的状态下进行备份操作(mysqldump)
七,增量备份
一,增量备份的特点
- 增量备份的优点是没有重复数据,备份量不大,时间短
- 缺点也很明显,需要上次完全备份及完全备份之后所有的增量备份才能恢复,而且对所有增量备份进行逐个反推恢复,操作较为繁锁
- MySQL 没有提供直接的增量备份方法,但是可以通过 MySQL 的二进制日志(binary
logs)间接实现增量备份
二,增备备份的三种恢复方式
- 一般恢复
将所有备份的二进制日志内容全部恢复 - 基于位置恢复
数据库在某一时间点可能既有错误的操作也有正确的操作
可以基于精准的位置跳过错误的操作
发生错误节点之前的一个节点,上一次正确操作的位置点停止 - 基于时间点恢复
跳过某个发生错误的时间点实现数据恢复
在错误时间点停止,在下一个正确时间点开始
三、增量备份实验
1.开启二进制日志功能g
[root@nginx1 opt]# vim /etc/my.cnf
在下面插入
[mysqld]
……
log-bin=mysql-bin //开启二进制日志功能
binlog_format = MIXED //可选,指定二进制日志(binlog)的记录格式为MIXED(混合输入)
z //可加可不加该命令
#修改完后重启,使其配置文件生效
[root@nginx1 opt]# systemctl restart mysqld.service
#查看二进制文件
[root@nginx1 opt]# cd /usr/local/mysql/data
[root@nginx1 data]# ll mysql-bin.*
-rw-r----- 1 mysql mysql 154 8月 10 19:16 mysql-bin.000001
-rw-r----- 1 mysql mysql 19 8月 10 19:16 mysql-bin.index
- 环境模板
#切换库
use zone
#创建一个表
create table lion (id int(10) not null,name varchar(40),age int(5));
#添加新的数据
insert into lion values(1,'zhangsan',20);
mysql> select * from lion;
+----+----------+------+
| id | name | age |
+----+----------+------+
| 1 | zhangsan | 20 |
+----+----------+------+
1.1 二进制日志(binlog)3种不同的记录格式
STATEMENT(基于SQL语句)
- 每一条涉及到被修改的sql 都会记录在binlog中
- 缺点:日志量过大,如sleep()函数,last_insert_id()>,以及user-defined fuctions(udf)、主从复制等架构记录日志时会出现问题
- 总结:增删改查通过sql语句来实现记录,如果用高并发可能会出错,可能时间差异或者延迟,可能不是我们想想的恢复可能你先删除或者在修改,可能会倒过来。准确率底
ROW(基于行)
- 只记录变动的记录,不记录sql的上下文环境
- 缺点:如果遇到update…set…where true 那么binlog的数据量会越来越大
- 总结:update、delete以多行数据起作用,来用行记录下来,
只记录变动的记录,不记录sql的上下文环境,
比如sql语句记录一行,但是ROW就可能记录10行,但是准确性高,高并发的时候由于操作量,性能变低 比较大所以记录都记下来,
MIXED 推荐使用
- 一般的语句使用statement,函数使用ROW方式存储
1.2 二进制日志对备份的意义如下
- 二进制日志保存了所有更新或者可能更新数据库的操作
- 二进制日志在启动 MySQL 服务器后开始记录,并在文件达到 max_binlog_size 所设置的大小或者接收到 flush logs 命令后重新创建新的日志文件
- 只需要定时执行 flush logs 方法重新创建新的日志,生成二进制文件序列,并及时把这些日志保存到安全的地方就完成了一个时间段的增量备份
2.进行完全备份
- 增量备份时基于完全备份的,所以我们直接完全备份数据库)
- 也可设置定时备份
#先完全备份
mysqldump -uroot -p123456 zone lion > /opt/zone_lion_$(date +%F).sql //备份表
mysqldump -uroot -p123456 zone > /opt/zone_$(date +%F).sql //备份库
crontab -e
30 3 * * 3 mysqldump -uroot -p123456 zone lion > /opt/zone_lion_$(dat
e +%F).sql
30 3 * * 3 mysqldump -uroot -p123456 zone > /opt/zone_$(date +%F).s
ql
#每周三的凌晨 3:00 对数据库和表进行完全备份
3.可每天进行增量备份操作
- 生成新的二进制文件(例:mysql-bin.0000002)
mysqladmin -uroot -p123456 flush-logs
cd /usr/local/mysql/data
ll mysql-bin.*
-rw-r----- 1 mysql mysql 1722 10月 26 22:45 mysql-bin.000001
-rw-r----- 1 mysql mysql 785 10月 26 22:50 mysql-bin.000002
-rw-r----- 1 mysql mysql 57 10月 26 22:50 mysql-bin.index
4.插入新数据,以模拟数据的增加或变更
- 在第一次完全备份之后刷新二进制文件,在第二个二进制文件中记载着"增量备份的数据"
use zone;
#插入两条新数据
insert into lion values(2,'lisi',30),(3,'wangwu',40);
mysql> select * from lion;
+----+----------+------+
| id | name | age |
+----+----------+------+
| 1 | zhangsan | 20 |
| 2 | lisi | 30 |
| 3 | wangwu | 40 |
+----+----------+------+
3 rows in set (0.00 sec)
5.生成新的二进制文件并查看其内容
mysqladmin -uroot -p123456 flush-logs //刷新
ll mysql-bin.*
-rw-r----- 1 mysql mysql 1722 10月 26 22:45 mysql-bin.000001
-rw-r----- 1 mysql mysql 785 10月 26 22:50 mysql-bin.000002
-rw-r----- 1 mysql mysql 154 10月 26 22:50 mysql-bin.000003 //多出个3
-rw-r----- 1 mysql mysql 57 10月 26 22:50 mysql-bin.index
cp /usr/local/mysql/data/mysql-bin.000002 /opt/
#将记录变更的二进制文件02复制至/opt目录下
cd /opt/
ls
#使用64位编码机制去解码,按行读取详细内容
mysqlbinlog --no-defaults --base64-output=decode-rows -v /opt/mysql-bin.000002
#--base64-output=decode-rows 使用64位编码机制去解码并按行读取
#-v 显示详细内容
#--no-defaults 不加的话汇报一个UTF-8的错
6.模拟丢失所有数据的用二进制文件恢复步骤
- 当完全备份和增量备份之后,所有的数据丢失,需要把完全备份和所有增量备份文件逐个恢复
#模拟丢失所有数据###########################################################################################
mysql -uroot -p123456
show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| zone |
+--------------------+
5 rows in set (0.00 sec)
mysql> drop database zone;
Query OK, 1 row affected (0.01 sec)
#基于mysql-bin.000002、mysql-bin.000002恢复##################################################################################
#因为把库删了,所以新建一个库
create database zone;
mysqlbinlog --no-defaults /opt/mysql-bin.000001 | mysql -u root -p
mysqlbinlog --no-defaults /opt/mysql-bin.000002 | mysql -u root -p
#检查表内容是否恢复
mysql -uroot -p123456 -e "select * from zone.zone;"
四、MySQL增量恢复
- 增量恢复比完全恢复操作更为繁琐
- 每个增量备份都是单独的个体,数据不重复,需要控制得更加精确
1.一般恢复
1.1 模拟丢失更改的数据的恢复步骤(直接使用恢复即可)
#备份test库中lion表
mysqldump -uroot -p123456 test.lion > /opt/tset.lion_$(date +%F).sql
#删除test库中lion表
drop table test.lion;
mysql> show tables; //此时查看已没有表
Empty set (0.00 sec)
#恢复lion表
mysql -uroot -p test < /opt/tset.lion_2021-10-26.sql //再次查看,表已经恢复
mysql> show tables;
+----------------+
| Tables_in_test |
+----------------+
| lion |
+----------------+
1 row in set (0.00 sec)
#查看日志文件
mysqlbinlog --no-defaults --base64-output=decode-rows -v mysql-bin.000002
2.断点恢复
######例子:
mysqlbinlog --no-defaults --base64-output=decode-rows -v /opt/mysql-bin.000002
例:
# at 302
#201122 16:41:16
插入了"user3"的用户数据
# at 623
#201122 16:41:24
插入了"user4"的用户数据
2.1 基于位置恢复
- ①插入2条新数据
use zone;
mysql> insert into lion values(4,'jjj',50);
Query OK, 1 row affected (0.00 sec)
mysql> insert into lion values(5,'lkg',60);
Query OK, 1 row affected (0.00 sec)
- 此时,数据4打错了,我想要恢复至数据4之前的状态
- ②确认位置点
#找到那条命令的节点
mysqlbinlog --no-defaults --base64-output=decode-rows -v /opt/mysql-bin.000003
#刷新日志
mysqladmin -uroot -p123123 flush-logs
#删除表
delete from lion;
- ③ 基于位置点恢复
#仅恢复到操作 ID 为“6118"之前的数据,即不恢复数据4
mysqlbinlog --no-defaults --stop-position='6118' /opt/mysql-bin.000002| mysql -uroot -p123456
2.2 基于时间点恢复
- 格式:
mysqlbinlog [--no-defaults] --start-datetime='年-月-日 小时:分钟:秒' --stop-datetime='年-月-日小时:分钟:秒' 二进制日志 | mysql -u 用户名 -p 密码
#仅恢复到16:41:24 之前的数据,即不恢复"数据4"的数据
mysqlbinlog --no-defaults --stop-datetime='2021-10-27 16:41:24' /opt/mysql-bin.000002 | mysql -uroot -p
如果恢复某条SQL语之前的所有数据,就stop在这个语句的位置节点或者时间点
如果恢复某条SQL语句以及之后的所有数据,就从这个语句的位置节点或者时间点start
以上小总结
- 开启二进制日志,设置二进制日志格式MIXED
- 进行一次完全备份,可每周备份一次,通过crontab -e
- 使用mysqladm -uroot -p flush-logs刷新分割出二进制日志,由于刷新之前的数据操作都记录在老的二进制日志里,所以需要把老的二进制日志复制到一个安全的目录中保管
- 可以通过mysqlbinlog --no-defaults --base64-output=decode-rows -v二进制日志文件名查看日志内容
- 可以通过mysqlbinlog --no-defaults二进制日志文件名l mysql -uroot -p恢复丢失的数据
e=‘年-月-日小时:分钟:秒’ 二进制日志 | mysql -u 用户名 -p 密码