暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Starrocks主键报错问题的一个案例诊断

skylines 2024-04-10
469

最近在使用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: 75
    2024-04-10 09:24:07,783 WARN com.starrocks.connector.flink.manager.StarRocksSinkManager [] - Failed to flush batch data to StarRocks, retry times = 10
    com.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字段作为主键,另外新建一个字段作为主键。

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

    文章转载自skylines,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

    评论