文章目录
在生产环境中,数据的安全性是至关重要的,任何数据的丢失都可能产生严重的后果。所以数据库需要备份。这里以新版mysql5.7为例。
一、数据库备份分类:
从物理与逻辑的角度,备份可分为物理备份和逻辑备份。
(1)物理备份:对数据库操作系统的物理文件(如数据文件、日志文件等)的备份。又可以分为冷备份和热备份。
冷备份:关闭数据库时进行的备份操作
热备份:在数据库运行状态中进行备份操作,这种备份方法依赖于数据库的日志文件。
(2)逻辑备份:对数据库逻辑组件(如表等数据库对象)的备份。
从数据库的备份策略角度,备份可分为完全备份、差异备份、增量备份。
(1)完全备份:每次对数据库进行完整的备份。可以备份单个数据库,多个数据库,所有数据库,也可以备份数据
库中的单个表,多个表。
(2)差异备份:备份那些自从上次完全备份之后被修改过的文件,只备份数据库部分内容,但是存储和恢复速度快
(3)增量备份:只有那些在上次完全备份或者增量备份后被修改的文件才会被备份。
二、完全备份与恢复
备份
使用mysqldump工具可以灵活的控制备份的内容,比如某几个表或库都可以单独备份。
- 对单个库进行完全备份。命令格式如下:
mysqldump -u用户名 -p[密码] [选项] [数据库名] > /备份路径/备份文件名
例:
mysqldump -u root -p123456 mysql > /bak/mysql_bak/$(date +%F).sql
图解:
如果不想出现那个warning信息,可以执行export MYSQL_PWD=123456,然后下次可以不用输入密码参数了。
2、对多个库进行完全备份。命令格式如下:
mysqldump -u用户名 -p[密码] [选项] --databases 库名1 库名2 ... > /备份路径/备份文件名
3. 对所有库进行完全备份。命令格式如下:
mysqldump -u用户名 -p[密码] --opt --all-databases > /备份路径/备份文件名
4. 对表结构进行完全备份。命令格式如下:
mysqldump -u用户名 -p[密码] -d 数据库名 表名 > /备份路径/备份文件名
例:
mysqldump -uroot -p123456 -d zcy1 student > /bak/mysql_bak/$(date +%F).sql
5. 对表进行完全备份。命令格式如下:
mysqldump -u用户名 -p[密码] 数据库名 表名 > /备份路径/备份文件名
恢复
- 登录mysql,使用source命令恢复库。命令格式如下:
source 库备份脚本的路径
2. 在不登录MySQL的情况下,使用mysql命令直接恢复整库。命令格式如下:
mysql -u用户名 -p[密码] < 库备份脚本的路径
例:
mysql -u root -p123456 < /bak/mysql_bak/2021-02-03.sql
完全备份后恢复的实验。
恢复单个库
环境:假设数据库损坏,删除数据库zcy1。
drop database zcy1;
1、 使用source命令恢复。
注意:先创建一个同名的数据库,再进入数据库,用surce命令恢复,否则会报错。
source /bak/mysql_bak-2021-01-30.sql
2、使用mysql命令恢复。
再一次删掉数据库zcy1。
drop database zcy1;
然后在linux下恢复:
mysql -u root -p123456 < /bak/mysql_bak/2021-02-03.sql
恢复之后成功进入
恢复单个表
先将表模拟删除,再恢复。
drop table student;
然后进行恢复
source /bak/mysql_bak/2021-02-03.zcy1.student.sql
使用Linux命令恢复
模拟一下删表,然后再恢复
表已经没了,现在我们来恢复一下
mysql -uroot -p 123456 zcy1 < /bak/mysql_bak/2021-02-03.zcy1.student.sql
恢复成功了。
三、增量备份与恢复
MySQL没有提供直接的增量办法,但是可以通过对MySQL的二进制日志间接实现增量备份。二进制日志保存了所有更新或者可能更新数据库的操作。
特点:
- 没有重复数据,备份量不大,时间短
- 需要上次完全备份及完全备份之后所有的增量备份才能恢复,而且要进行逐个反推恢复,操作繁琐。
1.实现增量备份
要进行MySQL增量备份,首先要开启二进制日志功能。
(1)在mysql的配置文件的[mysqld]选项中加入log-bin=mysql-bin,然后重启服务。
vim /etc/my.cnf
[mysqld]
log-bin=mysql-bin
然后重启mysql
(2)使用mysqldump完全备份school库。
mysqldump -u root -p123456 zcy1 > /bak/mysql_bak/$(date +%F).sql
(3)使用mysqladmin的选项flush-logs生成新的二进制文件,这样在插入新的数据后,新的二进制文件对应的就是数据库的变化的内容。
mysqladmin -uroot -p123456 flush-logs
(4)插入一条新的数据,以模拟数据的增加或变更。
此时的数据库变化保存在编号2 的二进制文件中,使用mysqlbinlog命令可以查看二进制文件的内容,里面保存了插入数据的语句。
mysqlbinlog --no-defaults --base64-output=decode-rows -v mysql-bin.000002
(5)再次执行flush- logs操作生成新的二进制文件,而新的二进制文件会保存之后的数据操作。
mysqladmin -uroot -p123456 flush-logs
(6)再次向数据库插入一条数据。
insert into student (id,name,age) values (7,'wl','30');
(7)最后再执行一次flush-logs操作,确保之前的二进制文件不再发生变化。
2.丢失完全备份之后更改的数据的恢复
(1)使用delete删除插入的两条数据,也就是假设完全备份后的数据丢失了。
delete from student where id=6;
delete from student where id=7;
(2)使用二进制文件恢复时需要注意的是恢复顺序,要先恢复最先生成的二进制文件,然后依次执行。
mysqlbinlog --no-defaults /usr/local/mysql/data/mysql-bin.000002|mysql -uroot -p123456
mysqlbinlog --no-defaults /usr/local/mysql/data/mysql-bin.000003|mysql -uroot -p123456
3. 完全备份之后丢失所有数据的恢复
当完全备份和增量备份之后,所有数据丢失,需要把完全备份和所有增量备份文件逐个恢复。
(1)执行flush-logs操作分割日志,插入一条数据。
insert into student (id,name,age) values (8,'wangw','20');
这条插入语句保存在mysql-bin.000005二进制文件中。
(2)再执行一次flush-logs操作,插入一条数据,之后还要再执行一次flush-logs操作,确保插入数据保存在二进制文件中,不再改变。
mysqladmin -uroot -p123456 flush-logs
insert into student (id,name,age) values (9,'lqw','22');
mysqladmin -uroot -p123456 flush-logs
这条插入语句保存在mysql-bin.000006二进制文件中。
(3)使用drop删除表student,也就是假设完全备份前info的数据和完全备份后的数据都丢失了。
drop table student;
(4)先使用mysql命令进行完全备份的恢复操作。
show tables;
(5)使用二进制文件恢复时需要注意的是恢复顺序,要先恢复最先生成的二进制文件,然后依次执行。
mysqlbinlog --no-defaults /usr/local/mysql/data/mysql-bin.000005|mysql -uroot -p123456
mysqlbinlog --no-defaults /usr/local/mysql/data/mysql-bin.000006|mysql -uroot -p123456
4. 基于时间点与位置恢复
利用二进制日志可实现基于时间点与位置的恢复,例如由于误操作删除了一张表,这时完全恢复时没有用的,因为日志里面还存在误操作的语句。我们需要的是恢复到误操作前的状态,然后跳过误操作的语句,再恢复后面操作的语句。
以此表为实验对象:
首先对数据库进行备份。
基于时间点恢复
将某个起始时间的二进制日志导入数据库中,从而跳过某个发生错误的时间点实现数据的恢复。
1)执行flush-logs操作生成新的二进制文件。
mysqladmin -uroot -p123456 flush-logs
2)插入两条数据,但由于误操作,两条插入语句中间删除了一条数据,而这条数据是不应该删除的。为了确保数据保存在二进制文件中不改变,执行一次flush-logs操作。
生成新的二进制文件
mysqladmin -uroot -p123456 flush-logs
3)假设数据损坏,删除表info。
drop table student;
4)使用mysql命令进行完全备份的恢复操作。
mysql -uroot -p123456 zcy1 < /bak/mysql_bak/2021-02-04.sql
可以看到,刚才删除的表又被恢复了。
5)查看数据操作语句保存的二进制文件mysql-bin.0000020。
mysqlbinlog --no-defaults --base64-output=decode-rows -v mysql-bin.000008
6)根据二进制文件的数据操作语句的时间点进行完全备份后增量备份的恢复操作。
mysqlbinlog --no-defaults /usr/local/mysql/data/mysql-bin.000008 --stop-datetime='21-02-04 18:08:47'|mysql -uroot -p123456
mysqlbinlog --no-defaults /usr/local/mysql/data/mysql-bin.000008 --start-datetime='21-02-04 18:09:03'|mysql -uroot -p123456
基于位置恢复
使用基于时间点的恢复可能会出现在一个时间点里既同时存在正确的操作又存在错误的操作,基于位置是一种更为精确的恢复方式。
实验对象表:
1)执行flush-logs操作生成新的二进制文件。
mysqladmin -uroot -p123456 flush-logs
2)插入两条数据,但由于误操作,两条插入语句中间删除了一条数据,而这条数据是不应该删除的。为了确保数据保存在二进制文件中不改变,执行一次flush-logs操作。
insert into student (id,name,age) values (10,'ten','10');
delete from student where id=8;
insert into student (id,name,age) values (11,'bba','11');
再生成一条二进制日志,保存之后的操作数据。
mysqladmin -uroot -p123456 flush-logs
3)查看数据操作语句保存的二进制文件mysql-bin.0000010。
mysqlbinlog --no-defaults --base64-output=decode-rows -v mysql-bin.0000010
4)假设数据损坏,删除表 student。
drop table student;
5)使用mysql命令进行完全备份的恢复操作。
mysql -uroot -p123456 zcy1 < /bak/mysql_bak/2021-02-04.sql
全量备份恢复成功,下面进行增加备份的恢复。
4)根据二进制文件的数据操作语句的时间点进行完全备份后增量备份的恢复操作。
mysqlbinlog --no-defaults /usr/local/mysql/data/mysql-bin.000010 --stop-position='615'|mysql -uroot -p123456
mysqlbinlog --no-defaults /usr/local/mysql/data/mysql-bin.000010 --start-position='665'|mysql -uroot -p123456
备份恢复成功,连之前误操作的删除数据也都恢复了。