spark 2.3 alter table partition 造成分区create_time丢失

简介

使用spark 2.3进行hive表修改分区信息是,会造成hive元数据的create_time置为0。

复现

使用spark执行ALTER TABLE PARTITION

spark.sql("""ALTER TABLE test.test PARTITION (sdate='2021-12-24') RENAME TO PARTITION (sdate='2021-12-25')""")

执行后,partitions表里的create_time置为0执行结果
同样的,使用ANALYZE TABLE test.test PARTITION (sdate='2021-12-24') COMPUTE STATISTICS分析分区数据,也会造成create_time为0.

原因

执行sparkSession.sessionState.catalog.alterPartitions(tableName: TableIdentifier, parts: Seq[CatalogTablePartition])函数,
会调用org.apache.spark.sql.hive.HiveExternalCatalog的alterPartitions函数
继续调用org.apache.spark.sql.hive.client.HiveClientImpl的alterPartitions函数,接着调用自己的toHivePartition, 代码如下。

def toHivePartition(
      p: CatalogTablePartition,
      ht: HiveTable): HivePartition = {
    val tpart = new org.apache.hadoop.hive.metastore.api.Partition
    val partValues = ht.getPartCols.asScala.map { hc =>
      p.spec.get(hc.getName).getOrElse {
        throw new IllegalArgumentException(
          s"Partition spec is missing a value for column '${hc.getName}': ${p.spec}")
      }
    }
    val storageDesc = new StorageDescriptor
    val serdeInfo = new SerDeInfo
    p.storage.locationUri.map(CatalogUtils.URIToString(_)).foreach(storageDesc.setLocation)
    p.storage.inputFormat.foreach(storageDesc.setInputFormat)
    p.storage.outputFormat.foreach(storageDesc.setOutputFormat)
    p.storage.serde.foreach(serdeInfo.setSerializationLib)
    serdeInfo.setParameters(p.storage.properties.asJava)
    storageDesc.setSerdeInfo(serdeInfo)
    tpart.setDbName(ht.getDbName)
    tpart.setTableName(ht.getTableName)
    tpart.setValues(partValues.asJava)
    tpart.setSd(storageDesc)
    tpart.setParameters(mutable.Map(p.parameters.toSeq: _*).asJava)
    new HivePartition(ht, tpart)
  }

没有保存create_time和last_access_time。

修复

在spark2.4修复了这个问题。
SPARK-21687
生产上暂时不升级spark,只是在执行alter partition语句之前将create_time手动保存在自己的表里。

你可能感兴趣的:(spark,sql,spark,hive,big,data)