MySQL备份与恢复 详解

为什么要进行数据库备份

数据备份的重要性

在生产环境中,数据的安全性至关重要
任何数据的丢失都可能产生严重的后果
造成数据丢失的原因
程序错误
人为操作错误
运算错误
磁盘故障
灾难(如火灾、地震)和盗窃
数据丢失会造成严重的经济损失,如携程网因数据丢失原因每小时损失106万美元。

MySQL的备份类型

备份类型可以分为物理备份和逻辑备份两种

物理备份是指通过拷贝数据库文件的方式完成备份,这种备份方式适用于数据库很大,数据重要且需要快速恢复的数据库
物理备份方法
。冷备份(脱机备份):是在关闭数据库的时候进行的
。热备份(联机备份):数据库处于运行状态,依赖于数据库的日志文件
。温备份:数据库锁定表格(不可写入但可读)的状态下进行备份操作

逻辑备份是指通过备份数据库的逻辑结构(create database/table语句)和数据内容(insert语句或者文本文件)的方式完成备份。这种备份方式适用于数据库不是很大,或者你需要对导出的文件做一定的修改,又或者是希望在另外的不同类型服务器上重新建立此数据库的情况
物理备份通常要求在数据库关闭的情况下执行,但如果是在数据库运行情况下执行,则要求备份期间数据库不能修改
逻辑备份的速度要慢于物理备份,是因为逻辑备份需要访问数据库并将内容转化成逻辑备份需要的格式;通常输出的备份文件大小也要比物理备份大;另外逻辑备份也不包含数据库的
配置文件和日志文件内容;备份和恢复的粒度可以是所有数据库,也可以是单个数据库,也可以是单个表;逻辑备份需要再数据库运行的状态下执行;它的执行工具可以是mysqldump或者是select … into outfile两种方式
备份又可以分为在线备份和离线备份两种
在线备份是指在数据库运行的状态下执行的备份
而离线备份是指在数据库关闭情况下执行的备份
备份还可以分为本地备份和远程备份两种
本地备份是指备份是在和当前MySQL运行的相同主机上发起和执行
而离线备份是指在数据库关闭情况下执行的备份
备份还可以分为本地备份和远程备份两种
本地备份是指备份是在和当前MySQL运行的相同主机上发起和执行
远程备份是指备份是在和当前MySQL运行的不同主机上发起和执行
比如mysqldump命令可以连接本机MySQL,也可以连接远程MySQL;在比如select …into outfile命令可以通过本地或者远程的MySQL客户端执行,但生成的文件则会存放在MySQL实例运行的主机上
对物理备份来说启动备份的过程是MySQL实例主机,但备份的地址有可能是远程的某个 存储

数据库备份比较

在这里插入图片描述
从表中可以看出
完全备份是每次都将整个数据库中的内容进行备份
差异备份是自从上次完全备份后被修改的内容 优点存储恢复速度快
增量备份是自从上次完全备份或增量备份后被修改的内容备份

mysql完全备份与恢复

是对整个数据库、数据库结构和文件结构的备份
保存的是备份完成时刻的数据库
是差异备份与增量备份的基础
优点
备份与恢复操作简单方便
缺点
数据存在大量的重复
占用大量的备份空间
备份与恢复时间长
生产环境中常是完全备份与增量备份结合使用

备份演练

MySQL中的逻辑备份是将数据库中的数据备份为一个文本文件,备份的文件可以被查看和编辑。在MySQL中,使用mysaldump工具来完成备份。有以下4种来调用mysqldump
1、对单库进行备份
mysqldump -u 用户名 -p [密码] [选项] [数据库名] > /备份路径/备份文件名

create database shool;        //创建一个库
create table info (id int(4) not null primary key auto_increment,name varchar(10) not null,scrore decimal(5,2));    //创建表主键是id 且递增形式 有名字和成绩
insert into info (name,scrore) values ('zhangsan',88),('lisi',90);  //给表中添加数据
\q                    //退出数据库

