Skip to content

Bulk delete - #6682

Merged
RussellSpitzer merged 12 commits into
apache:masterfrom
RussellSpitzer:BulkDelete
Mar 2, 2023
Merged

Bulk delete#6682
RussellSpitzer merged 12 commits into
apache:masterfrom
RussellSpitzer:BulkDelete

Conversation

@RussellSpitzer

Copy link
Copy Markdown
Member

Changes all Deleting Spark Actions to use FileIO Bulk Operations, adds Bulk delete to HadoopIO

The basic idea here is all of our deletes should use the bulk api or have their parallelism controlled at the FileIO level primarily. All deletes should use some parallelism by default.

…ailable
Previously deletes were handled by a per Action execution service that would be used
to parallelize single deletes. In this PR we move the responsibility of performing the
deletes and the parallelization of those deletes to the FileIO via SupportsBulkOperations.
This deprecates all methods which used to be used for doing single deletes as well as
passing executor services to Actions which delete many files.
@amogh-jahagirdar

Copy link
Copy Markdown
Contributor

Thanks a ton for closing the loop on this @RussellSpitzer ! Left some comments

@aokolnychyi

Copy link
Copy Markdown
Contributor

I am getting to this today, hopefully.

@dramaticllydramaticlly left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Would love to see this merged, thank you @RussellSpitzer

Comment threadapi/src/main/java/org/apache/iceberg/actions/DeleteOrphanFiles.java Outdated
Comment threadapi/src/main/java/org/apache/iceberg/actions/DeleteOrphanFiles.java Outdated
Comment threadapi/src/main/java/org/apache/iceberg/actions/DeleteOrphanFiles.java Outdated
Comment threadcore/src/main/java/org/apache/iceberg/hadoop/HadoopFileIO.java Outdated
@aokolnychyi

Copy link
Copy Markdown
Contributor

I agree with the overall direction but I'd try to support the existing API to avoid massive deprecation and simplify the implementation. It will be hard to test all possible scenarios.

Comment threadcore/src/main/java/org/apache/iceberg/BaseIncrementalScan.java Outdated
Comment threadapi/src/main/java/org/apache/iceberg/actions/DeleteOrphanFiles.java Outdated
Comment threadapi/src/main/java/org/apache/iceberg/actions/ExpireSnapshots.java Outdated
Comment threadapi/src/main/java/org/apache/iceberg/actions/DeleteReachableFiles.java Outdated
Comment threadapi/src/main/java/org/apache/iceberg/actions/ExpireSnapshots.java Outdated
Comment threadcore/src/main/java/org/apache/iceberg/hadoop/HadoopFileIO.java Outdated
Comment threadcore/src/main/java/org/apache/iceberg/hadoop/HadoopFileIO.java Outdated
Comment threadapi/src/main/java/org/apache/iceberg/actions/ExpireSnapshots.java Outdated
Comment threadcore/src/main/java/org/apache/iceberg/hadoop/HadoopFileIO.java Outdated
.onFailure(
(f, e) -> {
LOG.error("Failure during bulk delete on file: {} ", f, e);
failureCount.incrementAndGet();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This is going to increment the count on each failed attempt and won't be accurate. We could count the number of successfully deleted files instead and then use Iterables.size(pathsToDelete) to find how many we were supposed to delete.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

Ah I thought it was once per element

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

I'm not sure we want to go over the iterable more than once ... let me think about this

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

I double checked this, it only fires off when all retries are exhausted so it is correct as is.

scala>deftestFailure() = { varfailureCount=0Tasks.foreach("value")
.retry(3)
.onFailure((y, x: Throwable) => failureCount +=1)
.suppressFailureWhenFinished()
.run(x =>thrownewException("ohNO"))
failureCount
}
scala> testFailure()
23/03/0110:16:22WARNTasks:Retrying task after failure: ohNO
java.lang.Exception: ohNO
... 23/03/0110:16:23WARNTasks:Retrying task after failure: ohNO
java.lang.Exception: ohNO
...
23/03/0110:16:25WARNTasks:Retrying task after failure: ohNO
java.lang.Exception: ohNO
...
res21:Int=1

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

runTaskWithRetry(task, item);
succeeded.add(item);
} catch (Exceptione) {
exceptions.add(e);
if (onFailure != null) {
tryRunOnFailure(item, e);
Code in question (RunWithRetry) does all retries before hitting "onFailure"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

You are right, we overlooked it while reviewing another PR. I like it more. I'll update SparkCleanupUtil to follow this patter as well.

Comment threadcore/src/main/java/org/apache/iceberg/hadoop/HadoopFileIO.java Outdated
.suppressFailureWhenFinished()
.onFailure((file, exc) -> LOG.warn("Failed to delete file: {}", file, exc))
.run(deleteFunc::accept);
if (deleteFunc == null && table.io() instanceof SupportsBulkOperations) {

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

This is the new pattern

if (bulk)
Bulkelse {
ifnocustomdeletetable.io:: deleteIfcustomdeletecustomDelete
}

This logic is repeated in all of the actions

if (deleteFunc == null && io instanceof SupportsBulkOperations) {
summary = deleteFiles((SupportsBulkOperations) io, files);
} else {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I actually meant an empty line after DeleteSummary var but formatting here is up to you.
I like the new pattern.


if (deleteFunc == null) {
LOG.info(
"Table IO {} does not support bulk operations. Using non-bulk deletes.", table.io());

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Same here.

@aokolnychyiaokolnychyi left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

A few non-blocking nits. Looks great otherwise. Thanks, @RussellSpitzer! Feel free to merge whenever you are ready.

@RussellSpitzer

Copy link
Copy Markdown
MemberAuthor

Thanks @amogh-jahagirdar , @dramaticlly and @aokolnychyi I'll merge when tests pass. I'll do the Backport Pr's after my subsurface talk.

@RussellSpitzer
RussellSpitzer merged commit 5e40182 into apache:masterMar 2, 2023
@RussellSpitzer
RussellSpitzer deleted the BulkDelete branch March 2, 2023 17:27
RussellSpitzer added a commit to RussellSpitzer/iceberg that referenced this pull request Mar 8, 2023
aokolnychyi pushed a commit that referenced this pull request Mar 10, 2023
This change backports PR #6682 to Spark 3.2.
krvikash pushed a commit to krvikash/iceberg that referenced this pull request Mar 16, 2023
Previously deletes were handled by a per Action execution service that would be used
to parallelize single deletes. In this PR we move the responsibility of performing the
deletes and the parallelization of those deletes to the FileIO via SupportsBulkOperations.
krvikash pushed a commit to krvikash/iceberg that referenced this pull request Mar 16, 2023
sunchao pushed a commit to sunchao/iceberg that referenced this pull request May 10, 2023
Previously deletes were handled by a per Action execution service that would be used
to parallelize single deletes. In this PR we move the responsibility of performing the
deletes and the parallelization of those deletes to the FileIO via SupportsBulkOperations.
zhongyujiang pushed a commit to zhongyujiang/iceberg that referenced this pull request Apr 16, 2025
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@RussellSpitzer@amogh-jahagirdar@aokolnychyi@dramaticlly