解決 誤刪除ibdata1文件,導致數據庫無法啓動

解決思路:利用獨立表空間的方式將業務庫的.ibd結尾的文件,導出,然後在一個新的數據庫中,創建表結構一樣的數據庫,然後導入表空間。

這個方式相當於不修復原來的數據庫(因爲共享表空間壞了,那個比較難搞)但是這樣的方式可以實現業務庫可以恢復到一個新的數據庫上,不影響使用。

這樣做的一個難題就是,ibdata1共享表空間壞了,我們要怎麼知道數據庫下的表結構呢?

用到了mysqlfrm工具

可以得知業務庫的表結構,那麼就可以解決問題了。
恢復業務庫,搞起。

下載

yum install https://mirrors.tuna.tsinghua.edu.cn/epel/7/x86_64/Packages/m/mysql-connector-python-1.1.6-1.el7.noarch.rpm
yum install https://mirrors.tuna.tsinghua.edu.cn/epel/7/x86_64/Packages/m/mysql-utilities-1.3.6-1.el7.noarch.rpm

第一步:得知原來數據庫的表結構,以便我們在新的數據庫中創建出一樣的表結構。

[root@db01 tools]# mysqlfrm   --diagnostic /data/3306/data/world
# WARNING: Cannot generate character set or collation names without the --server option.
# CAUTION: The diagnostic mode is a best-effort parse of the .frm file. As such, it may not identify all of the components of the table correctly. This is especially true for damaged files. It will also not read the default values for the columns and the resulting statement may not be syntactically correct.
# Reading .frm file for /data/3306/data/world/city.frm:
# The .frm file is a TABLE.
# CREATE TABLE Statement:

CREATE TABLE `world`.`city` (
  `ID` int(11) NOT NULL AUTO_INCREMENT,
  `Name` char(35) NOT NULL,
  `CountryCode` char(3) NOT NULL,
  `District` char(20) NOT NULL,
  `Population` int(11) NOT NULL,
PRIMARY KEY `PRIMARY` (`ID`),
KEY `CountryCode` (`CountryCode`)
) ENGINE=InnoDB;

# Reading .frm file for /data/3306/data/world/country.frm:
# The .frm file is a TABLE.
# CREATE TABLE Statement:

CREATE TABLE `world`.`country` (
  `Code` char(3) NOT NULL,
  `Name` char(52) NOT NULL,
  `Continent` enum('Asia','Europe','North America','Africa','Oceania','Antarctica','South America') NOT NULL,
  `Region` char(26) NOT NULL,
  `SurfaceArea` float(10,2) NOT NULL,
  `IndepYear` smallint(6) DEFAULT NULL,
  `Population` int(11) NOT NULL,
  `LifeExpectancy` float(3,1) DEFAULT NULL,
  `GNP` float(10,2) DEFAULT NULL,
  `GNPOld` float(10,2) DEFAULT NULL,
  `LocalName` char(45) NOT NULL,
  `GovernmentForm` char(45) NOT NULL,
  `HeadOfState` char(60) DEFAULT NULL,
  `Capital` int(11) DEFAULT NULL,
  `Code2` char(2) NOT NULL,
PRIMARY KEY `PRIMARY` (`Code`)
) ENGINE=InnoDB;

# Reading .frm file for /data/3306/data/world/countrylanguage.frm:
# The .frm file is a TABLE.
# CREATE TABLE Statement:

CREATE TABLE `world`.`countrylanguage` (
  `CountryCode` char(3) NOT NULL,
  `Language` char(30) NOT NULL,
  `IsOfficial` enum('T','F') NOT NULL,
  `Percentage` float(4,1) NOT NULL,
PRIMARY KEY `PRIMARY` (`CountryCode`,`Language`),
KEY `CountryCode` (`CountryCode`)
) ENGINE=InnoDB;

#...done.
[root@db01 tools]#

第二步在新數據庫中新建表結構(如果沒有相應的庫,也要先建立數據庫)

