「深入了解数据库中的ibd」 (数据库中的ibd是什么意思)

深入了解数据库中的ibd

在日常生活中,我们常常需要使用各种各样的软件来存储、管理和处理大量的数据。而数据库就是其中一个重要的工具,它通过定义结构化的数据模型,可以帮助我们高效地管理和查询数据。在数据库中,每个表都会对应一个或多个数据文件,其中最常见的就是 ibd 文件。那么,什么是 ibd 文件?如何深入了解它们呢?本文将对此进行介绍。

一、ibd 文件的概述

在 InnoDB 存储引擎中,ibd 是一种独立存储的文件类型,它专门用来存储表的数据和索引信息。每个 ibd 文件都对应一个表,而且可以存储多个表空间。一个表空间是一个数据文件,它可以存储一个或多个表的数据和索引。

在 InnoDB 中,每个表都有一个独立的 ibd 文件,这个文件的名称与表的名称保持一致。例如,在一个名为 mydb 的数据库中,有一个名为 mytable 的表,那么该表对应的 ibd 文件就是 mytable.ibd。当我们在数据库中创建表时,实际上是在磁盘上创建了一个 ibd 文件。

二、ibd 文件的组成

ibd 文件一般由多个页(page)组成,页是存储数据的最小单位。每个页的大小是固定的,一般为 16KB。InnoDB 存储引擎中的文件和页的管理采用了类似于文件系统的方式。文件和页被组织成一个多层的树形结构,这个结构被称为 B+ 树。

在 B+ 树中,每个叶子节点都对应着一个存储表记录的数据页,数据页可以包含多个记录。而非叶子节点则存储着索引信息,例如节点的键值范围和指向下一级节点的指针。这种 B+ 树的结构可以有效地提高数据的查询效率,并且支持高并发的工作负载。

三、ibd 文件的使用方式

在使用 ibd 文件时,我们需要注意以下几点:

1. 对于 InnoDB 存储引擎而言,ibd 文件是不可或缺的,因为它包含了表的所有数据和索引信息,如果 ibd 文件损坏,则数据库中的数据可能会完全丢失。

2. 在进行 MySQL 主从同步时,如果 ibd 文件没有同步到从服务器上,那么从服务器将无法获取完整的数据,因此ibd 文件的同步非常重要。

3. 在 InnoDB 存储引擎中,每个表都应该只有一个 ibd 文件,多个 ibd 文件会影响数据库的性能。

4. 为避免出现 ibd 文件损坏的情况,我们可以定期备份 ibd 文件,并在进行数据操作前进行数据备份。

四、处理 ibd 文件的常见问题

在使用 ibd 文件的过程中,可能会遇到一些常见问题,本文对其进行了:

1. ibd 文件损坏:ibd 文件一旦被损坏,就会导致数据库无法正常访问。出现这种情况时,我们可以尝试使用 InnoDB 的修复工具进行修复。

2. ibd 文件删除:删除 ibd 文件时需要谨慎操作,因为这可能会导致数据库中的数据丢失。

3. ibd 文件太大:如果 ibd 文件太大,可能会导致数据库性能下降。此时,我们可以尝试使用数据压缩等方式来减小文件的大小。

四、结语

通过本文的介绍,我们可以更深入地了解数据库中的 ibd 文件。在实际操作中,我们需要注意 ibd 文件的管理和备份,避免出现文件损坏或数据丢失等情况。同时,针对常见的问题,我们可以采取一些对策来保障数据库的正常运行。

相关问题拓展阅读:

MYSQL怎么样能读取.ibd文件中的数据

有两种方法,一种方法使用mysql的check table和repair table 的sql语句,另一种方法是使用MySQL提供的多个myisamchk, isamchk数据检测恢复工具。前者使用起来比较简便。推荐使用。

1. check table 和 repair table

登陆mysql 终端:

mysql -uxx -p dbname

check table tabTest;

如果出现的结果说Status是OK,则不用修复,如果有Error,可以用:

repair table tabTest;

进行修复,修复之后可以在用check table命令来进行检查。在新版本的phpMyAdmin里面也可以使用check/repair的功能。

