從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;


這篇文章有用嗎?