Spark2.2执行INSERT OVERWRITE写入分区表触发全表覆盖问题咨询
核心原因
- 默认静态分区覆盖逻辑导致全表清空:Spark 2.3之前版本,
spark.sql.sources.partitionOverwriteMode参数默认值为STATIC(静态覆盖模式)。该模式下执行INSERT OVERWRITE分区表操作时,会先删除目标表的所有存量分区数据,再写入SELECT语句返回的结果,完全不区分SELECT结果中包含的分区范围,因此你执行后原表中dt=20210915的分区数据被全部清空,仅保留了待写入的dt=20210914分区数据。 - 你的SQL语法本身没有错误,只是默认配置不符合你需要的「仅覆盖查询结果存在的分区」的需求。
Spark 2.2版本可用的解决方案
方案1:开启动态分区覆盖模式
执行写入逻辑前,先添加一行参数配置,将分区覆盖模式改为动态:
spark.sql("set spark.sql.sources.partitionOverwriteMode=DYNAMIC")
配置生效后再执行你原有的INSERT语句,即可实现仅覆盖SELECT结果中存在的dt=20210914分区,其余分区数据保持不变。该方案适合需要同时覆盖多个不固定分区的场景。
方案2:显式指定待覆盖分区(更稳妥)
如果本次仅需要覆盖单个已知值的分区,可以直接将分区值写死在PARTITION子句中,无需依赖模式配置,写法如下:
df.createOrReplaceGlobalTempView(tempTable) # 注意PARTITION子句直接指定分区值,SELECT语句不需要再返回dt列 insertSql = "INSERT OVERWRITE TABLE {} PARTITION(dt='20210914') SELECT column1, column2 FROM {}".format(exportTable, tempTable) spark.sql(insertSql)
该写法不受分区覆盖模式参数影响,只会操作指定的dt=20210914分区,不会改动其他任何分区数据,稳定性更高。
内容的提问来源于stack exchange,提问作者wow_fan
相关产品推荐
相关产品推荐

