Commit a0d598a4 authored by Krunal Bauskar's avatar Krunal Bauskar Committed by Marko Mäkelä

MDEV-22794: Avoid potential rollback segment contention with

            increased scalability through even distribution

Rollback segments are allocated to transactions in round-robin fashion.
This is controlled by incrementing a static-scope counter named rseg_slot.

Said logic is not protected by any mutex or use of atomic for the counter.
This potentially can cause the same rollback segment to get allocated to
N different transactions (requesting allocation at the same time).
While this is not an issue as a rollback segment can host multiple
transactions from contention (performance) perspective it is better to
allocate these rollback segments in round-robin fashion.

Fix for the said issue ports use of atomic for the said counter that would
ensure the original design semantic (even distribution through round-robin)
is retained.
parent 592a10d0
...@@ -842,14 +842,9 @@ static trx_rseg_t* trx_assign_rseg_low() ...@@ -842,14 +842,9 @@ static trx_rseg_t* trx_assign_rseg_low()
/* Choose a rollback segment evenly distributed between 0 and /* Choose a rollback segment evenly distributed between 0 and
innodb_undo_logs-1 in a round-robin fashion, skipping those innodb_undo_logs-1 in a round-robin fashion, skipping those
undo tablespaces that are scheduled for truncation. undo tablespaces that are scheduled for truncation. */
static Atomic_counter<unsigned> rseg_slot;
Because rseg_slot is not protected by atomics or any mutex, race ulong slot = ulong{rseg_slot++} % srv_undo_logs;
conditions are possible, meaning that multiple transactions
that start modifications concurrently will write their undo
log to the same rollback segment. */
static ulong rseg_slot;
ulint slot = rseg_slot++ % srv_undo_logs;
trx_rseg_t* rseg; trx_rseg_t* rseg;
#ifdef UNIV_DEBUG #ifdef UNIV_DEBUG
...@@ -941,11 +936,8 @@ trx_t::assign_temp_rseg() ...@@ -941,11 +936,8 @@ trx_t::assign_temp_rseg()
compile_time_assert(ut_is_2pow(TRX_SYS_N_RSEGS)); compile_time_assert(ut_is_2pow(TRX_SYS_N_RSEGS));
/* Choose a temporary rollback segment between 0 and 127 /* Choose a temporary rollback segment between 0 and 127
in a round-robin fashion. Because rseg_slot is not protected by in a round-robin fashion. */
atomics or any mutex, race conditions are possible, meaning that static Atomic_counter<unsigned> rseg_slot;
multiple transactions that start modifications concurrently
will write their undo log to the same rollback segment. */
static ulong rseg_slot;
trx_rseg_t* rseg = trx_sys.temp_rsegs[ trx_rseg_t* rseg = trx_sys.temp_rsegs[
rseg_slot++ & (TRX_SYS_N_RSEGS - 1)]; rseg_slot++ & (TRX_SYS_N_RSEGS - 1)];
ut_ad(!rseg->is_persistent()); ut_ad(!rseg->is_persistent());
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment