Skip to content

Commit 5d43f1d

Browse files
prakharjain09vkorukanti
authored andcommitted
Protocol changes for log compaction
Protocol changes for log compaction Issue: #2072 Closes #2122 GitOrigin-RevId: c15ff24a2a4242520f5cf8ffdb8604a4ffc36805
1 parent eb33558 commit 5d43f1d

File tree

1 file changed

+77
-26
lines changed

1 file changed

+77
-26
lines changed

PROTOCOL.md

Lines changed: 77 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@
1010
- [Change Data Files](#change-data-files)
1111
- [Delta Log Entries](#delta-log-entries)
1212
- [Checkpoints](#checkpoints)
13+
- [Log Compaction Files](#log-compaction-files)
1314
- [Last Checkpoint File](#last-checkpoint-file)
14-
- [Last Checkpoint File Schema](#last-checkpoint-file-schema)
1515
- [Actions](#actions)
1616
- [Change Metadata](#change-metadata)
1717
- [Format Specification](#format-specification)
@@ -89,8 +89,9 @@
8989
- [Column Metadata](#column-metadata)
9090
- [Example](#example)
9191
- [Checkpoint Schema](#checkpoint-schema)
92-
- [JSON checksum](#json-checksum)
93-
- [How to URL encode keys and string values](#how-to-url-encode-keys-and-string-values)
92+
- [Last Checkpoint File Schema](#last-checkpoint-file-schema)
93+
- [JSON checksum](#json-checksum)
94+
- [How to URL encode keys and string values](#how-to-url-encode-keys-and-string-values)
9495

9596
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
9697

@@ -253,6 +254,54 @@ as of now. The add and remove file actions are stored as their individual column
253254

254255
These files reside in the `_delta_log/_sidecars` directory.
255256

257+
### Log Compaction Files
258+
259+
Log compaction files reside in the `_delta_log` directory. A log compaction file from a start version `x` to an end version `y` will have the following name:
260+
`<x>.<y>.compact.json`. This contains the aggregated
261+
actions for commit range `[x, y]`. Similar to commits, each row in the log
262+
compaction file represents an [action](#actions).
263+
The commit files for a given range are created by doing [Action Reconciliation](#action-reconciliation)
264+
of the corresponding commits.
265+
Instead of reading the individual commit files in range `[x, y]`, an implementation could choose to read
266+
the log compaction file `<x>.<y>.compact.json` to speed up the snapshot construction.
267+
268+
Example:
269+
Suppose we have `4.json` as:
270+
```
271+
{"commitInfo":{...}}
272+
{"add":{"path":"f2",...}}
273+
{"remove":{"path":"f1",...}}
274+
```
275+
`5.json` as:
276+
```
277+
{"commitInfo":{...}}
278+
{"add":{"path":"f3",...}}
279+
{"add":{"path":"f4",...}}
280+
{"txn":{"appId":"3ae45b72-24e1-865a-a211-34987ae02f2a","version":4389}}
281+
```
282+
`6.json` as:
283+
```
284+
{"commitInfo":{...}}
285+
{"remove":{"path":"f3",...}}
286+
{"txn":{"appId":"3ae45b72-24e1-865a-a211-34987ae02f2a","version":4390}}
287+
```
288+
289+
Then `4.6.compact.json` will have the following content:
290+
```
291+
{"add":{"path":"f2",...}}
292+
{"add":{"path":"f4",...}}
293+
{"remove":{"path":"f1",...}}
294+
{"remove":{"path":"f3",...}}
295+
{"txn":{"appId":"3ae45b72-24e1-865a-a211-34987ae02f2a","version":4390}}
296+
```
297+
298+
Writers:
299+
- Can optionally produce log compactions for any given commit range
300+
301+
Readers:
302+
- Can optionally consume log compactions, if available
303+
- The compaction replaces the corresponding commits during action reconciliation
304+
256305
### Last Checkpoint File
257306
The Delta transaction log will often contain many (e.g. 10,000+) files.
258307
Listing such a large directory can be prohibitively expensive.
@@ -261,26 +310,6 @@ The last checkpoint file can help reduce the cost of constructing the latest sna
261310
Rather than list the entire directory, readers can locate a recent checkpoint by looking at the `_delta_log/_last_checkpoint` file.
262311
Due to the zero-padded encoding of the files in the log, the version id of this recent checkpoint can be used on storage systems that support lexicographically-sorted, paginated directory listing to enumerate any delta files or newer checkpoints that comprise more recent versions of the table.
263312

264-
#### Last Checkpoint File Schema
265-
266-
This last checkpoint file is encoded as JSON and contains the following information:
267-
268-
Field | Description
269-
-|-
270-
version | The version of the table when the last checkpoint was made.
271-
size | The number of actions that are stored in the checkpoint.
272-
parts | The number of fragments if the last checkpoint was written in multiple parts. This field is optional.
273-
sizeInBytes | The number of bytes of the checkpoint. This field is optional.
274-
numOfAddFiles | The number of AddFile actions in the checkpoint. This field is optional.
275-
checkpointSchema | The schema of the checkpoint file. This field is optional.
276-
tags | String-string map containing any additional metadata about the last checkpoint. This field is optional.
277-
checksum | The checksum of the last checkpoint JSON. This field is optional.
278-
279-
The checksum field is an optional field which contains the MD5 checksum for fields of the last checkpoint json file.
280-
Last checkpoint file readers are encouraged to validate the checksum, if present, and writers are encouraged to write the checksum
281-
while overwriting the file. Refer to [this section](#json-checksum) for rules around calculating the checksum field
282-
for the last checkpoint JSON.
283-
284313
## Actions
285314
Actions modify the state of the table and they are stored both in delta files and in checkpoints.
286315
This section lists the space of available actions as well as their schema.
@@ -1232,7 +1261,9 @@ the `cutoffCommit`, because a commit exactly at midnight is an acceptable cutoff
12321261
2. Identify the newest checkpoint that is not newer than the `cutOffCommit`. A checkpoint at the `cutOffCommit` is ideal, but an older one will do. Lets call it `cutOffCheckpoint`.
12331262
We need to preserve the `cutOffCheckpoint` and all commits after it, because we need them to enable
12341263
time travel for commits between `cutOffCheckpoint` and the next available checkpoint.
1235-
3. Delete all [delta log entries](#delta-log-entries) and [checkpoint files](#checkpoints) before the `cutOffCheckpoint` checkpoint.
1264+
3. Delete all [delta log entries](#delta-log-entries and [checkpoint files](#checkpoints) before the
1265+
`cutOffCheckpoint` checkpoint. Also delete all the [log compaction files](#log-compaction-files) having
1266+
startVersion <= `cutOffCheckpoint`'s version.
12361267
4. Now read all the available [checkpoints](#checkpoints-1) in the _delta_log directory and identify
12371268
the corresponding [sidecar files](#sidecar-files). These sidecar files need to be protected.
12381269
5. List all the files in `_delta_log/_sidecars` directory, preserve files that are less than a day
@@ -1795,7 +1826,27 @@ Checkpoint schema (just the `add` column):
17951826
| | | |-- col-04ee4877-ee53-4cb9-b1fb-1a4eb74b508c: long
17961827
```
17971828

1798-
## JSON checksum
1829+
## Last Checkpoint File Schema
1830+
1831+
This last checkpoint file is encoded as JSON and contains the following information:
1832+
1833+
Field | Description
1834+
-|-
1835+
version | The version of the table when the last checkpoint was made.
1836+
size | The number of actions that are stored in the checkpoint.
1837+
parts | The number of fragments if the last checkpoint was written in multiple parts. This field is optional.
1838+
sizeInBytes | The number of bytes of the checkpoint. This field is optional.
1839+
numOfAddFiles | The number of AddFile actions in the checkpoint. This field is optional.
1840+
checkpointSchema | The schema of the checkpoint file. This field is optional.
1841+
tags | String-string map containing any additional metadata about the last checkpoint. This field is optional.
1842+
checksum | The checksum of the last checkpoint JSON. This field is optional.
1843+
1844+
The checksum field is an optional field which contains the MD5 checksum for fields of the last checkpoint json file.
1845+
Last checkpoint file readers are encouraged to validate the checksum, if present, and writers are encouraged to write the checksum
1846+
while overwriting the file. Refer to [this section](#json-checksum) for rules around calculating the checksum field
1847+
for the last checkpoint JSON.
1848+
1849+
### JSON checksum
17991850
To generate the checksum for the last checkpoint JSON, firstly, the checksum JSON is canonicalized and converted to a string. Then
18001851
the 32 character MD5 digest is calculated on the resultant string to get the checksum. Rules for [JSON](https://datatracker.ietf.org/doc/html/rfc8259) canonicalization are:
18011852

@@ -1826,7 +1877,7 @@ Json: `{"k0":"'v 0'", "checksum": "adsaskfljadfkjadfkj", "k1":{"k2": 2, "k3": ["
18261877
Canonicalized form: `"k0"="%27v%200%27","k1"+"k2"=2,"k1"+"k3"+0="v3","k1"+"k3"+1+0=1,"k1"+"k3"+1+1=2,"k1"+"k3"+2+"k4"="v4","k1"+"k3"+2+"k5"+0="v5","k1"+"k3"+2+"k5"+1="v6","k1"+"k3"+2+"k5"+2="v7"`\
18271878
Checksum is `6a92d155a59bf2eecbd4b4ec7fd1f875`
18281879

1829-
### How to URL encode keys and string values
1880+
#### How to URL encode keys and string values
18301881
The [URL Encoding](https://datatracker.ietf.org/doc/html/rfc3986) spec is a bit flexible to give a reliable encoding. e.g. the spec allows both
18311882
uppercase and lowercase as part of percent-encoding. Thus, we require a stricter set of rules for encoding:
18321883

0 commit comments

Comments
 (0)