三角洲湖回滚

时间:2019-08-26 22:53:54

标签: apache-spark rollback databricks delta-lake

需要一种优雅的方式将Delta Lake回滚到以前的版本。

下面列出了我目前的方法:

import io.delta.tables._

val deltaTable = DeltaTable.forPath(spark, testFolder)

spark.read.format("delta")
  .option("versionAsOf", 0)
  .load(testFolder)
  .write
  .mode("overwrite")
  .format("delta")
  .save(testFolder)

但是,这很丑陋,因为需要重写整个数据集。似乎有些元更新就足够了,并且不需要数据I / O。有谁知道更好的方法吗?

5 个答案:

答案 0 :(得分:1)

这是一个残酷的解决方案。这并不理想,但是考虑到用分区覆盖大型数据集可能会很昂贵,因此这种简单的解决方案可能会有所帮助。

如果在所需的回滚时间之后对更新不是很敏感,只需删除_delta_log中晚于回滚时间的所有版本文件。未引用的文件可以稍后使用vacuum释放。

保留完整历史记录的另一种解决方案是:1)deltaTable.delete 2)将所有日志按顺序(直到版本号增加)依次复制到回滚到删除日志文件的末尾。这模仿了直到回滚日期为止的三角洲湖泊的形成。但这肯定不漂亮。

答案 1 :(得分:1)

您应该使用时间旅行功能:https://databricks.com/blog/2019/02/04/introducing-delta-time-travel-for-large-scale-data-lakes.html

您以时间戳读取数据:

val inputPath = "/path/to/my/table@20190101000000000"

然后使用“回滚”版本覆盖现有数据。

关于丑陋,我不确定我能帮上什么忙。您可以使用分区限制数据。或者,您可以找出哪些记录已更改,而仅覆盖它们。

答案 2 :(得分:1)

如果您的目标是修复错误的数据,并且对更新不是很敏感,则可以间隔一段时间。

 df.write
      .format("delta")
      .mode("overwrite")
      .option("replaceWhere", "date >= '2017-01-01' AND date <= '2017-01-31'")
      .save("/delta/events")

答案 3 :(得分:0)

我曾经遇到过类似的Delta问题,我曾在1个事务中调用多个dml操作。例如我有一个调用合并的要求,然后在1个单个事务中删除。因此,在这种情况下,它们要么必须一起成功,要么如果其中任何一个失败,则回滚状态。

为解决此问题,我已在事务开始之前备份了_delta_log(我们称其为稳定状态)目录。如果事务中的两个DML操作均成功,则丢弃先前的稳定状态并使用_delta_log中提交的新状态,如果任何dml操作失败,则只需将_delta_log目录替换为您之前进行备份的稳定状态开始交易。替换为稳定状态后,只需运行吸尘器即可删除可能在交易期间创建的过时文件。

答案 4 :(得分:0)

从Delta Lake 0.7.0开始,您可以使用RESTORE command回滚到Delta Lake表的早期版本。这是使用时间旅行回滚表的更简单的方法。

scala:

 ForEach(model) { value in
                ZStack {
                    VStack(alignment: .leading) {
                        HStack {
                            Text(value.name)
                                .font(.system(size: 15))
                                .background(Color.red)
                                .padding(.trailing, 10.0)
                        }
                        HStack {
                            Text(value.statelong)
                                .foregroundColor(Color.gray)
                                .font(.system(size: 13))
                            Spacer()
                        }
                        
                    }
                    Spacer()
                }.contentShape(Rectangle())
                .frame(maxWidth: .infinity)
                .onTapGesture {
                    isOpen = true
                    defaults.setValue(value.name, forKey: "location")
                }.fullScreenCover(isPresented: $isOpen, content: MainView.init)
            }

Python:

import io.delta.tables._

val deltaTable = DeltaTable.forPath(spark, "/path/to/delta-table")

deltaTable.restoreToVersion(0)

SQL

from delta.tables import * deltaTable = DeltaTable.forPath(spark, "/path/to/delta-table") deltaTable.restoreToVersion(0)

如果您更愿意用这种方式做事,也可以使用RESTORE TABLE delta.`/path/to/delta-table` TO VERSION AS OF 0命令。 Read the documentation了解更多详情。