最近优化GTID模式下事务表和非事务表更新报错处理时,发现某几张表更改存储引擎为InnoDB报错如下:
mysql> alter table sc_xxx_video_xxxxengine = innodb; ERROR 1031 (HY000): Table storage engine for '#sql-81a_32739' doesn't have this option
查看报错的几张表的定义语句如下:
CREATE TABLE `sc_sys_vedio_relation` ( `catalog_id` int(11) NOT NULL COMMENT '视频目录id', `vedio_id` int(11) NOT NULL COMMENT '视频资源id' ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED
发现报错的几张表的ROW_FORMAT格式都是FIXED,并不是我们熟悉的Dynamic。查看资料和官方文档发现不同版本或者不同源的MySQL对于行记录格式的处理方式不一样,解决上述问题就先要了解row_format的改进历程,这里简单介绍下MyISAM和InnoDB两种存储引擎对于row_format格式的处理。
MyISAM行存储
MyISAM有3种行存储格式:fixed/dynamic/compressed
1、fixed:为默认格式,只有当表不包含变长字段(varchar/varbinary/blob/text)时使用,该每行都是固定的,所以很容易获取行在页上的具体位置,存取效率比较高,但是占用磁盘空间较多
2、dynamic:每行都有一个行头部,包含bitmap,用以记录那些列为空(NULL列不算为空)
3、compressed只能通过myisampack创建且为只读
InnoDB行存储
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 sc_xxx_video_xxxxROW_FORMAT = default; Query OK, 0 rows affected (0.15 sec) Records: 0 Duplicates: 0 Warnings: 0 mysql> alter table sc_xxx_video_xxxxengine = innodb; Query OK, 0 rows affected (2.67 sec) Records: 0 Duplicates: 0 Warnings: 0