Skip to content

Manifests with all-DELETED entries are not dropped during manifest list construction #1393

Description

@debugmiller

Apache Iceberg version

main (development)

Please describe the bug 🐞

Manifests with only DELETEs are not pruned when creating new snapshots, causing large numbers of extra manifests to accumulate.

overwriteFiles.existingManifests iterates each parent snapshot manifest with discardDeleted=true, which skips entries with status=DELETED. For a manifest where every entry is DELETED, the iterator yields nothing (since foundDeletedCount=0 and len(notDeleted)=0) which the code interprets as "manifest was unaffected by this operation" and retains instead of dropping it at

if foundDeletedCount == 0 {
existingFiles = append(existingFiles, m)
continue
}

I think the fix is small, at L190, only retain the manifest if the iterator actually found live entries:

 if foundDeletedCount == 0 {
-    existingFiles = append(existingFiles, m)
+    if len(notDeleted) > 0 {
+        existingFiles = append(existingFiles, m)
+    }
+    // len(notDeleted)==0: all entries are DELETED and were skipped by
+    // discardDeleted=true. The manifest is empty — drop it.
     continue
 }

We observed this when using overwrite on small tables, which produces one DELETE manifest via deletedFilesManifests. Since these are never pruned, they accumulate: after N overwrites the current snapshot's manifest list contains N all-DELETED manifests alongside the live data manifests, causing a growing set of unnecessary snapshots.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions