【黄啊码】MySQL入门—17、在没有备份的情况下,如何恢复数据库数据?

news2024/11/24 17:59:56

大家好!我是黄啊码,MySQL的入门篇已经讲到第16个课程了,今天我们继续讲讲大白篇系列——科技与狠活之恢复数据库

在没做数据库备份,没有开启使用 Binlog 的情况下,尽可能地找回数据。

今天的内容主要包括以下几个部分:

InnoDB 存储引擎的表空间 InnoDB

存储引擎的文件格式是.ibd 文件,数据会按照表空间(tablespace)进行存储, 分为共享表空间和独立表空间。如果想要查看表空间的存储方式,我们可以对 innodb_file_per_table变量进行查询,使用show variables like 'innodb_file_per_table';。ON 表示独立表空间,而 OFF 则表示共享表空间。

如果采用共享表空间的模式,InnoDB 存储的表数据都会放到共享表空间中,也就是多个数 据表共用一个表空间,同时表空间也会自动分成多个文件存放到磁盘上。这样做的好处在于 单个数据表的大小可以突破文件系统大小的限制,最大可以达到 64TB,也就是 InnoDB 存 储引擎表空间的上限。不足也很明显,多个数据表存放到一起,结构不清晰,不利于数据的 找回,同时将所有数据和索引都存放到一个文件中,也会使得共享表空间的文件很大。

采用独立表空间的方式可以让每个数据表都有自己的物理文件,也就是 table_name.ibd 的 文件,在这个文件中保存了数据表中的数据、索引、表的内部数据字典等信息。它的优势在 于每张表都相互独立,不会影响到其他数据表,存储结构清晰,利于数据恢复,同时数据表 还可以在不同的数据库之间进行迁移。 

如果.ibd 文件损坏了,数据如何找回

如果我们之前没有做过全量备份,也没有开启 Binlog,那么我们还可以通过.ibd 文件进行 数据恢复,采用独立表空间的方式可以很方便地对数据库进行迁移和分析。如果我们误删除 (DELETE)某个数据表或者某些数据行,也可以采用第三方工具回数据。

我们这里可以使用 Percona Data Recovery Tool for InnoDB 工具,能使用工具进行修复 是因为我们在使用 DELETE 的时候是逻辑删除。我们之前学习过 InnoDB 的页结构,在保 存数据行的时候还有个删除标记位,对应的是页结构中的 delete_mask 属性,该属性为 1 的时候标记了记录已经被逻辑删除,实际上并不是真的删除。

不过当有新的记录插入的时 候,被删除的行记录可能会被覆盖掉。所以当我们发生了 DELETE 误删除的时候,一定要 第一时间停止对误删除的表进行更新和写入,及时将.ibd 文件拷贝出来并进行修复。 如果已经开启了 Binlog,就可以使用闪回工具,比如 mysqlbinlog 或者 binlog2sql,从 工具名称中也能看出来它们都是基于 Binlog 来做的闪回。

原理就是因为 Binlog 文件本身 保存了数据库更新的事件(Event),通过这些事件可以帮我们重现数据库的所有更新变 化,也就是 Binlog 回滚。

下面我们就来看下没有做过备份,也没有开启 Binlog 的情况下,如果.ibd 文件发生了损 坏,如何通过数据库自身的机制来进行数据恢复。

实际上,InnoDB 是有自动恢复机制的,如果发生了意外,InnoDB 可以在读取数据表时自 动修复错误。但有时候.ibd 文件损坏了,会导致数据库无法正常读取数据表,这时我们就 需要人工介入,调整一个参数,这个参数叫做innodb_force_recovery。

我们可以通过命令

show variables like 'innodb_force_recovery';

来查看当前 参数的状态,你能看到默认为 0,表示不进行强制恢复。如果遇到错误,比如 ibd 文件中 的数据页发生损坏,则无法读取数据,会发生 MySQL 宕机的情况,此时会将错误日志记 录下来。

 innodb_force_recovery参数一共有 7 种状态,除了默认的 0 以外,还可以为 1-6 的 取值,分别代表不同的强制恢复措施。

当我们需要强制恢复的时候,可以将innodb_force_recovery设置为 1,表示即使发现 了损坏页也可以继续让服务运行,这样我们就可以读取数据表,并且对当前损坏的数据表进 行分析和备份。 通常innodb_force_recovery参数设置为 1,只要能正常读取数据表即可。

但如果参数 设置为 1 之后还无法读取数据表,我们可以将参数逐一增加,比如 2、3 等。一般来说不需 要将参数设置到 4 或以上,因为这有可能对数据文件造成永久破坏。另外当 innodb_force_recovery设置为大于 0 时,相当于对 InnoDB 进行了写保护,只能进行 SELECT 读取操作,还是有限制的读取,对于 WHERE 条件以及 ORDER BY 都无法进行操 作。

