Loading innobase/include/sync0sync.h +2 −0 Original line number Diff line number Diff line Loading @@ -415,6 +415,8 @@ or row lock! */ /*------------------------------------- Insert buffer tree */ #define SYNC_IBUF_BITMAP_MUTEX 351 #define SYNC_IBUF_BITMAP 350 /*------------------------------------- MySQL query cache mutex */ /*------------------------------------- MySQL binlog mutex */ /*-------------------------------*/ #define SYNC_KERNEL 300 #define SYNC_REC_LOCK 299 Loading innobase/row/row0ins.c +4 −1 Original line number Diff line number Diff line Loading @@ -723,7 +723,10 @@ row_ins_foreign_check_on_constraint( trx = thr_get_trx(thr); /* Since we are going to delete or update a row, we have to invalidate the MySQL query cache for table */ the MySQL query cache for table. A deadlock of threads is not possible here because the caller of this function does not hold any latches with the sync0sync.h rank above the kernel mutex. The query cache mutex has a rank just above the kernel mutex. */ row_ins_invalidate_query_cache(thr, table->name); Loading sql/ha_innodb.cc +19 −1 Original line number Diff line number Diff line Loading @@ -765,7 +765,14 @@ returns TRUE for all tables in the query. If thd is not in the autocommit state, this function also starts a new transaction for thd if there is no active trx yet, and assigns a consistent read view to it if there is no read view yet. */ read view to it if there is no read view yet. Why a deadlock of threads is not possible: the query cache calls this function at the start of a SELECT processing. Then the calling thread cannot be holding any InnoDB semaphores. The calling thread is holding the query cache mutex, and this function will reserver the InnoDB kernel mutex. Thus, the 'rank' in sync0sync.h of the MySQL query cache mutex is above the InnoDB kernel mutex. */ my_bool innobase_query_caching_of_table_permitted( Loading Loading @@ -802,6 +809,13 @@ innobase_query_caching_of_table_permitted( trx = check_trx_exists(thd); } if (trx->has_search_latch) { ut_print_timestamp(stderr); fprintf(stderr, " InnoDB: Error: the calling thread is holding the adaptive search\n" "InnoDB: latch though calling innobase_query_caching_of_table_permitted\n"); } innobase_release_stat_resources(trx); if (!(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) { Loading Loading @@ -877,6 +891,10 @@ innobase_invalidate_query_cache( ulint full_name_len) /* in: full name length where also the null chars count */ { /* Note that the sync0sync.h rank of the query cache mutex is just above the InnoDB kernel mutex. The caller of this function must not have latches of a lower rank. */ /* Argument TRUE below means we are using transactions */ #ifdef HAVE_QUERY_CACHE query_cache.invalidate((THD*)(trx->mysql_thd), Loading Loading
innobase/include/sync0sync.h +2 −0 Original line number Diff line number Diff line Loading @@ -415,6 +415,8 @@ or row lock! */ /*------------------------------------- Insert buffer tree */ #define SYNC_IBUF_BITMAP_MUTEX 351 #define SYNC_IBUF_BITMAP 350 /*------------------------------------- MySQL query cache mutex */ /*------------------------------------- MySQL binlog mutex */ /*-------------------------------*/ #define SYNC_KERNEL 300 #define SYNC_REC_LOCK 299 Loading
innobase/row/row0ins.c +4 −1 Original line number Diff line number Diff line Loading @@ -723,7 +723,10 @@ row_ins_foreign_check_on_constraint( trx = thr_get_trx(thr); /* Since we are going to delete or update a row, we have to invalidate the MySQL query cache for table */ the MySQL query cache for table. A deadlock of threads is not possible here because the caller of this function does not hold any latches with the sync0sync.h rank above the kernel mutex. The query cache mutex has a rank just above the kernel mutex. */ row_ins_invalidate_query_cache(thr, table->name); Loading
sql/ha_innodb.cc +19 −1 Original line number Diff line number Diff line Loading @@ -765,7 +765,14 @@ returns TRUE for all tables in the query. If thd is not in the autocommit state, this function also starts a new transaction for thd if there is no active trx yet, and assigns a consistent read view to it if there is no read view yet. */ read view to it if there is no read view yet. Why a deadlock of threads is not possible: the query cache calls this function at the start of a SELECT processing. Then the calling thread cannot be holding any InnoDB semaphores. The calling thread is holding the query cache mutex, and this function will reserver the InnoDB kernel mutex. Thus, the 'rank' in sync0sync.h of the MySQL query cache mutex is above the InnoDB kernel mutex. */ my_bool innobase_query_caching_of_table_permitted( Loading Loading @@ -802,6 +809,13 @@ innobase_query_caching_of_table_permitted( trx = check_trx_exists(thd); } if (trx->has_search_latch) { ut_print_timestamp(stderr); fprintf(stderr, " InnoDB: Error: the calling thread is holding the adaptive search\n" "InnoDB: latch though calling innobase_query_caching_of_table_permitted\n"); } innobase_release_stat_resources(trx); if (!(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) { Loading Loading @@ -877,6 +891,10 @@ innobase_invalidate_query_cache( ulint full_name_len) /* in: full name length where also the null chars count */ { /* Note that the sync0sync.h rank of the query cache mutex is just above the InnoDB kernel mutex. The caller of this function must not have latches of a lower rank. */ /* Argument TRUE below means we are using transactions */ #ifdef HAVE_QUERY_CACHE query_cache.invalidate((THD*)(trx->mysql_thd), Loading