Skip to content

Trigger master upgrade from the election vote-tally, not bdb_open_int - #6093

Merged
emelialei88 merged 1 commit into
bloomberg:mainfrom
emelialei88:fix/election-gen
Aug 11, 2026
Merged

emelialei88 merged 1 commit into
bloomberg:mainfrom
emelialei88:fix/election-gen

Conversation

@emelialei88

@emelialei88 emelialei88 commented Jul 28, 2026 •

Copy link
Copy Markdown
Contributor

Why

On a contested cold-restart election the election could complete (a node wins) without ever triggering bdb_upgrade. bdb_open_int then force-upgraded the winner via its fallback rep_start, using the stale recovered generation instead of the won one, so the committed generation regressed (noresetgen: prev == new).

What

The root cause is in the berkdb vote tally. The winner's self-vote is tallied into rep->votes from the (GEN_)VOTE1 path but never emits DB_REP_NEWMASTER. The (GEN_)VOTE2 path decided whether to emit NEWMASTER from the vote count (votes > nsites/2 + 1), so once the self-vote had pushed the count past the bare-majority slot, the peer vote2 that completed the majority returned DB_HAS_MAJORITY instead and bdb_upgrade never fired.

  • Emit DB_REP_NEWMASTER on the first majority-crossing vote2 of the term, discriminated by REP_F_MASTERELECT (set at elect, cleared at upgrade) instead of the fragile count.
  • Keep the self-vote path a pure tally: it runs without the vote2 lock, so returning NEWMASTER there would abort() in the dispatch.
  • Remove the bdb_open_int master-start rep_start fallback entirely; the election path is now the single upgrade source.

Risk

berkdb election/upgrade path. Validated on a 3-node cluster: noresetgen gen strictly increasing across 10 restarts (7→33, master rotating across all nodes); sqllogfill_reset_gen still resets; server logs show one NEWMASTER per election, no abort() / DUPMASTER / gen regression.

@emelialei88
emelialei88 force-pushed the fix/election-gen branch 2 times, most recently from cb4f499 to 054d999 Compare July 28, 2026 21:50

@roborivers roborivers left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cbuild submission: Success ✓.
Regression testing: Success ✓.

The first 10 failing tests are:
bulkimport_simpleauth [setup failed]
simpleauth_password [setup failed]
blockaccess [setup failed]
simpleauth [setup failed]
sc_timepart_logicalsc_generated [db unavailable at finish]
sc_resume_logicalsc_generated **quarantined**
timepart_auth
sqllogfill_reset_gen
consumer_non_atomic_default_consumer_generated **quarantined**
auth_cleanup

@roborivers roborivers left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cbuild submission: Success ✓.
Regression testing: Success ✓.

The first 10 failing tests are:
disttxn [setup failed]
bulkimport_simpleauth [setup failed]
simpleauth_password [setup failed]
blockaccess [setup failed]
simpleauth [setup failed]
timepart_auth
sqllogfill_reset_gen
sp_snapshot_generated
consumer_non_atomic_default_consumer_generated **quarantined**
auth_cleanup

@roborivers roborivers left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cbuild submission: Success ✓.
Regression testing: Success ✓.

The first 10 failing tests are:
sc_redo [failed with core dumped]
consumer_non_atomic_default_consumer_generated **quarantined**
sc_downgrade [timeout] **quarantined**

@roborivers roborivers left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cbuild submission: Error ⚠.
Regression testing: Success ✓.

The first 10 failing tests are:
sqllogfill_reset_gen
ssl_san
consumer_non_atomic_default_consumer_generated **quarantined**
ssl_set_cmd
ssl_prefer
ssl_dbname
sc_downgrade [timeout] **quarantined**
reco-ddlk-sql [timeout] **quarantined**

@roborivers roborivers left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cbuild submission: Error ⚠.
Regression testing: Success ✓.

The first 10 failing tests are:
sc_resume_logicalsc_generated **quarantined**
consumer_non_atomic_default_consumer_generated **quarantined**
sc_downgrade [timeout] **quarantined**

@roborivers roborivers left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cbuild submission: Success ✓.
Regression testing: Success ✓.

The first 10 failing tests are:
sc_resume_logicalsc_generated **quarantined**
consumer_non_atomic_default_consumer_generated **quarantined**
sc_downgrade [timeout] **quarantined**

@emelialei88 emelialei88 changed the title change gen->egen here since gen is stale Trigger master upgrade from the election vote-tally, not bdb_open_int Aug 6, 2026

@roborivers roborivers left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cbuild submission: Error ⚠.
Regression testing: Success ✓.

The first 10 failing tests are:
ssl_san
consumer_non_atomic_default_consumer_generated **quarantined**
builtin_ruleset
ssl_set_cmd
ssl_prefer
ssl_dbname
sc_downgrade [timeout] **quarantined**
reco-ddlk-sql [timeout] **quarantined**

@roborivers roborivers left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cbuild submission: Error ⚠.
Regression testing: Success ✓.

The first 10 failing tests are:
consumer_non_atomic_default_consumer_generated **quarantined**
builtin_ruleset
sc_downgrade [timeout] **quarantined**

On a contested cold-restart election the election could complete without
triggering bdb_upgrade, so bdb_open_int's fallback rep_start ran with the stale
recovered gen and the generation regressed (noresetgen: prev == new).

Emit DB_REP_NEWMASTER on the first majority-crossing vote2 of the term,
discriminated by REP_F_MASTERELECT rather than the vote count, and remove the
bdb_open_int master-start rep_start fallback so the election path is the single
upgrade source.

Validated on a 3-node cluster: noresetgen gen strictly increasing across 10
restarts, sqllogfill_reset_gen still resets, no abort/DUPMASTER.

Signed-off-by: Emelia Lei <wlei29@bloomberg.net>

@roborivers roborivers left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cbuild submission: Error ⚠.
Regression testing: Success ✓.

The first 10 failing tests are:
sc_resume_logicalsc_generated **quarantined**
cdb2jdbc
consumer_non_atomic_default_consumer_generated **quarantined**
sc_downgrade [timeout] **quarantined**
phys_rep_tiered [timeout]
phys_rep_tiered_nosource_generated [timeout]
truncatesc_offline_generated [timeout] **quarantined**
phys_rep_tiered_firstfile_generated [timeout]
reco-ddlk-sql [timeout] **quarantined**

@emelialei88
emelialei88 marked this pull request as ready for review August 11, 2026 15:14
@emelialei88
emelialei88 merged commit a31f516 into bloomberg:main Aug 11, 2026
3 of 4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants