-
Notifications
You must be signed in to change notification settings - Fork 2.5k
[HUDI-3421]Pending clustering may break AbstractTableFileSystemView#getxxBaseFile() #4810
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
Changes from 4 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||
|---|---|---|---|---|
|
|
@@ -380,6 +380,19 @@ protected boolean isBaseFileDueToPendingCompaction(HoodieBaseFile baseFile) { | |||
| && baseFile.getCommitTime().equals(compactionWithInstantTime.get().getKey()); | ||||
| } | ||||
|
|
||||
| /** | ||||
| * With async clustering, it is possible to see partial/complete base-files due to inflight-clustering, Ignore those | ||||
| * base-files. | ||||
| * | ||||
| * @param baseFile base File | ||||
| */ | ||||
| protected boolean isBaseFileDueToPendingClustering(HoodieBaseFile baseFile) { | ||||
| List<String> pendingReplaceInstants = | ||||
| metaClient.getActiveTimeline().filterPendingReplaceTimeline().getInstants().map(HoodieInstant::getTimestamp).collect(Collectors.toList()); | ||||
|
|
||||
| return !pendingReplaceInstants.isEmpty() && pendingReplaceInstants.contains(baseFile.getCommitTime()); | ||||
| } | ||||
|
|
||||
| /** | ||||
| * Returns true if the file-group is under pending-compaction and the file-slice' baseInstant matches compaction | ||||
| * Instant. | ||||
|
|
@@ -492,7 +505,7 @@ public final Stream<HoodieBaseFile> getLatestBaseFilesBeforeOrOn(String partitio | |||
| .map(fileGroup -> Option.fromJavaOptional(fileGroup.getAllBaseFiles() | ||||
| .filter(baseFile -> HoodieTimeline.compareTimestamps(baseFile.getCommitTime(), HoodieTimeline.LESSER_THAN_OR_EQUALS, maxCommitTime | ||||
| )) | ||||
| .filter(df -> !isBaseFileDueToPendingCompaction(df)).findFirst())) | ||||
| .filter(df -> !isBaseFileDueToPendingCompaction(df) && !isBaseFileDueToPendingClustering(df)).findFirst())) | ||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Shouldn't the caller pass in the right
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. When inflight clustering at the earliest instant of the active timeline, this bug could happen(based on follow code). So that no matter what maxCommitTime is, we can' t filter it out. hudi/hudi-common/src/main/java/org/apache/hudi/common/model/HoodieFileGroup.java Line 120 in 55ecbc6
|
||||
| .filter(Option::isPresent).map(Option::get) | ||||
| .map(df -> addBootstrapBaseFileIfPresent(new HoodieFileGroupId(partitionPath, df.getFileId()), df)); | ||||
| } finally { | ||||
|
|
@@ -511,7 +524,7 @@ public final Option<HoodieBaseFile> getBaseFileOn(String partitionStr, String in | |||
| } else { | ||||
| return fetchHoodieFileGroup(partitionPath, fileId).map(fileGroup -> fileGroup.getAllBaseFiles() | ||||
| .filter(baseFile -> HoodieTimeline.compareTimestamps(baseFile.getCommitTime(), HoodieTimeline.EQUALS, | ||||
| instantTime)).filter(df -> !isBaseFileDueToPendingCompaction(df)).findFirst().orElse(null)) | ||||
| instantTime)).filter(df -> !isBaseFileDueToPendingCompaction(df) && !isBaseFileDueToPendingClustering(df)).findFirst().orElse(null)) | ||||
| .map(df -> addBootstrapBaseFileIfPresent(new HoodieFileGroupId(partitionPath, fileId), df)); | ||||
| } | ||||
| } finally { | ||||
|
|
@@ -547,7 +560,7 @@ public final Stream<HoodieBaseFile> getLatestBaseFilesInRange(List<String> commi | |||
| .filter(fileGroup -> !isFileGroupReplacedBeforeAny(fileGroup.getFileGroupId(), commitsToReturn)) | ||||
| .map(fileGroup -> Pair.of(fileGroup.getFileGroupId(), Option.fromJavaOptional( | ||||
| fileGroup.getAllBaseFiles().filter(baseFile -> commitsToReturn.contains(baseFile.getCommitTime()) | ||||
| && !isBaseFileDueToPendingCompaction(baseFile)).findFirst()))).filter(p -> p.getValue().isPresent()) | ||||
| && !isBaseFileDueToPendingCompaction(baseFile) && !isBaseFileDueToPendingClustering(baseFile)).findFirst()))).filter(p -> p.getValue().isPresent()) | ||||
| .map(p -> addBootstrapBaseFileIfPresent(p.getKey(), p.getValue().get())); | ||||
| } finally { | ||||
| readLock.unlock(); | ||||
|
|
@@ -563,7 +576,7 @@ public final Stream<HoodieBaseFile> getAllBaseFiles(String partitionStr) { | |||
| return fetchAllBaseFiles(partitionPath) | ||||
| .filter(df -> !isFileGroupReplaced(partitionPath, df.getFileId())) | ||||
| .filter(df -> visibleCommitsAndCompactionTimeline.containsOrBeforeTimelineStarts(df.getCommitTime())) | ||||
| .filter(df -> !isBaseFileDueToPendingCompaction(df)) | ||||
| .filter(df -> !isBaseFileDueToPendingCompaction(df) && !isBaseFileDueToPendingClustering(df)) | ||||
| .map(df -> addBootstrapBaseFileIfPresent(new HoodieFileGroupId(partitionPath, df.getFileId()), df)); | ||||
| } finally { | ||||
| readLock.unlock(); | ||||
|
|
@@ -953,7 +966,7 @@ public Stream<HoodieBaseFile> fetchLatestBaseFiles(final String partitionPath) { | |||
|
|
||||
| protected Option<HoodieBaseFile> getLatestBaseFile(HoodieFileGroup fileGroup) { | ||||
| return Option | ||||
| .fromJavaOptional(fileGroup.getAllBaseFiles().filter(df -> !isBaseFileDueToPendingCompaction(df)).findFirst()); | ||||
| .fromJavaOptional(fileGroup.getAllBaseFiles().filter(df -> !isBaseFileDueToPendingCompaction(df) && !isBaseFileDueToPendingClustering(df)).findFirst()); | ||||
| } | ||||
|
|
||||
| /** | ||||
|
|
||||
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.
Can we not reuse
isPendingClusteringScheduledForFileId()orgetPendingClusteringInstant()? So, we maintain a map offgIdToPendingClusteringwhich supports various methods. If we can reuse one of them then we need to call active timeline.Uh oh!
There was an error while loading. Please reload this page.
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.
Emmm, maybe we can't use
fgIdToPendingClusteringto do filter here.Because the files recorded in
fgIdToPendingClusteringare committed file and need to be seen.What we need to filter here are the in-flight uncommitted data files produced by clustering job.
So that we need to know the instant time of
xxxx.replacecommit.requestedorxxxx.replacecommit.inflightand use it to filter out uncommitted clustering creating data files instead of the files which need to be clustering.