当我们开启了强制恢复之后,数据库的功能会受到很多限制,我们需要尽快把有问题的数据 表备份出来,完成数据恢复操作。整体的恢复步骤可以按照下面的思路进行:

1. 使用innodb_force_recovery

启动服务器 将innodb_force_recovery参数设置为 1,启动数据库。如果数据表不能正常读取,需 要调大参数直到能读取数据为止。通常设置为 1 即可。

2. 备份数据表

在备份数据之前,需要准备一个新的数据表,这里需要使用 MyISAM 存储引擎。原因很简 单,InnoDB 存储引擎已经写保护了,无法将数据备份出来。然后将损坏的 InnoDB 数据表 备份到新的 MyISAM 数据表中。

3. 删除旧表

改名新表 数据备份完成之后,我们可以删除掉原有损坏的 InnoDB 数据表,然后将新表进行改名。

4. 关闭innodb_force_recovery

并重启数据库 innodb_force_recovery大于 1 的时候会有很多限制,我们需要将该功能关闭,然后重 启数据库,并且将数据表的 MyISAM 存储引擎更新为 InnoDB 存储引擎。

InnoDB 文件的损坏与恢复实例

我们刚才说了 InnoDB 文件损坏时的人工操作过程,下面我们用一个例子来模拟下。

生成 InnoDB 数据表

为了简便,我们创建一个数据表 t1,只有 id 一个字段,类型为 int。使用命令create table t1(id int);即可。

然后创建一个存储过程帮我们生成一些数据 

BEGIN
-- 当前数据行
DECLARE i INT DEFAULT 0;
-- 最大数据行数
DECLARE max_num INT DEFAULT 100;
-- 关闭自动提交
SET autocommit=0;
REPEAT
SET i=i+1;
-- 向 t1 表中插入数据
INSERT INTO t1(id) VALUES(i);
UNTIL i = max_num
END REPEAT;
-- 提交事务
COMMIT;
END

然后我们运行call insert_t1(),这个存储过程帮我们插入了 100 条数据,这样我们就 有了 t1.ibd 这个文件。

模拟损坏.ibd 文件

实际工作中我们可能会遇到各种各样的情况,比如.ibd 文件损坏等,如果遇到了数据文件 的损坏,MySQL 是无法正常读取的。在模拟损坏.ibd 文件之前,我们需要先关闭掉 MySQL 服务,然后用编辑器打开 t1.ibd,类似下图所示:

 文件是有二进制编码的,看不懂没有关系,我们只需要破坏其中的一些内容即可,比如我在 t1.ibd 文件中删除了 2 行内容(文件大部分内容为 0,我们在文件中间部分找到一些非 0 的取值,然后删除其中的两行:4284 行与 4285 行,原 ibd 文件和损坏后的 ibd 文件见 GitHub地址。其中 t1.ibd 为创建的原始数据文件,t1- 损坏.ibd 为损坏后的数据文件, 你需要自己创建 t1 数据表,然后将 t1- 损坏.ibd 拷贝到本地,并改名为 t1.ibd)。

然后我们保存文件,这时.ibd 文件发生了损坏,如果我们没有打开 innodb_force_recovery,那么数据文件无法正常读取。为了能读取到数据表中的数 据,我们需要修改 MySQL 的配置文件,找到[mysqld]的位置,然后再下面增加一行 innodb_force_recovery=1。

备份数据表

当我们设置innodb_force_recovery参数为 1 的时候,可以读取到数据表 t1 中的数 据,但是数据不全。我们使用SELECT * FROM t1 LIMIT 10;读取当前前 10 条数据。

 但是如果我们想要完整的数据,使用SELECT * FROM t1 LIMIT 100;就会发生如下错 误。

 这是因为读取的部分包含了已损坏的数据页,我们可以采用二分查找判断数据页损坏的位 置。这里我们通过实验,可以得出只有最后一个记录行收到了损坏,而前 99 条记录都可以 正确读出(具体实验过程省略)。

这样我们就能判断出来有效的数据行的位置,从而将它们备份出来。首先我们创建一个相同 的表结构 t2,存储引擎设置为 MyISAM。我刚才讲过这里使用 MyISAM 存储引擎是因为 在innodb_force_recovery=1的情况下,无法对 innodb 数据表进行写数据。使用命令 CREATE TABLE t2(id int) ENGINE=MyISAM;。

然后我们将数据表 t1 中的前 99 行数据复制给 t2 数据表,使用:

INSERT INTO t2 SELECT * FROM t1 LIMIT 99;

 我们刚才讲过在分析 t1 数据表的时候无法使用 WHERE 以及 ORDER BY 等子句,这里我 们可以实验一下,如果想要查询 id<10 的数据行都有哪些,那么会发生如下错误。原因是 损坏的数据页无法进行条件判断。

