文章目录
- 备份类型
- 备份内容
- 备份工具
- mysqldump备份
- 实战案例:恢复误删除的表
- 准备工作
- 2:30完全备份
- 完全备份后更新数据表
- 10:00误删students表
- 需要恢复还原的状态
- 开始还原恢复
为什么要备份?
备份是为了:灾难恢复:硬件故障、软件故障、自然灾害、黑客攻击、误操作等数据丢失场景。
备份类型
完全备份:整个数据集
部分备份:只备份数据子集,如部分库或表
增量备份:仅备份最近一次完全备份或增量备份(如果存在增量)以来变化的数据,备份较快,还原复杂
差异备份:仅备份最近一次完全备份以来变化的数据,备份较慢,还原简单。冷备份:读写操作均不可进行,数据库停止服务
温备份;读操作可执行,但写操作不可执行
热备份:读写操作均可执行MyISAM: 温备,不支持热备
InnoDB: 都支持物理备份:直接复制数据文件进行备份,与存储引擎有关,占用较多的空间,速度快
逻辑备份:从数据库中“导出”数据另存而进行备份,与存储引擎无关,占用空间少,速度慢,可能丢失精度。
注意:二进制日志文件不应该与数据文件放在同一磁盘。
备份内容
备份什么?1.数据2.二进制日志、InnoDB的事务日志3.用户账号,权限设置,程序代码(存储过程、函数、触发器,事件调度器)4.服务器的配置文件
备份工具
mysqldump备份
命令格式
Usage: mysqldump [OPTIONS] database [tables]
OR mysqldump [OPTIONS] --databases [OPTIONS] DB1 [DB2 DB3...]
OR mysqldump [OPTIONS] --all-databases [OPTIONS]
实战案例:恢复误删除的表
案例说明:每天凌晨2:30做完全备份,早上10:00误删除了students表,10:10才发现故障,现在需要将数据库还原到10:10的状态,且恢复被删除的students表。
准备工作
恢复数据之前的准备工作1.准备数据库和数据表2.确保二进制日志已经开启
现有hellodb数据库中的students、teachers…等数据表
mysql> use hellodb;
Database changedmysql> show tables;
+-------------------+
| Tables_in_hellodb |
+-------------------+
| classes |
| coc |
| courses |
| scores |
| students |
| teachers |
| toc |
+-------------------+
7 rows in set (0.01 sec)
现students、teachers表中有如下数据
mysql> select * from students;
+-------+---------------+-----+--------+---------+-----------+
| StuID | Name | Age | Gender | ClassID | TeacherID |
+-------+---------------+-----+--------+---------+-----------+
| 1 | Shi Zhongyu | 22 | M | 2 | 3 |......
| 24 | Xu Xian | 27 | M | NULL | NULL |
| 25 | Sun Dasheng | 100 | M | NULL | NULL |
+-------+---------------+-----+--------+---------+-----------+
25 rows in set (0.00 sec)mysql> select * from teachers;
+-----+---------------+-----+--------+
| TID | Name | Age | Gender |
+-----+---------------+-----+--------+
| 1 | Song Jiang | 45 | M |
......
| 3 | Miejue Shitai | 77 | F |
| 4 | Lin Chaoying | 93 | F |
+-----+---------------+-----+--------+
4 rows in set (0.01 sec)
确认二进制日志是否开启
#确认log_bin和sql_log_bin这两个变量是否为1mysql> select @@log_bin;
+-----------+
| @@log_bin |
+-----------+
| 1 |
+-----------+mysql> select @@sql_log_bin;
+---------------+
| @@sql_log_bin |
+---------------+
| 1 |
+---------------+
目前二进制日志文件的位置
mysql> show master logs;
+---------------+-----------+-----------+
| Log_name | File_size | Encrypted |
+---------------+-----------+-----------+
| binlog.000001 | 10753 | No |
+---------------+-----------+-----------+
# 执行备份之前二进制日志文件,文件名为binlog.000001,文件大小(File_size)在10753处
2:30完全备份
mysqldump -uroot -F -A --single-transaction --master-data=2 > /data/full_`date +%F`.sql#WARNING: --master-data is deprecated and will be removed in a future version. Use --source-data instead.mysqldump -uroot -F -A --single-transaction --source-data=2 > /data/full_`date +%F`.sqlmaster-data参数mysql8.0.26以后的版本改为source-data了,上面的WARNING中有提示,我的这个是8.0.32版本的
full_2024-03-29.sql中记录着二进制日志文件的位置,如下截图:
完全备份后更新数据表
在完全备份之后,系统可能做了很多的数据库操作,很多的操作会导致越来越多的二进制文件生成binlog.000004、binlog.000005…等等
我们可以使用flush log来模拟下生成了多个二进制日志文件
mysql> flush logs;
Query OK, 0 rows affected (0.03 sec)mysql> show master logs;
+---------------+-----------+-----------+
| Log_name | File_size | Encrypted |
+---------------+-----------+-----------+
| binlog.000001 | 10797 | No |
| binlog.000002 | 201 | No |
| binlog.000003 | 809 | No |
| binlog.000004 | 157 | No |
+---------------+-----------+-----------+
4 rows in set (0.00 sec)mysql> insert students (name,age,gender) values('leilei',20,'F');
Query OK, 1 row affected (0.00 sec)mysql> insert students (name,age,gender) values('mengm',18,'M');
Query OK, 1 row affected (0.00 sec)mysql> show master logs;
+---------------+-----------+-----------+
| Log_name | File_size | Encrypted |
+---------------+-----------+-----------+
| binlog.000001 | 10797 | No |
| binlog.000002 | 201 | No |
| binlog.000003 | 809 | No |
| binlog.000004 | 768 | No |
+---------------+-----------+-----------+
4 rows in set (0.00 sec)
10:00误删students表
mysql> drop table students;
Query OK, 0 rows affected (0.01 sec)
students表误删后,teachers表还在持续更新中
mysql> drop table students;
Query OK, 0 rows affected (0.01 sec)mysql> insert teachers (name,age,gender) values('wang',30,'M');
Query OK, 1 row affected (0.00 sec)mysql> insert teachers (name,age,gender) values('mage',28,'M');
Query OK, 1 row affected (0.01 sec)
mysql> select * from teachers;
+-----+---------------+-----+--------+
| TID | Name | Age | Gender |
+-----+---------------+-----+--------+
| 1 | Song Jiang | 45 | M |
| 2 | Zhang Sanfeng | 94 | M |
| 3 | Miejue Shitai | 77 | F |
| 4 | Lin Chaoying | 93 | F |
| 5 | wang | 30 | M |
| 6 | mage | 28 | M |
+-----+---------------+-----+--------+
6 rows in set (0.00 sec)
需要恢复还原的状态
此时继2:30分的完全备份后,我们需要恢复还原哪些数据
继2:30的完全备份后我们需要恢复1.students表更新的4条记录2.十点钟误删的students表3.teachers表更新的2条记录
开始还原恢复
在做数据的恢复还原之前,有几句心得不知当讲不当讲!!!
还是讲吧,“不要拿生产做测试啊!!!”,这是领导怼我的原话。懂我意思吧,能感受到语气的气浪吗!!!记住,哥们,就算你再有把握恢复数据,也请单独拿一个测试机出来,真正恢复出来了再上生产!!!切记!!!切记!!!切记!!!程序数据这玩意儿你还真得信邪,搞不好生产环境被你弄成一锅粥还不如不恢复!!!
我们将备份出来的sql拷贝到另一台远程主机上做测试
凌晨2:30分的完全备份后的数据更新是从二进制日志文件binlog.000003的157处开始的,所以完全备份之后的更新数据是从157之后的所有内容。
将二进制备份出来的内容导入到一个sql文件中
mysqlbinlog --start-position=157 /var/lib/mysql/binlog.000003 > /data/inc.sqlmysqlbinlog /var/lib/mysql/binlog.000004 >> /data/inc.sql # '>>'是追加内容,不会覆盖之前的内容。
至此2:30已将数据完全备份至full_2024-03-29.sql文件中,
2:30和10:00之间数据库更新删除操作已经备份至inc.sql文件中了。
因为inc.sql中有drop table students的语句,所以我们要找到这个误删除的语句,搞掉这个drop语句之后再恢复还原。
grep -i drop inc.sql
#DROP TABLE `students` /* generated by server */
sed -n '/DROP TABLE `students`/p' inc.sql
#DROP TABLE `students` /* generated by server */
sed -i '/DROP TABLE `students`/d' inc.sql
sed -n '/DROP TABLE `students`/p' inc.sql
将备份出来的sql文件拷贝到另一台远程主机10.0.0.206的data目录下,先在206这台机器上做测试还原,没问题了再在原来的主机上还原恢复。
[root@rocky data]# scp /data/* 10.0.0.206:/data
The authenticity of host '10.0.0.206 (10.0.0.206)' can't be established.
ECDSA key fingerprint is SHA256:jXjzWTy4SJ9SVHPzyzO0XRP60n9QAWDC5kwQBX/tc0U.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '10.0.0.206' (ECDSA) to the list of known hosts.
root@10.0.0.206's password:
full_2024-03-29.sql 100% 1262KB 106.0MB/s 00:00
inc.sql 100% 12KB 14.7MB/s 00:00
[root@rocky data]#
执行远程拷贝过来的sql原文件
mysql> source /data/full_2024-03-29.sql;mysql> source /data/inc.sql;
如下图已经将2:30分的完全备份和2:30到10:00之前的新增数据都还原恢复了。