概要描述
studio3.0.1版本,客户对mysql数据库元数据采集时执行失败,日志显示 Cause: java.sql.SQLException: Incorrect string value: '\xF1\xBE\xAD\xBC',...' for column 'ddl_create' at row 15
详细说明
1.开启审计日志抓取sql
从采集日志未能看出执行的具体sql语句,对kundb元数据库每个kungate 临时开启audit审计日志:
set kundb_audit_filter="DCL,DDL,DML,INSERT,UPDATE,REPLACE,DELETE,SHOW,SET,TRANS,OTHER";
再次触发采集动作,抓到了执行报错的sql语句。这个sql由多个values组成,我们重点关注ddl_create中DDL的comment字段,发现 engineering-brain.dict_industry_label 表的 表级comment,还有字段 guanlian 的列comment里面有特殊字符。
2.简化问题sql
我们创建一张和database_table一样结构的测试表,手动insert这条数据,最终确认是字段guanlian的comment里面有特殊字符导致的,简化复现语句如下:
drop table if exists test1;
create table test1 like connector_foundation1.database_table;
INSERT INTO test1( is_deleted,name,owner,data_entity_type,authority,create_time,update_time,access_time,database_id,comment,size,ddl,ddl_create,table_location,storage_type )
values
( 0, 'dict_industry_label', '-', 'MYSQL_TABLE', '', '2020-06-18 20:21:34', '2020-06-18 20:21:34', null, 706, '', '3 row(s)', null,
"CREATE TABLE engineering-brain.dict_industry_label (
id int(11) NOT NULL AUTO_INCREMENT,
pid varchar(255) DEFAULT NULL,
code varchar(255) DEFAULT NULL,
pcode varchar(255) DEFAULT NULL,
name varchar(255) DEFAULT NULL,
remark varchar(255) DEFAULT NULL,
latitudes varchar(255) DEFAULT NULL,
longitudes varchar(255) DEFAULT NULL,
simple_name varchar(255) DEFAULT NULL,
state int(11) DEFAULT '0',
bs int(11) DEFAULT '0',
--这里的comment包含了表情符号
guanlian int(11) DEFAULT '0' COMMENT '',
title varchar(50) DEFAULT NULL,
e_id int(11) DEFAULT '0',
order int(255) DEFAULT NULL,
PRIMARY KEY (id) USING BTREE)
ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT=''",
null, 'binlog' );
解决方案:
连接到kundb3元数据库修改字段ddl_create的编码:
ALTER TABLE connector_foundation1.database_table CHANGE ddl_create ddl_create longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
表默认使用的是 utf8mb3 编码,新的字符集是 utf8mb4,MySQL 将会尝试将这些数据无损地转换为 utf8mb4 编码。utf8mb3(即 utf8)和 utf8mb4 都是 UTF-8 编码的变种,但 utf8mb4 支持更多的 Unicode 字符(包括一些表情符号和一些非常罕见的字符),而 utf8mb3 只支持最多三个字节的 UTF-8 字符。
因为 utf8mb3 是 utf8mb4 的子集,所以转换通常是安全的,数据不会丢失或改变。