• MySQL数据文件被误删,如何进行恢复?


    在我们实际工作中,尤其在公司的测试环境下,经常会有多个业务方服务共用同一套服务器,部署自身MySQL环境。很不巧的是,会出现有MySQL数据文件被删除/误删除的情况发生。假如真的发生了,想想就很令人崩溃对不对?

    先别着急,今天来跟大家分享一个对于MySQL数据文件被误删除后尝试恢复的办法。一旦发生上述情况,同时实例数据未做备份,是否有机会进行数据恢复呢?

    接下来,就让我们来做下尝试数据恢复过程的演示:

    1、构建模拟数据

    模拟数据准备:

    1. CREATE TABLE `t1` (
    2. `id` int(11) DEFAULT NULL
    3. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
    4. mysql> select * from t1;
    5. +------+
    6. | id |
    7. +------+
    8. | 1 |
    9. | 2 |
    10. | 3 |
    11. | 4 |
    12. | 5 |
    13. +------+
    14. 5 rows in set (0.00 sec)
    15. 复制代码

    2、删除数据文件

    在操作系统层进行数据文件的删除。

    1. [root@admin-db12 test]# ll
    2. total 112
    3. -rw-r----- 1 mysql mysql 67 Nov 22 10:01 db.opt
    4. -rw-r----- 1 mysql mysql 8556 Nov 22 11:48 t1.frm
    5. -rw-r----- 1 mysql mysql 98304 Nov 22 11:48 t1.ibd
    6. [root@admin-db12 test]# pwd
    7. /mysql/multi/3303/data/test
    8. [root@admin-db12 test]# ll
    9. total 112
    10. -rw-r----- 1 mysql mysql 67 Nov 22 10:01 db.opt-rw-r----- 1 mysql mysql 8556 Nov 22 11:48 t1.frm-rw-r----- 1 mysql mysql 98304 Nov 22 11:48 t1.ibd
    11. [root@admin-db12 test]# rm -rf *
    12. [root@admin-db12 test]# ll
    13. total 0
    14. 复制代码

    3、查询验证数据

    在数据库层,查看当前表中数据,发现当前表数据目前已空空如也。

    1. #当前实例
    2. mysql> select * from t1;
    3. Empty set (0.00 sec)
    4. 复制代码

    4、OS层获取内存中的数据

    当前实例没有关闭的情况下,查看实例pid。

    1. [root@admin-db62 test]# ps aux | grep 3303
    2. root 21952 0.0 0.0 113304 1648 ? S 11:47 0:00 /bin/sh /mysql/multi/3303/private/bin/mysqld_safe --defaults-file=/mysql/multi/3303/etc/my.cnf
    3. mysql 23356 0.2 1.1 19529408 1568416 ? Sl 11:47 0:04 /mysql/multi/3303/private/bin/mysqld --defaults-file=/mysql/multi/3303/etc/my.cnf --basedir=/mysql/multi/3303/private --datadir=/mysql/multi/3303/data --plugin-dir=/mysql/multi/3303/private/lib/plugin --user=mysql --log-error=/mysql/multi/3303/log/mysql-error.log --open-files-limit=65535 --pid-file=/mysql/multi/3303/pid/mysql.pid --socket=/mysql/multi/3303/socket/mysql.sock --port=3303
    4. [root@admin-db62 fd]# cd /proc/23356/fd
    5. [root@admin-db62 fd]# ll
    6. lrwx------ 1 root root 64 Nov 22 11:52 39 -> /mysql/multi/3303/data/mysql/time_zone.ibdlrwx------ 1 root root 64 Nov 22 11:52 4 -> /mysql/multi/3303/data/ib_logfile0lrwx------ 1 root root 64 Nov 22 11:52 40 -> /mysql/multi/3303/data/mysql/time_zone_transition.ibdlrwx------ 1 root root 64 Nov 22 11:52 42 -> /mysql/multi/3303/data/test/t1.ibd (deleted)
    7. 复制代码

    通过上述操作我们发现,被我们干掉的数据文件显示状态为”deleted“,被删除。

    5、恢复处理操作

    为保护好当前服务器现场、在另一台服务器上开始恢复数据。

    1. #目标端
    2. [root@admin-db64 3306]# nc -l 13306 > /mysql/multi/3306/data/t1.ibd #db64这台服务器上,3306实例中来恢复上述被删除的数据。/mysql/mysql/multi/3306/data为临时存放数据目录
    3. #远端
    4. lrwx------ 1 root root 64 Nov 22 11:52 42 -> /mysql/multi/3303/data/test/t1.ibd (deleted)
    5. [root@admin-db62 fd]# cat 42 | nc 10.26.65.74 13306
    6. #如上操作,将在OS层,内存里的数据拷贝并传输至远程恢复服务器上。
    7. 复制代码

    【注意】不要在本机进行恢复、保留线上环境,避免二次伤害。

    6、恢复数据处理

    在源端服务器进行数据恢复操作。

    1. [root@admin-db64 3306]# nc -l 13306 > /mysql/multi/3306/data/t1.ibd
    2. [root@admin-db64 3306]# cd data/
    3. [root@admin-db64 data]# ll
    4. total 100
    5. -rw-r----- 1 mysql mysql 67 Nov 22 12:36 db.opt-rw-r--r-- 1 root root 98304 Nov 22 12:37 t1.ibd
    6. [root@admin-db64 data]# chown -R mysql.mysql t1.ibd #更改属主
    7. 复制代码

    登录源端进行恢复实例操作:

    1. mysql > use test;
    2. Database changed
    3. mysql> show tables;
    4. Empty set (0.00 sec)
    5. #1、根据表结构创建表(不要告诉我表结构也已经没有了...)
    6. CREATE TABLE `t1` (
    7. `id` int(11) DEFAULT NULL
    8. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
    9. #2、discard 表空间
    10. mysql> alter table t1 discard tablespace;
    11. Query OK, 0 rows affected, 1 warning (0.01 sec)
    12. #3、将上面准备好的数据文件放入正确目录
    13. [root@admin-db64 data]#mv t1.ibd test/
    14. #4、import 表空间
    15. mysql> alter table t1 import tablespace;
    16. Query OK, 0 rows affected, 1 warning (0.01 sec)
    17. #5、查看数据是否可以正常查看
    18. mysql> select * from t1;
    19. +------+
    20. | id |
    21. +------+
    22. | 1 |
    23. | 2 |
    24. | 3 |
    25. | 4 |
    26. | 5 |
    27. +------+
    28. 5 rows in set (0.00 sec)
    29. 复制代码

    通过上述步骤的操作,发现数据已经可以正常查看,后面只需要将其备份出来,恢复到待恢复实例即可。此处不再赘述。

    写在最后

    今天跟大家分享了一种误删数据文件利用内存数据恢复的方法,其实还有一些其他的恢复方法,需要根据不同场景去选取最优的处理方案。

    最后,需要跟大家强调的是:预防远比处理的意义大得多

    另外,在 MySQL 的集群方案中,会时不时地用到备份来恢复实例,因此定期检查备份的有效性也很有必要。 如果你是业务开发同学,你可以用 show grants 命令查看账户的权限,如果权限过大,可以建议 DBA 同学给你分配权限低一些的账号;你也可以评估业务的重要性,和 DBA 商量备份的周期、是否有必要创建延迟复制的备库等等。

    记住,数据和服务的可靠性不止是运维团队的工作,最终是各个合作环节一起保障的结果。

  • 相关阅读:
    接口自动化测试(Python+Requests+Unittest)
    AJAX(二):axios 和 fetch函数发送AJAX请求、同源策略、 jsonp、CORS
    Vue2:路由组件缓存技术
    设计模式:单例、原型和生成器
    SpringCloud微服务介绍+系统架构
    Linux进程间通信
    【C++】算法STL库
    axios传递数组格式参数
    Kubernetes: kube-apiserver 之认证
    10 个超实用的 JavaScript 技巧,让你的日常工作更轻松
  • 原文地址:https://blog.csdn.net/m0_71777195/article/details/128014264