mysql> create database  world;
Query OK, 1 row affected (0.00 sec)

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| world              |
+--------------------+
5 rows in set (0.00 sec)
mysql> use world
Database changed
mysql> show  tables;
Empty set (0.00 sec)

第三步導入數據庫的建表語句,得到相同的表結構
PS:如果表比較多的話建議使用concat方式拼接語句,批量創建。

mysql> CREATE TABLE `world`.`city` (
    ->   `ID` int(11) NOT NULL AUTO_INCREMENT,
    ->   `Name` char(35) NOT NULL,
    ->   `CountryCode` char(3) NOT NULL,
    ->   `District` char(20) NOT NULL,
    ->   `Population` int(11) NOT NULL,
    -> PRIMARY KEY `PRIMARY` (`ID`),
    -> KEY `CountryCode` (`CountryCode`)
    -> ) ENGINE=InnoDB;
Query OK, 0 rows affected (0.01 sec)

mysql> CREATE TABLE `world`.`country` (
    ->   `Code` char(3) NOT NULL,
    ->   `Name` char(52) NOT NULL,
    ->   `Continent` enum('Asia','Europe','North America','Africa','Oceania','Antarctica','South America') NOT NULL,
    ->   `Region` char(26) NOT NULL,
    ->   `SurfaceArea` float(10,2) NOT NULL,
    ->   `IndepYear` smallint(6) DEFAULT NULL,
    ->   `Population` int(11) NOT NULL,
    ->   `LifeExpectancy` float(3,1) DEFAULT NULL,
    ->   `GNP` float(10,2) DEFAULT NULL,
    ->   `GNPOld` float(10,2) DEFAULT NULL,
    ->   `LocalName` char(45) NOT NULL,
    ->   `GovernmentForm` char(45) NOT NULL,
    ->   `HeadOfState` char(60) DEFAULT NULL,
    ->   `Capital` int(11) DEFAULT NULL,
    ->   `Code2` char(2) NOT NULL,
    -> PRIMARY KEY `PRIMARY` (`Code`)
    -> ) ENGINE=InnoDB;
Query OK, 0 rows affected (0.01 sec)

mysql>
mysql>
mysql> CREATE TABLE `world`.`countrylanguage` (
    ->   `CountryCode` char(3) NOT NULL,
    ->   `Language` char(30) NOT NULL,
    ->   `IsOfficial` enum('T','F') NOT NULL,
    ->   `Percentage` float(4,1) NOT NULL,
    -> PRIMARY KEY `PRIMARY` (`CountryCode`,`Language`),
    -> KEY `CountryCode` (`CountryCode`)
    -> ) ENGINE=InnoDB;
Query OK, 0 rows affected (0.01 sec)

查看一下

mysql> show  tables;
+-----------------+
| Tables_in_world |
+-----------------+
| city            |
| country         |
| countrylanguage |
+-----------------+
3 rows in set (0.00 sec)

第四步單獨刪除空的表空間文件(刪除的是獨立表的空間)(保留t100w的frm,ibdata1中關於系統的數據信息)

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

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

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

第五步將源數據庫表的ibd文件拷貝到目標庫底下並設置權限

[root@db01 world]# cp  *.ibd  /data/3308/data/world/
[root@db01 world]# chown  -R  mysql. /data/

第六步在目標庫將ibd文件導入表空間

mysql>
mysql>
mysql> alter  table  world.city import  tablespace;
Query OK, 0 rows affected, 1 warning (0.02 sec)

mysql> alter  table  world.country import  tablespace;
Query OK, 0 rows affected, 1 warning (0.01 sec)

mysql> alter  table  world.countrylanguage import  tablespace;
Query OK, 0 rows affected, 1 warning (0.02 sec)

查看一下是否成功

mysql> select count(*) from world.city;
+----------+
| count(*) |
+----------+
|     4079 |
+----------+
1 row in set (0.00 sec)

至此已經恢復業務庫數據到一個新的數據庫中。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章