找不到事务日志中引用的一个文件

问题

作业失败并显示错误消息:A file referenced in the transaction log cannot be found.

示例堆栈跟踪:

Error in SQL statement: SparkException: Job aborted due to stage failure: Task 0 in stage 6.0 failed 4 times, most recent failure: Lost task 0.3 in stage 6.0 (TID 106, XXX.XXX.XXX.XXX, executor 0): com.databricks.sql.io.FileReadException: Error while reading file dbfs:/mnt/<path>/part-00000-da504c51-3bb4-4406-bb99-3566c0e2f743-c000.snappy.parquet. A file referenced in the transaction log cannot be found. This occurs when data has been manually deleted from the file system rather than using the table `DELETE` statement. For more information, see https://docs.databricks.com/delta/delta-intro.html#frequently-asked-questions ... Caused by: java.io.FileNotFoundException: dbfs:/mnt/<path>/part-00000-da504c51-3bb4-4406-bb99-3566c0e2f743-c000.snappy.parquet ...

原因

有三个常见原因会导致出现此错误消息。

  • 原因 1:启动 Delta 流式处理作业,但在流式处理作业开始处理之前,基础数据被删除。
  • 原因 2:执行对 Delta 表的更新,但未用最新的详细信息更新事务文件。
  • 原因 3:尝试对同一 Delta 表执行多群集读取或更新操作,从而导致群集引用了群集上已删除的并重新创建的文件。

解决方案

  • 原因 1:应该使用新的检查点目录,或在群集的 Spark 配置 中将 Spark 属性 truetrue
  • 原因 2:等待数据加载后,刷新表。 还可以运行 fsck 来通过最新的详细信息更新事务文件。

注意

fsck 从 Delta 表的事务日志中删除无法在基础文件系统中找到的任何文件条目。

  • 原因 3:删除并重新创建表后,驱动程序中的元数据缓存不正确。 不应删除表,应始终覆盖表。 如果删除了某个表,则应清除元数据缓存以缓解此问题。 可以使用 Python 或 Scala 笔记本命令清除缓存。
spark._jvm.com.databricks.sql.transaction.tahoe.DeltaLog.clearCache()
com.databricks.sql.transaction.tahoe.DeltaLog.clearCache()