文章目录
数据库备份的重要性
在生产环境中,数据的安全性至关重要任何数据的丢失都可能产生严重的后果
造成数据丢失的原因
程序错误
人为操作错误
运算错误
磁盘故障
灾难(如火灾和地震)和盗窃
数据库备份的分类
从物理与逻辑的角度,备份可分为:
物理备份:对数据库操作系统的物理文件(如数据文件、日志文件等)的备份
物理备份方法
冷备份(脱机备份):是在关闭数据库的时候进行的
热备份(联机备份):数据库处于运行状态,依赖于数据库的日志文件
温备份:数据库锁定表格(不可写入但可读)的状态下进行备份操作
逻辑备份:对数据库逻辑组件(如:表等数据库对象)的备份
数据库的备份
从数据库的备份策略角度,备份可分为
完全备份:每次对数据库进行完整的备份
差异备份:备份自从上次完全备份之后被修改过的文件,每当出现新的备份,都要从第一次备份开始,有重复数据
增量备份:只有在上次完全备份或者增量备份后被修改的文件才会被备份,每当出现新的备份,不需要从开始备份,接上一个备份之后备份即可
常见的备份方法
物理冷备
备份时数据库处于关闭状态,直接打包数据库文件
备份速度快,恢复时也是最简单的
专用备份工具mydump或mysqlhotcopy
mysqldump常用的逻辑备份工具
mysqlhotcopy仅拥有备份MyISAM和ARCHIVE表
启用二进制日志进行增量备份
进行增量备份,需要刷新二进制日志
第三方工具备份
免费的MySQL热备份软件Percona XtraBackup
MySQL完全备份
是对整个数据库、数据库结构和文件结构的备份
保存的是备份完成时刻的数据库
是差异备份与增量备份的基础
优点
备份与恢复操作简单方便
缺点
数据存在大量的重复
占用大量的备份空间
备份与恢复时间长
数据库完全备份分类
物理冷备份与恢复
关闭MySQL数据库
使用tar命令直接打包数据库文件夹
直接替换现有MySQL目录即可
mysqldump备份与恢复
MySQL自带的备份工具,可方便实现对MySQL的备份
可以将指定的库、表导出为SQL脚本
使用命令mysql导入备份的数据
MySQL物理冷备份及恢复
[root@server1 ~]#mysql -uroot -p123456
mysql> create database abc; //创建数据库
mysql> use abc; //进入数据库
mysql> create table a(id int(2) not null, name varchar(6) not null);//创建表结构
mysql> insert into a(id,name) values (1,'liming');
mysql> insert into a(id,name) values (2,'xuzhi');
mysql> select * from a;
+----+--------+
| id | name |
+----+--------+
| 1 | liming |
| 2 | xuzhi |
+----+--------+
mysql> exit
[root@server1 ~]# systemctl stop mysqld //停止数据库 冷备份一定要关闭数据库服务
[root@server1 ~]# tar zcvf all_databases-$(data +%F).tar.gz /usr/local/mysql/data //进行打包
/usr/local/mysql/data:备份源文件,数据库基本目录
[root@server1 ~]# systemctl start mysqld //开启数据库
[root@server1 ~]# mysql -uroot -p123456
mysql> use abc;
mysql> drop table a; //进行误操作删除
mysql> exit
[root@server1 ~]# systemctl stop mysqld //停止数据库
[root@server1 ~]# mkdir /oldbak //创建旧目录
[root@server1 ~]# mv /usr/local/mysql/data /oldbak //把老数据存放到oldbak下
[root@server1 ~]# mkdir /resotre //创建恢复的目录
[root@server1 ~]# ls -lh
-rw-r--r-- 1 root root 2.3M 10月 25 14:52 all_databases-.tar.gz 查看打包文件
[root@server1 ~]# tar zxvf all_databases-.tar.gz -C /resotre/ //将打包软件解压到restore目录下
[root@server1 ~]# mv /resotre/usr/local/mysql/data/ /usr/local/mysql/ 将resore下的/usr/local/mysql/data/文件移到到 /usr/local/mysql/
[root@server1 ~]# cd /usr/local/mysql/
[root@server1 mysql]# ls -lh 查看发现数据已恢复
总用量 64K
drwxr-xr-x. 2 mysql root 4.0K 10月 17 21:30 bin
-rw-r--r--. 1 mysql root 18K 9月 13 2017 COPYING
-rw-r--r--. 1 mysql root 18K 9月 13 2017 COPYING-test
drwxr-x--- 7 mysql mysql 169 10月 25 14:51 data
drwxr-xr-x. 2 mysql root 55 10月 17 21:30 docs
drwxr-xr-x. 3 mysql root 4.0K 10月 17 21:30 include
drwxr-xr-x. 4 mysql root 191 10月 17 21:30 lib
drwxr-xr-x. 4 mysql root 30 10月 17 21:30 man
drwxr-xr-x. 10 mysql root 4.0K 10月 17 21:31 mysql-test
-rw-r--r--. 1 mysql root 2.5K 9月 13 2017 README
-rw-r--r--. 1 mysql root 2.5K 9月 13 2017 README-test
drwxr-xr-x. 28 mysql root 4.0K 10月 17 21:31 share
drwxr-xr-x. 2 mysql root 90 10月 17 21:31 support-files
drwxr-xr-x. 3 mysql root 17 10月 17 21:30 usr
[root@server1 mysql]# cd
[root@server1 ~]# systemctl start mysqld //开启数据库
[root@server1 ~]# mysql -uroot -p123456
mysql> use abc;
mysql> show tables;
+---------------+
| Tables_in_abc |
+---------------+
| a |
+---------------+
mysql> select * from a;
+----+--------+
| id | name |
+----+--------+
| 1 | liming |
| 2 | xuzhi |
mysql> exit
mysqldump备份数据库
备份数据库/表/表结构
#mysqldump -u root -p --all-databases > all-data-$(data +%F).sql //备份所有数据库
#mysqldump -u root -p --databases auth myqsl > auth-mysql.sql //备份auth和mysql数据库
#mysqldump -u root -p auth > auth-$(data +%F).sql //备份mysql的user表
#mysqldump -u root -p mysql user > mysql-user-$(data +%F).sql //备份mysql的user表
#mysqldump -u root -p -d mysql user > /tmp/desc-myqsl-user.sql //备份mysql库user表的结构
备份所有数据库
mysql> create database school;//新建school库
mysql> use school;
mysql> create table data(name varchar(64) not null, age int(3) not null,stunum int(5) not null);
mysql> insert into data(name,age,stunum) values('lili',20,201001);
mysql> insert into data(name,age,stunum) values('wangwu',19,201002);
mysql> insert into data(name,age,stunum) values('zhangsan',21,201003);
mysql> select * from data;
+----------+-----+--------+
| name | age | stunum |
+----------+-----+--------+
| lili | 20 | 201001 |
| wangwu | 19 | 201002 |
| zhangsan | 21 | 201003 |
+----------+-----+--------+
mysql> exit
[root@server1 ~]# mysqldump -u root -p123456 --all-databases > all_databases_2-$(date +%F).sql //备份所有数据库
[root@server1 ~]# mysql -uroot -p123456
mysql> use school;
mysql> show tables;
+------------------+
| Tables_in_school |
+------------------+
| data |
+------------------+
mysql> select * from data;
+----------+-----+--------+
| name | age | stunum |
+----------+-----+--------+
| lili | 20 | 201001 |
| wangwu | 19 | 201002 |
| zhangsan | 21 | 201003 |
+----------+-----+--------+
mysql> delete from data where name='lili';
mysql> delete from data where name='zhangsan';
mysql> select * from data;
+--------+-----+--------+
| name | age | stunum |
+--------+-----+--------+
| wangwu | 19 | 201002 |
+--------+-----+--------+
mysql> exit
[root@server1 ~]# mysql -uroot -p123456
mysql> drop database school;
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| abc |
| bbs |
| mysql |
| performance_schema |
| sys |
mysql> create database school;
mysql> exit
[root@server1 ~]# ls -lh
-rw-r--r-- 1 root root 3.0M 10月 25 15:32 all_databases_2-2020-10-25.sql
[root@server1 ~]# mysql -uroot -p123456 < all_databases_2-2020-10-25.sql
mysql: [Warning] Using a password on the command line interface can be insecure.
[root@server1 ~]# mysql -uroot -p123456
mysql> use school;
mysql> show tables;
mysql> select * from data;
+----------+-----+--------+
| name | age | stunum |
+----------+-----+--------+
| lili | 20 | 201001 |
| wangwu | 19 | 201002 |
| zhangsan | 21 | 201003 |
+----------+-----+--------+
误操作,删除lili与zhangsan表
mysql> delete from data where name='lili';
Query oK,1 row affected (0.02 sec)
mysql> delete from data where name='zhangsan';
Query oK,1 row affected (0.02 sec)
进行查看发现只剩下一条数据
mysql> exit
方法一恢复:库外恢复
[root@server1 ~]#mysql -u root -pabc123
mysql> drop daabase school;//删除school数据库
mysql> show databases; //查看所有数据库,确认school库已删除
mysql> create database school; //创建school数据库,建立空库
mysql> exit
[root@server2 ~]# mysql -uroot -p123456 < all_databases_2-2020-10-25.sql(复制ll里面的文件)
[root@server2 ~]# mysql -uroot -p123456
mysql> use school;
mysql> select * from data; //发现数据已恢复
备份单个数据库school数据库
mysqldump -uroot -p123456 school > school-$(date +%F).sql;
mysqldump: [Warning] Using a password on the command line interface can be insecure.
[root@server1 ~]# mysql -uroot -p123456
mysql> use school;
mysql> drop table data; //进行误删除
mysql> exit
方法二恢复:库内恢复
[root@server1 ~]# ls -lh
-rw-r--r-- 1 root root 1.9K 10月 25 16:04 school-2020-10-25.sql
[root@server1 ~]# mysql -uroot -p123456
mysql> drop database school; //删除数据库,以为库已经坏了,所以要删除
mysql> create database school; //创建空库 school
mysql> use school;
mysql> source /root/school-2020-10-25.sql
mysql> select * from data; //发现数据已恢复
+----------+-----+--------+
| name | age | stunum |
+----------+-----+--------+
| lili | 20 | 201001 |
| wangwu | 19 | 201002 |
| zhangsan | 21 | 201003 |
mysqldump备份数据库表
mysqldump可针对库内特定的表进行备份
使用mysqldump备份表的操作
mysqldump -u 用户名 -p [密码][选项] 数据库名 表名> /备份路径/备份文件名
备份表的示例
mysqldump -u root -p mysql user > /backup/mysql-user.sql/
恢复数据库
使用mysqldump导出的脚本,可使用导入的方法
mysql命令
使用source恢复数据库的步骤
登录到MySQL数据库
执行source备份sql脚本的路径
source恢复的示例
MySQL[(none)]> source /backup/all-data.sql
source命令
mysql命令
使用source恢复数据库的步骤
登录到MySQL数据库
执行source备份sql脚本的路径
source恢复的示例
MySQL[(none)]> source /backup/all-data.sql
source命令恢复:
drop database client;
create database client;
use client;
mysql>source /root/client_user_info-$(data +%F).sql
mysql命令
使用mysql命令恢复数据
mysql -u 用户名 -p [密码]<库备份脚本的路径
mysql命令恢复的示例
mysql -u root -p < /backup/all-data.sql
drop database client;
show databases;
create database client; //建立空库
mysql -u root -p client < client_user_info-$(data +%F).sql
恢复表的操作
恢复表时同样可以使用source或者mysql命令
source恢复表的操作与恢复库的操作相同
当备份文件中只包含表的备份,而不包括创建库的语句时,必须指定库名,且目标库必须存在
mysql -u 用户名 -p [密码]<表备份脚本的路径
mysql -u root -p mysql< /backup/mysql-user.sql
在生产环境中,可以使用shell脚本自动实现定时备份
MySQL增量备份与恢复
MySQL增量备份
使用mysqldump进行完全备份存在的问题
备份数据中有重复数据
备份时间与恢复时间过长
MySQL增量备份是自上一次备份后增加/变化的文件或者内容
特点
没有重复数据,备份量不大,时间短
恢复需要上次完全备份及完全备份之后所有的增量备份才能恢复,而且要对所有增量备份进行逐个反推恢复
MySQL没有提供直接的增量备份方法
可通过MySQL提供的二进制日志间接实现增量备份
MySQL二进制日志对备份的意义
二进制日志保存了所有更新或者可能更新数据库的操作
二进制日志在启动MySQL服务器后开始记录,并在文件达到max_binlog_size所设置的大小或者接收到flush logs命令后重新创建新的日志文件
只需要定时执行flush logs方法重新创建新的日志,生成二进制文件序列,并及时把这些日志保存到安全的地方就完成了一个时间段的增量备份
MySQL数据库增量恢复
一般恢复
将所有备份的二进制日志内容全部恢复
基于位置恢复
数据库在某一时间点可能既有错误的操作也有正确的操作
可以基于精准的位置跳过错误的操作
基于时间点恢复
跳过某个发生错误的时间点实现数据恢复
一般恢复
mysqlbinlog [–no-defaults] 增量备份文件 | mysql -u 用户名 -p
基于时间点恢复
[root@server2 ~]# vi /etc/my.cnf 修改一下参数
最后一行添加该内容log_bin=/usr/local/mysql/data/mysql_bin //开启二进制日志功能打开
[root@server2 ~]# systemctl restart mysqld
[root@server2 ~]# cd /usr/local/mysql/data
[root@server2 data]# ll 查看是否有一下文件生成
-rw-r-----. 1 mysql mysql 154 11月 2 12:16 mysql_bin.000001
[root@server2 ~]# mysql -uroot -p123456//进入数据库
mysql> create database school;//创建school数据库
Query OK, 1 row affected (0.01 sec)
mysql> use school;
Database changed
mysql> create table ttt(name char(16), scores int(3)); //创建表
mysql> insert into ttt values('sam',80);//在表内添加数据1
mysql> insert into ttt values('jack',70);//在表内添加数据2
mysql> select * from ttt; //查看表里面的内容
+------+--------+
| name | scores |
+------+--------+
| sam | 80 |
| jack | 70 |
+------+--------+
2 rows in set (0.00 sec)
mysql> exit
Bye
[root@server2 ~]# mysqlbinlog --no-defaults -v /usr/local/mysql/data/mysql_bin.000001//查看二进制日志内容是否正确
[root@server2 ~]# mysqldump -uroot -p123456 school > /opt/bak_school-$(date +%F).sql//做一个完全备份
mysqldump: [Warning] Using a password on the command line interface can be insecure.
[root@server2 ~]# mysqladmin -uroot -p123456 flush-logs//刷新一下二进制日志文件
mysqladmin: [Warning] Using a password on the command line interface can be insecure.
[root@server2 ~]# cd /usr/local/mysql/data
[root@server2 data]# ll //查看是否生成以下内容
-rw-r-----. 1 mysql mysql 154 11月 2 16:21 mysql_bin.000002
[root@server2 data]# mysql -uroot -p123456 //进入数据库
mysql> use school;
mysql> insert into ttt values('sisi',90); //添加数据,即执行正确的操作
mysql> delete from ttt where name='jack';//进行误删除
mysql> insert into ttt values('haha',65);添加数据,即执行正确的操作
mysql> select * from ttt; //查看ttt表中的数据
+------+--------+
| name | scores |
+------+--------+
| sam | 80 |
| sisi | 90 |
| haha | 65 |201102 17:29:59 201102 17:30:06
+------+--------+
mysql> exit
[root@server2 data]# mysqladmin -uroot -p123456 flush-logs
mysqladmin: [Warning] Using a password on the command line interface can be insecure.
//刷新二进制日志,作用使刚才执行的命令,能够在数据库二进制日志文件中能看见
[root@server2 data]# ll //查看是否有以下文件生成,因为刚生成的文件查看不了,要查看上一个文件及000002
-rw-r-----. 1 mysql mysql 154 11月 2 16:32 mysql_bin.000003
[root@server2 data]# mysqlbinlog --no-defaults --base64-output=decode-rows -v /usr/local/mysql/data/mysql_bin.000002
记录错误时间前:201102 16:27:23 下一个正确时间:201102 16:28:34
[root@server2 data]# cd
[root@server2 ~]# mysql -uroot -p123456
mysql> use school;
mysql> drop table ttt;//删除表,并进行mysql> exit
[root@server2 ~]# mysql -uroot -p123456 school < /opt/bak_school-2020-11-02.sql //完全备份的恢复
mysql: [Warning] Using a password on the command line interface can be insecure.
[root@server2 ~]# mysql -uroot -p123456
mysql> use school;
mysql> select * from ttt;
+------+--------+
| name | scores |
+------+--------+ | sam | 80 |
| jack | 70 |
+------+--------+
2 rows in set (0.00 sec)
mysql> exit
进行增量恢复
[root@server2 ~]# mysqlbinlog --no-defaults --stop-datetime='20-11-02 16:27:23' /usr/local/mysql/data//mysql_bin.000002 | mysql -uroot -p123456 错误点
mysql: [Warning] Using a password on the command line interface can be insecure.
[root@server2 ~]# mysqlbinlog --no-defaults --start-datetime='20-11-02 16:28:34' /usr/local/mysql/data//mysql_bin.000002 | mysql -uroot -p123456 下一次正确点
mysql: [Warning] Using a password on the command line interface can be insecure.
[root@server2 ~]# mysql -uroot -p123456
mysql> use school;
mysql> select * from ttt; 发现备份已恢复
+------+--------+
| name | scores |
+------+--------+
| sam | 80 |
| jack | 70 |
| sisi | 90 |
| haha | 65 |
+------+--------+
位置点恢复(由于上个实验已经基于完全备份之上,本次实验是需建立在上一个增量备份之上就可以,无需基于完全备份)
mysql> delete from ttt where name='sisi'; 误删除
mysql> delete from ttt where name='haha'; 误删除
mysql> select * from ttt;
+------+--------+
| name | scores |
+------+--------+
| sam | 80 |
| jack | 70 |
+------+--------+
mysql> exit
[root@server2 ~]# cd /usr/local/mysql/data/
[root@server2 data]# ll //查看日志文件
-rw-r-----. 1 mysql mysql 2493 11月 2 18:49 mysql_bin.000003
[root@server2 data]# mysqlbinlog --no-defaults --base64-output=decode-rows -v /usr/local/mysql/data/mysql_bin.000003
记录上一次正确操作的位置点:2417
下一次正确操作位置点:2462
#at 2417
#201102 18:49:34 server id 1 end_log_pos 2462 CRC32 0x1dd89837 Delete_rows: table id 221 flags: STMT_END_F
DELETE FROM `school`.`ttt`
WHERE
@1='haha'
@2=65
at 2462
[root@server2 ~]# cd
[root@server2 ~]#mysqlbinlog --no-defaults --stop-position='2417' /usr/local/mysql/data/mysql_bin.000003 | mysql -uroot -p123456
[root@server2 ~]# mysqlbinlog --no-defaults --start-position='2462' /usr/local/mysql/data/mysql_bin.000003 | mysql -uroot -p123456
[root@server2 data]# mysql -uroot -p123456
mysql> use school;
mysql> select * from ttt; //查看发现只恢复了一条数据,sisi的没有恢复
+------+--------+
| name | scores |
+------+--------+
| sam | 80 |
| jack | 70 |
| haha | 65 |
+------+--------+
mysql> exit
[root@server2 data]#mysqlbinlog --no-defaults --base64-output=decode-rows -v /usr/local/mysql/data/mysql_bin.000003
at 6587
#201102 19:20:34 server id 1 end_log_pos 6632 CRC32 0xce91848a Delete_rows: table id 227 flags: STMT_END_F
DELETE FROM `school`.`ttt`
WHERE
@1='sisi'
@2=90
#at 6632
记录上一次正确操作的位置点:6587
下一次正确操作位置点:6632
mysqlbinlog --no-defaults --stop-position='6587' /usr/local/mysql/data/mysql_bin.000003 | mysql -uroot -p123456 //上一次正确操作的位置点停止
mysqlbinlog --no-defaults --start-position='6632' /usr/local/mysql/data/mysql_bin.000003 | mysql -uroot -p123456 //下一次正确操作的位置点开始
[root@server2 ~]# mysql -uroot -p123456
mysql> use school;
mysql> select * from ttt;
+------+--------+
| name | scores |
+------+--------+
| sam | 80 |
| jack | 70 |
| sisi | 90 |
| haha | 65 |
+------+--------+