eugene-polozhenkov opened a new pull request, #26158: URL: https://github.com/apache/pulsar/pull/26158
Fixes #26157 ### Motivation When using Oxia as the metadata backend, `markLedgerReplicated()` in `PulsarLedgerUnderreplicationManager` leaves orphaned intermediate nodes in the under-replication (UR) tree after every ledger is successfully replicated. `OxiaMetadataStore.doStorePut()` calls `createParents()` to explicitly create up to 4 intermediate path entries for every UR leaf (Oxia is a flat key-value store; parent nodes must be created explicitly). However, the hierarchy cleanup in `markLedgerReplicated()` was gated on an `instanceof` check that excluded `OxiaMetadataStore`, so those parent nodes were never deleted. Additionally, the inner catch block only handled ZK's `KeeperException.NotEmptyException`. Oxia threw a plain `MetadataStoreException` for the same "node has children" condition, causing a spurious `log.warn()` on every successfully-replicated ledger. Over time, orphaned nodes accumulate proportionally to replication activity and cause `getLedgerToRereplicateFromHierarchy()` to traverse empty subtrees on every replication poll, driving sustained elevated metadata store list ops. ### Modifications - Add `MetadataStoreException.NotEmptyException` to the metadata API, consistent with the existing `NotFoundException` / `BadVersionException` pattern - Map ZK's `NOTEMPTY` error code to `NotEmptyException` in `ZKMetadataStore.getException()` (was falling through to `default`) - Throw `NotEmptyException` from `OxiaMetadataStore.storeDelete()` instead of a plain `MetadataStoreException`, so both backends surface the same exception type - Add `OxiaMetadataStore` to the `instanceof` guard in `markLedgerReplicated()` - Replace the ZK-specific `KeeperException.NotEmptyException` check with a clean `instanceof MetadataStoreException.NotEmptyException` check ### Verifying this change This change added tests and can be verified as follows: - Extended `testMarkReplicatedDeletesEmptyParentNodes` to run against all distributed metadata backends (`dataProvider = "distributedImpl"`: ZK + Oxia) instead of ZK-only (`dataProvider = "zkImpls"`). The test asserts that all 4 parent hierarchy nodes are deleted after `markLedgerReplicated()` completes. ### Does this pull request potentially affect one of the following parts: - [ ] Dependencies (add or upgrade a dependency) - [x] The public API — added `MetadataStoreException.NotEmptyException` (new subclass, backward-compatible) - [ ] The schema - [ ] The default values of configurations - [ ] The threading model - [ ] The binary protocol - [ ] The REST endpoints - [ ] The admin CLI options - [ ] The metrics - [ ] Anything that affects deployment -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
