使用Firehose写入Iceberg表后执行MERGE INTO报ICEBERG_BAD_DATA错误求助
问题原因与解决方案
这个错误的核心是Firehose自动添加的元数据字段与Iceberg内部行标识字段键冲突。Firehose写入Iceberg表时,默认会附加Kinesis流相关的元数据字段(如_pos,记录Kinesis流中的数据位置),而Iceberg内部维护的$row_id.pos字段用于行唯一标识,两者的键值重复,触发了ICEBERG_BAD_DATA错误。
而CTAS语句仅复制原表中的业务数据字段,不会包含Firehose注入的这些额外元数据字段,因此新表不存在字段键冲突,MERGE INTO操作可以正常执行。
解决步骤
- 检查Firehose元数据配置:进入Firehose控制台,查看Iceberg目标的配置项,确认是否开启了
Include Kinesis record metadata选项。如果开启,该选项会自动添加_pos、_record_timestamp等元数据字段,这些字段与Iceberg内部字段冲突。 - 调整Firehose配置:
- 若不需要这些元数据,直接关闭
Include Kinesis record metadata选项; - 若需要保留元数据,通过自定义字段名的方式避免冲突,例如将
_pos重命名为kinesis_record_pos。
- 若不需要这些元数据,直接关闭
- 清理原表冲突元数据:通过Glue控制台或Iceberg元数据命令(如
DESCRIBE EXTENDED)查看原表元数据,确认冲突字段后,可通过ALTER TABLE语句移除冲突的元数据字段,或重新创建表并禁用Firehose元数据注入后重新写入数据。 - 优化MERGE语句:如果必须保留冲突元数据,在MERGE INTO操作中明确指定仅更新业务字段,避免触碰
_pos这类元数据字段,减少冲突触发的概率。
内容的提问来源于stack exchange,提问作者Martin Macak
相关产品推荐
相关产品推荐

