Skip to content

Commit

Permalink
MDEV-24789: Reduce lock_sys.wait_mutex contention
Browse files Browse the repository at this point in the history
A performance regression was introduced by
commit e71e613 (MDEV-24671)
and mostly addressed by
commit 455514c.

The regression is likely caused by increased contention
lock_sys.latch (former lock_sys.mutex), possibly indirectly
caused by contention on lock_sys.wait_mutex. This change aims to
reduce both, but further improvements will be needed.

lock_wait(): Minimize the lock_sys.wait_mutex hold time.

lock_sys_t::deadlock_check(): Add a parameter for indicating
whether lock_sys.latch is exclusively locked.

trx_t::was_chosen_as_deadlock_victim: Always use atomics.

lock_wait_wsrep(): Assume that no mutex is being held.

Deadlock::report(): Always kill the victim transaction.

lock_sys_t::timeout: New counter to back MONITOR_TIMEOUT.
  • Loading branch information
dr-m committed Feb 26, 2021
1 parent d9898c9 commit 7cf4419
Show file tree
Hide file tree
Showing 8 changed files with 166 additions and 158 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ metadata_table_handles_opened metadata 0 NULL NULL NULL 0 NULL NULL NULL NULL NU
metadata_table_handles_closed metadata 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of table handles closed
metadata_table_reference_count metadata 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Table reference counter
lock_deadlocks lock 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 value Number of deadlocks
lock_timeouts lock 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of lock timeouts
lock_timeouts lock 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 value Number of lock timeouts
lock_rec_lock_waits lock 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of times enqueued into record lock wait queue
lock_table_lock_waits lock 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of times enqueued into table lock wait queue
lock_rec_lock_requests lock 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of record locks requested
Expand Down
2 changes: 1 addition & 1 deletion storage/innobase/handler/ha_innodb.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4494,8 +4494,8 @@ static void innobase_kill_query(handlerton*, THD *thd, enum thd_kill_levels)
lock_cancel_waiting_and_release(lock);
trx->mutex_unlock();
}
lock_sys.deadlock_check(true);
}
lock_sys.deadlock_check();
mysql_mutex_unlock(&lock_sys.wait_mutex);
}
}
Expand Down
7 changes: 5 additions & 2 deletions storage/innobase/include/lock0lock.h
Original file line number Diff line number Diff line change
Expand Up @@ -710,6 +710,8 @@ class lock_sys_t
public:
/** number of deadlocks detected; protected by wait_mutex */
ulint deadlocks;
/** number of lock wait timeouts; protected by wait_mutex */
ulint timeouts;
/**
Constructor.
Expand Down Expand Up @@ -814,8 +816,9 @@ class lock_sys_t
void close();


/** Check for deadlocks */
static void deadlock_check();
/** Check for deadlocks
@param locked lock_sys.is_writer() */
static void deadlock_check(bool locked);


/** Note that a record lock wait started */
Expand Down
13 changes: 3 additions & 10 deletions storage/innobase/include/trx0trx.h
Original file line number Diff line number Diff line change
Expand Up @@ -429,19 +429,12 @@ struct trx_lock_t
trx_t *wait_trx;
/** condition variable for !wait_lock; used with lock_sys.wait_mutex */
pthread_cond_t cond;
/** lock wait start time, protected only by lock_sys.wait_mutex */
my_hrtime_t suspend_time;
/** lock wait start time */
Atomic_relaxed<my_hrtime_t> suspend_time;

#ifdef WITH_WSREP
/** 2=high priority wsrep thread has marked this trx to abort;
/** 2=high priority WSREP thread has marked this trx to abort;
1=another transaction chose this as a victim in deadlock resolution. */
Atomic_relaxed<byte> was_chosen_as_deadlock_victim;
#else
/** When the transaction decides to wait for a lock, it clears this;
set if another transaction chooses this transaction as a victim in deadlock
resolution. Protected by lock_sys.latch and lock_sys.wait_mutex. */
bool was_chosen_as_deadlock_victim;
#endif

/** Next available rec_pool[] entry */
byte rec_cached;
Expand Down
Loading

0 comments on commit 7cf4419

Please sign in to comment.