删除旧表,改名新表 

刚才我们已经恢复了大部分的数据。虽然还有一行记录没有恢复,但是能找到绝大部分的数 据也是好的。然后我们就需要把之前旧的数据表删除掉,使用DROP TABLE t1;。

更新表名,将数据表名称由 t2 改成 t1,使用RENAME TABLE t2 to t1;。

 将新的数据表 t1 存储引擎改成 InnoDB,不过直接修改的话,会报如下错误:

关闭innodb_force_recovery,并重启数据库 因为上面报错,所以我们需要将 MySQL 配置文件中的innodb_force_recovery=1删除 掉,然后重启数据库。最后将 t1 的存储引擎改成 InnoDB 即可,使用ALTER TABLE t1 engine = InnoDB;。

总结:用这种方式恢复丢失的数据不可能100%完全找回来,只能尽可能找到,我们平常最主要的就是应该及时备份,并且开启二进制日志,这样当有误 操作的时候就可以通过数据库备份以及 Binlog 日志来完成数据恢复。同时采用延迟备份的 策略也可以尽量抵御误操作。

好了,今天的课程学到这里,有问题的留个言,别忘了一键三连,下次我们还会再见!

我是黄啊码,码字的码,退。。。退。。。退。。。朝! 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2090.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2022NISCTF--web

easyssrf 打开题目&#xff0c;显示的是 尝试输入&#xff0c; 发现输入flag有东西 读取文件 访问下一个网站 读取文件 不能以file开头 直接伪协议&#xff0c;base64解码 checkIn 奇怪的unicode编码 当选中左边的时候右边也会被选中 我们在vscode看看 这样的额 展示的是UTF-1…

Linux系统中利用open函数多次打开同一个文件操作方法

大家好。 今天的话主要和大家聊一聊&#xff0c;在Linux系统中如果一个文件被打开多次会出现什么情况。 目录 第一&#xff1a;多次打开同一个文件 ​第二&#xff1a;一个文件被打开多次&#xff0c;在内存中不会存在多份动态文件 ​第三&#xff1a;多次open打开同一…

第一章 - Windows安装VMware Workstation Pro

文章目录前言一、VMware Workstation Pro安装的前提条件二、VMware Workstation Pro下载三、VMware Workstation Pro安装前言 Linux是一个开源、免费的操作系统&#xff0c;其稳定性、安全性、处理多并发已经得到业界认可&#xff0c;目前很多企业级的项目都会部署到Linux系统…

结构体内存对齐

在知道了结构体类型的基本使用之后&#xff0c;我们需要深入探讨一个问题&#xff0c;即计算结构体的大小&#xff0c;这也是一个热门的考点&#xff1a;结构体内存对齐。 目录 一、结构体的对齐规则 二、例题 2.1 例题一 2.2 例题二 2.3 例题三 ​编辑 三、为什么存在内存…

【C++】vector,list迭代器失效

1.vector迭代器失效 vector容器的物理基础是线性表&#xff0c;底层是指针变量实现的。 在这里导致vector迭代器失效的原因会有两种-----插入失效&#xff0c;删除失效。 1.2插入数值导致迭代器失效 1.21扩容导致迭代器失效 我们在一块vector空间插入pos&#xff08;20&…

第三章 单向链表的讲解与实现

初阶数据结构 第一章 时间复杂度和空间复杂度 第二章 动态顺序表的实现 第三章 单向链表的讲解与实现 文章目录初阶数据结构前言一、什么是链表&#xff1f;二、节点的定义&#xff1a;三、单向链表接口函数1、打印&#xff1a;2、尾插&#xff1a;3、头插&#xff1a;4、尾删…

改进YOLOv7系列: 最新结合用于小目标的新CNN卷积构建块

&#x1f4a1;统一使用 YOLOv7 代码框架&#xff0c;结合不同模块来构建不同的YOLO目标检测模型。&#x1f31f;本项目包含大量的改进方式,降低改进难度,改进点包含【Backbone特征主干】、【Neck特征融合】、【Head检测头】、【注意力机制】、【IoU损失函数】、【NMS】、【Loss…

Linux-进程控制

进程控制进程创建fork函数写时拷贝fork常规用法fork调用失败的原因进程终止进程等待进程程序替换程序替换的原理如何程序替换进程创建 fork函数 fork之前父进程独立运行&#xff0c;fork之后&#xff0c;父子两个执行流分别执行。 进程具有独立性&#xff0c;代码和数据必须独立…

机器学习HMM模型

目录1 马尔科夫链1.1 简介1.2 经典举例1.3 小结2 HMM简介2.1 简单案例2.2 案例进阶2.2.1 问题阐述2.2.2 问题解决3 HMM模型基础3.1 什么样的问题需要HMM模型3.2 HMM模型的定义3.3 一个HMM模型实例3.4 HMM观测序列的生成3.5 HMM模型的三个基本问题4 前向后向算法评估观察序列概率…

