heesung-sohn opened a new issue, #4668:
URL: https://github.com/apache/bookkeeper/issues/4668

   **BUG REPORT**
   
   ***Describe the bug***
   bk recover command throws BKLedgerFencedException.
   
   bin/bookkeeper shell recover 
pulsar-mini-bookie-4.pulsar-mini-bookie.pulsar.svc.cluster.local:3181 
   
   ```
   bookie:pulsar-mini-bookie-2.pulsar-mini-bookie.pulsar.svc.cluster.local:3181 
rc:EOK, ledger:20:entry:110:entryLength:23886
   2025-09-25T20:09:23,397+0000 [BookKeeperClientWorker-OrderedExecutor-3-0] 
DEBUG org.apache.bookkeeper.proto.PerChannelBookieClient - Got Add response 
from 
bookie:pulsar-mini-bookie-0.pulsar-mini-bookie.pulsar.svc.cluster.local:3181 
rc:EFENCED, ledger:7:entry:3900
   2025-09-25T20:09:23,397+0000 [BookKeeperClientWorker-OrderedExecutor-3-0] 
ERROR org.apache.bookkeeper.client.LedgerFragmentReplicator - BK error writing 
entry for ledgerId: 7, entryId: 3900, bookie: 
pulsar-mini-bookie-0.pulsar-mini-bookie.pulsar.svc.cluster.local:3181
   org.apache.bookkeeper.client.BKException$BKLedgerFencedException: Ledger has 
been fenced off. Some other client must have opened it to read
        at org.apache.bookkeeper.client.BKException.create(BKException.java:99) 
~[org.apache.bookkeeper-bookkeeper-server-4.16.7.jar:4.16.7]
        at 
org.apache.bookkeeper.client.LedgerFragmentReplicator$2.writeComplete(LedgerFragmentReplicator.java:357)
 ~[org.apache.bookkeeper-bookkeeper-server-4.16.7.jar:4.16.7]
        at 
org.apache.bookkeeper.proto.PerChannelBookieClient$AddCompletion.writeComplete(PerChannelBookieClient.java:2200)
 ~[org.apache.bookkeeper-bookkeeper-server-4.16.7.jar:4.16.7]
        at 
org.apache.bookkeeper.proto.PerChannelBookieClient$AddCompletion.handleResponse(PerChannelBookieClient.java:2257)
 ~[org.apache.bookkeeper-bookkeeper-server-4.16.7.jar:4.16.7]
        at 
org.apache.bookkeeper.proto.PerChannelBookieClient$AddCompletion.handleV2Response(PerChannelBookieClient.java:2236)
 ~[org.apache.bookkeeper-bookkeeper-server-4.16.7.jar:4.16.7]
        at 
org.apache.bookkeeper.proto.PerChannelBookieClient$ReadV2ResponseCallback.run(PerChannelBookieClient.java:1407)
 ~[org.apache.bookkeeper-bookkeeper-server-4.16.7.jar:4.16.7]
        at 
org.apache.bookkeeper.common.util.SingleThreadExecutor.safeRunTask(SingleThreadExecutor.java:137)
 ~[org.apache.bookkeeper-bookkeeper-common-4.16.7.jar:4.16.7]
        at 
org.apache.bookkeeper.common.util.SingleThreadExecutor.run(SingleThreadExecutor.java:107)
 ~[org.apache.bookkeeper-bookkeeper-common-4.16.7.jar:4.16.7]
        at 
io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
 ~[io.netty-netty-common-4.1.122.Final.jar:4.1.122.Final]
        at java.lang.Thread.run(Thread.java:840) ~[?:?]
   ```
   
   This ledger fenced exception during recovery can be caused by a racing 
condition between admin ledger recovery and bk’s over-replicated-ledger gc. If 
admin ledger recovery is slow, and if the over-replicated-ledger gc happens to 
clean recovering ledgers, this fenced exception could hit and further block the 
recovery.
   
   
   To mitigate the issue, we could restart the destination bookies. Also, we 
