背景: 公司在做敏感信息加密存储的事情,加密后的字符串长度现在的字段长度放不下(当前:varchar(32)),需要扩充字段长度到varchar(255)。直接操作的话,当前场景Online DDL方式又不支持。一般情况下,为了不影响业务,让用户无感知,不影响使用体验,应当使用pt-osc或gh-ost这些开源工具来做,但是公司性质属于某企,使用的数据库使某云产品,现在杯具了!不允许使用这些开源工具。。。(xxoo),好吧。言归正传,没得办法,上面有要求只好采用备库扩充-HA切换-原主库扩充的方案了。现在备库扩充字段后遇到了 cannot be converted from type 'varchar(96(bytes))' to type 'varchar(765(bytes) utf8)' 错误。过程如下: 备库上临时关闭binlog写入 mysql> set session sql_log_bin=0; Query OK, 0 rows affected (0.00 sec) mysql> ALTER TABLE user_base_064 MODIFY COLUMN bank_account VARCHAR(255) DEFAULT NULL COMMENT 'ceshi-account'; Query OK, 368570 rows affected (25.64 sec) Records: 368570 Duplicates: 0 Warnings: 0 ok,备库操作完毕,HA切换前先检查一波复制延迟情况,然后悲剧了。复制出现了异常。 ![]() 检查了error.log发现报错信息 2025-03-27T16:48:41.047694+08:00 600 [ERROR] Slave SQL for channel '': Worker 1 failed executing transaction '498a666b-58cd-11ec-8c73-e8611f2a1bfb:84027231' at master log mysql-bin.004836, end_log_pos 15449089; Column 15 of table 'clw_user_okvo_0016.user_base_064' cannot be converted from type 'varchar(96(bytes))' to type 'varchar(765(bytes) utf8)', Error_code: 1677 好吧,去检查下回放relay log哪个事务异常了 mysqlbinlog -vv --base64-output=decode-rows slave-relay.000006 | less SET @@SESSION.GTID_NEXT= '498a666b-58cd-11ec-8c73-e8611f2a1bfb:84027231'/*!*/; # at 6930 #250327 16:47:01 server id 694425475 end_log_pos 15448785 CRC32 0x750e6776 Query thread_id=17152062 exec_time=0 error_code=0 SET TIMESTAMP=1743065221/*!*/; BEGIN /*!*/; # at 7016 #250327 16:47:01 server id 694425475 end_log_pos 15448954 CRC32 0x1b549b94 Table_map: `clw_user_okvo_0016`.`user_base_064` mapped to number 161 # at 7185 #250327 16:47:01 server id 694425475 end_log_pos 15449089 CRC32 0x7533c912 Write_rows: table id 161 flags: STMT_END_F ### INSERT INTO `clw_user_okvo_0016`.`user_base_064` ### SET ### @1=228850496 /* LONGINT meta=0 nullable=0 is_null=0 */ ### @2=NULL /* LONGINT meta=96 nullable=1 is_null=1 */ ### @3=NULL /* LONGINT meta=0 nullable=1 is_null=1 */ ### @4=NULL /* LONGINT meta=18 nullable=1 is_null=1 */ ### @5='2' /* VARSTRING(18) meta=18 nullable=1 is_null=0 */ ### @6='80103864118|2006916' /* VARSTRING(765) meta=765 nullable=1 is_null=0 */ ### @7=NULL /* VARSTRING(765) meta=96 nullable=1 is_null=1 */ ### @8=NULL /* VARSTRING(765) meta=96 nullable=1 is_null=1 */ ### @9=NULL /* VARSTRING(765) meta=765 nullable=1 is_null=1 */ ### @10='80103864118' /* VARSTRING(3000) meta=3000 nullable=1 is_null=0 */ ### @11='2006916' /* VARSTRING(96) meta=96 nullable=1 is_null=0 */ ### @12=118 /* INT meta=0 nullable=1 is_null=0 */ ### @13='2025-03-08 08:15:51' /* DATETIME(0) meta=0 nullable=1 is_null=0 */ ### @14=0 /* INT meta=0 nullable=1 is_null=0 */ ### @15=NULL /* INT meta=96 nullable=1 is_null=1 */ ### @16=NULL /* INT meta=96 nullable=1 is_null=1 */ ### @17=NULL /* INT meta=96 nullable=1 is_null=1 */ ### @18=NULL /* INT meta=96 nullable=1 is_null=1 */ ### @19=NULL /* INT meta=18 nullable=1 is_null=1 */ ### @20=NULL /* INT meta=0 nullable=1 is_null=1 */ ### @21=NULL /* INT meta=24 nullable=1 is_null=1 */ ### @22=NULL /* INT meta=384 nullable=1 is_null=1 */ ### @23=1 /* INT meta=0 nullable=1 is_null=0 */ ### @24=NULL /* INT meta=96 nullable=1 is_null=1 */ ### @25=NULL /* INT meta=384 nullable=1 is_null=1 */ ### @26=NULL /* INT meta=0 nullable=1 is_null=1 */ ### @27=0 /* INT meta=0 nullable=1 is_null=0 */ ### @28=1 /* INT meta=0 nullable=1 is_null=0 */ ### @29=NULL /* INT meta=96 nullable=1 is_null=1 */ ### @30=NULL /* INT meta=96 nullable=1 is_null=1 */ ### @31=NULL /* INT meta=96 nullable=1 is_null=1 */ ### @32=NULL /* INT meta=96 nullable=1 is_null=1 */ ### @33='2025-03-08 08:15:51' /* DATETIME(0) meta=0 nullable=1 is_null=0 */ ### @34=NULL /* DATETIME(0) meta=0 nullable=1 is_null=1 */ ### @35='2025-03-08 08:15:51' /* DATETIME(0) meta=0 nullable=1 is_null=0 */ ### @36=1 /* INT meta=0 nullable=1 is_null=0 */ ### @37=NULL /* INT meta=765 nullable=1 is_null=1 */ ### @38=NULL /* INT meta=0 nullable=1 is_null=1 */ ### @39=NULL /* INT meta=48 nullable=1 is_null=1 */ ### @40=NULL /* INT meta=192 nullable=1 is_null=1 */ ### @41=NULL /* INT meta=0 nullable=1 is_null=1 */ # at 7320 #250327 16:47:01 server id 694425475 end_log_pos 15449120 CRC32 0xf5f6b3ba Xid = 4956006199 COMMIT/*!*/; 又通过审计日志查到了原始的SQL语句 replace INTO user_base ( user_type, phone, password, ou_code, reg_channel, reg_time, is_id_checked, user_state, is_internal_employee, is_order_charge, create_time, update_time, state ) VALUES ( '2', '80103864118|2006916', '80103864118', '2006916', 118, '2025-03-08 08:15:50.623', 0, 1, 0, 1, '2025-03-08 08:15:50.623', '2025-03-08 08:15:50.623', 1 ) ; 又检查了主备库的表结构情况,字符集,数据库版本等情况,完全一致。表结构如下: CREATE TABLE `user_base` ( `id` bigint(20) NOT NULL AUTO_INCREMENT , `user_code` varchar(32) DEFAULT NULL, `merge_userid` bigint(20) DEFAULT NULL, `merge_type` varchar(6) DEFAULT NULL, `user_type` varchar(6) DEFAULT NULL, `phone` varchar(255) DEFAULT NULL, `login_alias` varchar(32) DEFAULT NULL, `user_name` varchar(32) DEFAULT NULL, `real_name` varchar(255) DEFAULT NULL, `password` varchar(1000) DEFAULT NULL, `ou_code` varchar(32) DEFAULT NULL, `reg_channel` int(6) DEFAULT NULL, `reg_time` datetime DEFAULT CURRENT_TIMESTAMP, `is_id_checked` int(6) DEFAULT '0', `bank_code` varchar(32) DEFAULT NULL, `bank_account` varchar(32) DEFAULT NULL, `bank_account_no` varchar(32) DEFAULT NULL, `bank_account_phone` varchar(32) DEFAULT NULL, `user_level` varchar(6) DEFAULT NULL, `cancel_time` datetime DEFAULT NULL, `cancel_reason` varchar(8) DEFAULT NULL, `cancel_content` varchar(128) DEFAULT NULL, `user_state` int(6) DEFAULT '1', `record_phone` varchar(32) DEFAULT NULL, `token` varchar(128) DEFAULT NULL, `operator_id` int(11) DEFAULT NULL, `is_internal_employee` int(6) DEFAULT '0', `is_order_charge` int(6) DEFAULT '1', `referee_name` varchar(32) DEFAULT NULL, `referee_phone` varchar(32) DEFAULT NULL, `referee_unit` varchar(32) DEFAULT NULL, `build_operator` varchar(32) DEFAULT NULL, `create_time` datetime DEFAULT CURRENT_TIMESTAMP , `updater` int(11) DEFAULT NULL , `update_time` datetime DEFAULT NULL , `state` int(6) DEFAULT '1' , `remark` varchar(255) DEFAULT NULL , `is_proprietary_merchant` int(6) DEFAULT NULL , `stop_code` varchar(16) DEFAULT NULL, `corp_bank` varchar(64) DEFAULT NULL , `channel_type` int(6) DEFAULT NULL , PRIMARY KEY (`id`), KEY `phone` (`phone`), KEY `login_alias` (`login_alias`), KEY `token` (`token`), KEY `Phone_UserType` (`phone`,`user_type`), KEY `oucode` (`ou_code`) USING BTREE, KEY `oucode_usertype` (`user_type`,`ou_code`) USING BTREE, KEY `ubase_uptime_id` (`update_time`), KEY `reg_time_ind` (`reg_time`), KEY `phone_ind` (`phone`), KEY `reg_channel_ind` (`reg_channel`), KEY `id_type_ind` (`id`,`user_type`) ) ENGINE=InnoDB AUTO_INCREMENT=228874244 DEFAULT CHARSET=utf8; 之前,作者多使用gh-ost或gh-ost工具,再不济了使用Online DDL方式,备库操作-HA切换方式接触不多,现在请求各方大佬给点提示,需要往哪方面注意下。不胜感激! |
yejr
3 天前
| ||
lizibin
3 天前
| ||
yejr
3 天前
| ||
lizibin
3 天前
| ||
yejr
3 天前
| ||
合作电话:010-64087828
社区邮箱:greatsql@greatdb.com