一、故障現象
今天將一個在MySQL5.7上的數據導入到MySQL5.6里面去,默認存儲引擎都是InnoDB,導入報錯如下:
[root@oratest52 data]# mysql -uroot -p123456 < /data/127.sql
ERROR 1031 (HY000) at line 598885: Table storage engine for 't_config_dbconnects' doesn't have this option
報錯提示598885行有問題,t_config_dbconnects表的存儲引擎不支持這個選項。由於備份文件較大(50G),不可能用vi打開去看,用sed文件查看該表的建表sql如下:
[root@oratest52 data]# sed -n '598870,598899p' 127.sql
--
-- Current Database: `db_config`
--
CREATE DATABASE /*!32312 IF NOT EXISTS*/ `db_config` /*!40100 DEFAULT CHARACTER SET utf8 */;
USE `db_config`;
--
-- Table structure for table `t_config_dbconnects`
--
DROP TABLE IF EXISTS `t_config_dbconnects`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `t_config_dbconnects` (
`ID` smallint(6) unsigned NOT NULL AUTO_INCREMENT,
`NAME` char(50) DEFAULT NULL,
`HOST` char(50) NOT NULL DEFAULT '',
`PORT` char(10) NOT NULL DEFAULT '',
`USER` char(50) NOT NULL DEFAULT '',
`PASSWORD` char(50) NOT NULL DEFAULT '',
`CHARSET` char(30) DEFAULT NULL,
`DBNAME` char(50) NOT NULL DEFAULT '',
`ABOUT` char(200) DEFAULT NULL,
`POSTTIME` datetime DEFAULT NULL,
`LASTUSER` char(50) DEFAULT NULL,
PRIMARY KEY (`ID`),
UNIQUE KEY `IDX_NAME` (`NAME`)
) ENGINE=InnoDB AUTO_INCREMENT=84 DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED;
可以看到最后一行中有ROW_FORMAT=FIXED
二、初步分析
發現報錯的表的ROW_FORMAT格式是FIXED,並不是我們熟悉的Dynamic。查看資料和官方文檔發現不同版本或者不同源的MySQL對於行記錄格式的處理方式不一樣,解決上述問題就先要了解row_format的改進歷程,這里簡單介紹下MyISAM和InnoDB兩種存儲引擎對於row_format格式的處理。
2.1MyISAM存儲引擎
MyISAM有3種行存儲格式:fixed/dynamic/compressed
- fixed:為默認格式,只有當表不包含變長字段(varchar/varbinary/blob/text)時使用,該每行都是固定的,所以很容易獲取行在頁上的具體位置,存取效率比較高,但是占用磁盤空間較多
- dynamic:每行都有一個行頭部,包含bitmap,用以記錄那些列為空(NULL列不算為空)
- compressed只能通過myisampack創建且為只讀
2.2InnoDB存儲引擎
Innodb plugin新引入Barracuda,其包含compressed/dynamic兩種行格式,而之前的compact/redundant統屬於antelope;目前可選值為Antelope和Barracuda,低版本默認為Antelope,高版本默認為Barracuda。
了解這兩種存儲引擎如上兩種row_format格式后,就能明白對一張MyISAM表且row_format為fixed格式的表更改存儲殷勤為InnoDB肯定是不行的,因為InnoDB的row_format不支持fixed格式。所以可以先備份要更改引擎的表數據,然后將表的row_format更改為存儲引擎都能識別的row_format,再進行引擎的變更。
mysql> alter table t_config_dbconnects ROW_FORMAT = default;
Query OK, 0 rows affected (0.15 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> alter table t_config_dbconnects engine = innodb;
Query OK, 0 rows affected (2.67 sec)
Records: 0 Duplicates: 0 Warnings: 0