-
Notifications
You must be signed in to change notification settings - Fork 3.8k
[fix](editlog) Fix BDBJEJournal.write() burning journal IDs on failure #62063
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -131,7 +131,8 @@ public synchronized long write(JournalBatch batch) throws IOException { | |||||||||
| List<JournalBatch.Entity> entities = batch.getJournalEntities(); | ||||||||||
| int entitySize = entities.size(); | ||||||||||
| long dataSize = 0; | ||||||||||
| long firstId = nextJournalId.getAndAdd(entitySize); | ||||||||||
| // Reserve IDs only after successful commit to avoid burning IDs on write failure. | ||||||||||
| long firstId = nextJournalId.get(); | ||||||||||
|
|
||||||||||
| // Write the journals to bdb. | ||||||||||
| for (int i = 0; i < RETRY_TIME; i++) { | ||||||||||
|
|
@@ -155,6 +156,7 @@ public synchronized long write(JournalBatch batch) throws IOException { | |||||||||
|
|
||||||||||
| txn.commit(); | ||||||||||
| txn = null; | ||||||||||
| nextJournalId.addAndGet(entitySize); | ||||||||||
|
||||||||||
|
|
||||||||||
| if (MetricRepo.isInit) { | ||||||||||
| MetricRepo.COUNTER_EDIT_LOG_SIZE_BYTES.increase(dataSize); | ||||||||||
|
|
@@ -237,8 +239,9 @@ public synchronized long write(short op, Writable writable) throws IOException { | |||||||||
| entity.setOpCode(op); | ||||||||||
| entity.setData(writable); | ||||||||||
|
|
||||||||||
| // id is the key | ||||||||||
| long id = nextJournalId.getAndIncrement(); | ||||||||||
| // id is the key. Reserve ID only after successful write to avoid burning IDs on failure. | ||||||||||
| // This is safe because the method is synchronized. | ||||||||||
|
Comment on lines
+242
to
+243
|
||||||||||
| // id is the key. Reserve ID only after successful write to avoid burning IDs on failure. | |
| // This is safe because the method is synchronized. | |
| // id is the key. We advance nextJournalId only after successful write/commit | |
| // to avoid burning IDs on failure. This is safe because the method is synchronized. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nextJournalId.addAndGet(entitySize)is performed inside the retry loop. This is safe only if the method exits/breaks immediately after a successful commit; otherwise a future refactor (or a subtle control-flow change) could advance the counter multiple times for the same batch. To make this robust, consider structuring the success path to return/break immediately aftertxn.commit()(and then advance once), or perform theaddAndGetin a single place that is executed exactly once whenwriteSucceedis finalized.