Skip to content

Core: cleanExpiredMetadata cleans unreferenced encryption keys - #18102

Open
Hugo-WB wants to merge 6 commits into
apache:mainfrom
Hugo-WB:cleanup-encryption-keys-when-cleanup-metadata
Open

Hugo-WB wants to merge 6 commits into
apache:mainfrom
Hugo-WB:cleanup-encryption-keys-when-cleanup-metadata

Conversation

@Hugo-WB

@Hugo-WB Hugo-WB commented Sep 14, 2026

Copy link
Copy Markdown
Contributor

Fixes part 2 of: #16352

The implementation constructs a set of "reachable"/"referenced" encryption keys-ids. Any key that is not referenced, we delete.

A key can be referenced in 2 places:

  • In the snapshot list. Under key-id for every snapshot. This references the key that was used to encrypt the manifest list for that snapshot
  • In the encrypted-by-id for another encryption key.

@Hugo-WB
Hugo-WB force-pushed the cleanup-encryption-keys-when-cleanup-metadata branch from fda6a74 to f052872 Compare September 14, 2026 15:24
Comment on lines +284 to +290

Set<String> encryptionKeysToRemove =
base.encryptionKeys().stream()
.map(EncryptedKey::keyId)
.filter(keyId -> !reachableKeyIds.contains(keyId))
.collect(Collectors.toSet());
encryptionKeysToRemove.forEach(updatedMetaBuilder::removeEncryptionKey);

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

In a similar line to: #12670

I see 2 arguments to introduce/make RemoveEncryptionKey -> RemoveEncryptionKeys. (Bulk).

Performance: We've ran into performance issues server side when expiring 150k+ snapshots in a non-bulk way. Bulking the changes fixed it. Although I don't expect RemoveEncryptionKey to be as expensive of a call as RemoveSnapshot. So perhaps a premature optimisation.
Consistency: Consistent with the other RemovePartitionSpecs and RemoveSchemas
Curious to hear thoughts.

Comment on lines +247 to +251
Set<String> reachableKeyIds =
base.encryptionKeys().stream()
.map(EncryptedKey::encryptedById)
.filter(Objects::nonNull)
.collect(Collectors.toCollection(Sets::newConcurrentHashSet));

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

For my own understanding. Couldn't figure out why encryptedById is nullable. In what cases do we expect this to be null?

key -> referencedKeyIds.contains(key.keyId()) || keyEncryptionKeyId.equals(key.keyId()))
.forEach(builder::addEncryptionKey);
return builder.build();
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Need this in HiveTableOperations because we currently add all encryption keys from the encryptionManager (constructed from old metadata), and we add it to the new metadata.

This method only adds the encryption keys that are still referenced within the given metadata.

@Hugo-WB
Hugo-WB marked this pull request as ready for review September 14, 2026 15:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant