目录
一、数据备份概述
1.1 数据备份的重要性
- 在生产环境中,数据的安全性至关重要
- 任何数据的丢失都有可能产生验证的后果
- 造成数据丢失的原因
程序错误 ,认为操作错误(大部分),运算错误,磁盘故障,灾难(如地震火灾)和盗窃
1.2 数据库备份的分类
- 从物理与逻辑的角度,可分为:
物理备份:对数据库操作系统的物理文件(如数据文件、日志文件等)的备份
逻辑备份:对数据库逻辑组件(如:表等数据库对象)的备份 - 物理备份的方法:
冷备份(脱机备份):是在关闭数据库的时候进行的
热备份(联机备份):数据库处于运行状态,依赖于数据库的日志文件
温备份:数据库锁定表格(不可写入但可读)的状态进行备份操作
1.3常用的备份方法
- 物理备份
备份时数据库处于关闭状态,直接打包数据库文件
备份速度快,恢复时也是最简单的 - 专用备份工具mydump或mysqlhotcopy
mysqldump常用的逻辑备份工具
mysqlhotcopy 仅拥有备份MyISAM和ARCHIVE表 - 启用二进制日志进行增量备份
进行增量备份,需要刷新二进制日志 - 第三方工具
免费的Mysql热备份软件Percona XtraBackup
1.4 Mysql完全备份
- 是对整个数据库、数据库结构和文件结构的备份。
- 保存的是备份完成时候的数据库
- 是差异备份与增量备份的基础
- 优点:备份与恢复操作简单方便
- 缺点:数据存在大量的重复
占用大量的备份空间
备份与恢复时间长
1.4.1 数据库完全备份分类
- 物理冷备份与恢复
关闭Mysql数据库
使用tar命令直接打包数据库文件夹
直接替换现有Mysql目录即可 - mysqldump备份与恢复
MySQL 自带的备份工具,可方便对实现对 MySQL的备份
可以将指定的库、表导出为SQL 脚本
使用命令mysql 导入备份的数据
二、MySQL物理冷备份及恢复
- 备份
[root@localhost ~]# systemctl stop mysqld
[root@localhost ~]# tar zcf /opt/mysql_all-$(date +%F).tar.gz /usr/local/mysql/data/
- 还原
[root@localhost mnt]# mkdir /bak/
[root@localhost mnt]# mv /usr/local/mysql/data/ /mnt/bak/ ## 将出现问题的数据移/mnt/bak里面
[root@localhost opt]# tar zxf /opt/mysql_all-2020-08-23.tar.gz -C /mnt/ ## 解压备份的文件到mnt下
[root@localhost mnt]# mv usr/local/mysql/data/ /usr/local/mysql/ ## 将备份文件移动至库文件夹下
[root@localhost ~]# systemctl start mysqld ## 重新启动服务
三、mysqldump备份数据库
- mysqldump命令对单个库进行完全备份
- 基本格式
mysqldump -u 用户名 -p [密码][选项][数据库] > /备份路径/备份文件名
例:
[root@localhost mysql]# mysqldump -uroot -p students > /opt/students.sql
Enter password:
- 对数据库进行完全备份
mysqldump -u 用户名 -p [密码][选项] --all-databases > /备份路径/备份文件名
例:
[root@localhost mysql]# mysqldump -uroot -p --all-databases > /opt/all_data.sql
- 针对库内特定的表进行备份
mysqldump -u 用户名 -p [密码][选项] 数据库名 表名 > /备份路径/备份文件名
例:
[root@localhost mysql]# mysqldump -uroot -p students test > /opt/students-test.sql
四、恢复数据库或表
4.1 恢复数据库
-
使用mysqldump导出的脚本,可使用导入的方法
source命令 mysql命令 -
使用source 恢复数据库的步骤
-
登录到MySQL数据库
-
执行source 备份sql脚本的路径
-
source 恢复的示例
mysql> source /opt/students.sql
- mysql 恢复的示例
[root@localhost mysql]# mysql -uroot -pabc123 students < /opt/students.sql ## mysql单个库的还原需要指定库,
## 两个或两个以上的恢复,就不需要,因为此时本分的文件里有了创建数据库的操作,单个的话没有
4.2 恢复表
- 恢复表时同样可以使用source或者mysql命令
- source恢复表的操作与恢复库的操作相同
- 当备份文件中只包含表的备份,而不包括创建库的语句时,需指定库名,且目标库必须存在
mysql -u [用户名] -p [密码] < 表备份脚本的路径
五、增量备份
是上一次备份后增加备份/变化的文件或者内容(增量备份的基础是上一次的完全备份)
- 特点
没有重复数据,备份量不大,时间段。
恢复需要上次完全备份及完全备份之后所有的增量备份才能恢复,而且要对所有增量备份进行逐个反推恢复。
mysql没有直接的备份方法,可通过mysql提供的二进制日志间接备份
- mysql二进制日志对备份的意义:
二进日志保存了所有更新或者可能更新数据库的操作
二进制日志在启动mysql服务器后开始记录,并在文件达到max_binlog_size所设置的大小或者接受到flush logs命令后重新创建新的日志文件
只需定时执行flush logs方法重新创建新的日志,生成二进制文件序列,并及时把这些日志保存到安全的地方就完成了一个时间段的增量备份
5.1 MySQL数据库增量恢复
5.1.1 一般恢复
一般恢复:将所有二进制日志内容全部恢复
- 基本格式
mysqlbinlog [--no-defaults] 增量备份文件 | mysql -u 用户名 -p
5.1.2 基于位置恢复
-
基于位置恢复:在某一错误操作段进行恢复,可跳过错误的操作进行恢复
-
恢复数据到指定位置(即到指定位置停止)
mysqlbinlog [--no-defaults] --stop-position='操作 id' 二进制文件 | mysql -u 用户名 -p 密码
- 从指定的位置开始恢复数据
mysqlbinlog [--no-defaults] --start-position='操作 id' 二进制文件 | mysql -u 用户名 -p 密码
5.1.3 基于时间点恢复
基于时间点恢复:跳过存在错误操作的时间点
- 从日志开头截至到某个时间点的恢复
mysqlbinlog [--no-defaults] --stop-datetime='年-月-日 小时:分钟:秒' 二进制日志 | mysql -u 用户名 -p 密码``
- 从某个时间点到日志结尾的恢复
mysqlbinlog [--no-defaults] --start-datetime='年-月-日 小时:分钟:秒' 二进制日志 | mysql -u 用户名 -p 密码
- 从某个时间点到某个时间的恢复
mysqlbinlog [--no-defaults] --start-datetime='年-月-日 小时:分钟:秒' --stop-datetime='年-月-日 小时:分钟:秒' 二进制日志 | mysql -u 用户名 -p 密码
5.1.4 二进制日志文件
- 开启二进制日志功能
vim /etc/cnf
在mysqld 中加 log-bin=mysql-bin
- 查看二进制日志文件
mysqlbinlog --no-defaults mysql-bin.000001 ## mysql-bin.000001为日志增量名
- 解码二进制文件
mysqlbinlog --no-defaults --base64-output=decode-rows -v mysql-bin.000001 >/opt/bk02.txt
- 操作完成生成新的二进制日志文件
mysqladmin -uroot -p flush-logs ## 刷新日志,生成新的存储日志的文件,备份增量日志
5.2 增量恢复文件
5.2.1 开启二进制日志功能
[root@localhost ~]# systemctl stop mysqld ## 先关闭数据库
[root@localhost ~]# vim /etc/my.cnf
[mysqld]
省略不写……
log-bin=mysql-bin ## 在mysqld模块下添加二进制日志功能
[root@localhost ~]# ls /usr/local/mysql/data/ ## mysql-bin.000001 发现二进制日志文件
auto.cnf ibdata1 ib_logfile1 mysql mysql-bin.index students
ib_buffer_pool ib_logfile0 ibtmp1 mysql-bin.000001 performance_schema sys
5.2.2 进行操作
[root@localhost ~]# mysqldump -uroot -p students > /mnt/students.sql ## 进行数据库students的备份
[root@localhost data]# mysqladmin -uroot -pabc123 flush-logs ## 生成新的增量备份文件
mysql> select * from xuesheng; ## 查看未操作的表
+----+----------+-------+----------+-------+
| id | name | score | address | hobby |
+----+----------+-------+----------+-------+
| 1 | zhangsan | 90 | nanjing | 1 |
| 2 | lisi | 88 | chengdu | 1 |
| 3 | wangwu | 75 | shanghai | 2 |
| 4 | zhaoliu | 60 | beijing | 2 |
| 5 | tianqi | 78 | hangzhou | 1 |
| 6 | heiba | 78 | hangzhou | 1 |
| 7 | heiba1 | 78 | hangzhou | 1 |
| 8 | heiba2 | 78 | hangzhou | 1 |
+----+----------+-------+----------+-------+
8 rows in set (0.00 sec)
mysql> insert into xuesheng(name,score,address,hobby) values('tom',85,'guangzhou',1);
Query OK, 1 row affected (0.00 sec)
mysql> insert into xuesheng(name,score,address,hobby) values('jerry',62,'chongqing',2);
Query OK, 1 row affected (0.01 sec)
mysql> delete from xuesheng where id=2; ## 模拟误操作
Query OK, 1 row affected (0.00 sec)
mysql> insert into xuesheng(name,score,address,hobby) values('lilei',73,'wuhan',1);
Query OK, 1 row affected (0.00 sec)
mysql> select * from xuesheng;
+----+----------+-------+-----------+-------+
| id | name | score | address | hobby |
+----+----------+-------+-----------+-------+
| 1 | zhangsan | 90 | nanjing | 1 |
| 3 | wangwu | 75 | shanghai | 2 |
| 4 | zhaoliu | 60 | beijing | 2 |
| 5 | tianqi | 78 | hangzhou | 1 |
| 6 | heiba | 78 | hangzhou | 1 |
| 7 | heiba1 | 78 | hangzhou | 1 |
| 8 | heiba2 | 78 | hangzhou | 1 |
| 9 | tom | 85 | guangzhou | 1 |
| 10 | jerry | 62 | chongqing | 2 |
| 11 | lilei | 73 | wuhan | 1 |
+----+----------+-------+-----------+-------+
10 rows in set (0.00 sec)
5.2.3 对二进制文件进行解码
[root@localhost data]# mysqladmin -uroot -pabc123 flush-logs ## 保存刚刚的增量备份二进制文件,生成新的备份文件
乱码看不懂 需解码
64位解码 -v 显示更详细信息
mysqlbinlog --no-defaults --base64-output=decode-rows -v mysql-bin.000002 >/mnt/bk02.txt
[root@localhost mnt]# vim /mnt/bk02.txt
# at 891 ## 误操作时间与位置
#200824 10:21:46 server id 1 end_log_pos 954 CRC32 0x0d15a891 Table_map: `students`.`xuesheng` mapped to number 124
# at 954
#200824 10:21:46 server id 1 end_log_pos 1015 CRC32 0xc2261844 Delete_rows: table id 124 flags: STMT_END_F
### DELETE FROM `students`.`xuesheng`
### WHERE
### @1=2
### @2='lisi'
### @3=88
### @4='chengdu'
### @5=1
# at 1187 ## 紧接着插入lilei的时间与位置
#200824 10:22:23 server id 1 end_log_pos 1250 CRC32 0xfa311240 Table_map: `students`.`xuesheng` mapped to number 124
# at 1250
#200824 10:22:23 server id 1 end_log_pos 1310 CRC32 0x9bce74dd Write_rows: table id 124 flags: STMT_END_F
### INSERT INTO `students`.`xuesheng`
### SET
### @1=11
### @2='lilei'
### @3=73
### @4='wuhan'
### @5=1
5.2.4 基于位置恢复文件
- 基于位置恢复
mysql> drop table xuesheng; ## 删除操作错误后存在的表
Query OK, 0 rows affected (0.01 sec)
mysql> source /mnt/students.sql ## 用完整备份的文件恢复
mysql> select * from xuesheng;
+----+----------+-------+----------+-------+
| id | name | score | address | hobby |
+----+----------+-------+----------+-------+
| 1 | zhangsan | 90 | nanjing | 1 |
| 2 | lisi | 88 | chengdu | 1 |
| 3 | wangwu | 75 | shanghai | 2 |
| 4 | zhaoliu | 60 | beijing | 2 |
| 5 | tianqi | 78 | hangzhou | 1 |
| 6 | heiba | 78 | hangzhou | 1 |
| 7 | heiba1 | 78 | hangzhou | 1 |
| 8 | heiba2 | 78 | hangzhou | 1 |
+----+----------+-------+----------+-------+
8 rows in set (0.00 sec)
[root@localhost data]# mysqlbinlog --no-defaults --stop-position='891' /usr/local/mysql/data/mysql-bin.000002 | mysql -u root -p
mysql> select * from xuesheng; ## 此时已经恢复了tom 和jerry
+----+----------+-------+-----------+-------+
| id | name | score | address | hobby |
+----+----------+-------+-----------+-------+
| 1 | zhangsan | 90 | nanjing | 1 |
| 2 | lisi | 88 | chengdu | 1 |
| 3 | wangwu | 75 | shanghai | 2 |
| 4 | zhaoliu | 60 | beijing | 2 |
| 5 | tianqi | 78 | hangzhou | 1 |
| 6 | heiba | 78 | hangzhou | 1 |
| 7 | heiba1 | 78 | hangzhou | 1 |
| 8 | heiba2 | 78 | hangzhou | 1 |
| 9 | tom | 85 | guangzhou | 1 |
| 10 | jerry | 62 | chongqing | 2 |
+----+----------+-------+-----------+-------+
[root@localhost data]# mysqlbinlog --no-defaults --start-position='1187' /usr/local/mysql/data/mysql-bin.000002 | mysql -uroot -p
mysql> select * from xuesheng; ## 恢复lilei 未删除lisi
+----+----------+-------+-----------+-------+
| id | name | score | address | hobby |
+----+----------+-------+-----------+-------+
| 1 | zhangsan | 90 | nanjing | 1 |
| 2 | lisi | 88 | chengdu | 1 |
| 3 | wangwu | 75 | shanghai | 2 |
| 4 | zhaoliu | 60 | beijing | 2 |
| 5 | tianqi | 78 | hangzhou | 1 |
| 6 | heiba | 78 | hangzhou | 1 |
| 7 | heiba1 | 78 | hangzhou | 1 |
| 8 | heiba2 | 78 | hangzhou | 1 |
| 9 | tom | 85 | guangzhou | 1 |
| 10 | jerry | 62 | chongqing | 2 |
| 11 | lilei | 73 | wuhan | 1 |
+----+----------+-------+-----------+-------+
5.2.5基于时间点恢复文件
- 前面操作都一样 只是后面恢复的命令不一样
[root@localhost data]# mysqlbinlog --no-defaults --stop-datetime='2020-08-24 10:21:46' /usr/local/mysql/data/mysql-bin.000002 |mysql -uroot -p
[root@localhost data]# mysqlbinlog --no-defaults --start-datetime='2020-08-24 10:22:23' /usr/local/mysql/data/mysql-bin.000002 | mysql -uroot -p