@@ -1093,6 +1093,8 @@ lock_rec_set_nth_bit(
10931093 bit_index = i % 8 ;
10941094
10951095 ((byte*) &lock[1 ])[byte_index] |= 1 << bit_index;
1096+
1097+ ++lock->trx ->lock .n_rec_locks ;
10961098}
10971099
10981100/* *********************************************************************/ /* *
@@ -1140,6 +1142,10 @@ lock_rec_reset_nth_bit(
11401142 bit_index = i % 8 ;
11411143
11421144 ((byte*) &lock[1 ])[byte_index] &= ~(1 << bit_index);
1145+
1146+ --lock->trx ->lock .n_rec_locks ;
1147+
1148+ ut_ad (lock->trx ->lock .n_rec_locks >= 0 );
11431149}
11441150
11451151/* ********************************************************************/ /* *
@@ -1750,28 +1756,9 @@ lock_number_of_rows_locked(
17501756/* =======================*/
17511757 const trx_lock_t * trx_lock) /* !< in: transaction locks */
17521758{
1753- const lock_t * lock;
1754- ulint n_records = 0 ;
1755-
17561759 ut_ad (lock_mutex_own ());
17571760
1758- for (lock = UT_LIST_GET_FIRST (trx_lock->trx_locks );
1759- lock != NULL ;
1760- lock = UT_LIST_GET_NEXT (trx_locks, lock)) {
1761-
1762- if (lock_get_type_low (lock) == LOCK_REC) {
1763- ulint n_bit;
1764- ulint n_bits = lock_rec_get_n_bits (lock);
1765-
1766- for (n_bit = 0 ; n_bit < n_bits; n_bit++) {
1767- if (lock_rec_get_nth_bit (lock, n_bit)) {
1768- n_records++;
1769- }
1770- }
1771- }
1772- }
1773-
1774- return (n_records);
1761+ return (trx_lock->n_rec_locks );
17751762}
17761763
17771764/* ============== RECORD LOCK CREATION AND QUEUE MANAGEMENT =============*/
@@ -4076,10 +4063,14 @@ lock_table_create(
40764063 any locks. */
40774064 assert_trx_in_list (trx);
40784065
4079- if ((type_mode & LOCK_MODE_MASK) == LOCK_AUTO_INC) {
4066+ ulint extract_mode = (type_mode & LOCK_MODE_MASK);
4067+ if (extract_mode == LOCK_AUTO_INC) {
4068+
40804069 ++table->n_waiting_or_granted_auto_inc_locks ;
40814070 }
40824071
4072+ table->lock_counter [extract_mode]++;
4073+
40834074 /* For AUTOINC locking we reuse the lock instance only if
40844075 there is no wait involved else we allocate the waiting lock
40854076 from the transaction lock heap. */
@@ -4245,6 +4236,9 @@ lock_table_remove_low(
42454236 UT_LIST_REMOVE (trx_locks, trx->lock .trx_locks , lock);
42464237 UT_LIST_REMOVE (un_member.tab_lock .locks , table->locks , lock);
42474238
4239+ table->lock_counter [lock_get_mode (lock)]--;
4240+ ut_ad (table->lock_counter [lock_get_mode (lock)] >= 0 );
4241+
42484242 MONITOR_INC (MONITOR_TABLELOCK_REMOVED);
42494243 MONITOR_DEC (MONITOR_NUM_TABLELOCK);
42504244}
@@ -4348,6 +4342,21 @@ lock_table_enqueue_waiting(
43484342 return (DB_LOCK_WAIT);
43494343}
43504344
4345+ /* ********************************************************************/ /* *
4346+ Checks if there are table locks incompatible with current lock type.
4347+ @return true if compatible. */
4348+ static
4349+ my_bool
4350+ lock_table_compatible_fast_check (
4351+ /* =============================*/
4352+ enum lock_mode mode, /* !< in: lock mode */
4353+ const dict_table_t * table) /* !< in: table */
4354+ {
4355+ return ((mode == LOCK_IS || mode == LOCK_IX)
4356+ && table->lock_counter [LOCK_S] == 0
4357+ && table->lock_counter [LOCK_X] == 0 );
4358+ }
4359+
43514360/* ********************************************************************/ /* *
43524361Checks if other transactions have an incompatible mode lock request in
43534362the lock queue.
@@ -4368,6 +4377,11 @@ lock_table_other_has_incompatible(
43684377
43694378 ut_ad (lock_mutex_own ());
43704379
4380+ if (lock_table_compatible_fast_check (mode, table)) {
4381+
4382+ return (NULL );
4383+ }
4384+
43714385 for (lock = UT_LIST_GET_LAST (table->locks );
43724386 lock != NULL ;
43734387 lock = UT_LIST_GET_PREV (un_member.tab_lock .locks , lock)) {
@@ -4526,14 +4540,27 @@ lock_table_dequeue(
45264540 they are now qualified to it */
45274541{
45284542 lock_t * lock;
4543+ dict_table_t * table;
4544+ enum lock_mode type = lock_get_mode (in_lock);
45294545
45304546 ut_ad (lock_mutex_own ());
45314547 ut_a (lock_get_type_low (in_lock) == LOCK_TABLE);
45324548
45334549 lock = UT_LIST_GET_NEXT (un_member.tab_lock .locks , in_lock);
45344550
4551+ table = in_lock->un_member .tab_lock .table ;
4552+
45354553 lock_table_remove_low (in_lock);
45364554
4555+ /* If there isn't any LOCK_S/LOCK_X request, and current lock type is
4556+ LOCK_IX/LOCK_IS, then we know we don't need to grant for any table
4557+ lock request because LOCK_IX/LOCK_IS only conflict with
4558+ LOCK_S/LOCK_X. */
4559+ if (lock_table_compatible_fast_check (type, table)) {
4560+
4561+ return ;
4562+ }
4563+
45374564 /* Check if waiting locks in the queue can now be granted: grant
45384565 locks if there are no conflicting locks ahead. */
45394566
@@ -6885,6 +6912,8 @@ lock_trx_release_locks(
68856912
68866913 lock_release (trx);
68876914
6915+ trx->lock .n_rec_locks = 0 ;
6916+
68886917 lock_mutex_exit ();
68896918}
68906919
0 commit comments