Skip to content

Conversation

@kevinjqliu
Copy link
Contributor

@kevinjqliukevinjqliu commented Apr 28, 2024

Resolves#594 (and part of #511)

This PR creates a metadata table for "Metadata Log Entries", similar to its spark equivalent (metadata_log_entries).

To query the metadata table, use

tbl.inspect.metadata_log_entries() 

References

Metadata log, append the latest metadata

The metadata log entries append the latest TableMetadata in its operation (code).

This leads to a surprising behavior where the last row of the metadata entries table is based on when the query ran.

For example,

a = spark.sql(f"SELECT * FROM{identifier}.metadata_log_entries").toPandas() import time time.sleep(5) b = spark.sql(f"SELECT * FROM{identifier}.metadata_log_entries").toPandas() (Pdb) display(a) display (a): timestamp file latest_snapshot_id latest_schema_id latest_sequence_number 0 2024-04-28 17:21:31.336 s3://warehouse/default/table_metadata_log_entr... NaN NaN NaN 1 2024-04-28 17:21:31.531 s3://warehouse/default/table_metadata_log_entr... 4.105762e+18 0.0 0.0 2 2024-04-28 17:21:31.600 s3://warehouse/default/table_metadata_log_entr... 7.201925e+18 0.0 0.0 3 2024-04-28 17:21:34.204 s3://warehouse/default/table_metadata_log_entr... 1.984627e+18 0.0 0.0 (Pdb) display(b) display (b): timestamp file latest_snapshot_id latest_schema_id latest_sequence_number 0 2024-04-28 17:21:31.336 s3://warehouse/default/table_metadata_log_entr... NaN NaN NaN 1 2024-04-28 17:21:31.531 s3://warehouse/default/table_metadata_log_entr... 4.105762e+18 0.0 0.0 2 2024-04-28 17:21:31.600 s3://warehouse/default/table_metadata_log_entr... 7.201925e+18 0.0 0.0 3 2024-04-28 17:21:42.336 s3://warehouse/default/table_metadata_log_entr... 1.984627e+18 0.0 0.0 # Notice the timestamp in the last row of a and b differs by more than 5 seconds 

Snapshot sequence-number default value

There's an issue with reading V1 spec where the sequence-number is None instead of 0. According to the Iceberg spec, when reading v1 metadata for v2, the Snapshot field sequence-number must default to 0 (source).

Snapshot JSON: sequence-number was added and is required; default to 0 when reading v1 metadata 

Similarly when writing V1 spec from V2, the sequence-number should not be written. This is achieved by the new field_serializer function in TableMetadataCommonFields.

Writing v1 metadata: Snapshot field sequence-number should not be written 

@kevinjqliukevinjqliu marked this pull request as ready for review April 28, 2024 17:18
parent_snapshot_id: Optional[int] =Field(alias="parent-snapshot-id", default=None)
sequence_number: Optional[int] =Field(alias="sequence-number", default=None)
# cannot import `INITIAL_SEQUENCE_NUMBER` due to circular import
sequence_number: Optional[int] =Field(alias="sequence-number", default=0)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason the default value for the sequence number has to be changed to 0 as opposed to None?

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to the spec, https://iceberg.apache.org/spec/#version-2

Snapshot JSON: sequence-number was added and is required; default to 0 when reading v1 metadata 

Also added this in the PR description

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kevinjqliu Thanks for spotting this! We definitely need to read snapshot.sequence_number as 0 for v1. However, as we have observed in the test outcome, making sequence_number default to 0 here leads to sequence_number=0 be written to version 1 table metada's snapshots, which is not allowed by spec:

Writing v1 metadata: Snapshot field sequence-number should not be written 

I think we may need a new field_serializer in TableMetadataCommonFields class or some other ways to correct the behavior on write. WDYT?

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you! I missed the part about the V1 spec. Following your suggestion, I added a field_serializer for TableMetadataCommonFields. This will ensure that the Snapshot pydantic object will not have the sequence-number field for V1 format

@FokkoFokko mentioned this pull request May 13, 2024
8 tasks
@kevinjqliukevinjqliu mentioned this pull request May 14, 2024
39 tasks
@kevinjqliu
Copy link
ContributorAuthor

r? @Fokko@HonahX @syun64 please take a look when you get a chance

Copy link
Contributor

@HonahXHonahX left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kevinjqliu Thanks for working on this! It looks geat.

Comment on lines 3853 to 3856
# imitates `addPreviousFile` from Java
# https://github.com/apache/iceberg/blob/8248663a2a1ffddd2664ea37b45882455466f71c/core/src/main/java/org/apache/iceberg/TableMetadata.java#L1450-L1451
metadata_log_entries=self.tbl.metadata.metadata_log+ [
MetadataLogEntry(metadata_file=self.tbl.metadata_location, timestamp_ms=self.tbl.metadata.last_updated_ms)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems this line acts more like https://github.com/apache/iceberg/blob/8a70fe0ff5f241aec8856f8091c77fdce35ad256/core/src/main/java/org/apache/iceberg/MetadataLogEntriesTable.java#L62-L66.
Just curious the reason that you mention addPreviousFile here, which seem to be more relevant when we update the metadata_log during table commit.

BTW, this reminds me that currently non-rest catalog does not update the metadata_log field during commit.

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good catch! I link the wrong code. I was trying to find all the places where the metadata log was modified

parent_snapshot_id: Optional[int] =Field(alias="parent-snapshot-id", default=None)
sequence_number: Optional[int] =Field(alias="sequence-number", default=None)
# cannot import `INITIAL_SEQUENCE_NUMBER` due to circular import
sequence_number: Optional[int] =Field(alias="sequence-number", default=0)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kevinjqliu Thanks for spotting this! We definitely need to read snapshot.sequence_number as 0 for v1. However, as we have observed in the test outcome, making sequence_number default to 0 here leads to sequence_number=0 be written to version 1 table metada's snapshots, which is not allowed by spec:

Writing v1 metadata: Snapshot field sequence-number should not be written 

I think we may need a new field_serializer in TableMetadataCommonFields class or some other ways to correct the behavior on write. WDYT?

@kevinjqliukevinjqliu requested a review from HonahXJune 24, 2024 18:35
Copy link
Contributor

@HonahXHonahX left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kevinjqliu Thanks for the quick update! Just have one minor comment for the test. Overall it looks great!

@HonahXHonahX merged commit 9cb3cd5 into apache:mainJun 26, 2024
@HonahX
Copy link
Contributor

Merged! @kevinjqliu Thanks for another great metadata table work! Thanks @corleyma @syun64 @Fokko for reviewing!

@kevinjqliukevinjqliu deleted the kevinjqliu/metadata_log_entries branch June 26, 2024 19:47
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[feat request] Add metadata_log_entries metadata table

5 participants

@kevinjqliu@HonahX@Fokko@corleyma@sungwy