This is an automated email from the ASF dual-hosted git repository.

merlimat pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/pulsar.git


The following commit(s) were added to refs/heads/master by this push:
     new 8d5cac607646 [fix][metadata] Fix orphaned UR parent nodes not cleaned 
up with Oxia metadata backend (#26158)
8d5cac607646 is described below

commit 8d5cac607646ccda183373ad7b31e6ffb7e13836
Author: Eugene Polozhenkov <[email protected]>
AuthorDate: Tue Jul 7 15:50:12 2026 -0400

    [fix][metadata] Fix orphaned UR parent nodes not cleaned up with Oxia 
metadata backend (#26158)
    
    Co-authored-by: ievgenpolozhenkov <[email protected]>
---
 .../pulsar/metadata/api/MetadataStoreException.java      |  8 ++++++++
 .../bookkeeper/PulsarLedgerUnderreplicationManager.java  | 16 +++++++++++-----
 .../pulsar/metadata/impl/oxia/OxiaMetadataStore.java     |  2 +-
 .../bookkeeper/LedgerUnderreplicationManagerTest.java    |  4 ++--
 4 files changed, 22 insertions(+), 8 deletions(-)

diff --git 
a/pulsar-metadata/src/main/java/org/apache/pulsar/metadata/api/MetadataStoreException.java
 
b/pulsar-metadata/src/main/java/org/apache/pulsar/metadata/api/MetadataStoreException.java
index 898832a18986..76649f08175b 100644
--- 
a/pulsar-metadata/src/main/java/org/apache/pulsar/metadata/api/MetadataStoreException.java
+++ 
b/pulsar-metadata/src/main/java/org/apache/pulsar/metadata/api/MetadataStoreException.java
@@ -172,6 +172,14 @@ public class MetadataStoreException extends IOException {
         }
     }
 
+    public static class NotEmptyException extends MetadataStoreException {
+        private static final long serialVersionUID = 1L;
+
+        public NotEmptyException(String path) {
+            super("Key '" + path + "' has children");
+        }
+    }
+
     public static MetadataStoreException unwrap(Throwable t) {
         if (t instanceof MetadataStoreException) {
             return (MetadataStoreException) t;
diff --git 
a/pulsar-metadata/src/main/java/org/apache/pulsar/metadata/bookkeeper/PulsarLedgerUnderreplicationManager.java
 
b/pulsar-metadata/src/main/java/org/apache/pulsar/metadata/bookkeeper/PulsarLedgerUnderreplicationManager.java
index 1c9648af175b..d1b299848881 100644
--- 
a/pulsar-metadata/src/main/java/org/apache/pulsar/metadata/bookkeeper/PulsarLedgerUnderreplicationManager.java
+++ 
b/pulsar-metadata/src/main/java/org/apache/pulsar/metadata/bookkeeper/PulsarLedgerUnderreplicationManager.java
@@ -68,6 +68,7 @@ import org.apache.pulsar.metadata.api.extended.CreateOption;
 import org.apache.pulsar.metadata.api.extended.MetadataStoreExtended;
 import org.apache.pulsar.metadata.impl.DualMetadataStore;
 import org.apache.pulsar.metadata.impl.ZKMetadataStore;
+import org.apache.pulsar.metadata.impl.oxia.OxiaMetadataStore;
 import org.apache.zookeeper.KeeperException;
 
 @CustomLog
@@ -434,7 +435,8 @@ public class PulsarLedgerUnderreplicationManager implements 
LedgerUnderreplicati
                 store.delete(getUrLedgerPath(ledgerId), 
Optional.of(l.getLedgerNodeVersion()))
                         .get(BLOCKING_CALL_TIMEOUT, MILLISECONDS);
                 if (store instanceof ZKMetadataStore
-                        || store instanceof DualMetadataStore) {
+                        || store instanceof DualMetadataStore
+                        || store instanceof OxiaMetadataStore) {
                     try {
                         // clean up the hierarchy
                         String[] parts = getUrLedgerPath(ledgerId).split("/");
@@ -452,10 +454,14 @@ public class PulsarLedgerUnderreplicationManager 
implements LedgerUnderreplicati
                         // It's safe to ignore, it simply means another
                         // ledger in the same hierarchy has been marked as
                         // underreplicated.
-                        if (ee.getCause() instanceof MetadataStoreException && 
ee.getCause().getCause()
-                                instanceof KeeperException.NotEmptyException) {
-                            //do nothing.
-                        } else {
+                        // Oxia raises NotEmptyException directly; ZK wraps
+                        // KeeperException.NotEmptyException inside a 
MetadataStoreException.
+                        boolean isNotEmpty =
+                                ee.getCause() instanceof 
MetadataStoreException.NotEmptyException
+                                || (ee.getCause() instanceof 
MetadataStoreException
+                                        && ee.getCause().getCause()
+                                                instanceof 
KeeperException.NotEmptyException);
+                        if (!isNotEmpty) {
                             log.warn().exception(ee).log("Error deleting 
underreplicated ledger parent node");
                         }
                     }
diff --git 
a/pulsar-metadata/src/main/java/org/apache/pulsar/metadata/impl/oxia/OxiaMetadataStore.java
 
b/pulsar-metadata/src/main/java/org/apache/pulsar/metadata/impl/oxia/OxiaMetadataStore.java
index 336c1d942ffa..ed1bc9c80a16 100644
--- 
a/pulsar-metadata/src/main/java/org/apache/pulsar/metadata/impl/oxia/OxiaMetadataStore.java
+++ 
b/pulsar-metadata/src/main/java/org/apache/pulsar/metadata/impl/oxia/OxiaMetadataStore.java
@@ -187,7 +187,7 @@ public class OxiaMetadataStore extends 
AbstractMetadataStore {
                         children -> {
                             if (!children.isEmpty()) {
                                 return CompletableFuture.failedFuture(
-                                        new MetadataStoreException("Key '" + 
path + "' has children"));
+                                        new 
MetadataStoreException.NotEmptyException(path));
                             } else {
                                 Set<DeleteOption> delOption = 
deleteOptions(opts, expectedVersion);
                                 CompletableFuture<Boolean> result = 
client.delete(path, delOption);
diff --git 
a/pulsar-metadata/src/test/java/org/apache/pulsar/metadata/bookkeeper/LedgerUnderreplicationManagerTest.java
 
b/pulsar-metadata/src/test/java/org/apache/pulsar/metadata/bookkeeper/LedgerUnderreplicationManagerTest.java
index 205d617c4aca..a35e60dec9bc 100644
--- 
a/pulsar-metadata/src/test/java/org/apache/pulsar/metadata/bookkeeper/LedgerUnderreplicationManagerTest.java
+++ 
b/pulsar-metadata/src/test/java/org/apache/pulsar/metadata/bookkeeper/LedgerUnderreplicationManagerTest.java
@@ -299,8 +299,8 @@ public class LedgerUnderreplicationManagerTest extends 
BaseMetadataStoreTest {
         assertEquals(l, lB.get(), "Should be the ledger I marked");
     }
 
-    @Test(dataProvider = "zkImpls", timeOut = 10000)
-    public void testZkMetasStoreMarkReplicatedDeleteEmptyParentNodes(String 
provider, Supplier<String> urlSupplier)
+    @Test(dataProvider = "distributedImpl", timeOut = 10000)
+    public void testMarkReplicatedDeletesEmptyParentNodes(String provider, 
Supplier<String> urlSupplier)
             throws Exception {
         methodSetup(urlSupplier);
 

Reply via email to