需要一种优雅的方式将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。有谁知道更好的方法吗?
答案 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了解更多详情。