Transaction_Log

本文深入探讨DeltaLake中TransactionLog的作用与工作机制,包括其在ACID事务、元数据管理和时间追溯上的关键作用,以及如何通过版本和时间戳实现时间旅行功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

参考阅读

Transaction Log

  • 理解Transaction Log是理解Delta Lake的关键
  • Transaction Log 关联到了一些重要功能的实现,如:ACID事务,动态扩展元数据处理,时间追溯
  • Delta Lake transaction log 是在Delta Lake table 上执行过的有序的transaction记录。

Transaction Log 用途

  • 建立在Apache spark之上,允许在同一个表上同时进行多个读写操作
  • 中央仓库追踪所有用户对表的变化
  • 当用户第一次读取Delta Lake表 或者查询时,日志就会被更新
  • Delta lake 通过 Transaction Log 机制保证 原子性

Transaction Log 如何工作

  • 用户的更新表的操作(INSERT,UPDATE,DELETE操作),Delta Lake将该操作分解为一系列离散步骤,这些步骤由以下一个或多个操作组成
    • add file -- 添加一个数据文件
    • remove file -- 删除一个数据文件
    • update metadata -- 更新表的元数据(表面,schema,分区)
    • set transaction -- structured streaming 任务提交的带id的微批处理数据集
    • change protocol -- 修改协议,添加新功能
    • commit info -- 包含此次提交相关的基础信息,如哪个操作,在哪里什么时候

The Delta Lake Transaction Log 文件层级结构

  • 当用户创建Delta Lake 表时,该表对应的Transaction Log会被自动创建在 _delta_log 的子文件夹
    • 当用户修改表时,那些变化的记录会顺序的原子的提交到Transaction Log
  • 每个commit被组织成json格式,文件开头为000000.json
  • 后序的修改操作commit文件会自增000001.json,000002.json
  • 每10个文件提交会自动生成一个chcheckeckpoint
    • checkpoint 文件保存了当前表的状态, 使用parquet格式,方便spark读取
time travel
通过版本方式

image-20200705144529792

通过时间戳方式
TIme travel 限制
  • 事务日志的有效期: delta.logRetentionDuration
  • 数据文件的有效期:delta.deletedFileRetentionDuration
    • 通过执行Vacuum, 删除这些失效的文件
  • time travel 对于存储和性能的损耗,不建议支持年维度
    • 主要用来防止一开始错误使用数据,可以返回之前的版本重新尝试
