Spark3.1.2执行INSERT写入Hive表报错Can only write data to relations with a single path
Spark 3.1.2写入Hive表报
Can only write data to relations with a single path异常解决方案 异常说明
错误堆栈核心信息:
org.apache.spark.sql.AnalysisException: Can only write data to relations with a single path. at org.apache.spark.sql.execution.datasources.DataSourceAnalysis$$anonfun$apply$1.applyOrElse(DataSourceStrategy.scala:202) ...执行的插入SQL:
INSERT INTO table1 PARTITION (part1,part2) SELECT * FROM TEMP_TABLE_APPEND TEMP_TABLE
这个错误是Spark 3.x对分区表写入路径的强校验导致的,当目标Hive表关联了多个存储路径时就会触发,常见的路径不一致场景有:
- 目标分区表的根LOCATION和部分子分区的LOCATION指向不同存储路径,比如手动迁移过分区数据、建分区时单独指定了其他路径
- 表曾被修改过根LOCATION,历史分区路径没有同步更新
- 外部表关联了多个存储目录
修复方案
1. 先定位异常分区
先在Hive客户端执行命令检查路径配置:
- 查看表的根存储路径:
输出结果中DESCRIBE FORMATTED table1;Location字段对应的值就是表的根路径 - 查看所有分区列表:
SHOW PARTITIONS table1; - 逐个检查分区的存储路径,找到和表根路径不匹配的分区:
DESCRIBE FORMATTED table1 PARTITION(part1='替换为实际分区值', part2='替换为实际分区值');
2. 修复异常分区
路径不匹配的分区可以两种方式修复:
- 保留分区数据:将分区数据迁移到表根路径下对应的
part1=xxx/part2=xxx目录,再修改分区LOCATION配置:ALTER TABLE table1 PARTITION(part1='xxx', part2='xxx') SET LOCATION '替换为表根路径下的对应分区目录'; - 不需要保留分区数据:直接删除异常分区,Spark后续写入会自动生成符合路径规则的分区:
ALTER TABLE table1 DROP PARTITION(part1='xxx', part2='xxx');
3. 临时规避方案(仅紧急场景使用)
如果来不及修复分区,可以在Spark会话配置中关闭路径校验,参数如下:
spark.sql.legacy.allowAddingLocationToPartitionedTable = true
该方案会跳过Spark的路径合法性校验,可能出现数据写入路径混乱的问题,不建议长期使用。
内容的提问来源于stack exchange,提问作者Maorb
相关产品推荐
相关产品推荐

