diff --git a/storage/innobase/include/trx0trx.h b/storage/innobase/include/trx0trx.h index fcc9ed05081594eb18e0812c72f437471cabe3d2..57b91844aca6bb78bcf8197f7cfba5d28def6ddc 100644 --- a/storage/innobase/include/trx0trx.h +++ b/storage/innobase/include/trx0trx.h @@ -1009,6 +1009,19 @@ struct trx_t{ /*------------------------------*/ char detailed_error[256]; /*!< detailed error message for last error, or empty. */ + /* Lock wait statistics */ + ulint n_rec_lock_waits; + /*!< Number of record lock waits, + might not be exactly correct. */ + ulint n_table_lock_waits; + /*!< Number of table lock waits, + might not be exactly correct. */ + ulint total_rec_lock_wait_time; + /*!< Total rec lock wait time up + to this moment. */ + ulint total_table_lock_wait_time; + /*!< Total table lock wait time + up to this moment. */ }; /* Transaction isolation levels (trx->isolation_level) */ diff --git a/storage/innobase/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc index 6c6b406e38a769b11dedca272da7a66292240ba6..e41423c0cd38f2f7578e4cb847a48d84129664f4 100644 --- a/storage/innobase/lock/lock0lock.cc +++ b/storage/innobase/lock/lock0lock.cc @@ -2034,6 +2034,8 @@ lock_rec_enqueue_waiting( MONITOR_INC(MONITOR_LOCKREC_WAIT); + trx->n_rec_lock_waits++; + return(DB_LOCK_WAIT); } @@ -2454,6 +2456,15 @@ lock_grant( } } + /* Cumulate total lock wait time for statistics */ + if (lock_get_type_low(lock) & LOCK_TABLE) { + lock->trx->total_table_lock_wait_time += + (ulint)difftime(ut_time(), lock->trx->lock.wait_started); + } else { + lock->trx->total_rec_lock_wait_time += + (ulint)difftime(ut_time(), lock->trx->lock.wait_started); + } + trx_mutex_exit(lock->trx); } @@ -4458,6 +4469,7 @@ lock_table_enqueue_waiting( trx->lock.wait_started = ut_time(); trx->lock.was_chosen_as_deadlock_victim = FALSE; + trx->n_table_lock_waits++; ut_a(que_thr_stop(thr)); @@ -5458,6 +5470,14 @@ loop: trx->read_view->up_limit_id); } + /* Total trx lock waits and times */ + fprintf(file, "Trx #rec lock waits %lu #table lock waits %lu\n", + trx->n_rec_lock_waits, trx->n_table_lock_waits); + fprintf(file, "Trx total rec lock wait time %lu SEC\n", + trx->total_rec_lock_wait_time); + fprintf(file, "Trx total table lock wait time %lu SEC\n", + trx->total_table_lock_wait_time); + if (trx->lock.que_state == TRX_QUE_LOCK_WAIT) { fprintf(file, diff --git a/storage/xtradb/include/trx0trx.h b/storage/xtradb/include/trx0trx.h index c97be0e4f0327ee81a4b285c220a90b3d68d5199..fc1871d438e9d93a7db66d442e6dbc149be6b173 100644 --- a/storage/xtradb/include/trx0trx.h +++ b/storage/xtradb/include/trx0trx.h @@ -1,6 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2013, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2015, MariaDB Corporation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -1058,6 +1059,20 @@ struct trx_t{ #define DPAH_SIZE 8192 byte* distinct_page_access_hash; ibool take_stats; + + /* Lock wait statistics */ + ulint n_rec_lock_waits; + /*!< Number of record lock waits, + might not be exactly correct. */ + ulint n_table_lock_waits; + /*!< Number of table lock waits, + might not be exactly correct. */ + ulint total_rec_lock_wait_time; + /*!< Total rec lock wait time up + to this moment. */ + ulint total_table_lock_wait_time; + /*!< Total table lock wait time + up to this moment. */ }; /* Transaction isolation levels (trx->isolation_level) */ diff --git a/storage/xtradb/lock/lock0lock.cc b/storage/xtradb/lock/lock0lock.cc index 38f74f9845f9066de38b92ba9a0c6dd11bfbf461..bbc19417b68737bf814f01b43620a8c0c7f60f72 100644 --- a/storage/xtradb/lock/lock0lock.cc +++ b/storage/xtradb/lock/lock0lock.cc @@ -2055,6 +2055,8 @@ lock_rec_enqueue_waiting( MONITOR_INC(MONITOR_LOCKREC_WAIT); + trx->n_rec_lock_waits++; + return(DB_LOCK_WAIT); } @@ -2474,6 +2476,15 @@ lock_grant( } } + /* Cumulate total lock wait time for statistics */ + if (lock_get_type_low(lock) & LOCK_TABLE) { + lock->trx->total_table_lock_wait_time += + (ulint)difftime(ut_time(), lock->trx->lock.wait_started); + } else { + lock->trx->total_rec_lock_wait_time += + (ulint)difftime(ut_time(), lock->trx->lock.wait_started); + } + trx_mutex_exit(lock->trx); } @@ -4484,6 +4495,7 @@ lock_table_enqueue_waiting( trx->lock.wait_started = ut_time(); trx->lock.was_chosen_as_deadlock_victim = FALSE; + trx->n_table_lock_waits++; if (UNIV_UNLIKELY(trx->take_stats)) { ut_usectime(&sec, &ms); @@ -5495,6 +5507,14 @@ loop: trx->read_view->up_limit_id); } + /* Total trx lock waits and times */ + fprintf(file, "Trx #rec lock waits %lu #table lock waits %lu\n", + trx->n_rec_lock_waits, trx->n_table_lock_waits); + fprintf(file, "Trx total rec lock wait time %lu SEC\n", + trx->total_rec_lock_wait_time); + fprintf(file, "Trx total table lock wait time %lu SEC\n", + trx->total_table_lock_wait_time); + if (trx->lock.que_state == TRX_QUE_LOCK_WAIT) { fprintf(file,