<think>好的,我现在需要分析用户提供的SQL DELETE语句,并解释其功能。首先,我会仔细阅读并理解每一部分的作用。 用户给出的SQL语句是: DELETE a, b, c FROM inv a INNER JOIN task_list b ON a.trace_id = b.fm_id INNER JOIN act_transaction_log c ON c.doc_no = b.doc_no WHERE a.location_id = 'SHKW01' AND b.task_process IN ('NEW', 'RELEASED') AND a.create_time < DATE_FORMAT(CURDATE(), '%Y-%m-01') 首先,注意到这是一个多表删除操作,DELETE后面跟着三个别名a, b, c,这意味着会同时从三个表中删除记录。需要确认的是MySQL是否支持这种多表删除语法。回想一下,MySQL确实允许在DELETE语句中指定多个表,但需要确保JOIN条件正确,以避免意外删除。 接下来分析FROM和JOIN部分。主表是inv,别名为a,然后INNER JOIN task_list b,连接条件是a.trace_id = b.fm_id。接着再INNER JOIN act_transaction_log c,连接条件是c.doc_no = b.doc_no。这里使用了两个内连接,意味着只有三个表中都有匹配记录的才会被选中。 然后是WHERE子句,条件包括a.location_id = 'SHKW01',筛选出库存位置为SHKW01的记录;b.task_process处于'NEW'或'RELEASED'状态;a.create_time小于当前月份的第一天。这里DATE_FORMAT(CURDATE(), '%Y-%m-01')的作用是获取当月第一天的日期,比如今天是2023-10-15,这个函数会返回'2023-10-01',因此create_time需要早于这个日期,即上个月或更早的数据。 接下来需要验证逻辑是否正确。首先,内连接意味着只有三个表都有对应关联记录的数据才会被删除。如果目的是删除满足条件的所有三个表中的数据,这样的写法是有效的。但需要注意,如果某个表中的记录在其他表中没有关联,但符合WHERE条件,这里不会被删除,因为内连接的条件限制了必须三者关联。 另外,需要特别注意多表删除的风险,因为一旦执行,会同时从多个表中删除数据,可能导致数据丢失,尤其是在JOIN条件不正确的情况下。例如,如果task_list或act_transaction_log中有多条记录匹配,可能会导致更多的数据被删除。需要确认业务逻辑是否确实需要同时删除三个表中的记录,或者是否只需删除主表inv,而其他表通过级联删除处理。 此外,WHERE条件中的日期判断是否正确。使用CURDATE()获取当前日期,并格式化为当月第一天,比如今天是2023-10-15,则DATE_FORMAT结果为'2023-10-01',那么create_time需要小于这个日期,即9月30日及之前的数据。这可能是为了删除上个月之前的数据,但需确认业务需求是否符合。 最后,考虑是否有索引优化。如果inv表的location_id和create_time字段没有索引,可能会导致删除操作效率低下,尤其是在数据量大的情况下。同样,task_list的task_process和fm_id,以及act_transaction_log的doc_no是否有索引也会影响性能。 总结来说,这个DELETE语句的作用是删除满足以下条件的三张表的数据: 1. inv表的位置是SHKW01; 2. task_list的状态是NEW或RELEASED; 3. inv表的创建时间早于当月第一天; 4. 三个表通过trace_id=fm_id和doc_no相关联。 需要确认业务逻辑是否需要同时删除三个表的数据,以及连接条件和过滤条件是否正确,避免误删。建议在执行前备份数据,或在测试环境验证。</think>以下是对您提供的 SQL 删除语句的逐步分析: ### 1. **语句功能** 这是一个 **多表删除操作**,会同时从 `inv`(库存表)、`task_list`(任务表)和 `act_transaction_log`(操作日志表)中删除符合条件的关联数据。 --- ### 2. **核心逻辑拆解** #### (1) **删除目标** ```sql DELETE a, b, c -- 同时删除三张表的记录 ``` - `a`: 代表 `inv` 表的别名 - `b`: 代表 `task_list` 表的别名 - `c`: 代表 `act_transaction_log` 表的别名 #### (2) **表关联方式** ```sql FROM inv a INNER JOIN task_list b ON a.trace_id = b.fm_id -- inv 与 task_list 通过 trace_id/fm_id 关联 INNER JOIN act_transaction_log c ON c.doc_no = b.doc_no -- task_list 与 act_transaction_log 通过 doc_no 关联 ``` - 使用 **内连接(INNER JOIN)**,意味着只有三张表 **同时满足关联条件** 的记录才会被选中删除。 #### (3) **过滤条件** ```sql WHERE a.location_id = 'SHKW01' -- 库存位置为 SHKW01 AND b.task_process IN ('NEW', 'RELEASED') -- 任务状态是 NEW 或 RELEASED AND a.create_time < DATE_FORMAT(CURDATE(), '%Y-%m-01') -- 创建时间早于当月第一天 ``` - `DATE_FORMAT(CURDATE(), '%Y-%m-01')` 会返回当前月份的第一天(例如:今天是 2023-10-15,结果为 `2023-10-01`)。 - 因此 `create_time < '2023-10-01'` 表示删除 **上月及更早** 创建的记录。 --- ### 3. **潜在风险与注意事项** #### 🔴 **多表删除风险** - 该语句会 **同时删除三张表的数据**。如果关联条件不准确,可能导致 **误删重要数据**。 - **建议**:先使用 `SELECT *` 替换 `DELETE` 验证目标数据,确认无误后再执行删除。 #### 🔴 **日期逻辑验证** - 假设业务需求是清理 **上月之前** 的旧数据,当前逻辑正确。 - 若需要清理 **当月之前**(即所有历史数据),则条件合理。 #### 🔴 **索引优化** - 确保 `inv.location_id`、`inv.create_time`、`task_list.fm_id`、`act_transaction_log.doc_no` 等字段有索引,否则大表删除可能极慢。 --- ### 4. **等价改写(可选)** 如果只需删除主表 `inv` 的数据,而其他表通过外键级联删除,可简化为: ```sql DELETE FROM inv WHERE location_id = 'SHKW01' AND create_time < DATE_FORMAT(CURDATE(), '%Y-%m-01') AND EXISTS ( SELECT 1 FROM task_list b INNER JOIN act_transaction_log c ON c.doc_no = b.doc_no WHERE a.trace_id = b.fm_id AND b.task_process IN ('NEW', 'RELEASED') ) ``` --- ### 5. **执行建议** 1. **备份数据**:操作前备份相关表。 2. **事务控制**:使用 `BEGIN; ... COMMIT/ROLLBACK;` 确保可回滚。 3. **分批删除**:若数据量巨大,建议分批次删除(例如按时间分段)。 希望以上分析对您有所帮助!如果还有其他疑问,欢迎继续交流。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值