从DELTA_LOG腐败错误中恢复过来

学习如何修理三角洲表查询时报告IllegalStateException错误。

写的gopinath.chandrasekaran

去年发表在:2023年2月17日

问题

要查询一个增量表当你得到一个IllegalStateException错误说,元数据无法恢复。

错误的SQL语句:IllegalStateException:δ表的元数据无法恢复,重建版本:691193。你_delta_log目录中手动删除文件了吗?spark.databricks.delta.stateReconstructionValidation.enabled设置为“false”跳过验证。

导致

三角洲表由于损坏的CRC或JSON文件无法访问。

例如,您禁用multicluster写(AWS|Azure|GCP),但是你仍有多个集群试图写入同一个表,导致腐败。

解决方案

删除

警告

这个解决方案是一个解决方案,使您能够恢复三角洲表,使其可读。这个解决方案假设δ表扩展。

如果你的三角洲表包含一个更新操作使用这个解决方案。打开一张票与砖的支持。

这些步骤使表可读性和让你安全地删除损坏三角洲交易文件。

  1. 禁用验证配置。这允许你绕过IllegalStateException当您运行一个查询错误三角洲表。这个不应该用于生产,但需要访问的表的版本。任何正在运行的集群可以用于这一过程。重新启动集群在该属性不需要做出更改。
    % sql设置spark.databricks.delta.stateReconstructionValidation.enabled = False;
  2. 识别哪些版本的表损坏。
    1. 确定最新的三角洲版本的表通过检查_delta_log文件夹中。
      % fs ls / delta-table-root-folder / _delta_log
    2. 运行最新select * from table@v (< >)在SQL笔记本电池。您应该看到空结果最新版本是损坏的。保持运行select * from table@v (< latest-x >)直到你找到一个不是损坏的版本。对于本文的目的,假设版本6和7是损坏的。版本5是完整的,没有损坏。

  3. 镶花的文件进行备份(数据文件)添加到表在版本6和7。

    此示例代码将检查机关文件备份文件夹。
    % python导入操作系统导入shutil def get_parquet_files_list (corrupted_versions):“获得列表包含损坏的json版本,确定拼花这些版本并将它们返回的数据文件列表”“final_list corrupted_versions =[]文件:delta_table_location = ' < delta-table-location > ' #不需要前缀/ dbfs json_path = delta_table_location + ' / _delta_log”+ str(文件)df = spark.read.json (< json_path >) .select (“add.path”) target_list =列表(df.select(路径).toPandas()(“路径”))final_list.extend (target_list)返回列表(过滤器(没有,final_list)) def copy_file (final_list, source_folder backup_folder):“‘拼花文件从源复制到备份文件夹“i = 1 file_path final_list: src_path = source_folder + file_path trg_path = backup_folder + file_path os.makedirs (os.path.dirname (trg_path) exist_ok = True) shutil。复制(src_path trg_path)打印(“- - >”+ str(我)我= + 1 def主要():source_folder = ' < delta-table-location > #前缀/ dbfs需表位置dbfs文件夹或挂载点backup_folder = ' < backup-folder-storage-path > #前缀/需要dbfs corrupted_versions = [00000000000000000006. json, 00000000000000000007。json) #在这里输入的json版本文件final_list = get_parquet_files_list (corrupted_versions) copy_file (final_list、source_folder backup_folder) if __name__ = =“__main__”:主要()
  4. 删除的CRC和JSON文件损坏的版本的表。
    % fs rm / delta-table-root-folder / _delta_log / 00000000000000000006。json rm / delta-table-root-folder / _delta_log / 00000000000000000006. crc
    % fs rm / delta-table-root-folder / _delta_log / 00000000000000000007。json rm / delta-table-root-folder / _delta_log / 00000000000000000007. crc
  5. 运行恢复表恢复δ表的最新版本是没有损坏。在我们的例子中,这是版本5。
    % sql恢复表<表名称> 5版本
  6. 现在损坏的文件已经被删除,任何版本的表可以查询。为了避免数据丢失,您必须添加拼花您之前备份的文件。这将确保任何数据添加到损坏的版本的表插入到恢复版本和不必要的数据丢失是可以避免的。

    虽然附加,请核实:
    1. 如果目标表分区。如果是分区,包括partitionBy选择的附加声明。
    2. 确认所有数据类型匹配的目标表。
      % python backup_folder = ' /备份文件夹' target_table_path = ' / delta-table-root-folder / ' append_df = spark.read.format(铺).load(<备份文件夹>)append_df_new = append_df.withColumn (col1,坳(col1) .cast('字符串'))#铸造匹配目标表模式append_df_new.write.format(δ).partitionBy (‘col2’,‘col3’,‘col4’) .mode .option(“追加”)(“路径”,< target-table-path >) .saveAsTable (“db.tableName”)
  7. 重新启用验证检查。
    % sql设置spark.databricks.delta.stateReconstructionValidation.enabled = True;


这篇文章有用吗?