[Bug] transferToFsStore deletes POP KV records even when the checkpoint put fails, losing in-flight messages
Maintainer thường phản hồi trong vòng 1 ngày
Đánh giá
- Độ khó
- 3/5
- Thời gian dự kiến
- 1-2 ngày
- Mức phù hợp với người mới
- 62/100
Hướng nghiên cứu
Start in PopConsumerService.transferToFsStore(), where the PutMessageResult from asyncPutMessage(ckMsg).join() is discarded before popConsumerStore.deleteRecords(consumerRecords) runs. Use handleCkMessagePutResult in PopBufferMergeService as the reference for which statuses count as success. The reproduction is PopConsumerServiceTest#transferToFsStoreTest with a stub returning SERVICE_NOT_AVAILABLE; done means that test shows the record still present after the put fails, and the retry loop no longer spins forever.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
Before Creating the Bug Report
- This is a reproducible bug rather than a usage question.
- I searched open and closed issues, pull requests, and Discussions and found no duplicate.
- The affected code is in this RocketMQ repository.
Runtime platform environment
Linux x86_64. The reproduction is a deterministic broker unit test and does not require a running RocketMQ cluster.
RocketMQ version
- Branch:
develop - Commit:
a7edeecfb
JDK Version
OpenJDK 17
Describe the Bug
PopConsumerService.transferToFsStore() migrates in-flight POP consumer records from the RocksDB KV store to the FS (revive topic) store when an operator switches the pop consumption implementation back to the filesystem store (AdminBrokerProcessor#transferPopToFsStore). For each record it builds a PopCheckPoint and appends it to the revive topic:
brokerController.getMessageStore().asyncPutMessage(ckMsg).join();
The returned PutMessageResult is discarded, and afterwards the whole scanned batch is removed from the KV store unconditionally:
this.popConsumerStore.deleteRecords(consumerRecords);
When the checkpoint put does not succeed (SERVICE_NOT_AVAILABLE, OS_PAGECACHE_BUSY, CREATE_MAPPED_FILE_FAILED, ...), no checkpoint exists in the FS store, yet the KV record is deleted anyway. The popped-but-not-yet-acked message then has no checkpoint in either store: if the consumer never acks it (client crash, processing failure), nothing will ever revive or re-deliver it - the message is silently lost. Note that store puts are most likely to fail exactly when a broker is degraded, which is precisely when an operator performs this migration, so an entire batch (up to popReviveMaxReturnSizePerRead records) can be dropped in one pass.
Two related consequences in the same method:
- If
asyncPutMessagecompletes exceptionally,join()throws, thecatch (Throwable)block only logs, and thewhile (true)loop rescans the same (still present) records forever inside asynchronizedmethod. The admin request never returns, and any later invocation of the method blocks on the monitor. - The per-batch log line always reports the scanned count as transferred, so even the logs claim records were migrated that were not persisted.
Steps to Reproduce
A deterministic JUnit + Mockito reproduction, mirroring the existing PopConsumerServiceTest#transferToFsStoreTest:
- Build a
PopConsumerServicewith the usual mockedBrokerControllerand start its KV store. - Write one
PopConsumerRecord(e.g. offset 0) into the store. - Stub
messageStore.asyncPutMessage(any())to complete withnew PutMessageResult(PutMessageStatus.SERVICE_NOT_AVAILABLE, null). - Call
consumerService.transferToFsStore(). - Call
popConsumerStore.scanExpiredRecords(0, Long.MAX_VALUE, 10).
Actual: the scan returns 0 records - the record was deleted from the KV store although no checkpoint was ever persisted.
Expected: the record must still be present (1 record), because its checkpoint was not put successfully; it should stay revivable/re-migratable.
Additional Context
PopBufferMergeService#handleCkMessagePutResult and ChangeInvisibleTimeProcessor#appendCheckPointThenAckOrigin already treat only PUT_OK, FLUSH_DISK_TIMEOUT, FLUSH_SLAVE_TIMEOUT and SLAVE_NOT_AVAILABLE as success when appending checkpoints to the revive topic; transferToFsStore should not use a weaker contract than the other checkpoint writers.
- Ngôn ngữ chính
- Java
- Star
- 22.7k
- Fork
- 12k
- Merge trung bình
- 3 ngày 18 giờ
- Pull request đã merge (30 ngày)
- 17
Chuẩn bị môi trường
- Không có Dockerfile hay tệp Docker Compose
- Có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của apache/rocketmq
-
[Bug] RemotingHelper.connect swaps the socket send and receive buffer configurationCó thể đã có người làm @amalsaidov đã nhận hôm nay. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 82/100
Maintainer thường phản hồi trong vòng 1 ngày
-
CompressionType.of fails under the Turkish localeCó thể đã có người làm @sharanggupta đã nhận hôm nay. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 83/100
Maintainer thường phản hồi trong vòng 1 ngày
-
[rocketmq-client-python] TransactionMQProducer allocates an unused producer during initializationĐang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 82/100
Maintainer thường phản hồi trong vòng 1 ngày
-
[Bug] notifyMasterOnline aborts the long-polling wake-up with a NullPointerException when an arrival drains a bucket firstCó thể đã có người làm @iloveeyjafjalla đã nhận 29 ngày trước. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 82/100
apache/rocketmq#11441 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
[Enhancement] FilterFactory duplicate-registration and unregister semantics lack testsCó thể đã có người làm @chennaji9 đã nhận 34 ngày trước. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 84/100
apache/rocketmq#11340 · 2 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
Tất cả issue của apache/rocketmq
Issue tương tự
-
bug emitter:client:csharp
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 84/100
microsoft/typespec#12572 · 1 bình luận · 1 reaction ·
Maintainer thường phản hồi trong vòng 1 ngày
-
GCC 15.2: -Wcast-qual warning - cast discards const qualifier from pointer target type (H5trace.c)Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 73/100
Maintainer thường phản hồi trong vòng 1 ngày
-
needs-area-label
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
Maintainer thường phản hồi trong vòng 2 ngày
-
area/ai area/backend component/zeebe kind/task
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 68/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
spAnser/reacharound#38 ·