数据库备份与恢复

数据库备份的重要性

1、在生产环境中,数据的安全性至关重要
2、任何数据的丢失都可能产生严重的后果
3、造成数据丢失的原因

  • 程序错误
  • 人为操作错误
  • 运算错误
  • 磁盘故障
  • 灾难(如火灾,地震)和盗窃

数据库备份的分类

从物理与逻辑的角度,备份可分为

物理备份:对数据库操作系统的物理文件(如数据文件、日志文件等)的备份
物理备份方法

  • 冷备份(脱机备份):是在关闭数据库的时候进行的
  • 热备份(联机备份):数据库处于运行状态,依赖于数据库的日志文件
  • 温备份:数据库锁定表格(不可写入但可读)的状态下进行备份操作

逻辑备份:对数据库逻辑组件(如:表等数据库对象)的备份

从数据库的备份策略角度,备份可分为

完全备份:每次对数据库进行完整的备份
差异备份:备份自从上次完全备份之后被修改过的文件
增量备份:只有在上次完全备份或者增量备份后被修改的文件才会被备份

MySQL数据库完全备份与恢复

常见的备份方法

物理冷备
备份时数据库处于关闭状态,直接打包数据库文件
备份速度快,恢复时也是最简单的

专业备份工具mysqldump或mysqlhotcopy
mysqldump常用的逻辑备份工具
mysqlhotcopy仅拥有备份MyISAM和ARCHIVE表

启用二进制日志进行增量备份
进行增量备份,需要刷新二进制日志

第三方工具备份
免费的MySQL热备份软件Percona XtraBackup

MySQL数据库完全备份简介

1、是对整个数据库、数据库结构和文件结构的备份
2、保存的是备份完成时刻的数据库
3、是差异备份与增量备份的基础
4、每次对数据进行完整的备份,完全备份是增量备份的基础,完全备份保存的是备份完成时刻的数据库
5、优点:
备份与恢复操作简单方便
6、缺点
数据存在大量的重复
占用大量的备份空间
备份与恢复时间长

数据库完全备份分类

物理冷备份与恢复
关闭MySQL数据库
使用tar命令直接打包数据库文件夹
直接替换现有MySQL目录即可

mysqldump备份与恢复
MySQL自带的备份工具,可方便实现对MySQL的备份
可以将指定的库、表导出为SQL脚本(.sql结尾)
使用命令MySQL导入备份的数据

物理冷备份与恢复步骤

在MySQL中先创建库,再创建表,写入记录(用于验证)

mysql> select * from abc;
+------+----------+-------+-------+
| id   | name     | score | hobby |
+------+----------+-------+-------+
| NULL | zhangsan |    99 |     2 |
| NULL | wangwu   |    98 |     1 |
| NULL | chenqi   |    97 |     3 |
+------+----------+-------+-------+
3 rows in set (0.00 sec)

先关闭数据库服务,再打包备份

[root@server1 ~]# systemctl stop mysqld.service 
[root@server1 ~]# tar zcvf /opt/mysql_all-$(date +%F).tar.gz /usr/local/mysql/data

[root@server1 ~]# cd /opt
[root@server1 opt]# ls
mysql_all-2020-12-24.tar.gz  rh

将原来的数据移走到备份文件夹中,解压刚才备份的tar包到/restore目录下,再移动到mysql服务的文件夹中

[root@server1 ~]# mkdir bak #创建备份文件夹
[root@server1 ~]# mv /usr/local/mysql/data bak #将现在的数据库文件移动至备份文件夹,以模拟数据库损坏
[root@server1 ~]# mkdir restore #创建恢复文件夹
[root@server1 ~]# tar zxvf /opt/mysql_all-2020-12-24.tar.gz -C restore/ #解压打包的备份至恢复文件夹

[root@server1 data]# ls
auto.cnf        ib_logfile0  mysql
ib_buffer_pool  ib_logfile1  performance_schema
ibdata1         lcx          sys
[root@server1 data]# pwd
/root/restore/usr/local/mysql/data

[root@server1 ~]# mv restore/usr/local/mysql/data/ /usr/local/mysql/ #将解压后的备份数据移动至数据库文件夹中

重启mysql服务,登录mysql,查看数据是否恢复

mysql> select * from lcx.abc;
+------+----------+-------+
| id   | name     | score |
+------+----------+-------+
|    1 | zhangsan |    99 |
|    2 | wangwu   |    98 |
|    3 | chenqi   |    97 |
+------+----------+-------+
3 rows in set (0.01 sec)

mysqldump备份和恢复

备份

mysqldump -u root -p --all-databses > all-data-$(date +%F).sql ###备份所有数据库
mysqldump -u root -p -databases auth mysql > auth-mysql.sql ###备份auth和mysql库
mysqldump -u root -p auth > auth-$(data +%F).sql ###备份auth数据库
mysqldump -u root -p mysql user > mysql-user-$(date +%F).sql ###备份mysql的user表
mysqldump -u root -p -d mysql user > /tmp/desc-mysql-user.sql ###备份mysql库user表的结构

恢复

方法一:基于mysql命令恢复

[root@server1 ~]# mysqldump -u root -p lcx > test-$(date +%F).sql #使用mysqldump工具备份lcx库
Enter password:  #输入密码,不显示

mysql> drop database lcx; #删除lcx库模拟数据库故障
Query OK, 1 row affected (0.00 sec)

mysql> create database test2; #建立空库
Query OK, 1 row affected (0.00 sec)

[root@server1 ~]# mysql -u root -p test2 < test-2020-12-24.sql #恢复至test2库
Enter password:  #输入密码,不显示

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| test2              |
+--------------------+
5 rows in set (0.00 sec)

mysql> use test2
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> show tables;
+-----------------+
| Tables_in_test2 |
+-----------------+
| abc             |
+-----------------+
1 row in set (0.00 sec)

mysql> select * from abc;
+------+----------+-------+
| id   | name     | score |
+------+----------+-------+
|    1 | zhangsan |    99 |
|    2 | wangwu   |    98 |
|    3 | chenqi   |    97 |
+------+----------+-------+
3 rows in set (0.00 sec)

方法二:source基于脚本恢复

mysql> use test2;
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> source /root/test-2020-12-24.sql; #通过.sql格式的备份文件恢复至当前库中
………………
Query OK, 3 rows affected (0.00 sec) #恢复三条记录
Records: 3  Duplicates: 0  Warnings: 0
………………

mysql> show tables;
+-----------------+
| Tables_in_test2 |
+-----------------+
| abc             |
+-----------------+
1 row in set (0.00 sec)

mysql> select * from abc;
+------+----------+-------+
| id   | name     | score |
+------+----------+-------+
|    1 | zhangsan |    99 |
|    2 | wangwu   |    98 |
|    3 | chenqi   |    97 |
+------+----------+-------+
3 rows in set (0.00 sec)

MySQL数据库增量备份与恢复

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密码
mysql> select * from abc; #未恢复前状态
+------+----------+-------+
| id   | name     | score |
+------+----------+-------+
|    1 | zhangsan |    99 |
|    2 | wangwu   |    98 |
|    3 | chenqi   |    97 |
+------+----------+-------+
3 rows in set (0.00 sec)

找出要恢复的位置

at 7079 #误操作前的位置,不要选择误操作的位置
at 7183 #误操作后正确操作的位置,与时间节点不同,选择误操作后的第一个位置节点
[root@server1 ~]# mysqlbinlog --no-defaults --stop-position='7079' /usr/local/mysql/data/mysql_bin.000002 | mysql -uroot -p123456
#根据日志文件选择恢复开始位置,路径,数据库,“--stop-datetime”换成“--stop-position”
基于时间点恢复

跳过某个发生错误的时间点实现数据恢复
恢复数据到指定时间(停止错误操作的时间)

mysqlbinlog --stop-datetime=‘错误时间’ 二进制日志 | mysql -u 用户名 -p密码
#恢复数据至指定的位置(误操作开始时间)
mysqlbinlog --start-datetime=‘正确操作时间’ 二进制日志 | mysql -u 用户名 -p密码 
#从指定的位置开始恢复数据(跳过误操作后指定正确操作的时间)

备份

[root@server1 ~]# mkdir -p /opt/time_sql #创建时间还原点文件夹
[root@server1 ~]# mysqldump -uroot -p test2 > /opt/time_sql/test2-$(date +%F).sql #备份test2库
Enter password: 

[root@server1 ~]# vi /etc/my.cnf #数据库配置文件中添加
[mysqld] #此模块添加
log_bin=/usr/local/mysql/data/mysql_bin #开启增量备份

[root@server1 ~]# systemctl restart mysqld.service 

[root@server1 ~]# ls /usr/local/mysql/data/ 查看会发现日志文件mysql_bin.00000,此时内容为空
auto.cnf        ib_logfile1       mysql_bin.index
ib_buffer_pool  ibtmp1            performance_schema
ibdata1         mysql             sys
ib_logfile0     mysql_bin.000001  test2

[root@server1 ~]# mysqldump -uroot -p123456 test2 > /opt/test2.sql #执行一次完整备份

[root@server1 ~]# mysqladmin -uroot -p123456 flush-logs #将二进制日志更新,产生新的日志文件
mysqladmin: [Warning] Using a password on the command line interface can be insecure.

[root@server1 ~]# ls /usr/local/mysql/data/ #查看产生第二个日志文件mysql_bin.000002
auto.cnf        ib_logfile1       mysql_bin.000002    test2
ib_buffer_pool  ibtmp1            mysql_bin.index
ibdata1         mysql             performance_schema
ib_logfile0     mysql_bin.000001  sys

[root@server1 ~]# mysql -uroot -p123456
mysql> select * from abc;
+------+----------+-------+
| id   | name     | score |
+------+----------+-------+
|    1 | zhangsan |    99 |
|    2 | wangwu   |    98 |
|    3 | chenqi   |    97 |
+------+----------+-------+
3 rows in set (0.00 sec)

mysql> insert into abc (id,name,score) values(1,'aaa',96),(2,'bbb',95),(3,'ccc',100); #正确操作
Query OK, 3 rows affected (0.00 sec)
Records: 3  Duplicates: 0  Warnings: 0

mysql> delete from abc where name='zhangsan'; #删除数据,模拟错误操作
Query OK, 1 row affected (0.00 sec)

mysql> insert into abc (id,name,score) values(6,'abc',100); #正确操作
Query OK, 1 row affected (0.00 sec)

mysql> select * from abc;
+------+--------+-------+
| id   | name   | score |
+------+--------+-------+
|    2 | wangwu |    98 |
|    3 | chenqi |    97 |
|    1 | aaa    |    96 |
|    2 | bbb    |    95 |
|    3 | ccc    |   100 |
|    6 | abc    |   100 |
+------+--------+-------+
6 rows in set (0.00 sec)

[root@server1 ~]# mysqladmin -uroot -p123456 flush-logs; #执行日志更新
mysqladmin: [Warning] Using a password on the command line interface can be insecure.


[root@server1 ~]# ls /usr/local/mysql/data/ #查看是否新生成的日志mysql_bin.000003,刚操作的动作不在新生成的日志文件中,在mysql_bin.000002中,可通过查看知道
auto.cnf        ib_logfile1       mysql_bin.000002    sys
ib_buffer_pool  ibtmp1            mysql_bin.000003    test2
ibdata1         mysql             mysql_bin.index
ib_logfile0     mysql_bin.000001  performance_schema

[root@server1 ~]# mysqlbinlog --no-defaults --base64-output=decode-rows -v /usr/local/mysql/data/mysql_bin.000002 ###查询该二进制日志内容是否正确,--base64以64为解码器,output=decode-rows输出并按行进行读取, -v显示
………………
# at 910 #操作位置
#201224 21:05:50 server id 1  end_log_pos 958 CRC32 0x1213a56a 	Write_rows: table id 219 flags: STMT_END_F #操作时间
### INSERT INTO `test2`.`abc` #以下为操作内容
### SET
###   @1=6
###   @2='abc'
###   @3=100
………………

找出要恢复的时间点

201224 21:05:24 --stop-datetime #误操作的时间
201224 21:05:50 --start-datetime #正确操作的时间

进数据库可以看到没有已经误操作的状态

mysql> select * from abc;
+------+--------+-------+
| id   | name   | score |
+------+--------+-------+
|    2 | wangwu |    98 |
|    3 | chenqi |    97 |
|    1 | aaa    |    96 |
|    2 | bbb    |    95 |
|    3 | ccc    |   100 |
|    6 | abc    |   100 |
+------+--------+-------+
6 rows in set (0.00 sec)

mysql> source /opt/test2.sql; #恢复原先的备份
mysql> show tables;
+-----------------+
| Tables_in_test2 |
+-----------------+
| abc             |
+-----------------+
1 row in set (0.00 sec)

mysql> select * from abc; #数据已经恢复,但没有刚才操作的数据
+------+----------+-------+
| id   | name     | score |
+------+----------+-------+
|    1 | zhangsan |    99 |
|    2 | wangwu   |    98 |
|    3 | chenqi   |    97 |
+------+----------+-------+
3 rows in set (0.00 sec)


[root@server1 ~]# mysqlbinlog --no-defaults --stop-datetime='2020-12-24 21:05:24' /usr/local/mysql/data/mysql_bin.000002 | mysql -uroot -p123456 #根据日志文件选择恢复停止时间,路径,数据库
mysql: [Warning] Using a password on the command line interface can be insecure.

mysql> select * from abc; #查看数据库可以查看恢复至误删除前的状态
+------+----------+-------+
| id   | name     | score |
+------+----------+-------+
|    1 | zhangsan |    99 |
|    2 | wangwu   |    98 |
|    3 | chenqi   |    97 |
|    1 | aaa      |    96 |
|    2 | bbb      |    95 |
|    3 | ccc      |   100 |
+------+----------+-------+
6 rows in set (0.00 sec)

[root@server1 ~]# mysqlbinlog --no-defaults --start-datetime='2020-12-24 21:05:50' /usr/local/mysql/data/mysql_bin.000002 | mysql -uroot -p123456 #根据日志文件选择恢复开始时间,路径,数据库
mysql: [Warning] Using a password on the command line interface can be insecure.
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值