2. myisamchk, isamchk

其中myisamchk适用于MYISAM类型的数枣绝据表,而isamchk适用于ISAM类型的数据表。这两条命令的主要参数相同,一般新的系统都使用MYISAM作为缺省的数据表类型,这里以myisamchk为例子进行说明。当发现某个数据表出现问题时可以使用:

myisamchk tablename.MYI

进行检测,如果需要修复的话,凳粗姿可以使用:

myisamchk -of tablename.MYI

关于myisamchk的详细参数说明,可以参见它的使用帮助。需要注意的时在进行修改时必须确保MySQL服务器没有访问这个数据表,保险的情况下是更好在进行检测时把MySQL服务器Shutdown掉。

-----------------------------

另外可以把下面的命令放在你的rc.local里面启动MySQL服务器前:

&& /pathtochk/myisamchk -of /DATA_DIR/*/*.MYI

其中的/tmp/mysql.sock是MySQL监听的Sock文件位置,对于使用RPM安装的用户应该是/var/lib/mysql/mysql.sock,对于使用源码安装则是/tmp/mysql.sock可以根据自己凳慎的实际情况进行变更,而pathtochk则是myisamchk所在的位置,DATA_DIR是你的MySQL数据库存放的位置。

需要注意的时,如果你打算把这条命令放在你的rc.local里面,必须确认在执行这条指令时MySQL服务器必须没有启动!检测修复所有数据库(表)

在 InnoDB 中,用户定义的表悉猜及其对应的索引数据存储在扩展名为 .ibd 的文件中。表空间有两种类型,常规(或共享)表空间和每表独立表空间。对睁蠢型于共享表空间,来自许多不同表及其对应索引的数据可以驻留在单个档搭 .ibd 文件中。而对于每表独立表空间,单个表的数据及其索引位于一个 .ibd 文件中。

. IBD 文件这些文件通常位于数据目录中。让我们尝试创建一个表 test.t1。

mysql>CREATE TABLE test.t1 (c INT) engine=InnoDB;

$ cd /test

$ ls

t1.ibd

上面是独立表空间文件,即与表 t1 相关的表和索引数据将驻留在此文件中。

如何从ibd文件中恢复数据

参考:

网页链接

在mysql中由于某种原因保存有ibd文件,但是表已经被删除或者frm文件损坏亦或者ibdata文件损坏/丢失等。本文模拟在这种情况下,通过mysql自身技术即可完成ibd文件恢复.

测试环境mysql版本

mysql> select version();++| version() |++| 5.6.25    |++1 row in set (0.00 sec)

   

mysql主要参数

mysql> show variables like ‘innodb_file_per_table’;+++| Variable_name| Value |+++| innodb_file_per_table | ON    |+++1 row in set (0.00 sec)mysql> show variables like ‘innodb_force_recovery’;+++| Variable_name| Value |+++| innodb_force_recovery ||+++1 row in set (0.00 sec)

   

innodb_file_per_table这个握郑橡参数为on才能够实现每个表存储单独的ibd文件.innodb_force_recovery参数默认范围0

测试表情况

mysql> use xifenfei;Database changedmysql> show tables;+-+| Tables_in_xifenfei|+-+| user_login    |+-+1 rows in set (0.00 sec) mysql> select count(*) from user_login;++| count(*) |++||++1 row in set (0.02 sec) mysql>丛慎 desc user_login;+++——+—–+++| Field      | Type| Null | Key | Default | Extra |+++——+—–+++| ID| varchar(255) | NO 段旁  | PRI | NULL    ||| ACCOUNT    | varchar(255) | YES  |     | NULL    ||| LifeCycle  | int(11)      | YES  |     | NULL    ||| Name| varchar(255) | YES  |     | NULL    ||| Password   | varchar(255) | YES  |     | NULL    ||| Role| varchar(255) | YES  |     | NULL    ||| UTime      | varchar(255) | YES  |     | NULL    ||| UserID     | varchar(255) | YES  |     | NULL    ||| UserName   | varchar(255) | YES  |     | NULL    ||| UserStatus | int(11)      | YES  |     | NULL    ||+++——+—–+++10 rows in set (0.05 sec) mysql> select * from user_login limit 1;+——++++——+——++——+++| ID   | ACCOUNT | LifeCycle | Name      | Password| Role | UTime | UserID| UserName | UserStatus |+——++++——+——++——+++| 010d6c85a76c44cba80d07cbd8590bb2 | hyh     || 胡元会    | 698d51a19d8a121ce581499d7b| |6|  |:04:32 | 0fe3bc4dda4b85065ed5cfee8 | NULL     ||+——++++——+——++——+++1 row in set (0.00 sec) mysql> show create table user_login \G;*************************** 1. row *************Table: user_loginCreate Table: CREATE TABLE `user_login` (  `ID` varchar(255) NOT NULL,  `ACCOUNT` varchar(255) DEFAULT NULL,  `LifeCycle` int(11) DEFAULT NULL,  `Name` varchar(255) DEFAULT NULL,  `Password` varchar(255) DEFAULT NULL,  `Role` varchar(255) DEFAULT NULL,  `UTime` varchar(255) DEFAULT NULL,  `UserID` varchar(255) DEFAULT NULL,  `UserName` varchar(255) DEFAULT NULL,  `UserStatus` int(11) DEFAULT NULL,  PRIMARY KEY (`ID`)) ENGINE=InnoDB DEFAULT CHARSET=utf81 row in set (0.00 sec)  mysql> show variables like ‘datadir’;+-+—–+| Variable_name | Value|+-+—–+| datadir| D:\xifenfei\mysql-5.6.25-winx64\data\ |+-+—–+1 row in set (0.00 sec)

   

备份ibd文件

C:\Users\XIFENFEI>dir D:\xifenfei\mysql-5.6.25-winx64\data\xifenfei\user_login.ibd 驱动器 D 中的卷没有标签。 卷的序列号是F18  D:\xifenfei\mysql-5.6.25-winx64\data\xifenfei 的目录0:98,304 user_login.ibd 1 个文件,304 字节 0 个目录 78,789,591,040 可用字节C:\Users\XIFENFEI>cp D:\xifenfei\mysql-5.6.25-winx64\data\xifenfei\user_login.ibd d:/C:\Users\XIFENFEI>dir d:\user_login.ibd 驱动器 D 中的卷没有标签。 卷的序列号是F18  d:\ 的目录3:98,304 user_login.ibd 1 个文件,304 字节 0 个目录 78,789,591,040 可用字节

   

模拟删除表(ibd文件也被删除)

mysql> drop table xifenfei.user_login;Query OK, 0 rows affected (0.03 sec)  C:\Users\XIFENFEI>dir D:\xifenfei\mysql-5.6.25-winx64\data\xifenfei\user_login.ibd 驱动器 D 中的卷没有标签。 卷的序列号是F18  D:\xifenfei\mysql-5.6.25-winx64\data\xifenfei 的目录 找不到文件

   

创建新表

mysql> CREATE TABLE `user_login` (    ->   `ID` varchar(255) NOT NULL,    ->   `ACCOUNT` varchar(255) DEFAULT NULL,    ->   `LifeCycle` int(11) DEFAULT NULL,    ->   `Name` varchar(255) DEFAULT NULL,    ->   `Password` varchar(255) DEFAULT NULL,    ->   `Role` varchar(255) DEFAULT NULL,    ->   `UTime` varchar(255) DEFAULT NULL,    ->   `UserID` varchar(255) DEFAULT NULL,    ->   `UserName` varchar(255) DEFAULT NULL,    ->   `UserStatus` int(11) DEFAULT NULL,    ->   PRIMARY KEY (`ID`)    -> ) ENGINE=InnoDB DEFAULT CHARSET=utf8;Query OK, 0 rows affected (0.03 sec) C:\Users\XIFENFEI>dir D:\xifenfei\mysql-5.6.25-winx64\data\xifenfei\user_login.ibd 驱动器 D 中的卷没有标签。 卷的序列号是F18  D:\xifenfei\mysql-5.6.25-winx64\data\xifenfei 的目录3:98,304 user_login.ibd 1 个文件,304 字节 0 个目录 78,789,591,040 可用字节 mysql> select count(*) from xifenfei.user_login;++| count(*) |++||++1 row in set (0.00 sec)

   

停掉mysql,替换user_login.ibd

C:\Users\XIFENFEI>dir D:\xifenfei\mysql-5.6.25-winx64\data\xifenfei\user_login.ibd 驱动器 D 中的卷没有标签。 卷的序列号是F18  D:\xifenfei\mysql-5.6.25-winx64\data\xifenfei 的目录3:98,304 user_login.ibd 1 个文件,304 字节 0 个目录 78,787,141,632 可用字节 C:\Users\XIFENFEI>cp d:\user_login.ibd D:\xifenfei\mysql-5.6.25-winx64\data\xifenfei\user_login.ibdC:\Users\XIFENFEI>dir D:\xifenfei\mysql-5.6.25-winx64\data\xifenfei\user_login.ibd 驱动器 D 中的卷没有标签。 卷的序列号是F18  D:\xifenfei\mysql-5.6.25-winx64\data\xifenfei 的目录0:98,304 user_login.ibd 1 个文件,304 字节 0 个目录 78,787,141,632 可用字节

   

启动mysql 服务,查询数据库

mysql> select count(*) from xifenfei.user_login;ERROR 2023 (HY000): Lost connection to MySQL server during querymysql> exitBye C:\Users\XIFENFEI>mysql -urootERROR 2023 (HY000): Can’t connect to MySQL server on ‘localhost’ (10061)

   

mysql 日志报错

:31: MySQL: ready for connections.Version: ‘5.6.25’  socket: ”  port:MySQL Community Server (GPL)InnoDB: Error: tablespace id is 56 in the data dictionaryInnoDB: but in file .\xifenfei\user_login.ibd it is 47!:31:31 2eb8  InnoDB: Assertion failure in threadin file fil0fil.cc line 796InnoDB: We intentionally generate a memory trap.InnoDB: Submit a detailed bug report to If you get repeated assertion failures or crashes, evenInnoDB: immediately after the mysqld startup, there may be

   

很明显由于替换的ibd文件和现在数据库记录的ibd文件的page的字典信息不匹配,因为数据库无法正常查询该数据,而且mysql为了安全直接把实例给crash了.

恢复操作

mysql> show variables like ‘innodb_force_recovery’;+++| Variable_name| Value |+++| innodb_force_recovery ||+++1 row in set (0.00 sec)mysql> alter table xifenfei.user_login discard tablespace;Query OK, 0 rows affected, 2 warnings (0.02 sec) mysql> alter table xifenfei.user_login import tablespace;Query OK, 0 rows affected, 1 warning (0.06 sec) mysql> select count(*) from xifenfei.user_login;++| count(*) |++||++1 row in set (0.00 sec) mysql> select * from xifenfei.user_login limit 1;+——++++——+——++——+++| ID   | ACCOUNT | LifeCycle | Name      | Password| Role | UTime | UserID| UserName | UserStatus |+——++++——+——++——+++| 010d6c85a76c44cba80d07cbd8590bb2 | hyh     || 胡元会    | 698d51a19d8a121ce581499d7b| |6|  |:04:32 | 0fe3bc4dda4b85065ed5cfee8 | NULL     ||+——++++——+——++——+++1 row in set (0.00 sec)

   

通过mysql自带的discard tablespace和import tablespace操作后,表数据已经可以完成查询了.

mysql日志

:34: InnoDB: Failed to find tablespace for table ‘”xifenfei”.”user_login”‘ in the cache. Attempting to load the tablespace with space id 56.:34: InnoDB: In file ‘.\xifenfei\user_login.ibd’, tablespace id and flags are 47 and 0, but in the InnoDB data dictionary they are 56 and 0. Have you moved InnoDB .ibd files around without using the commands DISCARD TABLESPACE and IMPORT TABLESPACE? Please refer to for how to resolve the issue.:34: InnoDB: Could not find a valid tablespace file for ‘xifenfei/user_login’. See for how to resolve the issue.:34:08 30e8 InnoDB: cannot calculate statistics for table “xifenfei”.”user_login” because the .ibd file is missing. For help, please refer to 23:34: InnoDB: Cannot delete tablespace 56 because it is not found in the tablespace memory cache.:34: InnoDB: Cannot delete tablespace 56 in DISCARD TABLESPACE. Tablespace not found:34: InnoDB: Sync to disk:34: InnoDB: Sync to disk – done!:34: InnoDB: Phase I – Update all pages:34: InnoDB: Sync to disk:34: InnoDB: Sync to disk – done!:34: InnoDB: Tablespace ‘xifenfei/user_login’ exists in the cache with id 47 !=23:34: InnoDB: Freeing existing tablespace ‘xifenfei/user_login’ entry from the cache with id23:34: InnoDB: Phase III – Flush changes to disk:34: InnoDB: Phase IV – Flush complete

   

mysql日志依旧报了page字典信息不匹配.但是数据已经可以访问,通过mysqldump导出重新创建表即可.如果由于ibd损坏使用该方法无法恢复,请参考:MySQL drop database恢复(恢复方法同样适用MySQL drop table,delete,truncate table)

在使用独立表空间的情况下,如果不慎使得innodb存储引擎的元数据文件ibdata损坏,我们还可以挽救宝贵的数据.因为在innodb使用独立表空间的情况下,ibdata文件会记录每个innodb表的id,只要使得ibd中的表id和ibdata文件中记录的表id相同,就能启轮够打开表,读取到数据.

#创建表

CREATE TABLE `ibdtest` (

  `id` int(11) NOT NULL AUTO_INCREMENT,

  `fid` int(11) NOT NULL COMMENT ‘表b中的id’,

  `content` char(255) NOT NULL COMMENT ‘操作内容,系统历唤生成’,

  `mark` char(255) NOT NULL COMMENT ‘备注’,

  PRIMARY KEY (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8

#添加数据

INSERT ibdtest (fid,content,mark) VALUES (1,’1′,’1′),(2,’2′,’2′);

SELECT * FROM ibdtest;

关闭MySQL将ibdtest.ibd copy出来,放悄烂信到其他数据库中来模拟灾难.

#/opt/soft/mysql/bin/mysqladmin -pshutdown

:31:50 mysqld_safe mysqld from pidfile /opt/soft/mysql/60137.localdomain.pid ended

+ Done      /opt/soft/mysql/bin/mysqld_safe–defaults-file=/opt/soft/mysql/config/my.cnf –user=mysql

 # cd /home/soft/mysql/data/test/

# ll

total 1296

-rw-rw—-. 1 mysql mysqlJan 18 00:06 a.frm

-rw-rw—-. 1 mysql mysqlJan 18 00:24 a.ibd

-rw-rw—-. 1 mysql mysqlJan 30 08:34 area.frm

-rw-rw—-. 1 mysql mysqlJan 30 08:36 area.ibd

-rw-rw—-. 1 mysql mysqlJan 18 00:05 b.frm

-rw-rw—-. 1 mysql mysqlJan 18 00:08 b.ibd

-rw-rw—-. 1 mysql mysqlJan 30 18:27 ibdtest.frm

-rw-rw—-. 1 mysql mysqlJan 30 18:28 ibdtest.ibd

-rw-rw—-. 1 mysql mysqlJan  6 16:23 testa.frm

-rw-rw—-. 1 mysql mysqlJan 10 04:10 testa.ibd

-rw-rw—-. 1 mysql mysqlJan 30 14:30 testmc.frm

-rw-rw—-. 1 mysql mysqlJan 30 14:30 testmc.ibd

-rw-rw—-. 1 mysql mysqlJan 30 13:54 testme.frm

-rw-rw—-. 1 mysql mysqlJan 30 13:55 testme.ibd

-rw-rw—-. 1 mysql mysqlJan 30 14:40 testmm.frm

-rw-rw—-. 1 mysql mysqlJan 30 14:45 testmm.ibd

-rw-rw—-. 1 mysql mysqlJan 30 13:40 testmu.frm

-rw-rw—-. 1 mysql mysqlJan 30 13:40 testmu.ibd

-rw-rw—-. 1 mysql mysqlJan 30 11:08 testmv.frm

-rw-rw—-. 1 mysql mysqlJan 30 11:10 testmv.ibd

-rw-rw—-. 1 mysql mysqlJan  4 21:55 testuser.frm

-rw-rw—-. 1 mysql mysqlJan  4 22:04 testuser.ibd

-rw-rw—-. 1 mysql mysqlJan 14 21:55 user.frm

-rw-rw—-. 1 mysql mysqlJan 14 21:55 user.ibd

# cp ibdtest.ibd /home/download/

# cd /home/download/

#vim打开ibd,使用16进制查看

# vim -b ibdtest.ibd 

:%!xxd  

从下图中能看到 此表在 当前mysql数据库中的id为0x10,即16.

此时,我们假设灾难发生,ibdata损坏…

只剩下了ibdtest.ibd文,我们跳转到另一个mysql服务器上,用同样的建表语句创建ibdtest表.

这时我们打开这个mysql服务器下的ibdtest.ibd看看:

这个表的id为0x16,即为22,那么,我们只需将原有的ibdtest.ibd表id修改为0x16即可.

出保存的时候一定要记得使用:%!xxd  -r

退出保存.

并将修改好的文件覆盖掉新的ibdtest.ibd即可,

此mysql服务器会认为该表损毁,无法打开,没关系,修改innodb_force_recovery = 6,

重启mysql服务:

Select下,就知道数据是否恢复了没有:

此时,无法执行写操作,应尽快将数据dump出来,修改innodb_force_recovery = 0,重启服务,创建新表后,把数据倒回去就ok了.恢复数据就不演示了.

创建已经丢失的表结构

先要安装 mysql-utilities。

// RedHatyum -y install mysql-server mysql-utilities// Debianapt install mysql-utilities

使用 mysqlfrm 从 .frm 文件里面找回建表语句。

// 分析一个 .frm 文件生成建表的语句mysqlfrm –diagnostic /var/lib/mysql/test/t1.frm// 分析一个目录下的全部.frm文件生成建表语句root@username:~# mysqlfrm –diagnostic /var/lib/mysql/my_db/bk/ >createtb.sqlroot@username:~# grep “^CREATE TABLE” createtb.sql |wc -l124

可以看到一共生成了 124 个建表语句。

有很多时候也可以从其它库里面生成建表语句,如同一个应用的其它数据库或不同的测试环境,采用下面的 mysqldump 生成建表语句:

mysqldump –no-data –compact my_db>createtb.sql

登录 MySQL 生成表。

mysql> create database my_db;mysql> use my_dbDatabase changedmysql> source createtb.sqlQuery OK, 0 rows affected (0.07 sec)……

导入旧的数据文件

将新建的没有包括数据的 .ibd 文件抛弃

root@username:/var/lib/mysql/my_db# ll *.ibd|wcroot@username:/var/lib/mysql/my_db# mysql -e “show tables from my_db” \| grep -v  Tables_in_my_db  \| while read a; do mysql -e “ALTER TABLE my_db.$a DISCARD TABLESPACE”; doneroot@username:/var/lib/mysql/my_db# ll *.ibd|wcls: cannot access ‘*.ibd’: No such file or directory000

可以看到所有的 .idb 文件都已经被抛弃了。然后把旧的有数据的 .ibd 文件拷贝到这个 my_db 目录下面,别忘了把属主改过来:chown mysql. *,再把这些数据文件 import 到数据库中。

root@username:/var/lib/mysql/my_db# mysql -e “前亩show tables from my_db” \| grep -v  Tables_in_my_db  \| while read a; \do mysql -e “ALTER TABLE my_db.$a import TABLESPACE”袭丛; done

导入完成后检拍悔樱查表

使用 mysqlcheck 对数据库 my_db 下的所有表进行检查:

root@username:/var/lib/mysql/my_db# mysqlcheck -c my_dbmy_db.cdp_backup_point OK……

关于数据库中的ibd是什么意思的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。


数据运维技术 » 「深入了解数据库中的ibd」 (数据库中的ibd是什么意思)