Skip to content
Snippets Groups Projects
Commit 896a20e4 authored by Serge Petrenko's avatar Serge Petrenko Committed by Kirill Yukhin
Browse files

txn_libmo: preserve confirmed_lsn after reading a PROMOTE

Previously we assumed that every PROMOTE request changes limbo owner,
and thus limbo should have confirmed_lsn = 0 after the request is
processed, because new confirmed lsn is yet unknown.

This is not true for PROMOTE requests coming in JOIN or saved in
snapshot: such requests don't change limbo owner: they are like
savepoints, they notify the instance of the current limbo state.

Such promotions may be detected by the rule
replica_id (old limbo owner) == origin_id (new limbo owner)

So, for the sake of correct split-brain detection, confirmed_lsn should
be nonzero after such promotions.

Part-of #5295

NO_DOC=internal change
NO_TEST=tested in future commits
NO_CHANGELOG=internal change
parent 978731b3
No related branches found
No related tags found
No related merge requests found
......@@ -536,14 +536,19 @@ txn_limbo_write_promote(struct txn_limbo *limbo, int64_t lsn, uint64_t term)
*/
static void
txn_limbo_read_promote(struct txn_limbo *limbo, uint32_t replica_id,
int64_t lsn)
uint32_t prev_id, int64_t lsn)
{
txn_limbo_read_confirm(limbo, lsn);
txn_limbo_read_rollback(limbo, lsn + 1);
assert(txn_limbo_is_empty(limbo));
limbo->owner_id = replica_id;
box_update_ro_summary();
limbo->confirmed_lsn = 0;
/*
* Only nullify confirmed_lsn when the new value is unknown. I.e. when
* prev_id != replica_id.
*/
if (replica_id != prev_id)
limbo->confirmed_lsn = 0;
}
void
......@@ -571,9 +576,9 @@ txn_limbo_write_demote(struct txn_limbo *limbo, int64_t lsn, uint64_t term)
* @sa txn_limbo_read_promote.
*/
static void
txn_limbo_read_demote(struct txn_limbo *limbo, int64_t lsn)
txn_limbo_read_demote(struct txn_limbo *limbo, uint32_t prev_id, int64_t lsn)
{
return txn_limbo_read_promote(limbo, REPLICA_ID_NIL, lsn);
return txn_limbo_read_promote(limbo, REPLICA_ID_NIL, prev_id, lsn);
}
void
......@@ -889,10 +894,11 @@ txn_limbo_req_commit(struct txn_limbo *limbo, const struct synchro_request *req)
txn_limbo_read_rollback(limbo, lsn);
break;
case IPROTO_RAFT_PROMOTE:
txn_limbo_read_promote(limbo, req->origin_id, lsn);
txn_limbo_read_promote(limbo, req->origin_id, req->replica_id,
lsn);
break;
case IPROTO_RAFT_DEMOTE:
txn_limbo_read_demote(limbo, lsn);
txn_limbo_read_demote(limbo, req->replica_id, lsn);
break;
default:
unreachable();
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment