解決思路:利用獨立表空間的方式將業務庫的.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)
至此已經恢復業務庫數據到一個新的數據庫中。