Tiered storage dispatch loop loses message buffers and NPEs when CQ/commitlog entries expire mid-batch
I maintainer di solito rispondono entro 1 giorno
Valutazione
- Difficoltà
- 4/5
- Tempo stimato
- 1-2 giorni
- Idoneità per principianti
- 50/100
- Tipo di issue
- Bug
- Chiarezza
- Specificata chiaramente
- Stato di attività
- Attiva
- Stack tecnologico
- java
- Ambito
- backend, distributed-systems
Direzione di ricerca
Start in MessageStoreDispatcherImpl#doScheduleDispatch and trace the group-commit append loop, GroupCommitContext#release(), and the paths that call commitAsync or constructIndexFile. Check how missing CQ units or message buffers and a failed consume-queue append affect the collected buffers. Done means dispatch handles these cases without an NPE or leaked mapped-buffer references; the issue does not name a test to run.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Background
MessageStoreDispatcherImpl#doScheduleDispatch is the tiered-storage dispatch loop. Before entering the group-commit append loop it preflights the first offset and guards both lookups (added by #8965 / issue #8955, which fixed the dispatch thread exiting on NPE):
CqUnit cqUnit = consumeQueue.get(currentOffset);
if (cqUnit == null) { log.warn(...); return ...completedFuture(false); }
SelectMappedBufferResult message = defaultStore.selectOneMessageByOffset(cqUnit.getPos(), cqUnit.getSize());
if (message == null) { log.warn(...); return ...completedFuture(false); }
However, the append loop that follows re-fetches the CQ unit and the message for every subsequent offset without any of those guards:
for (; offset < targetOffset; offset++) {
cqUnit = consumeQueue.get(offset);
bufferSize += cqUnit.getSize(); // NPE if cqUnit == null
...
message = defaultStore.selectOneMessageByOffset(cqUnit.getPos(), cqUnit.getSize());
appendingBufferList.add(message);
AppendResult result = flatFile.appendCommitLog(message); // NPE/garbage if message == null
...
}
Problem
-
Mid-loop NPE.
ConsumeQueueInterface#getreturns null once the consume queue has been truncated past the requested offset, andselectOneMessageByOffsetreturns null once the commitlog data has been deleted (expired files). Both events happen through the ordinary expiry sweeps while the dispatcher is catching up (e.g. after a downtime longer than the file retention). The preflight only proves the first offset of the batch is still there; the batch spans up totieredStoreGroupCommitCountmore offsets, so the lookups can fail inside the loop. The resulting NPE escapesdoScheduleDispatch(onlyConsumeQueueExceptionis caught there). -
Message buffer leak. Every
SelectMappedBufferResultfetched inside the loop is added toappendingBufferListand is only ever released throughGroupCommitContext#release(). When the loop dies with the NPE above, the context is never constructed, so every buffer fetched before the failing offset leaks itsMappedFilereference.The same leak exists on a non-exceptional path: if
appendCommitLogreturnsSUCCESSbut the followingappendConsumeQueuefails on the first message, the loop breaks withappendingBufferListnon-empty anddispatchRequestListempty. The context is built, but theif (!dispatchRequestList.isEmpty())block — the only place that hands it tocommitAsync/constructIndexFile, both of which release it — never runs. The context is silently dropped and its buffers leak.
Impact
- Repeated mapped-buffer/reference leaks on queues whose data expires while dispatch lags, and on flat files that fail a consume-queue append after a successful commitlog append — eventually holding expired commitlog files from being cleaned.
- The NPE aborts the current dispatch round for the queue (the dispatcher thread itself survives because
dispatch()catchesThrowable), so dispatch progress depends on the next cycle re-failing the preflight instead of degrading gracefully.
Suggestion
Mirror the preflight guards inside the loop (break on a missing CQ unit or message so the partial batch still commits and the context is still released), and release the context when nothing was appended to the consume queue so no code path will consume it.
- Lingua principale
- Java
- Stelle
- 22.7k
- Fork
- 12k
- Merge medio
- 4g 20h
- PR unite (30g)
- 11
Preparare l'ambiente
- Nessun Dockerfile né file Docker Compose
- Ha un modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di apache/rocketmq
-
[Bug] RemotingHelper.connect swaps the socket send and receive buffer configurationForse già presa @amalsaidov l’ha presa oggi. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 82/100
I maintainer di solito rispondono entro 1 giorno
-
CompressionType.of fails under the Turkish localeForse già presa @sharanggupta l’ha presa oggi. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 83/100
I maintainer di solito rispondono entro 1 giorno
-
[rocketmq-client-python] TransactionMQProducer allocates an unused producer during initializationAperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 82/100
I maintainer di solito rispondono entro 1 giorno
-
[Bug] notifyMasterOnline aborts the long-polling wake-up with a NullPointerException when an arrival drains a bucket firstForse già presa @iloveeyjafjalla l’ha presa 29 giorni fa. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 82/100
apache/rocketmq#11441 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
[Enhancement] FilterFactory duplicate-registration and unregister semantics lack testsForse già presa @chennaji9 l’ha presa 34 giorni fa. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 84/100
apache/rocketmq#11340 · 2 commenti ·
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di apache/rocketmq
Issue simili
-
bug emitter:client:csharp
Difficoltà 2/5 1-3 ore Idoneità per principianti 84/100
microsoft/typespec#12572 · 1 commento · 1 reazione ·
I maintainer di solito rispondono entro 1 giorno
-
GCC 15.2: -Wcast-qual warning - cast discards const qualifier from pointer target type (H5trace.c)Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 73/100
I maintainer di solito rispondono entro 1 giorno
-
needs-area-label
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
I maintainer di solito rispondono entro 2 giorni
-
area/ai area/backend component/zeebe kind/task
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
spAnser/reacharound#38 ·