[Commits] 273767b: Clean up InnoDB lock wait reporting.
Kristian Nielsen
knielsen at knielsen-hq.org
Fri Sep 2 13:58:29 EEST 2016
revision-id: 273767b9d6edd19c1724655d31ad94ef7782b601 (mariadb-10.2.1-11-g273767b)
parent(s): 244d925edf5c7b601c36c80bbdf3c2c65a792978
committer: Kristian Nielsen
timestamp: 2016-09-02 12:49:03 +0200
message:
Clean up InnoDB lock wait reporting.
With async deadlock kill for optimistic parallel replication, there is no
longer any locking issues around the thd_rpl_deadlock_check() call, so we
can remove all the cruft with struct thd_wait_reports.
Signed-off-by: Kristian Nielsen <knielsen at knielsen-hq.org>
---
storage/innobase/lock/lock0lock.cc | 95 ++++++--------------------------------
1 file changed, 13 insertions(+), 82 deletions(-)
diff --git a/storage/innobase/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc
index 1a466db..1c6fc3b 100644
--- a/storage/innobase/lock/lock0lock.cc
+++ b/storage/innobase/lock/lock0lock.cc
@@ -63,13 +63,6 @@ static const ulint TABLE_LOCK_CACHE = 8;
/** Size in bytes, of the table lock instance */
static const ulint TABLE_LOCK_SIZE = sizeof(ib_lock_t);
-/* Buffer to collect THDs to report waits for. */
-struct thd_wait_reports {
- struct thd_wait_reports *next; /*!< List link */
- ulint used; /*!< How many elements in waitees[] */
- trx_t *waitees[64]; /*!< Trxs for thd_rpl_deadlock_check() */
-};
-
/** Deadlock checker. */
class DeadlockChecker {
public:
@@ -98,7 +91,7 @@ class DeadlockChecker {
const trx_t* trx,
const lock_t* wait_lock,
ib_uint64_t mark_start,
- struct thd_wait_reports* waitee_buf_ptr)
+ bool report_waiters)
:
m_cost(),
m_start(trx),
@@ -106,7 +99,7 @@ class DeadlockChecker {
m_wait_lock(wait_lock),
m_mark_start(mark_start),
m_n_elems(),
- m_waitee_ptr(waitee_buf_ptr)
+ m_report_waiters(report_waiters)
{
}
@@ -265,8 +258,8 @@ class DeadlockChecker {
/** This is to avoid malloc/free calls. */
static state_t s_states[MAX_STACK_SIZE];
- /** Buffer to collect THDs to report waits for. */
- struct thd_wait_reports* m_waitee_ptr;
+ /** Set if thd_rpl_deadlock_check() should be called for waits. */
+ bool m_report_waiters;
};
/** Counter to mark visited nodes during deadlock search. */
@@ -7952,24 +7945,11 @@ DeadlockChecker::search()
layer. These locks are released before commit, so they
can not cause deadlocks with binlog-fixed commit
order. */
- if (m_waitee_ptr &&
+ if (m_report_waiters &&
(lock_get_type_low(lock) != LOCK_TABLE ||
lock_get_mode(lock) != LOCK_AUTO_INC)) {
- if (m_waitee_ptr->used ==
- sizeof(m_waitee_ptr->waitees) /
- sizeof(m_waitee_ptr->waitees[0])) {
- m_waitee_ptr->next =
- (struct thd_wait_reports *)
- ut_malloc_nokey(sizeof(*m_waitee_ptr));
- m_waitee_ptr = m_waitee_ptr->next;
- if (!m_waitee_ptr) {
- m_too_deep = true;
- return (m_start);
- }
- m_waitee_ptr->next = NULL;
- m_waitee_ptr->used = 0;
- }
- m_waitee_ptr->waitees[m_waitee_ptr->used++] = lock->trx;
+ thd_rpl_deadlock_check(m_start->mysql_thd,
+ lock->trx->mysql_thd);
}
if (lock->trx->lock.que_state == TRX_QUE_LOCK_WAIT) {
@@ -8049,40 +8029,6 @@ DeadlockChecker::trx_rollback()
trx_mutex_exit(trx);
}
-static
-void
-lock_report_waiters_to_mysql(
-/*=======================*/
- struct thd_wait_reports* waitee_buf_ptr, /*!< in: set of trxs */
- THD* mysql_thd, /*!< in: THD */
- const trx_t* victim_trx) /*!< in: Trx selected
- as deadlock victim, if
- any */
-{
- struct thd_wait_reports* p;
- struct thd_wait_reports* q;
- ulint i;
-
- p = waitee_buf_ptr;
- while (p) {
- i = 0;
- while (i < p->used) {
- trx_t *w_trx = p->waitees[i];
- /* There is no need to report waits to a trx already
- selected as a victim. */
- if (w_trx != victim_trx) {
- thd_rpl_deadlock_check(mysql_thd, w_trx->mysql_thd);
- }
- ++i;
- }
- q = p->next;
- if (p != waitee_buf_ptr) {
- ut_free(p);
- }
- p = q;
- }
-}
-
/** Checks if a joining lock request results in a deadlock. If a deadlock is
found this function will resolve the deadlock by choosing a victim transaction
and rolling it back. It will attempt to resolve all deadlocks. The returned
@@ -8101,35 +8047,20 @@ DeadlockChecker::check_and_resolve(const lock_t* lock, const trx_t* trx)
ut_ad(!srv_read_only_mode);
const trx_t* victim_trx;
- struct thd_wait_reports waitee_buf;
- struct thd_wait_reports*waitee_buf_ptr;
- THD* start_mysql_thd;
+ THD* start_mysql_thd;
+ bool report_waits = false;
start_mysql_thd = trx->mysql_thd;
- if (start_mysql_thd && thd_need_wait_for(start_mysql_thd)) {
- waitee_buf_ptr = &waitee_buf;
- } else {
- waitee_buf_ptr = NULL;
- }
+ if (start_mysql_thd && thd_need_wait_for(start_mysql_thd))
+ report_waits = true;
/* Try and resolve as many deadlocks as possible. */
do {
- DeadlockChecker checker(trx, lock, s_lock_mark_counter, waitee_buf_ptr);
-
- if (waitee_buf_ptr) {
- waitee_buf_ptr->next = NULL;
- waitee_buf_ptr->used = 0;
- }
+ DeadlockChecker checker(trx, lock, s_lock_mark_counter,
+ report_waits);
victim_trx = checker.search();
- /* Report waits to upper layer, as needed. */
- if (waitee_buf_ptr) {
- lock_report_waiters_to_mysql(waitee_buf_ptr,
- start_mysql_thd,
- victim_trx);
- }
-
/* Search too deep, we rollback the joining transaction only
if it is possible to rollback. Otherwise we rollback the
transaction that is holding the lock that the joining
More information about the commits
mailing list