mysqldump -uroot -p shool > /opt/shool.sql        ##对shool这个库进行备份并放在/op/目录下起个名字叫shool.sql
root@localhost opt]# vi shool.sql      ##里面的内容仅看懂部分就行 
省略部分内容
Table structure for table `info`                                  ##定义是那个表
DROP TABLE IF EXISTS `info`;                               ##初始化这个库 若是有原来有和它相同的表的话将之前的删除
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `info` (
  `id` int(4) NOT NULL AUTO_INCREMENT,
  `name` varchar(10) NOT NULL,
  `scrore` decimal(5,2) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `info`
--
LOCK TABLES `info` WRITE;                         ##锁表
/*!40000 ALTER TABLE `info` DISABLE KEYS */;
INSERT INTO `info` VALUES (1,'zhangsan',88.00),(2,'lisi',90.00);            ##这个备份的数据必须在上下两条之间
/*!40000 ALTER TABLE `info` ENABLE KEYS */;
UNLOCK TABLES;                                        ##解锁表
省略部分内容

2、对多库进行备份 比着1仅多个–databases 例如下

[root@localhost opt]# mysqldump -uroot -p --databases mysql shool > /opt/mysql-shool.sql

3、对所有的库进行备份
mysqldump -u 用户名 -p [密码] [选项] --all-databases > /备份路径/备份文件名

[root@localhost opt]# mysqldump -uroot -p --all-databases > /opt/allku.sql

4、对指定备份某个库的某个表
mysqldump -u 用户名 -p [密码] [选项] [数据库名] 表名 > /备份路径/备份文件名

对数据进行恢复

两种方法
1、直接在数据库中用source 备份路径 进行恢复 注意必须要先建一个空的库在进入里面恢复

mysql> drop databse shool;
mysql> create database stu;      ##建一个库
mysql> ues stu;
mysql> source /opt/shool.sql     ##恢复删除的数据
mysql> select * from info;      ##查看数据是否恢复

2、直接在库外面追加恢复 也需要先建立一个库

mysql> create database school;
[root@localhost opt]# mysql -uroot -p school < /opt/shool.sql       ##直接恢复就行
mysql> select * from info;
+----+----------+--------+
| id | name     | scrore |
+----+----------+--------+
|  1 | zhangsan |  88.00 |
|  2 | lisi     |  90.00 |
+----+----------+--------+

mysql增量备份与恢复

MySQL没有提供直接的增量备份方法
可通过MySQL提供的二进制日志间接实现增量备份
MySQL二进制日志对备份的意义
二进制日志保存了所有更新或者可能更新数据库的操作
二进制日志在启动MySQL服务器后开始记录,并在文件达到max_binlog_size所设置的大小或者接收到flush logs命令后重新创建新的日志文件
只需定时执行flush logs方法重新创建新的日志,生成二进制文件序列,并及时把这些日志保存到安全的地方就完成了一个时间段的增量备份

备份演练

首先基于上面添加的school库 添加相应数据模拟误删除 恢复

增量备份恢复类型
一般恢复
将所有备份的二进制日志内容全部恢复 需要保证你的所有超作都为正确的
语法:mysqlbinlog [–no-defaults] 增量备份文件 | mysql -u 用户名 -p
基于位置恢复
数据库在某一时间点可能既有错误的操作也有正确的操作可以基于精准的位置跳过错误的操作
恢复数据指定位置
mysqlbinlog --stop-position=‘超作 id’ 二进制日志 |mysql -u 用户名 -p 密码
从指定位置开始恢复数据
mysqlbinlog --start-position=‘超作 id’ 二进制日志 |mysql -u 用户名 -p 密码
基于时间点恢复
跳过某个发生错误的时间点实现数据恢复
1、先设置让数据库能产生二进制日志
添加后可在/usr/local/mysql/data/中看到二进制日志文件

[root@localhost opt]# vi /etc/my.cnf
[mysqld]
....
socket = /usr/local/mysql/mysql.sock
log-bin = ejzwn    ##添加能产生二进制文件的命令“=”后面可是别的文件名
server-id = 1
...
systemctl restart mysqld
cd /usr/local/mysql/data/    ##用ls可看到有二进制文件
ls
会有这个文件ejzwn.000001

2、进行数据写入

mysql> use school;
mysql> insert into info (name,scrore) values ('wangwu',98);
Query OK, 1 row affected (0.01 sec)
mysql> delete from info where name = 'zhangsan';      ##模拟误删除
Query OK, 1 row affected (0.00 sec)
mysql> insert into info (name,scrore) values ('zhaoliu',83);
Query OK, 1 row affected (0.00 sec)
[root@localhost data]# mysqladmin -uroot -pabc123 flush-logs;     ##刷新日志
root@localhost data]# mysqlbinlog --no-defaults ejzwn.000001      ##查看日志
[root@localhost data]# mysqlbinlog --no-defaults --base64-output=decode-rows -v ejzwn.000001>/opt/share.tas
按64位解码输出按每一行自动换行添加到/opt/目录下取名为share.tas 注意必须要在data目录下

