最近在使用flink-cdc同步MySQL数据到starrocks的时候,有一个奇怪的现象。在对一个拥有几十个表的数据库进行整库同步的是时候,发现整个库中只有一个表的数据不能同步过去。在源端MySQL库上,这个表有40000条记录,到了目标端,一条记录都没有。然后去检查smt的配置文件,以及这个表对应的source table和sink table,都没有问题。把同步任务重启了多次,也没有解决问题,也看不出任何问题。
本身从MySQL同步数据到starrocks数据库上,基本有比较高的兼容,因为后者的后台就是采用MySQL的,客户端也是采用MySQL的客户端。再由于整库所有表一起同步的时候,说的日志太多了,又因为这个同步有异常的表排在第二个位置,对应的同步日志内容早就被刷过去了。想到把这个表从大任务中单独拆出来,进行同步,看能否从日志中发现有价值的内容。把这个单表的同步任务跑起来之后,查看<flink-home>/log/flink-root-standalonesession-0-ubuntuserver.log日志之后,果然看到的报错的信息。

2024-04-10 09:24:07,763 INFO com.starrocks.connector.flink.manager.StarRocksStreamLoadVisitor [] - Start to join batch data: label[93a35173-ea99-400e-b1b2-ec239b542e25].2024-04-10 09:24:07,764 INFO com.starrocks.connector.flink.manager.StarRocksStreamLoadVisitor [] - Executing stream load to: 'http://192.168.10.105:8030/api/infocenterdata/Azure_MS_CognitiveServices_Deployments_tbl/_stream_load', size: '30965', thread: 752024-04-10 09:24:07,783 WARN com.starrocks.connector.flink.manager.StarRocksSinkManager [] - Failed to flush batch data to StarRocks, retry times = 10com.starrocks.connector.flink.manager.StarRocksStreamLoadFailedException: Failed to flush data to StarRocks, Error response:{"Status":"Fail","BeginTxnTimeMs":0,"Message":"192.168.10.107: primary key size exceed the limit.","NumberUnselectedRows":0,"CommitAndPublishTimeMs":0,"Label":"93a35173-ea99-400e-b1b2-ec239b542e25","LoadBytes":30965,"StreamLoadPlanTimeMs":1,"NumberTotalRows":0,"WriteDataTimeMs":8,"TxnId":5774,"LoadTimeMs":11,"ReadDataTimeMs":0,"NumberLoadedRows":0,"NumberFilteredRows":0}{}at com.starrocks.connector.flink.manager.StarRocksStreamLoadVisitor.doStreamLoad(StarRocksStreamLoadVisitor.java:104) ~[flink-connector-starrocks-1.2.3_flink-1.14_2.11.jar:?]at com.starrocks.connector.flink.manager.StarRocksSinkManager.asyncFlush(StarRocksSinkManager.java:316) ~[flink-connector-starrocks-1.2.3_flink-1.14_2.11.jar:?]at com.starrocks.connector.flink.manager.StarRocksSinkManager.lambda$startAsyncFlushing$0(StarRocksSinkManager.java:160) ~[flink-connector-starrocks-1.2.3_flink-1.14_2.11.jar:?]at java.lang.Thread.run(Thread.java:834) [?:?]
有一段很重要的信息:"Status":"Fail","BeginTxnTimeMs":0,"Message":"192.168.10.107: primary key size exceed the limit.",然后对这个表的主键,在源端和和目标端看了主键字段id的设置的长度,发现也是足够长的。上去了Starrocks的社区一查看,说是因为Starrocks的主键长度不能超过128个字段,然后到源端的MySQL查看主键的长度,发现所有记录的id长度都超过128个字节。这个id字段,采用的是varchar的数据类型,瞬时间就想到,为什么采用这么长的字符串作为主键呢。
接着,就先看一下,Starrocks为什么对主键会有这样的限制呢。

我就不作过多的解释了,上面都已经写得清清楚楚了。我使用flink从MySQL同步这个表的数据到Starrocks数据库,正是这个原因导致的。
如果解决这个同步问题,计划就是需要从源端MySQL数据库上,对这个表的表结构进行改造,比如拆解这个id字段的内容为多个字段,保留长度为较短的内容作为主键的内容,或者不采用这个id字段作为主键,另找字段作为主键。再一个改造方法,就是在目标端进行改造,启用这个id字段作为主键,另外新建一个字段作为主键。

所以说,表设计也很重要,一百多个字节长度的字符串作为主键,基本算是不规范的表设计了,一不留神,就给后面的数据流转挖了个坑。





