Apache Doris执行CTAS语句报[E-238] Too many segments in rowset错误求助
[E-238] Too many segments in rowset 错误分析与解决办法
错误原因
这个错误是因为CTAS语句生成的结果数据,在构建存储层的rowset时,包含的segment数量超过了Apache Doris的默认阈值。不管是笛卡尔积的全连接还是带ON条件的JOIN,只要最终结果集的数据量过大,或者生成过程中因为内存限制、分桶策略等因素导致被拆分成过多小segment,都会触发这个报错。
解决办法
调整CTAS写入参数
在CTAS语句末尾添加PROPERTIES配置,增大单个segment的大小,减少总segment数量:CREATE TABLE MY_DB_NAME.MY_TABLE_NAME AS SELECT T1.DATA_DATE AS SDATE, T2.* FROM DW_DATA T1 JOIN T_NCM_BUSINESS_DUEBILL T2 ON T1.ID = T2.ID PROPERTIES ( "segment_size" = "1024MB", -- 根据实际情况调整,比如512MB或2048MB "merge_small_segments" = "true" -- 自动合并小segment );同时提前设置会话级参数,开启磁盘溢出避免内存不足导致的分段:
SET enable_spill = true; SET exec_mem_limit = "32G"; -- 依据集群资源调整执行内存上限缩小结果集规模
若业务允许,先对源表做过滤或预聚合,减少JOIN后的数据量。比如按DATA_DATE分区过滤,分批处理数据再插入目标表:-- 先创建空表,匹配目标结构 CREATE TABLE MY_DB_NAME.MY_TABLE_NAME ( SDATE DATE, -- 其他字段根据T2结构定义 ) DISTRIBUTED BY HASH(ID) BUCKETS 32; -- 合理设置分桶数 -- 分批插入数据 INSERT INTO MY_DB_NAME.MY_TABLE_NAME SELECT T1.DATA_DATE AS SDATE, T2.* FROM DW_DATA T1 JOIN T_NCM_BUSINESS_DUEBILL T2 ON T1.ID = T2.ID WHERE T1.DATA_DATE = '2024-01-01'; -- 重复执行INSERT语句,覆盖所有需要的日期范围优化源表分桶/分区策略
如果源表分桶数过多,JOIN后每个分桶的结果可能生成独立segment,导致总数超标。可以先将源表数据重分布到更少的分桶中,再执行CTAS:-- 创建临时表合并源表分桶 CREATE TABLE DW_DATA_TMP AS SELECT * FROM DW_DATA DISTRIBUTED BY HASH(ID) BUCKETS 16; -- 设置比原表更少的分桶数 -- 用临时表执行JOIN和CTAS CREATE TABLE MY_DB_NAME.MY_TABLE_NAME AS SELECT T1.DATA_DATE AS SDATE, T2.* FROM DW_DATA_TMP T1 JOIN T_NCM_BUSINESS_DUEBILL T2 ON T1.ID = T2.ID;调整集群级参数(谨慎操作)
若上述方法无效,可修改FE配置文件fe.conf中的max_segment_num_per_rowset参数,增大允许的最大segment数,修改后需重启FE节点。注意这是集群级调整,会影响所有表的写入,需评估集群负载后操作。
内容的提问来源于stack exchange,提问作者Young
相关产品推荐
相关产品推荐

