mysql 使用idb文件恢复数据

Posted 孤独白鲸

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mysql 使用idb文件恢复数据相关的知识,希望对你有一定的参考价值。

前言,网上数据库恢复教程总是缺点东西,我写个留档自己备用

一.备份恢复前提:

1.必须要有原始.ibd文件,即备份文件

2.必须要有原始数据库的表结构,或一个往期的数据表

笔者的备份在阿里云那里下载的。其他的自行查找方案。

(先尝试1次,有疑问看第四步异常1)

二.恢复数据

第一步:将往期的数据表(主要是表结构)复制到另一数据库中,或者新建表结构

这一步会生成.idb和.frm文件

.frm禁止删除,覆盖等任何操作,否则mysql无法打开!

第二步:移除表空间

输入以下语句

ALTER TABLE 表名 DISCARD TABLESPACE

Cannot delete or update a parent row: a foreign key constraint fails ()

异常1:Cannot delete or update a parent row: a foreign key constraint fails ()

原因:外键绑定,需要解除外键约束

解决方案:执行 SET foreign_key_checks = 0; 

恢复结束后开启:SET foreign_key_checks = 1; 

第三步:导入备份数据

查找数据库文件路径

show global variables like "%datadir%";

中断mysql服务

将备份.idb文件赋值过来

.frm禁止删除,覆盖等任何操作,否则mysql无法打开!

第四步. 恢复数据库

输入下面指令,导入表空间

ALTER TABLE t_buyer IMPORT TABLESPACE;

异常1:

has ROW_TYPE_DYNAMIC row format, .ibd file has ROW_TYPE_COMPACT row format.

问题:数据库版本导致的表结构问题

解决方案:    ALTER TABLE 表 row_format=COMPACT;

通过表的.frm和.idb文件备份MySQL表

MySQL备份表(.frm,.idb文件)

😋目的: 利用表的.frm.idb文件备份MySQL表

👊一、找到目标表的.frm.idb文件

🙇‍♀1.在服务器上找到对应的文件,如果不清楚MySQL的数据路径在哪,可以参考如下:

[root@zxy_master /]# find / -iname 'bootstrap.frm'
/var/lib/mysql/bigdata/bootstrap.frm

🙇‍♀2.找到/var/lib/mysql/bigdata目录,bigdata为MySQL的一个数据库名称,bootstrapbigdata数据库下的一张表。一个表一般有两个文件,比如bootstrap表有bootstrap.frm,bootstrap.idb文件

[root@zxy_master /]# cd /var/lib/mysql/bigdata/
[root@zxy_master bigdata]# ls
bootstrap.frm  bootstrap.ibd

👊二、在备份机上创建相同结构的数据库和表

🙇‍♀1.为保险起见,直接查看原库原表的建表语句

mysql> show create database bigdata;
+----------+------------------------------------------------------------------+
| Database | Create Database                                                  |
+----------+------------------------------------------------------------------+
| maxwell  | CREATE DATABASE `bigdata` /*!40100 DEFAULT CHARACTER SET utf8 */ |
+----------+------------------------------------------------------------------+
1 row in set (0.00 sec)

mysql> show create table bigdata.bootstrap;
+-----------+----------------------------------------------------------------------------
| Table     | Create Table                                                               
| bootstrap | CREATE TABLE `bootstrap` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `database_name` varchar(255) NOT NULL,
  `table_name` varchar(255) NOT NULL,
  `where_clause` varchar(255) DEFAULT NULL,
  `is_complete` tinyint(1) unsigned NOT NULL DEFAULT '0',
  `inserted_rows` bigint(20) unsigned NOT NULL DEFAULT '0',
  `total_rows` bigint(20) unsigned NOT NULL DEFAULT '0',
  `created_at` datetime DEFAULT NULL,
  `started_at` datetime DEFAULT NULL,
  `completed_at` datetime DEFAULT NULL,
  `binlog_file` varchar(255) DEFAULT NULL,
  `binlog_position` int(10) unsigned DEFAULT '0',
  `client_id` varchar(255) CHARACTER SET latin1 NOT NULL DEFAULT 'maxwell',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 |
