-
Notifications
You must be signed in to change notification settings - Fork 330
Add policies for metadata compaction, orphan file removal and snapshot retention #969
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
| }, | ||
| "location": { | ||
| "type": "string", | ||
| "description": "Customized directory other than table location to look for files in." |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this should have a warning that if you specify locations other than the table base location for example s3://my-bucket instead of s3://my-bucket/my-table-location, all files not referenced by the table will purged including potentially other table files if those files are stored in the specified path. I think this aligns with best practice notes that one shouldn't store tables under the same location
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added a waning message.
| "type": "boolean", | ||
| "description": "Enable or disable orphan file removal." | ||
| }, | ||
| "older_than": { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might be easier to specify the file age for orphaned files in days instead of timestamp? I.e.
"max_orphan_file_age_in_days" : 30
instead of
"older_than": 1707315296
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1. Timestamp probably only makes sense for engines during operation runtime
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point, made the change.
| { | ||
| "version": "2025-02-03", | ||
| "enable": true, | ||
| "older_than": 1707315296, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
how about keeping all the 3 policies consistent with the format? metadata compaction and snapshot-expiry seem to follow the format:
"enable": true
"config" : {
"key1" : value1
"key2" : value2
}
But orphan file deletion has some of the properties older_than and location out side of config:
"enable": true,
"older_than": 1707315296,
"location": "s3://my-bucket/my-table-location",
"config": {
"prefix_mismatch_mode": "ignore",
"my_key": "my_value"
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The config map is used for customized properties. For example, a TMS may provide an optional feature that only a subset of tables need it.
| }, | ||
| "location": { | ||
| "type": "string", | ||
| "description": "Specifies a custom directory to search for files instead of the default table location. Use with caution—if set to a broad location (e.g., s3://my-bucket instead of s3://my-bucket/my-table-location), all unreferenced files in that path may be permanently deleted, including files from other tables. Following best practices, tables should be stored in separate locations to avoid accidental data loss." |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This hard to read in an IDE like IntelliJ as it is a single long line. Json doesn't support a way to break one line to multiple lines. This makes me think we may use the format yaml instead of json.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The alternative is just to put line breaks in the string, and then preprocess it anywhere we want to strip out the whitespace
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
put line breaks in the string
One of my versions was that :). It didn't help much, esp. in the IDE.
| "type": "number", | ||
| "description": "Specifies the maximum age (in days) for orphaned files before they are eligible for removal." | ||
| }, | ||
| "location": { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you think about making this property multi-value? This way, a user could support adding paths for multiple "namespaces".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess you don't mean namespaces but just "locations"?
I think having one policy map to one location is probably okay for now; I'm not sure if/how we plan to handle overlapping locations though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could support that. One use case is that table files might be stored in different locations based on the write.data.path and/or write.metadata.path settings. This is generally not recommended though, due to issues like it makes credential vending harder. Are there any other use cases you have in mind, @ashvina?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overlapping locations is very dangerous. No orphan file removal should happen in that case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Made it a string array type in the new commit.
| "license": "Licensed under the Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)", | ||
| "$id": "https://polaris.apache.org/schemas/policies/system/orphan-file-removal/2025-02-03.json", | ||
| "title": "Orphan File Removal Policy", | ||
| "description": "Inheritable Polaris policy schema for Iceberg table orphan file removal.", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- What does
Inheritablemean here? Polarisseems redundant, all of these are going to be Polaris schemas right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A inheritable policy means it can be applied to the under layer entities. For example, all tables under a namespace get the policies if it is assigned to the namespace.
I'm OK to remove it or keep it. Keeping it provides a complete view for anyone who read the schema, but without too much context of Polaris.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are all policies inheritable?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No. For example, column masking policy are not inheritable, which makes more sense, and also that's what most engines do.
polaris-core/src/main/resources/schemas/policies/system/snapshot-retention/2025-02-03.json
Outdated
Show resolved
Hide resolved
| @@ -0,0 +1,37 @@ | |||
| { | |||
| "license": "Licensed under the Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)", | |||
| "$id": "https://polaris.apache.org/schemas/policies/system/metadata-compaction/2025-02-03.json", | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does the JSON magically land at the location specified in the ID somehow? Or do we always need a followup PR?
Also, it looks a little funny to use dates here given that the date in the PR may not align with the date the schema actually becomes effective. In the worst case, we could merge two versions in one day. Maybe just an incrementing number is easier?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunately no. I hope I can publish it once for all based on the directory structure.
I want to keep them as the same for date as these are first batch, should be fine as nobody is using it. Once we release them at 1.0. We should follow the date schema strictly.
snazy
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Adding a note here as we might need a couple more days to review this one. Please do not merge yet.
@snazy, this PR was filed 10 days ago, and it's a small one. Can you review it in a timely manner? |
|
My concern with this change, and it's quickly merged predecessor #945, is that AFAIK we don't have a consensus on policies in general. And specifically where these files should live, how those are accessed by users and how those are used by implementations. I don't object on draft-code and draft-PRs, but I think that we should have a consensus first on those rather big topics before merging anything. Sure, this change is rather "small" or "innocent", but the topic is big. |
|
I believe we have reached a general consensus on policy management:
[1] https://docs.google.com/document/d/1kIiVkFFg9tPa5SH70b9WwzbmclrzH3qWHKfCKXw5lbs/edit?tab=t.0 |
| "type": "boolean", | ||
| "description": "Enable or disable orphan file removal." | ||
| }, | ||
| "max_orphan_file_age_in_days": { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@flyrain this also struggles me a bit, remove orphan policy can be even expressed in more than in just file age. We don't we opt for the config key similar to the other policies?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove orphan policy can be even expressed in more than in just file age.
Can you name them? We can put them into schema if they are commonly used, otherwise, the config map would be the best place to be.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd vote for the config map
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If no extra field is suggested, we could keep it as is.
(Not sure how the linked google doc is related to this PR) The points I raised are about:
I propose to move the work to a feature branch and go from there. |
|
Update the doc link.
It's a common and recommended way to break a big feature into multiple small PRs, which not only makes the process iterating faster, but also improve review/code quality. A separate branch is only necessary when a feature introduces breaking changes, which is not the case for this PR.
I'm surprised by this claim. It's a common practice to put non-code files in the dir |
No description provided.