Index: storage/innobase/lock/lock0lock.cc =================================================================== --- storage/innobase/lock/lock0lock.cc (revision 6451) +++ storage/innobase/lock/lock0lock.cc (working copy) @@ -4062,10 +4062,13 @@ any locks. */ assert_trx_in_list(trx); - if ((type_mode & LOCK_MODE_MASK) == LOCK_AUTO_INC) { + ulint extract_mode = (type_mode & LOCK_MODE_MASK); + if (extract_mode == LOCK_AUTO_INC) { ++table->n_waiting_or_granted_auto_inc_locks; } + table->lock_counter[extract_mode]++; + /* For AUTOINC locking we reuse the lock instance only if there is no wait involved else we allocate the waiting lock from the transaction lock heap. */ @@ -4230,6 +4233,8 @@ UT_LIST_REMOVE(trx_locks, trx->lock.trx_locks, lock); UT_LIST_REMOVE(un_member.tab_lock.locks, table->locks, lock); + table->lock_counter[lock_get_mode(lock)]--; + ut_ad(table->lock_counter[lock_get_mode(lock)] >= 0); MONITOR_INC(MONITOR_TABLELOCK_REMOVED); MONITOR_DEC(MONITOR_NUM_TABLELOCK); @@ -4353,6 +4358,12 @@ const lock_t* lock; ut_ad(lock_mutex_own()); + + if (srv_quick_check_table_lock && + (mode == LOCK_IS || mode == LOCK_IX) && + table->lock_counter[LOCK_S] == 0 && + table->lock_counter[LOCK_X] == 0) + return(NULL); for (lock = UT_LIST_GET_LAST(table->locks); lock != NULL; Index: storage/innobase/srv/srv0srv.cc =================================================================== --- storage/innobase/srv/srv0srv.cc (revision 6451) +++ storage/innobase/srv/srv0srv.cc (working copy) @@ -428,6 +428,7 @@ UNIV_INTERN ulint srv_main_thread_process_no = 0; UNIV_INTERN ulint srv_main_thread_id = 0; +UNIV_INTERN my_bool srv_quick_check_table_lock = FALSE; /* The following counts are used by the srv_master_thread. */ /** Iterations of the loop bounded by 'srv_active' label. */ Index: storage/innobase/handler/ha_innodb.cc =================================================================== --- storage/innobase/handler/ha_innodb.cc (revision 6451) +++ storage/innobase/handler/ha_innodb.cc (working copy) @@ -16433,6 +16433,11 @@ NULL, innodb_save_page_no, 0, 0, UINT_MAX32, 0); #endif /* UNIV_DEBUG */ +static MYSQL_SYSVAR_BOOL(quick_check_table_lock, srv_quick_check_table_lock, + PLUGIN_VAR_OPCMDARG, + "quick check table lock using lock counter", + NULL, NULL, FALSE); + static struct st_mysql_sys_var* innobase_system_variables[]= { MYSQL_SYSVAR(additional_mem_pool_size), MYSQL_SYSVAR(api_trx_level), @@ -16592,6 +16597,7 @@ MYSQL_SYSVAR(fil_make_page_dirty_debug), MYSQL_SYSVAR(saved_page_number_debug), #endif /* UNIV_DEBUG */ + MYSQL_SYSVAR(quick_check_table_lock), NULL }; Index: storage/innobase/include/dict0mem.h =================================================================== --- storage/innobase/include/dict0mem.h (revision 6451) +++ storage/innobase/include/dict0mem.h (working copy) @@ -1023,6 +1023,7 @@ UT_LIST_BASE_NODE_T(lock_t) locks; /*!< list of locks on the table; protected by lock_sys->mutex */ + ulong lock_counter[LOCK_NUM]; /*!< lock counter for each lock mode*/ #endif /* !UNIV_HOTBACKUP */ #ifdef UNIV_DEBUG Index: storage/innobase/include/srv0srv.h =================================================================== --- storage/innobase/include/srv0srv.h (revision 6451) +++ storage/innobase/include/srv0srv.h (working copy) @@ -438,6 +438,8 @@ extern my_bool srv_cmp_per_index_enabled; +extern my_bool srv_quick_check_table_lock; + /** Status variables to be passed to MySQL */ extern struct export_var_t export_vars;