+-----------+----------------------------------------------------------------------------
1 row in set (0.00 sec)

mysql>

🙇‍♀2.在备份机上执行建库建表语句


mysql> CREATE DATABASE `bigdata`;
Query OK, 1 row affected (0.00 sec)

mysql> use bigdata;
Database changed

mysql> CREATE TABLE `bootstrap` (
    ->   `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
    ->   `database_name` varchar(255) NOT NULL,
    ->   `table_name` varchar(255) NOT NULL,
    ->   `where_clause` varchar(255) DEFAULT NULL,
    ->   `is_complete` tinyint(1) unsigned NOT NULL DEFAULT '0',
    ->   `inserted_rows` bigint(20) unsigned NOT NULL DEFAULT '0',
    ->   `total_rows` bigint(20) unsigned NOT NULL DEFAULT '0',
    ->   `created_at` datetime DEFAULT NULL,
    ->   `started_at` datetime DEFAULT NULL,
    ->   `completed_at` datetime DEFAULT NULL,
    ->   `binlog_file` varchar(255) DEFAULT NULL,
    ->   `binlog_position` int(10) unsigned DEFAULT '0',
    ->   `client_id` varchar(255) CHARACTER SET latin1 NOT NULL DEFAULT 'maxwell',
    ->   PRIMARY KEY (`id`)
    -> ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
Query OK, 0 rows affected (0.05 sec)

mysql>

🙇‍♀3.查看备份机的/var/lib/mysql/bigdata目录下,是否生成对应.frm,.idb文件

[root@zxy_slave1 bigdata]# ls
bootstrap.frm  bootstrap.ibd  db.opt

👊三、清除表空间

🙇‍♀1.执行命令,将bootstrap表的表空间清除,清除后bootstrap.idb文件会消失

mysql> alter table bootstrap discard tablespace;
Query OK, 0 rows affected (0.05 sec)

🙇‍♀2.再次查看备份机的/var/lib/mysql/bigdata目录下,.idb文件是否消失

[root@zxy_slave1 bigdata]# ls
bootstrap.frm  db.opt

👊四、关闭数据库,复制.frm,.idb文件

🙇‍♀1.关闭数据库

[root@zxy_slave1 mysql]# systemctl stop mysqld
[root@zxy_slave1 mysql]#

🙇‍♀2.从主机复制bootstrap.frm,bootstrap.idb文件到备份机的指定目录

[root@zxy_master bigdata]# scp bootstrap.frm bootstrap.ibd root@slave1.spunsugar.top:/var/lib/mysql/bigdata
The authenticity of host 'slave1.spunsugar.top ' can't be established.
ECDSA key fingerprint is SHA256:C/+BHxQ00jdfgmaqAKHrdxx2HBl27GdHjCcerelvB9tH3s.
ECDSA key fingerprint is MD5:5e:08:d4:56:ad:24:cd:96:f9:ea:cr:68:51:7c:89:32.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'slave1.spunsugar.top' (ECDSA) to the list of known hosts.
root@slave1.spunsugar.top's password:
bootstrap.frm                                                                                                           100% 9092     3.4MB/s   00:00
bootstrap.ibd                                                                                                           100%   96KB  13.3MB/s   00:00
[root@zxy_master bigdata]#

🙇‍♀3.再次查看备份机的/var/lib/mysql/bigdata目录下,两个文件是否复制成功

[root@zxy_slave1 bigdata]# ll
total 112
-rw-r----- 1 mysql mysql  9092 Aug 30 15:21 bootstrap.frm
-rw-r----- 1 root  root  98304 Aug 30 15:21 bootstrap.ibd
-rw-r----- 1 mysql mysql    65 Aug 30 15:07 db.opt

👊五、启动数据库,导入表空间

🙇‍♀1.启动数据库

[root@zxy_slave1 mysql]# systemctl start mysqld

🙇‍♀2.检查库表是否存在

mysql> use bigdata;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed, 1 warning
mysql> show tables;
+-------------------+
| Tables_in_bigdata |
+-------------------+
| bootstrap         |
+-------------------+
1 row in set (0.00 sec)

🙇‍♀3.导入表空间

mysql> alter table bootstrap import tablespace;
ERROR 1812 (HY000): Tablespace is missing for table `bigdata`.`bootstrap`.

## 在这里执行导入表空间命令后,会发现找不到表空间。
## 想想上一步清除表空间的时候,对应表的.idb文件是不是消失了
## 那么这里的找不到表空间,是否也跟.idb文件有关呢
## 我们再查看一下bigdata目录下有什么异常:

[root@zxy_slave1 bigdata]# ll
-rw-r----- 1 mysql mysql  9092 Aug 30 15:21 bootstrap.frm
-rw-r----- 1 root  root  98304 Aug 30 15:21 bootstrap.ibd
-rw-r----- 1 mysql mysql    65 Aug 30 15:07 db.opt

## 这里可以看到bootstrap.idb对应的用户和用户组是root
## 根据要求这些文件的用户和用户组必须是mysql
## 因为bootstrap.frm是覆盖后的文件,仍保留前文件的这些属性
## 而bootstrap.idb是新文件,而我当前使用的是root用户,所以用户和用户组是root
## 这里手动调整一下:

[root@zxy_slave1 bigdata]# chown mysql:mysql bootstrap.ibd
[root@zxy_slave1 bigdata]# ll
total 112
-rw-r----- 1 mysql mysql  9092 Aug 30 15:21 bootstrap.frm
-rw-r----- 1 mysql mysql 98304 Aug 30 15:21 bootstrap.ibd
-rw-r----- 1 mysql mysql    65 Aug 30 15:07 db.opt

## 再次导入表空间
mysql> alter table bootstrap import tablespace;
Query OK, 0 rows affected, 1 warning (0.07 sec)

## 查看表数据,已经成功备份

mysql> select *
    -> from bootstrap;
+----+---------------+---------------+--------------+-------------+---------------+------------+------------+---------------------+---------------------+-------------+-----------------+-----------+
| id | database_name | table_name    | where_clause | is_complete | inserted_rows | total_rows | created_at | started_at          | completed_at        | binlog_file | binlog_position | client_id |
+----+---------------+---------------+--------------+-------------+---------------+------------+------------+---------------------+---------------------+-------------+-----------------+-----------+
|  1 | bigdata       | base_province | NULL         |           1 |            34 |          0 | NULL       | 2022-06-18 12:43:36 | 2022-06-18 12:43:36 | NULL        |               0 | maxwell   |
|  2 | bigdata       | base_province | NULL         |           1 |            34 |          0 | NULL       | 2022-06-18 12:46:26 | 2022-06-18 12:46:26 | NULL        |               0 | maxwell   |
|  3 | bigdata       | base_province | NULL         |           1 |            34 |          0 | NULL       | 2022-06-18 12:47:31 | 2022-06-18 12:47:31 | NULL        |               0 | maxwell   |
+----+---------------+---------------+--------------+-------------+---------------+------------+------------+---------------------+---------------------+-------------+-----------------+-----------+
3 rows in set (0.00 sec)

以上是关于mysql 使用idb文件恢复数据的主要内容,如果未能解决你的问题,请参考以下文章

服务器(centos)意外损坏,mysql数据库.frm和.idb和ibdata1都在的情况下,怎么恢复数据

MySQL 8.0 恢复孤立文件每表ibd文件

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

MySQL 处理某个idb表文件过大

MySQL 处理某个idb表文件过大

MySQL Innodb数据库误删ibdata1后MySQL数据库的恢复案例