备库改完某张表的表结构,之后出现备库复制报错。
修改前表结构:
CREATE TABLE `vod_video_records` (
`video_id` varchar(64) NOT NULL COMMENT '视频唯一ID',
`owner_id` varchar(64) NOT NULL COMMENT '视频所属者ID',
`owner_name` varchar(64) NOT NULL COMMENT '视频所属者名称',
`title` varchar(200) NOT NULL COMMENT '视频名称',
`memo` varchar(2000) DEFAULT NULL COMMENT '视频简介',
......
PRIMARY KEY (`video_id`),
KEY `idx_owner_id` (`owner_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='视频分享表';
执行DDL:
ALTER TABLE `vod_video_records` MODIFY COLUMN `title` varchar(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL AFTER `owner_name`,
错误日志:
2015-09-01 09:50:22 14078 [ERROR] Slave SQL: Column 3 of table 'shipin7.vod_video_records' cannot be converted from type 'varchar(600)' to type 'varchar(256)', Error_code: 1677
执行前title字段是varchar(200),执行后为varchar(256)。
解决方法:
从错误信息来看表面上是由于在slave上无法执行一条转换字段类型的SQL语句。实际上并不是有这种语句直接引起的,而是间接引起的(之前某些操作导致主从表字段类型不一致,接下来对这个表进行DML时就会报错)。它的意思是在对这个表t进行DML操作时,发现主从上表结果不一致,比如这里是说在主上t的字段1是int类型,但是从上t的字段1是bigint类型,所以报错。那么为什么要报错呢?这是从安全角度考虑,因为如果字段类型不一致可能会导致数据截断之类的问题。那么解决方法呢?通过参数slave_type_conversions进行控制,它有三种取值:
ALL_LOSSY:仅支持有损转换,什么叫有损?比如一个值本来是bigint存储为9999999999999,现在转换为int类型势必会要截断从而导致数据不一致。
ALL_NON_LOSSY:仅支持无损转换,只能在无损的情况下才能进行转换
ALL_LOSSY,ALL_NON_LOSSY:有损/无算转换都支持 空,即不设置这个参数:必须主从的字段类型一模一样。 注意:
前面说的这几中情况都只在binlog_format=ROW的情况下才有效。