诡异的Databricks Delta Lake Table History
分类: Azure Databricks ◆ 标签: #Databricks #大数据 ◆ 发布于: 2025-02-16 20:00:33

如果大家对于什么是Databricks Delta Lake Table History
还不是太清楚,那么你一定要参考Databricks
的官方文档: https://docs.databricks.com/en/delta/history.html, 这篇官方文档里详细的描述了什么是Delta Lake
的Table History
, 以及主要支持的场景: Time Travel Query
。
有一些技术要点可以先在这里总结一下:
每一个针对
Delta Lake
表的写操作都会产生一个新的Table History version
, 即一个新的commit
。这里所谓的
Write
操作主要包括这些语句:WRITE
CREATE TABLE AS SELECT
REPLACE TABLE AS SELECT
COPY INTO
STREAMING UPDATE
DELETE
TRUNCATE
MERGE
UPDATE
FSCK
CONVERT
OPTIMIZE
CLONE
RESTORE
VACUUM
每个操作以及操作的内容,都一定会产生一个新的历史版本,而且这些历史版本在
Delta Lake
里使用一种叫做事务日志的机制保存起来,它的保存位置在表目录下的_delta_log
目录,每一个新版本的事务日志文件都是一个json
文件,注意: 每一个json
文件仅仅包含一个写动作。Delta Lake
默认情况会在每10次提交事务之后生成一个新的checkpoint
文件,这个checkpoint
文件是一个Parquet
文件,它记录所有json
文件的内容,主要用于优化查询。这里默认十次提交,可以通过配置delta.checkpointInterval
来更改,默认的表属性配置是10次,这个部分,可以参考Delta
开放的协议说明:https://github.com/delta-io/delta/blob/74d19a5ad2360d358563de27a0b1d90034983439/kernel/kernel-api/src/main/java/io/delta/kernel/internal/TableConfig.java#L74, 如下图:
Delta Table History
的所有日志记录称为事务日志,它和用户的数据文件是完全分开存放的。Time Travel Query
要完成查询同时依赖于事务日志和数据文件。事务日志的清理和保存时间由
delta Lake
自动处理,用户可以配置。数据文件的保留时间,用户需要通过命令
VACUUM
来参与保留和清除。
以上是
Delta Lake Table History
的理论总结部分,但是我认为它比较诡异的地方主要就在于Table History
可以保留的时长上。根据官方的文档描述:
Table history retention is determined by the table setting delta.logRetentionDuration, which is 30 days by default
这里描述的非常明确就是可以通过表属性
delta.logRetentionDuration
来控制事务日志可以保留的天数来控制Table History
可以保留的天数,同时结合Time Travel Query
的详细说明:To query a previous table version, you must retain both the log and the data files for that version.
Data files are deleted when VACUUM runs against a table. Delta Lake manages log file removal automatically after checkpointing table versions.
Because most Delta tables have VACUUM run against them regularly, point-in-time queries should respect the retention threshold for VACUUM, which is 7 days by default.
In order to increase the data retention threshold for Delta tables, you must configure the following table properties:
delta.logRetentionDuration = "interval <interval>": controls how long the history for a table is kept. The default is interval 30 days.
delta.deletedFileRetentionDuration = "interval <interval>": determines the threshold VACUUM uses to remove data files no longer referenced in the current table version. The default is interval 7 days.
You can specify Delta properties during table creation or set them with an ALTER TABLE statement. See Delta table properties reference.这段文字就描述得非常清楚了:
Time Travel
查询同时依赖数据文件的保留时间和事务日志的保留时间,默认情况下数据文件的保留时间是7天,事务日志的保留时间是30天。数据文件的保留时间可以通过选项:
delta.deletedFileRetentionDuration = "interval <interval>"
配置保留天数事务日志文件保留时间可以通过选项:
delta.logRetentionDuration = "interval <interval>"
配置保留天数。
为了验证上述的这个理论,我决定创建如下的表来验证:
首先是表一, 表参数配置:
CREATE TABLE test1day (
Id Integer,
Name Varchar(50)
)
USING delta
TBLPROPERTIES (
'delta.logRetentionDuration' = 'interval 1 days',
'delta.deletedFileRetentionDuration' = "interval 1 days"
);指定该表数据文件保留一天,事务日志保留一天。
作为对比,同时创建表:
CREATE TABLE test1sday (
Id Integer,
Name Varchar(50)
)
USING delta
TBLPROPERTIES (
'delta.logRetentionDuration' = 'interval 1 days'
);对照表仅仅指定事务日志保留为一天,但是数据文件保留默认是7天。
然后经过连续多天的测试, 每天都插入数据,形成新的提交:
-- 插入数据了. 每天做两次
insert into testdb1.test1day (Id, Name) values (1, 'test');
insert into testdb1.test1sday (Id, Name) values (1, 'test');然后我们使用
DESC History
查看多天的table history
返回记录:2024-8-27
:
2024-8-27的截图没有什么好说明的,因为是第一天的测试结果。
然后是第二天:
2024-8-28
:
请记得我们对于表一的设置是数据文件一天,事务日志文件一天,表二是事务日志一天,数据文件默认是7天,假设我们认为Databricks runtime有自己的考量,然后多放一天,假假的认为可能是正常的,我们继续看。
2024-8-29
:
然后就发现2024-8-29
的历史记录完全不知道该怎么形容了,就好像我们的配置在这里根本没起作用。
我故意将这个数据等待20多天之后,也就是2024-9-16, 继续观察:
2024-9-16
:
然后我观察更加令人惊悚的一幕:
表一的数据可能还说得过去,但是9/16和8/29差这么多是什么鬼?
表二的数据就完全没有办法理解了。。。。
因为这个表现,我和Databricks
的工程师做过很多次的讨论,很感谢Databricks
工程师给我分享了很多insight
, 虽然后来这些insight
我都从delta Lake
开源的协议中找到了明确的说明,同时也在源代码里找到了印证,但是始终不能说明官方文档里描述的各种特性和明确说明的配置效果。
通过分析Delta Lake
协议的源码以及文档,我还是建议大家在使用这个特性的时候,需要仔细的考量使用的场景,从官方的文档反馈以及我测试的结果,我个人发现这个功能还存在一些不确定性,将来未必没有更改的可能性。
注意:这是我个人的建议。