3、恢复数据

mysql> use school
mysql> show tables;
mysql> drop table info;                ##模拟删除表
Query OK, 0 rows affected (0.01 sec)
mysql> show tables;
Empty set (0.00 sec) 
mysql> source /opt/shool.sql;           ##先进行完全恢复
Query OK, 0 rows affected (0.00 sec)

4、基于位置的恢复首先需找到错误删除的内容 如下面 一定要找好位置在BEGIN之上的那个at点和COMMIT下面的那个at为结束点

[root@localhost data]# mysqlbinlog --no-defaults --base64-output=decode-rows -v ejzwn.000001       到这里面找到位置找到相应要恢复的位置
省略部分内容
# at 494
#201013 15:55:41 server id 1  end_log_pos 568 CRC32 0x158be875  Query thread_id=3 exec_time=0 error_code=0
SET TIMESTAMP=1602575741/*!*/;
BEGIN
/*!*/;
# at 568
#201013 15:55:41 server id 1  end_log_pos 623 CRC32 0x726de7a1  Table_map: `school`.`info` mapped to number 713
# at 623
#201013 15:55:41 server id 1  end_log_pos 675 CRC32 0x813d321e  Delete_rows: table id 713 flags: STMT_END_F
### DELETE FROM `school`.`info`
### WHERE
###   @1=1
###   @2='zhangsan'
###   @3=88.00
# at 675
#201013 15:55:41 server id 1  end_log_pos 706 CRC32 0x3ee680a6  Xid = 13
COMMIT/*!*/;
# at 706
省略部分内容

5、恢复误删除的内容 首先需要基于完全恢复的基础上将之前的都先恢复 然后注意的是不要恢复自己的错误操作 即从上面的494之前的进行结束恢复 在下面的706在开始恢复 这样的话就能够刚刚好的跳过了错误的操作了

[root@localhost data]# mysqlbinlog --no-defaults --start-position='706' ejzwn.000001 |mysql -uroot -p
Enter password: 
[root@localhost data]# mysqlbinlog --no-defaults --stop-position='494' ejzwn.000001 |mysql -uroot -p
Enter password: 
[root@localhost data]# mysql -uroot -p
mysql> use
mysql> select * from info;
+----+----------+--------+
| id | name     | scrore |
+----+----------+--------+
|  1 | zhangsan |  88.00 |
|  2 | lisi     |  90.00 |
|  3 | wangwu   |  98.00 |
|  4 | zhaoliu  |  83.00 |
+----+----------+--------+
4 rows in set (0.00 sec)

5、基于时间的恢复基本格式如下这里不再做实验;
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/Laiyunpeng666/article/details/109049037