-
Notifications
You must be signed in to change notification settings - Fork 998
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
[core] Support commit isolation level #3805
base: master
Are you sure you want to change the base?
Conversation
@JingsongLi Hi. Can you check this? Tks. |
@@ -238,6 +238,9 @@ default boolean tryToWriteAtomic(Path path, String content) throws IOException { | |||
try { | |||
writeFile(tmp, content, false); | |||
success = rename(tmp, path); | |||
} catch (IOException e) { | |||
// try check once | |||
success = exists(path) && !exists(tmp); |
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.
After throwing an IO exception, it's a good idea to check it again.Currently, this checking strategy is not fully applicable to object storage systems and may result in false positives.However, as the industry evolves, object storage systems are starting to support mutex operations.In the long run, I think we need to add check operations.
However, please note that we can only check for IO exceptions after they are caught, because they are thrown by the server, and we should not do any checking for client-side exceptions.
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 can be a separate PR?
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 can be a separate PR?
sure
// otherwise, we throw an exception. | ||
if (!success && useSerializableIsolation) { | ||
throw new CommitFailedException(e.getMessage(), e); | ||
} |
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 the rename operation succeeds, we should ignore any exceptions thrown after that.
if (useSerializableIsolation && !useLock) { | ||
// If the useSerializableIsolation is turned on,And we not use lock service, | ||
// we will remove all HINTs,as it may provide incorrect information. | ||
snapshotManager.removeSnapshotEarliestHint(); |
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 Serializable is turned on, and the locking service is not used, we should delete all HINT files, as they are always unreliable.
@@ -284,7 +284,7 @@ public void fastForward(String branchName) { | |||
.collect(Collectors.toList()); | |||
|
|||
// Delete latest snapshot hint | |||
snapshotManager.deleteLatestHint(); | |||
snapshotManager.removeSnapshotLatestHint(); |
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 previous method name wasn't clear enough, so I've replaced it
snapshots.add(snapshotManager.snapshot(id)); | ||
if (snapshotManager.snapshotExists(id)) { | ||
snapshots.add(snapshotManager.snapshot(id)); | ||
} |
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 a dirty commit occurs, the previous processing logic throws an exception, which affects the running of the test case.
} | ||
return committed; | ||
} catch (Exception e) { | ||
throw new CommitStateUnknownException(e.getMessage(), e); |
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 any exception occurs during the commit process, we should throw a CommitStateUnknownException and not clean up any data.
throw e; | ||
} catch (DirtyCommitException e) { | ||
// We need to clean up all the metadata information generated by this commit. | ||
cleanUpTmpManifests( |
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.
Maybe cleaning up dirty commits will interfere with the creation of branch/tag. But since we are always cleaning up snapshots that exceed snapshot.num-retained.max
.This shouldn't have much of an impact. After all, if we keep a snapshot that matches the characteristics of a dirty commit, we may never find the right time to delete it.
latestSnapshotIdAfterCommit > maxSaveSnapshotNum | ||
? latestSnapshotIdAfterCommit - maxSaveSnapshotNum | ||
: -1; | ||
fastFailIfDirtyCommit(newSnapshotId, waterMark, latestSnapshotIdAfterCommit); |
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.
Here we need to add the logic of whether the snapshot belongs to a branch or tag.PR 3787 (#3787) provides this functionality, I'm not sure if I need to merge it with that PR?
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.
For now I'm starting by porting some of the code from 3787 to the current PR.
Thanks @BsoBird ! I need time to look this, next week will give your feedback. |
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.
Hi @BsoBird , I have no idea why the changes is so big...
In my imagination, we only need one branch to complete the new commit mode.
Please note that this is the core code, and any modifications may result in serious consequences.
Purpose
For the file system catalog, there are many situations where we need to support stricter commit policies.This is especially true for third-party databases that use paimon as their underlying storage.
We define the commit isolation level option to control the behavior.
Linked issue: none
Tests
See FileStoreCommitTest.java.
API and Format
None
Documentation
Glossary:
Flow chat (use strict mode):