could consider disabling this over-replicated-ledger gc during the decommission 
process(by gcOverreplicatedLedgerWaitTime=-1).
   
   
   ***To Reproduce***
   
   Steps to reproduce the behavior:
   
   pulsar cluster with e.g. 5 bookies, ES=WQ=2 with the following configs.
   ```
   bookkeeper:
     podMonitor:
       enabled: false
     replicaCount: 5
     configData:
       # minimal memory use for bookkeeper
       # 
https://bookkeeper.apache.org/docs/reference/config#db-ledger-storage-settings
       dbStorage_writeCacheMaxSizeMb: "32"
       dbStorage_readAheadCacheMaxSizeMb: "32"
       dbStorage_rocksDB_writeBufferSizeMB: "8"
       dbStorage_rocksDB_blockCacheSize: "8388608"
       httpServerEnabled: "true"
       gcWaitTime: "60000"
       gcOverreplicatedLedgerWaitTime: "30000"
       openLedgerRereplicationGracePeriod: "100"
   
   broker:
     podMonitor:
       enabled: false
     replicaCount: 2
     configData:
       ## Enable `autoSkipNonRecoverableData` since bookkeeper is running
       ## without persistence
       autoSkipNonRecoverableData: "true"
       # storage settings
       managedLedgerDefaultEnsembleSize: "2"
       managedLedgerDefaultWriteQuorum: "2"
       managedLedgerDefaultAckQuorum: "2"
       managedLedgerMaxEntriesPerLedger: "50"
       managedLedgerMinLedgerRolloverTimeMinutes: "1"
   ```
   
   
   ```
   # producer
   bin/pulsar-admin tenants create my-tenant
   bin/pulsar-admin namespaces create my-tenant/my-ns
   bin/pulsar-admin namespaces set-retention my-tenant/my-ns --size -1 --time -1
   bin/pulsar-admin topics create-partitioned-topic 
persistent://my-tenant/my-ns/test-topic2 -p 10
   bin/pulsar-admin topics list my-tenant/my-ns
   bin/pulsar-admin namespaces get-retention my-tenant/my-ns
   bin/pulsar-perf produce persistent://my-tenant/my-ns/test-topic2 -r 10000
   
   
   # recover command on bk-4
   curl -X PUT -H "Content-Type: application/json" -d '{"readOnly": true}' 
http://localhost:8000/api/v1/bookie/state/readonly
   bin/bookkeeper shell recover 
pulsar-mini-bookie-4.pulsar-mini-bookie.pulsar.svc.cluster.local:3181  -rate 
1000000
   ```
   
   This will simulate this case:
   
   t0: L1.metadata = F1:[bk1,bk3], F2:[bk1,bk3]. L1 is replicated to bk1 and 
bk3 and has two fragments F1 and F2.
   t1: admin recover started with src bk3(to decommission bk3).
   t2: admin recover copied L1:F1 to bk2.
   t3: bk2 over-replicated cleanup kicked-in (timeout by 
gcOverreplicatedLedgerWaitTime)
   t4: bk2 sees L1 in its local active ledger list but the L1.metadata still 
shows L1.F1 ensemble is [bk1,bk3] (recovery ledger copy and metadata update are 
NOT transactional).
   t5: bk2 removed L1 locally as it thinks that L1 is over-replicated on bk2.
   t6: bk2 put L1 in recentlyFencedAndDeletedLedgers at 
markIfConflictWritingOccurs (ledgerDescriptor.isFenced() throws exception 
because [we remove the ledger index 
first.](https://github.com/apache/bookkeeper/blob/branch-4.17/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/storage/ldb/SingleDirectoryDbLedgerStorage.java#L938)
 )
   t7: the admin recover continued and tried to copy L1:F2 to bk2. It hit the 
ledger fenced exception from recentlyFencedAndDeletedLedgers check(L1).
   
   
   
   ***Expected behavior***
   The bk recover command finishes without exception.
   
   
   ***Screenshots***
   
   
   ***Additional context***
   
   


-- 
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]

Reply via email to