计算机毕业设计-SSM高校社团招新系统-JavaWeb大学生社团管理系统-源码+文档+讲解

注意&#xff1a;该项目只展示部分功能&#xff0c;如需了解&#xff0c;评论区咨询即可。 本文目录1.开发环境2.系统的设计背景3 前后台功能设计3.1 前台功能3.2 后台功能4 系统页面展示4.1 学生功能模块展示4.2 干部功能模块展示4.3 管理员功能模块展示5 更多推荐6 部分功能代…

如何用IDEA提高你的开发效率

前言 ​ 作为一名java开发工程师&#xff0c;IDEA无疑是我日常接触最多的工具。因此&#xff0c;能否高效使用IDEA软件&#xff0c;一定程度上决定了我们的开发效率。本文将主要介绍IDEA中的四个便于提高开发效率的功能&#xff0c;常用快捷键、实时模版、后缀补全、文件和代码…

《本地计算机DNS缓存文件》

C:\Windows\System32\drivers\etc 36.152.44.95 www.baidu.com 正常访问www.baidu.com可以DNS抓包&#xff0c;将百度的IP及域名加入文件位置的hosts文件中即该IP和域名将不再请求网络上的DNS服务器&#xff0c;即加快域名解析&#xff1b; 具体作用&#xff1a; 1.加快域名解…

什么是RPC框架?

什么是RPC&#xff1f; In distributed computing, a remote procedure call (RPC) is when a computer program causes a procedure (subroutine) to execute in a different address space (commonly on another computer on a shared network), which is coded as if it wer…

创新能力 | 产品经理实践中常犯的七大错误

做产品是一个既感性又理性的过程&#xff0c;纵然有很多前辈同行的经验传承和技巧指导&#xff0c;但在落到实处是时&#xff0c;总难免犯一些错误。有些是经验不足导致&#xff0c;有些则是产品经理对于人性的浅见寡闻。本文作为产品经理实践指南专题的中级篇&#xff0c;阐述…

用 AWTK 和 AWPLC 快速开发嵌入式应用程序 (2)-走马灯

AWPLC 目前还处于开发阶段的早期&#xff0c;写这个系列文章的目的&#xff0c;除了用来验证目前所做的工作外&#xff0c;还希望得到大家的指点和反馈。如果您有任何疑问和建议&#xff0c;请在评论区留言。 1. 背景 AWTK 全称 Toolkit AnyWhere&#xff0c;是 ZLG 开发的开源…

全球名校AI课程库(35)| 辛辛那提大学 · 微积分Ⅱ课程『MATH101 Calculus II』

&#x1f3c6; 课程学习中心 | &#x1f6a7; CS数学基础课程合辑 | &#x1f30d; 课程主页 | &#x1f4fa; 中英字幕视频 | &#x1f680; 项目代码解析 课程介绍 Trefor Bazett 教授在 Cincinnati 大学任教时&#xff0c;制作了两套完整的的数学课程&#xff08;微积分、离…

Eclipse创建Servlet项目-7

目录 1、创建动态 Web 项目 2、使用 Eclipse 创建 Servlet 3、配置 web.xml 4、部署项目并启动服务器 通过前面的学习&#xff0c;我们了解了如何在 Tomcat 目录下手动部署 Servlet&#xff0c;这种方式不但效率低下&#xff0c;而且容易出错。因此&#xff0c;在实际开发中…

变量常量,基本数据类型及数据类型转换

⭐️ 变量常量与基本数据类型及数据类型转换 &#x1f4cd; 来自&#xff1a;中南林业科技大学软件协会学术部&#xff1a;谢添 ⏲ 时间&#xff1a;2022 - 10 - 29 至 2022 - 10 - 30 &#x1f3e0; 官网&#xff1a;https://www.csuftsap.cn/ ✏️ 本章所有提供代码均已测…

四旋翼无人机学习第4节--STM32、MPU9250等器件的绘制

0 前言 当画stm32、mpu9250这种多引脚的芯片&#xff0c;就需要参考芯片手册啦。 这里给大家推荐一个芯片手册查询网站。 半导小芯-芯片查询工具 进入网站&#xff0c;输入芯片的具体名称&#xff0c;点击查询即可。 最后点击下载即可。 1 stm32芯片手册引脚查询 选择引脚…

学习在Git项目中使用子模块(图文教程)

一般认为 父项目 是当前正在做的主要工作&#xff0c;但需要依赖 子模块 中提供的算法或者工具。父项目 与 子模块 不是同一批人维护的&#xff0c;或者是需要分开维护的。 此情此景&#xff0c;需要学习该教程了&#xff01;&#xff01;&#xff01; 文章目录1 如何在父项目…