diff --git a/mysql-test/r/innodb.result b/mysql-test/r/innodb.result index f2d504f555f..4d104c64fa9 100644 --- a/mysql-test/r/innodb.result +++ b/mysql-test/r/innodb.result @@ -3159,3 +3159,21 @@ t2 CREATE TABLE `t2` ( CONSTRAINT `t2_t1` FOREIGN KEY (`id`) REFERENCES `t1` (`id`) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=latin1 DROP TABLE t2, t1; +CREATE TABLE t1 (a INT, INDEX(a)) ENGINE=InnoDB; +CREATE TABLE t2 (a INT, INDEX(a)) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1); +INSERT INTO t2 VALUES (1); +ALTER TABLE t2 ADD FOREIGN KEY (a) REFERENCES t1 (a) ON DELETE SET NULL; +ALTER TABLE t2 MODIFY a INT NOT NULL; +ERROR HY000: Error on rename of '#sql-temporary' to './test/t2' (errno: 150) +DELETE FROM t1; +DROP TABLE t2,t1; +CREATE TABLE t1 (a VARCHAR(5) COLLATE utf8_unicode_ci PRIMARY KEY) +ENGINE=InnoDB; +INSERT INTO t1 VALUES (0xEFBCA4EFBCA4EFBCA4); +DELETE FROM t1; +INSERT INTO t1 VALUES ('DDD'); +SELECT * FROM t1; +a +DDD +DROP TABLE t1; diff --git a/mysql-test/t/innodb.test b/mysql-test/t/innodb.test index 0937b4fd30d..c4b8491b39d 100644 --- a/mysql-test/t/innodb.test +++ b/mysql-test/t/innodb.test @@ -2293,6 +2293,34 @@ DELETE CASCADE ON UPDATE CASCADE; SHOW CREATE TABLE t2; DROP TABLE t2, t1; +# +# Bug #25927: Prevent ALTER TABLE ... MODIFY ... NOT NULL on columns +# for which there is a foreign key constraint ON ... SET NULL. +# + +CREATE TABLE t1 (a INT, INDEX(a)) ENGINE=InnoDB; +CREATE TABLE t2 (a INT, INDEX(a)) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1); +INSERT INTO t2 VALUES (1); +ALTER TABLE t2 ADD FOREIGN KEY (a) REFERENCES t1 (a) ON DELETE SET NULL; +--replace_regex /'\.\/test\/#sql-[0-9a-f_]*'/'#sql-temporary'/ +--error 1025 +ALTER TABLE t2 MODIFY a INT NOT NULL; +DELETE FROM t1; +DROP TABLE t2,t1; + +# +# Bug #26835: table corruption after delete+insert +# + +CREATE TABLE t1 (a VARCHAR(5) COLLATE utf8_unicode_ci PRIMARY KEY) +ENGINE=InnoDB; +INSERT INTO t1 VALUES (0xEFBCA4EFBCA4EFBCA4); +DELETE FROM t1; +INSERT INTO t1 VALUES ('DDD'); +SELECT * FROM t1; +DROP TABLE t1; + ####################################################################### # # # Please, DO NOT TOUCH this file as well as the innodb.result file. # diff --git a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c index ad775fbd6d5..c847b8db9e2 100644 --- a/storage/innobase/buf/buf0buf.c +++ b/storage/innobase/buf/buf0buf.c @@ -802,9 +802,7 @@ buf_awe_map_page_to_frame( { buf_block_t* bck; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(buf_pool->mutex))); -#endif /* UNIV_SYNC_DEBUG */ ut_ad(block); if (block->frame) { @@ -900,9 +898,7 @@ buf_block_make_young( /*=================*/ buf_block_t* block) /* in: block to make younger */ { -#ifdef UNIV_SYNC_DEBUG ut_ad(!mutex_own(&(buf_pool->mutex))); -#endif /* UNIV_SYNC_DEBUG */ /* Note that we read freed_page_clock's without holding any mutex: this is allowed since the result is used only in heuristics */ @@ -1635,10 +1631,9 @@ buf_page_init( in units of a page */ buf_block_t* block) /* in: block to init */ { -#ifdef UNIV_SYNC_DEBUG + ut_ad(mutex_own(&(buf_pool->mutex))); ut_ad(mutex_own(&(block->mutex))); -#endif /* UNIV_SYNC_DEBUG */ ut_a(block->state != BUF_BLOCK_FILE_PAGE); /* Set the state of the block */ diff --git a/storage/innobase/buf/buf0flu.c b/storage/innobase/buf/buf0flu.c index 650c9d5d707..423c08c0569 100644 --- a/storage/innobase/buf/buf0flu.c +++ b/storage/innobase/buf/buf0flu.c @@ -48,10 +48,7 @@ buf_flush_insert_into_flush_list( /*=============================*/ buf_block_t* block) /* in: block which is modified */ { -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(buf_pool->mutex))); -#endif /* UNIV_SYNC_DEBUG */ - ut_a(block->state == BUF_BLOCK_FILE_PAGE); ut_ad((UT_LIST_GET_FIRST(buf_pool->flush_list) == NULL) @@ -77,9 +74,7 @@ buf_flush_insert_sorted_into_flush_list( buf_block_t* prev_b; buf_block_t* b; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(buf_pool->mutex))); -#endif /* UNIV_SYNC_DEBUG */ prev_b = NULL; b = UT_LIST_GET_FIRST(buf_pool->flush_list); @@ -111,10 +106,8 @@ buf_flush_ready_for_replace( buf_block_t* block) /* in: buffer control block, must be in state BUF_BLOCK_FILE_PAGE and in the LRU list */ { -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(buf_pool->mutex))); ut_ad(mutex_own(&block->mutex)); -#endif /* UNIV_SYNC_DEBUG */ if (block->state != BUF_BLOCK_FILE_PAGE) { ut_print_timestamp(stderr); fprintf(stderr, @@ -147,10 +140,8 @@ buf_flush_ready_for_flush( BUF_BLOCK_FILE_PAGE */ ulint flush_type)/* in: BUF_FLUSH_LRU or BUF_FLUSH_LIST */ { -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(buf_pool->mutex))); ut_ad(mutex_own(&(block->mutex))); -#endif /* UNIV_SYNC_DEBUG */ ut_a(block->state == BUF_BLOCK_FILE_PAGE); if ((ut_dulint_cmp(block->oldest_modification, ut_dulint_zero) > 0) diff --git a/storage/innobase/buf/buf0lru.c b/storage/innobase/buf/buf0lru.c index 377552ece6c..1e27144bdbf 100644 --- a/storage/innobase/buf/buf0lru.c +++ b/storage/innobase/buf/buf0lru.c @@ -549,9 +549,7 @@ buf_LRU_old_adjust_len(void) ulint new_len; ut_a(buf_pool->LRU_old); -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(buf_pool->mutex))); -#endif /* UNIV_SYNC_DEBUG */ ut_ad(3 * (BUF_LRU_OLD_MIN_LEN / 8) > BUF_LRU_OLD_TOLERANCE + 5); for (;;) { @@ -593,6 +591,7 @@ buf_LRU_old_init(void) { buf_block_t* block; + ut_ad(mutex_own(&(buf_pool->mutex))); ut_a(UT_LIST_GET_LEN(buf_pool->LRU) == BUF_LRU_OLD_MIN_LEN); /* We first initialize all blocks in the LRU list as old and then use @@ -624,9 +623,7 @@ buf_LRU_remove_block( { ut_ad(buf_pool); ut_ad(block); -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(buf_pool->mutex))); -#endif /* UNIV_SYNC_DEBUG */ ut_a(block->state == BUF_BLOCK_FILE_PAGE); ut_a(block->in_LRU_list); @@ -690,9 +687,7 @@ buf_LRU_add_block_to_end_low( ut_ad(buf_pool); ut_ad(block); -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(buf_pool->mutex))); -#endif /* UNIV_SYNC_DEBUG */ ut_a(block->state == BUF_BLOCK_FILE_PAGE); @@ -755,9 +750,7 @@ buf_LRU_add_block_low( ut_ad(buf_pool); ut_ad(block); -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(buf_pool->mutex))); -#endif /* UNIV_SYNC_DEBUG */ ut_a(block->state == BUF_BLOCK_FILE_PAGE); ut_a(!block->in_LRU_list); @@ -858,10 +851,9 @@ buf_LRU_block_free_non_file_page( /*=============================*/ buf_block_t* block) /* in: block, must not contain a file page */ { -#ifdef UNIV_SYNC_DEBUG + ut_ad(mutex_own(&(buf_pool->mutex))); ut_ad(mutex_own(&block->mutex)); -#endif /* UNIV_SYNC_DEBUG */ ut_ad(block); ut_a((block->state == BUF_BLOCK_MEMORY) @@ -898,10 +890,8 @@ buf_LRU_block_remove_hashed_page( be in a state where it can be freed; there may or may not be a hash index to the page */ { -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(buf_pool->mutex))); ut_ad(mutex_own(&block->mutex)); -#endif /* UNIV_SYNC_DEBUG */ ut_ad(block); ut_a(block->state == BUF_BLOCK_FILE_PAGE); @@ -961,10 +951,9 @@ buf_LRU_block_free_hashed_page( buf_block_t* block) /* in: block, must contain a file page and be in a state where it can be freed */ { -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(buf_pool->mutex))); ut_ad(mutex_own(&block->mutex)); -#endif /* UNIV_SYNC_DEBUG */ + ut_a(block->state == BUF_BLOCK_REMOVE_HASH); block->state = BUF_BLOCK_MEMORY; diff --git a/storage/innobase/dict/dict0boot.c b/storage/innobase/dict/dict0boot.c index 08515d8fb13..f8849008854 100644 --- a/storage/innobase/dict/dict0boot.c +++ b/storage/innobase/dict/dict0boot.c @@ -86,9 +86,7 @@ dict_hdr_flush_row_id(void) dulint id; mtr_t mtr; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(dict_sys->mutex))); -#endif /* UNIV_SYNC_DEBUG */ id = dict_sys->row_id; diff --git a/storage/innobase/dict/dict0crea.c b/storage/innobase/dict/dict0crea.c index 76474c72c43..e060d45768e 100644 --- a/storage/innobase/dict/dict0crea.c +++ b/storage/innobase/dict/dict0crea.c @@ -212,9 +212,7 @@ dict_build_table_def_step( ulint i; ulint row_len; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(dict_sys->mutex))); -#endif /* UNIV_SYNC_DEBUG */ table = node->table; @@ -312,9 +310,7 @@ dict_create_sys_indexes_tuple( dfield_t* dfield; byte* ptr; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(dict_sys->mutex))); -#endif /* UNIV_SYNC_DEBUG */ ut_ad(index && heap); sys_indexes = dict_sys->sys_indexes; @@ -512,9 +508,7 @@ dict_build_index_def_step( dtuple_t* row; trx_t* trx; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(dict_sys->mutex))); -#endif /* UNIV_SYNC_DEBUG */ trx = thr_get_trx(thr); @@ -585,9 +579,7 @@ dict_create_index_tree_step( btr_pcur_t pcur; mtr_t mtr; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(dict_sys->mutex))); -#endif /* UNIV_SYNC_DEBUG */ index = node->index; table = node->table; @@ -642,10 +634,7 @@ dict_drop_index_tree( byte* ptr; ulint len; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(dict_sys->mutex))); -#endif /* UNIV_SYNC_DEBUG */ - ut_a(!dict_table_is_comp(dict_sys->sys_indexes)); ptr = rec_get_nth_field_old(rec, DICT_SYS_INDEXES_PAGE_NO_FIELD, &len); @@ -718,10 +707,7 @@ dict_truncate_index_tree( ulint comp; dict_index_t* index; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(dict_sys->mutex))); -#endif /* UNIV_SYNC_DEBUG */ - ut_a(!dict_table_is_comp(dict_sys->sys_indexes)); rec = btr_pcur_get_rec(pcur); ptr = rec_get_nth_field_old(rec, DICT_SYS_INDEXES_PAGE_NO_FIELD, &len); @@ -907,9 +893,7 @@ dict_create_table_step( trx_t* trx; ut_ad(thr); -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(dict_sys->mutex))); -#endif /* UNIV_SYNC_DEBUG */ trx = thr_get_trx(thr); @@ -1016,9 +1000,7 @@ dict_create_index_step( trx_t* trx; ut_ad(thr); -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(dict_sys->mutex))); -#endif /* UNIV_SYNC_DEBUG */ trx = thr_get_trx(thr); @@ -1440,9 +1422,7 @@ dict_create_add_foreigns_to_dictionary( ulint number = start_id + 1; ulint error; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(dict_sys->mutex))); -#endif /* UNIV_SYNC_DEBUG */ if (NULL == dict_table_get_low("SYS_FOREIGN")) { fprintf(stderr, diff --git a/storage/innobase/dict/dict0dict.c b/storage/innobase/dict/dict0dict.c index 6ae02c0b81a..e07d84a1ee0 100644 --- a/storage/innobase/dict/dict0dict.c +++ b/storage/innobase/dict/dict0dict.c @@ -689,9 +689,7 @@ dict_table_get_on_id( if we are doing a rollback to handle an error in TABLE CREATE, for example, we already have the mutex! */ -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(dict_sys->mutex))); -#endif /* UNIV_SYNC_DEBUG */ return(dict_table_get_on_id_low(table_id)); } @@ -854,9 +852,7 @@ dict_table_add_to_cache( ulint row_len; ut_ad(table); -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(dict_sys->mutex))); -#endif /* UNIV_SYNC_DEBUG */ ut_ad(table->n_def == table->n_cols - DATA_N_SYS_COLS); ut_ad(table->magic_n == DICT_TABLE_MAGIC_N); ut_ad(table->cached == FALSE); @@ -1003,9 +999,7 @@ dict_table_rename_in_cache( ibool success; ut_ad(table); -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(dict_sys->mutex))); -#endif /* UNIV_SYNC_DEBUG */ old_size = mem_heap_get_size(table->heap); @@ -1209,9 +1203,7 @@ dict_table_change_id_in_cache( dulint new_id) /* in: new id to set */ { ut_ad(table); -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(dict_sys->mutex))); -#endif /* UNIV_SYNC_DEBUG */ ut_ad(table->magic_n == DICT_TABLE_MAGIC_N); /* Remove the table from the hash table of id's */ @@ -1238,9 +1230,7 @@ dict_table_remove_from_cache( ulint size; ut_ad(table); -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(dict_sys->mutex))); -#endif /* UNIV_SYNC_DEBUG */ ut_ad(table->magic_n == DICT_TABLE_MAGIC_N); #if 0 @@ -1354,9 +1344,7 @@ dict_index_add_to_cache( ulint i; ut_ad(index); -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(dict_sys->mutex))); -#endif /* UNIV_SYNC_DEBUG */ ut_ad(index->n_def == index->n_fields); ut_ad(index->magic_n == DICT_INDEX_MAGIC_N); @@ -1452,9 +1440,7 @@ dict_index_remove_from_cache( ut_ad(table && index); ut_ad(table->magic_n == DICT_TABLE_MAGIC_N); ut_ad(index->magic_n == DICT_INDEX_MAGIC_N); -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(dict_sys->mutex))); -#endif /* UNIV_SYNC_DEBUG */ rw_lock_free(&index->lock); @@ -1484,9 +1470,7 @@ dict_index_find_cols( ut_ad(table && index); ut_ad(table->magic_n == DICT_TABLE_MAGIC_N); -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(dict_sys->mutex))); -#endif /* UNIV_SYNC_DEBUG */ for (i = 0; i < index->n_fields; i++) { ulint j; @@ -1648,9 +1632,7 @@ dict_index_build_internal_clust( ut_ad(table && index); ut_ad(index->type & DICT_CLUSTERED); -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(dict_sys->mutex))); -#endif /* UNIV_SYNC_DEBUG */ ut_ad(table->magic_n == DICT_TABLE_MAGIC_N); /* Create a new index object with certainly enough fields */ @@ -1803,9 +1785,7 @@ dict_index_build_internal_non_clust( ut_ad(table && index); ut_ad(0 == (index->type & DICT_CLUSTERED)); -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(dict_sys->mutex))); -#endif /* UNIV_SYNC_DEBUG */ ut_ad(table->magic_n == DICT_TABLE_MAGIC_N); /* The clustered index should be the first in the list of indexes */ @@ -1918,9 +1898,7 @@ dict_foreign_remove_from_cache( /*===========================*/ dict_foreign_t* foreign) /* in, own: foreign constraint */ { -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(dict_sys->mutex))); -#endif /* UNIV_SYNC_DEBUG */ ut_a(foreign); if (foreign->referenced_table) { @@ -1951,9 +1929,7 @@ dict_foreign_find( { dict_foreign_t* foreign; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(dict_sys->mutex))); -#endif /* UNIV_SYNC_DEBUG */ foreign = UT_LIST_GET_FIRST(table->foreign_list); @@ -1994,9 +1970,12 @@ dict_foreign_find_index( ulint n_cols, /* in: number of columns */ dict_index_t* types_idx, /* in: NULL or an index to whose types the column types must match */ - ibool check_charsets) + ibool check_charsets, /* in: whether to check charsets. only has an effect if types_idx != NULL */ + ulint check_null) + /* in: nonzero if none of the columns must + be declared NOT NULL */ { dict_index_t* index; dict_field_t* field; @@ -2026,6 +2005,12 @@ dict_foreign_find_index( break; } + if (check_null + && (field->col->prtype & DATA_NOT_NULL)) { + + return(NULL); + } + if (types_idx && !cmp_cols_are_equal( dict_index_get_nth_col(index, i), dict_index_get_nth_col(types_idx, @@ -2113,9 +2098,7 @@ dict_foreign_add_to_cache( ibool added_to_referenced_list= FALSE; FILE* ef = dict_foreign_err_file; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(dict_sys->mutex))); -#endif /* UNIV_SYNC_DEBUG */ for_table = dict_table_check_if_in_cache_low( foreign->foreign_table_name); @@ -2144,7 +2127,7 @@ dict_foreign_add_to_cache( ref_table, (const char**) for_in_cache->referenced_col_names, for_in_cache->n_fields, for_in_cache->foreign_index, - check_charsets); + check_charsets, FALSE); if (index == NULL) { dict_foreign_error_report( @@ -2176,7 +2159,10 @@ dict_foreign_add_to_cache( for_table, (const char**) for_in_cache->foreign_col_names, for_in_cache->n_fields, - for_in_cache->referenced_index, check_charsets); + for_in_cache->referenced_index, check_charsets, + for_in_cache->type + & (DICT_FOREIGN_ON_DELETE_SET_NULL + | DICT_FOREIGN_ON_UPDATE_SET_NULL)); if (index == NULL) { dict_foreign_error_report( @@ -2186,7 +2172,9 @@ dict_foreign_add_to_cache( "the columns as the first columns," " or the data types in the\n" "table do not match" - " the ones in the referenced table."); + " the ones in the referenced table\n" + "or one of the ON ... SET NULL columns" + " is declared NOT NULL."); if (for_in_cache == foreign) { if (added_to_referenced_list) { @@ -2794,9 +2782,7 @@ dict_create_foreign_constraints_low( const char* column_names[500]; const char* referenced_table_name; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(dict_sys->mutex))); -#endif /* UNIV_SYNC_DEBUG */ table = dict_table_get_low(name); @@ -2994,7 +2980,8 @@ col_loop1: /* Try to find an index which contains the columns as the first fields and in the right order */ - index = dict_foreign_find_index(table, column_names, i, NULL, TRUE); + index = dict_foreign_find_index(table, column_names, i, + NULL, TRUE, FALSE); if (!index) { mutex_enter(&dict_foreign_err_mutex); @@ -3265,7 +3252,8 @@ try_find_index: if (referenced_table) { index = dict_foreign_find_index(referenced_table, column_names, i, - foreign->foreign_index, TRUE); + foreign->foreign_index, + TRUE, FALSE); if (!index) { dict_foreign_free(foreign); mutex_enter(&dict_foreign_err_mutex); @@ -3425,9 +3413,7 @@ dict_foreign_parse_drop_constraints( str = dict_strip_comments(*(trx->mysql_query_str)); ptr = str; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(dict_sys->mutex))); -#endif /* UNIV_SYNC_DEBUG */ loop: ptr = dict_scan_to(ptr, "DROP"); @@ -3864,9 +3850,7 @@ dict_foreign_print_low( { ulint i; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(dict_sys->mutex))); -#endif /* UNIV_SYNC_DEBUG */ fprintf(stderr, " FOREIGN KEY CONSTRAINT %s: %s (", foreign->id, foreign->foreign_table_name); @@ -3931,9 +3915,7 @@ dict_table_print_low( dict_foreign_t* foreign; ulint i; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(dict_sys->mutex))); -#endif /* UNIV_SYNC_DEBUG */ dict_update_statistics_low(table, TRUE); @@ -3989,9 +3971,7 @@ dict_col_print_low( { dtype_t type; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(dict_sys->mutex))); -#endif /* UNIV_SYNC_DEBUG */ dict_col_copy_type(col, &type); fprintf(stderr, "%s: ", dict_table_get_col_name(table, @@ -4011,9 +3991,7 @@ dict_index_print_low( ib_longlong n_vals; ulint i; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(dict_sys->mutex))); -#endif /* UNIV_SYNC_DEBUG */ if (index->n_user_defined_cols > 0) { n_vals = index->stat_n_diff_key_vals[ @@ -4061,9 +4039,8 @@ dict_field_print_low( /*=================*/ dict_field_t* field) /* in: field */ { -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(dict_sys->mutex))); -#endif /* UNIV_SYNC_DEBUG */ + fprintf(stderr, " %s", field->name); if (field->prefix_len != 0) { diff --git a/storage/innobase/dict/dict0load.c b/storage/innobase/dict/dict0load.c index e23795f9898..ba2e25cf031 100644 --- a/storage/innobase/dict/dict0load.c +++ b/storage/innobase/dict/dict0load.c @@ -67,9 +67,7 @@ dict_get_first_table_name_in_db( ulint len; mtr_t mtr; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(dict_sys->mutex))); -#endif /* UNIV_SYNC_DEBUG */ heap = mem_heap_create(1000); @@ -353,9 +351,7 @@ dict_load_columns( ulint i; mtr_t mtr; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(dict_sys->mutex))); -#endif /* UNIV_SYNC_DEBUG */ mtr_start(&mtr); @@ -478,11 +474,7 @@ dict_load_fields( ulint i; mtr_t mtr; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(dict_sys->mutex))); -#endif /* UNIV_SYNC_DEBUG */ - - UT_NOT_USED(table); mtr_start(&mtr); @@ -586,9 +578,7 @@ dict_load_indexes( dulint id; mtr_t mtr; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(dict_sys->mutex))); -#endif /* UNIV_SYNC_DEBUG */ if ((ut_dulint_get_high(table->id) == 0) && (ut_dulint_get_low(table->id) < DICT_HDR_FIRST_ID)) { @@ -754,9 +744,7 @@ dict_load_table( ulint err; mtr_t mtr; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(dict_sys->mutex))); -#endif /* UNIV_SYNC_DEBUG */ heap = mem_heap_create(1000); @@ -920,9 +908,7 @@ dict_load_table_on_id( dict_table_t* table; mtr_t mtr; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(dict_sys->mutex))); -#endif /* UNIV_SYNC_DEBUG */ /* NOTE that the operation of this function is protected by the dictionary mutex, and therefore no deadlocks can occur @@ -1003,9 +989,7 @@ dict_load_sys_table( { mem_heap_t* heap; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(dict_sys->mutex))); -#endif /* UNIV_SYNC_DEBUG */ heap = mem_heap_create(1000); @@ -1035,9 +1019,7 @@ dict_load_foreign_cols( ulint i; mtr_t mtr; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(dict_sys->mutex))); -#endif /* UNIV_SYNC_DEBUG */ foreign->foreign_col_names = mem_heap_alloc( foreign->heap, foreign->n_fields * sizeof(void*)); @@ -1113,9 +1095,7 @@ dict_load_foreign( ulint n_fields_and_type; mtr_t mtr; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(dict_sys->mutex))); -#endif /* UNIV_SYNC_DEBUG */ heap2 = mem_heap_create(1000); @@ -1243,9 +1223,7 @@ dict_load_foreigns( ulint err; mtr_t mtr; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(dict_sys->mutex))); -#endif /* UNIV_SYNC_DEBUG */ sys_foreign = dict_table_get_low("SYS_FOREIGN"); diff --git a/storage/innobase/fil/fil0fil.c b/storage/innobase/fil/fil0fil.c index 883fbd09ee4..c63d67cae60 100644 --- a/storage/innobase/fil/fil0fil.c +++ b/storage/innobase/fil/fil0fil.c @@ -409,9 +409,7 @@ fil_space_is_flushed( { fil_node_t* node; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(fil_system->mutex))); -#endif /* UNIV_SYNC_DEBUG */ node = UT_LIST_GET_FIRST(space->chain); @@ -514,9 +512,7 @@ fil_node_open_file( ulint space_id; #endif /* !UNIV_HOTBACKUP */ -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(system->mutex))); -#endif /* UNIV_SYNC_DEBUG */ ut_a(node->n_pending == 0); ut_a(node->open == FALSE); @@ -660,9 +656,7 @@ fil_node_close_file( ibool ret; ut_ad(node && system); -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(system->mutex))); -#endif /* UNIV_SYNC_DEBUG */ ut_a(node->open); ut_a(node->n_pending == 0); ut_a(node->n_pending_flushes == 0); @@ -705,9 +699,8 @@ fil_try_to_close_file_in_LRU( fil_system_t* system = fil_system; fil_node_t* node; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(system->mutex))); -#endif /* UNIV_SYNC_DEBUG */ + node = UT_LIST_GET_LAST(system->LRU); if (print_info) { @@ -765,9 +758,7 @@ fil_mutex_enter_and_prepare_for_io( ulint count = 0; ulint count2 = 0; -#ifdef UNIV_SYNC_DEBUG ut_ad(!mutex_own(&(system->mutex))); -#endif /* UNIV_SYNC_DEBUG */ retry: mutex_enter(&(system->mutex)); @@ -881,9 +872,7 @@ fil_node_free( fil_space_t* space) /* in: space where the file node is chained */ { ut_ad(node && system && space); -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(system->mutex))); -#endif /* UNIV_SYNC_DEBUG */ ut_a(node->magic_n == FIL_NODE_MAGIC_N); ut_a(node->n_pending == 0); @@ -3870,9 +3859,7 @@ fil_node_prepare_for_io( fil_space_t* space) /* in: space */ { ut_ad(node && system && space); -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(system->mutex))); -#endif /* UNIV_SYNC_DEBUG */ if (system->n_open > system->max_n_open + 5) { ut_print_timestamp(stderr); @@ -3917,9 +3904,7 @@ fil_node_complete_io( { ut_ad(node); ut_ad(system); -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(system->mutex))); -#endif /* UNIV_SYNC_DEBUG */ ut_a(node->n_pending > 0); diff --git a/storage/innobase/fsp/fsp0fsp.c b/storage/innobase/fsp/fsp0fsp.c index 00c5e582b3e..b5662fd24a4 100644 --- a/storage/innobase/fsp/fsp0fsp.c +++ b/storage/innobase/fsp/fsp0fsp.c @@ -2045,11 +2045,9 @@ fseg_create_general( mtr); } -#ifdef UNIV_SYNC_DEBUG ut_ad(!mutex_own(&kernel_mutex) || mtr_memo_contains(mtr, fil_space_get_latch(space), MTR_MEMO_X_LOCK)); -#endif /* UNIV_SYNC_DEBUG */ latch = fil_space_get_latch(space); mtr_x_lock(latch, mtr); @@ -2205,11 +2203,10 @@ fseg_n_reserved_pages( space = buf_frame_get_space_id(header); -#ifdef UNIV_SYNC_DEBUG ut_ad(!mutex_own(&kernel_mutex) || mtr_memo_contains(mtr, fil_space_get_latch(space), MTR_MEMO_X_LOCK)); -#endif /* UNIV_SYNC_DEBUG */ + mtr_x_lock(fil_space_get_latch(space), mtr); inode = fseg_inode_get(header, mtr); @@ -2601,11 +2598,9 @@ fseg_alloc_free_page_general( space = buf_frame_get_space_id(seg_header); -#ifdef UNIV_SYNC_DEBUG ut_ad(!mutex_own(&kernel_mutex) || mtr_memo_contains(mtr, fil_space_get_latch(space), MTR_MEMO_X_LOCK)); -#endif /* UNIV_SYNC_DEBUG */ latch = fil_space_get_latch(space); mtr_x_lock(latch, mtr); @@ -2751,11 +2746,9 @@ fsp_reserve_free_extents( ulint n_pages_added; ut_ad(mtr); -#ifdef UNIV_SYNC_DEBUG ut_ad(!mutex_own(&kernel_mutex) || mtr_memo_contains(mtr, fil_space_get_latch(space), MTR_MEMO_X_LOCK)); -#endif /* UNIV_SYNC_DEBUG */ *n_reserved = n_ext; latch = fil_space_get_latch(space); @@ -2853,9 +2846,8 @@ fsp_get_available_space_in_free_extents( rw_lock_t* latch; mtr_t mtr; -#ifdef UNIV_SYNC_DEBUG ut_ad(!mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ + mtr_start(&mtr); latch = fil_space_get_latch(space); @@ -3113,11 +3105,10 @@ fseg_free_page( { fseg_inode_t* seg_inode; -#ifdef UNIV_SYNC_DEBUG ut_ad(!mutex_own(&kernel_mutex) || mtr_memo_contains(mtr, fil_space_get_latch(space), MTR_MEMO_X_LOCK)); -#endif /* UNIV_SYNC_DEBUG */ + mtr_x_lock(fil_space_get_latch(space), mtr); seg_inode = fseg_inode_get(seg_header, mtr); @@ -3222,11 +3213,10 @@ fseg_free_step( space = buf_frame_get_space_id(header); -#ifdef UNIV_SYNC_DEBUG ut_ad(!mutex_own(&kernel_mutex) || mtr_memo_contains(mtr, fil_space_get_latch(space), MTR_MEMO_X_LOCK)); -#endif /* UNIV_SYNC_DEBUG */ + mtr_x_lock(fil_space_get_latch(space), mtr); descr = xdes_get_descriptor(space, buf_frame_get_page_no(header), mtr); @@ -3297,11 +3287,10 @@ fseg_free_step_not_header( space = buf_frame_get_space_id(header); -#ifdef UNIV_SYNC_DEBUG ut_ad(!mutex_own(&kernel_mutex) || mtr_memo_contains(mtr, fil_space_get_latch(space), MTR_MEMO_X_LOCK)); -#endif /* UNIV_SYNC_DEBUG */ + mtr_x_lock(fil_space_get_latch(space), mtr); inode = fseg_inode_get(header, mtr); diff --git a/storage/innobase/ha/ha0ha.c b/storage/innobase/ha/ha0ha.c index 07dfb66afa8..7f241140050 100644 --- a/storage/innobase/ha/ha0ha.c +++ b/storage/innobase/ha/ha0ha.c @@ -96,9 +96,8 @@ ha_insert_for_fold( ulint hash; ut_ad(table && data); -#ifdef UNIV_SYNC_DEBUG ut_ad(!table->mutexes || mutex_own(hash_get_mutex(table, fold))); -#endif /* UNIV_SYNC_DEBUG */ + hash = hash_calc_hash(fold, table); cell = hash_get_nth_cell(table, hash); @@ -194,9 +193,8 @@ ha_delete( { ha_node_t* node; -#ifdef UNIV_SYNC_DEBUG ut_ad(!table->mutexes || mutex_own(hash_get_mutex(table, fold))); -#endif /* UNIV_SYNC_DEBUG */ + node = ha_search_with_data(table, fold, data); ut_a(node); @@ -218,9 +216,7 @@ ha_search_and_update_if_found( { ha_node_t* node; -#ifdef UNIV_SYNC_DEBUG ut_ad(!table->mutexes || mutex_own(hash_get_mutex(table, fold))); -#endif /* UNIV_SYNC_DEBUG */ node = ha_search_with_data(table, fold, data); @@ -248,9 +244,8 @@ ha_remove_all_nodes_to_page( { ha_node_t* node; -#ifdef UNIV_SYNC_DEBUG ut_ad(!table->mutexes || mutex_own(hash_get_mutex(table, fold))); -#endif /* UNIV_SYNC_DEBUG */ + node = ha_chain_get_first(table, fold); while (node) { diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index e9309f4f8b8..2d8f3eb0ef9 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -56,53 +56,6 @@ bool innodb_inited= 0; */ static handlerton *legacy_innodb_hton; -/*-----------------------------------------------------------------*/ -/* These variables are used to implement (semi-)synchronous MySQL binlog -replication for InnoDB tables. */ - -pthread_cond_t innobase_repl_cond; /* Posix cond variable; - this variable is signaled - when enough binlog has been - sent to slave, so that a - waiting trx can return the - 'ok' message to the client - for a commit */ -pthread_mutex_t innobase_repl_cond_mutex; /* Posix cond variable mutex - that also protects the next - innobase_repl_... variables */ -uint innobase_repl_state; /* 1 if synchronous replication - is switched on and is working - ok; else 0 */ -uint innobase_repl_file_name_inited = 0; /* This is set to 1 when - innobase_repl_file_name - contains meaningful data */ -char* innobase_repl_file_name; /* The binlog name up to which - we have sent some binlog to - the slave */ -my_off_t innobase_repl_pos; /* The position in that file - up to which we have sent the - binlog to the slave */ -uint innobase_repl_n_wait_threads = 0; /* This tells how many - transactions currently are - waiting for the binlog to be - sent to the client */ -uint innobase_repl_wait_file_name_inited = 0; /* This is set to 1 - when we know the 'smallest' - wait position */ -char* innobase_repl_wait_file_name; /* NULL, or the 'smallest' - innobase_repl_file_name that - a transaction is waiting for */ -my_off_t innobase_repl_wait_pos; /* The smallest position in - that file that a trx is - waiting for: the trx can - proceed and send an 'ok' to - the client when MySQL has sent - the binlog up to this position - to the slave */ -/*-----------------------------------------------------------------*/ - - - /* Store MySQL definition of 'byte': in Linux it is char while InnoDB uses unsigned char; the header univ.i which we include next defines 'byte' as a macro which expands to 'unsigned char' */ @@ -222,6 +175,139 @@ static handler *innobase_create_handler(handlerton *hton, return new (mem_root) ha_innobase(hton, table); } +/*********************************************************************** +This function is used to prepare X/Open XA distributed transaction */ +static +int +innobase_xa_prepare( +/*================*/ + /* out: 0 or error number */ + handlerton* hton, + THD* thd, /* in: handle to the MySQL thread of the user + whose XA transaction should be prepared */ + bool all); /* in: TRUE - commit transaction + FALSE - the current SQL statement ended */ +/*********************************************************************** +This function is used to recover X/Open XA distributed transactions */ +static +int +innobase_xa_recover( +/*================*/ + /* out: number of prepared transactions + stored in xid_list */ + handlerton* hton, + XID* xid_list, /* in/out: prepared transactions */ + uint len); /* in: number of slots in xid_list */ +/*********************************************************************** +This function is used to commit one X/Open XA distributed transaction +which is in the prepared state */ +static +int +innobase_commit_by_xid( +/*===================*/ + /* out: 0 or error number */ + handlerton* hton, + XID* xid); /* in: X/Open XA transaction identification */ +/*********************************************************************** +This function is used to rollback one X/Open XA distributed transaction +which is in the prepared state */ +static +int +innobase_rollback_by_xid( +/*=====================*/ + /* out: 0 or error number */ + handlerton* hton, + XID *xid); /* in: X/Open XA transaction identification */ +/*********************************************************************** +Create a consistent view for a cursor based on current transaction +which is created if the corresponding MySQL thread still lacks one. +This consistent view is then used inside of MySQL when accessing records +using a cursor. */ +static +void* +innobase_create_cursor_view( +/*========================*/ + /* out: pointer to cursor view or NULL */ + handlerton* hton, /* in: innobase hton */ + THD* thd); /* in: user thread handle */ +/*********************************************************************** +Set the given consistent cursor view to a transaction which is created +if the corresponding MySQL thread still lacks one. If the given +consistent cursor view is NULL global read view of a transaction is +restored to a transaction read view. */ +static +void +innobase_set_cursor_view( +/*=====================*/ + handlerton* hton, + THD* thd, /* in: user thread handle */ + void* curview);/* in: Consistent cursor view to be set */ +/*********************************************************************** +Close the given consistent cursor view of a transaction and restore +global read view to a transaction read view. Transaction is created if the +corresponding MySQL thread still lacks one. */ +static +void +innobase_close_cursor_view( +/*=======================*/ + handlerton* hton, + THD* thd, /* in: user thread handle */ + void* curview);/* in: Consistent read view to be closed */ +/********************************************************************* +Removes all tables in the named database inside InnoDB. */ +static +void +innobase_drop_database( +/*===================*/ + /* out: error number */ + handlerton* hton, /* in: handlerton of Innodb */ + char* path); /* in: database path; inside InnoDB the name + of the last directory in the path is used as + the database name: for example, in 'mysql/data/test' + the database name is 'test' */ +/*********************************************************************** +Closes an InnoDB database. */ +static +int +innobase_end(handlerton *hton, ha_panic_function type); + +/********************************************************************* +Creates an InnoDB transaction struct for the thd if it does not yet have one. +Starts a new InnoDB transaction if a transaction is not yet started. And +assigns a new snapshot for a consistent read if the transaction does not yet +have one. */ +static +int +innobase_start_trx_and_assign_read_view( +/*====================================*/ + /* out: 0 */ + handlerton* hton, /* in: Innodb handlerton */ + THD* thd); /* in: MySQL thread handle of the user for whom + the transaction should be committed */ +/******************************************************************** +Flushes InnoDB logs to disk and makes a checkpoint. Really, a commit flushes +the logs, and the name of this function should be innobase_checkpoint. */ +static +bool +innobase_flush_logs( +/*================*/ + /* out: TRUE if error */ + handlerton* hton); /* in: InnoDB handlerton */ + +/**************************************************************************** +Implements the SHOW INNODB STATUS command. Sends the output of the InnoDB +Monitor to the client. */ +static +bool +innodb_show_status( +/*===============*/ + handlerton* hton, /* in: the innodb handlerton */ + THD* thd, /* in: the MySQL query thread of the caller */ + stat_print_fn *stat_print); +static +bool innobase_show_status(handlerton *hton, THD* thd, + stat_print_fn* stat_print, + enum ha_stat_type stat_type); /********************************************************************* Commits a transaction in an InnoDB database. */ @@ -379,11 +465,24 @@ innobase_release_stat_resources( } } +/************************************************************************ +Obtain the InnoDB transaction of a MySQL thread. */ +inline +trx_t*& +thd_to_trx( +/*=======*/ + /* out: reference to transaction pointer */ + THD* thd, /* in: MySQL thread */ + handlerton* hton) /* in: InnoDB handlerton */ +{ + return(*(trx_t**) thd_ha_data(thd, hton)); +} + /************************************************************************ Call this function when mysqld passes control to the client. That is to avoid deadlocks on the adaptive hash S-latch possibly held by thd. For more documentation, see handler.cc. */ - +static int innobase_release_temporary_latches( /*===============================*/ @@ -397,7 +496,7 @@ innobase_release_temporary_latches( return 0; } - trx = (trx_t*) thd->ha_data[hton->slot]; + trx = thd_to_trx(thd, hton); if (trx) { innobase_release_stat_resources(trx); @@ -857,12 +956,10 @@ check_trx_exists( handlerton* hton, /* in: handlerton for innodb */ THD* thd) /* in: user thread handle */ { - trx_t* trx; + trx_t*& trx = thd_to_trx(thd, hton); ut_ad(thd == current_thd); - trx = (trx_t*) thd->ha_data[hton->slot]; - if (trx == NULL) { DBUG_ASSERT(thd != NULL); trx = trx_allocate_for_mysql(); @@ -874,8 +971,6 @@ check_trx_exists( /* Update the info whether we should skip XA steps that eat CPU time */ trx->support_xa = (ibool)(thd->variables.innodb_support_xa); - - thd->ha_data[hton->slot] = trx; } else { if (trx->magic_n != TRX_MAGIC_N) { mem_analyze_corruption(trx); @@ -928,7 +1023,6 @@ ha_innobase::update_thd( /* out: 0 or error code */ THD* thd) /* in: thd to use the handle */ { - row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt; trx_t* trx; trx = check_trx_exists(ht, thd); @@ -1271,8 +1365,6 @@ void ha_innobase::init_table_handle_for_HANDLER(void) /*============================================*/ { - row_prebuilt_t* prebuilt; - /* If current thd does not yet have a trx struct, create one. If the current handle does not yet have a prebuilt struct, create one. Update the trx pointers in the prebuilt struct. Normally @@ -1283,8 +1375,6 @@ ha_innobase::init_table_handle_for_HANDLER(void) /* Initialize the prebuilt struct much like it would be inited in external_lock */ - prebuilt = (row_prebuilt_t*)innobase_prebuilt; - innobase_release_stat_resources(prebuilt->trx); /* If the transaction is not started yet, start it */ @@ -1331,7 +1421,7 @@ ha_innobase::init_table_handle_for_HANDLER(void) /************************************************************************* Opens an InnoDB database. */ - +static int innobase_init(void *p) /*===============*/ @@ -1620,7 +1710,7 @@ error: /*********************************************************************** Closes an InnoDB database. */ - +static int innobase_end(handlerton *hton, ha_panic_function type) /*==============*/ @@ -1658,7 +1748,7 @@ innobase_end(handlerton *hton, ha_panic_function type) /******************************************************************** Flushes InnoDB logs to disk and makes a checkpoint. Really, a commit flushes the logs, and the name of this function should be innobase_checkpoint. */ - +static bool innobase_flush_logs(handlerton *hton) /*=====================*/ @@ -1694,7 +1784,7 @@ Creates an InnoDB transaction struct for the thd if it does not yet have one. Starts a new InnoDB transaction if a transaction is not yet started. And assigns a new snapshot for a consistent read if the transaction does not yet have one. */ - +static int innobase_start_trx_and_assign_read_view( /*====================================*/ @@ -1908,7 +1998,7 @@ innobase_report_binlog_offset_and_commit( #if 0 /*********************************************************************** This function stores the binlog offset and flushes logs. */ - +static void innobase_store_binlog_offset_and_flush_log( /*=======================================*/ @@ -1951,7 +2041,7 @@ innobase_commit_complete( { trx_t* trx; - trx = (trx_t*) thd->ha_data[hton->slot]; + trx = thd_to_trx(thd, hton); if (trx && trx->active_trans) { @@ -2175,7 +2265,7 @@ innobase_close_connection( { trx_t* trx; - trx = (trx_t*)thd->ha_data[hton->slot]; + trx = thd_to_trx(thd, hton); ut_a(trx); @@ -2216,8 +2306,6 @@ ha_innobase::get_row_type() const /*=============================*/ /* out: ROW_TYPE_REDUNDANT or ROW_TYPE_COMPACT */ { - row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt; - if (prebuilt && prebuilt->table) { if (dict_table_is_comp_noninline(prebuilt->table)) { return(ROW_TYPE_COMPACT); @@ -2364,7 +2452,7 @@ ha_innobase::open( DBUG_RETURN(HA_ERR_NO_SUCH_TABLE); } - if (ib_table->ibd_file_missing && !thd->tablespace_op) { + if (ib_table->ibd_file_missing && !thd_tablespace_op(thd)) { ut_print_timestamp(stderr); sql_print_error("MySQL is trying to open a table handle but " "the .ibd file for\ntable %s does not exist.\n" @@ -2382,10 +2470,9 @@ ha_innobase::open( DBUG_RETURN(HA_ERR_NO_SUCH_TABLE); } - innobase_prebuilt = row_create_prebuilt(ib_table); + prebuilt = row_create_prebuilt(ib_table); - ((row_prebuilt_t*)innobase_prebuilt)->mysql_row_len = - table->s->reclength; + prebuilt->mysql_row_len = table->s->reclength; /* Looks like MySQL-3.23 sometimes has primary key number != 0 */ @@ -2404,8 +2491,8 @@ ha_innobase::open( "dictionary, but not in MySQL!", name); } - ((row_prebuilt_t*)innobase_prebuilt) - ->clust_index_was_generated = FALSE; + prebuilt->clust_index_was_generated = FALSE; + /* MySQL allocates the buffer for ref. key_info->key_length includes space for all key columns + one byte for each column that may be NULL. ref_length must be as exact as possible to @@ -2426,8 +2513,7 @@ ha_innobase::open( "of the table.", name); } - ((row_prebuilt_t*)innobase_prebuilt) - ->clust_index_was_generated = TRUE; + prebuilt->clust_index_was_generated = TRUE; ref_length = DATA_ROW_ID_LEN; @@ -2474,7 +2560,7 @@ ha_innobase::close(void) { DBUG_ENTER("ha_innobase::close"); - row_prebuilt_free((row_prebuilt_t*) innobase_prebuilt); + row_prebuilt_free(prebuilt); my_free((gptr) upd_buff, MYF(0)); free_share(share); @@ -3264,34 +3350,31 @@ ha_innobase::write_row( /* out: error code */ mysql_byte* record) /* in: a row in MySQL format */ { - row_prebuilt_t* prebuilt = (row_prebuilt_t*)innobase_prebuilt; int error; longlong auto_inc; longlong dummy; ibool auto_inc_used= FALSE; + THD* thd = current_thd; + trx_t* trx = thd_to_trx(thd, ht); DBUG_ENTER("ha_innobase::write_row"); - if (prebuilt->trx != - (trx_t*) current_thd->ha_data[ht->slot]) { + if (prebuilt->trx != trx) { sql_print_error("The transaction object for the table handle is at " "%p, but for the current thread it is at %p", - prebuilt->trx, - (trx_t*) current_thd->ha_data[ht->slot]); + prebuilt->trx, trx); fputs("InnoDB: Dump of 200 bytes around prebuilt: ", stderr); ut_print_buf(stderr, ((const byte*)prebuilt) - 100, 200); fputs("\n" - "InnoDB: Dump of 200 bytes around transaction.all: ", + "InnoDB: Dump of 200 bytes around ha_data: ", stderr); - ut_print_buf(stderr, - ((byte*)(&(current_thd->ha_data[ht->slot]))) - 100, - 200); + ut_print_buf(stderr, ((const byte*) trx) - 100, 200); putc('\n', stderr); ut_error; } - statistic_increment(current_thd->status_var.ha_write_count, + statistic_increment(thd->status_var.ha_write_count, &LOCK_status); if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT) @@ -3655,14 +3738,13 @@ ha_innobase::update_row( const mysql_byte* old_row,/* in: old row in MySQL format */ mysql_byte* new_row)/* in: new row in MySQL format */ { - row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt; upd_t* uvect; int error = 0; + trx_t* trx = thd_to_trx(current_thd, ht); DBUG_ENTER("ha_innobase::update_row"); - ut_a(prebuilt->trx == - (trx_t*) current_thd->ha_data[ht->slot]); + ut_a(prebuilt->trx == trx); if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE) table->timestamp_field->set_time(); @@ -3671,7 +3753,7 @@ ha_innobase::update_row( prebuilt->sql_stat_start = TRUE; last_query_id = user_thd->query_id; - innobase_release_stat_resources(prebuilt->trx); + innobase_release_stat_resources(trx); } if (prebuilt->upd_node) { @@ -3692,11 +3774,11 @@ ha_innobase::update_row( assert(prebuilt->template_type == ROW_MYSQL_WHOLE_ROW); - innodb_srv_conc_enter_innodb(prebuilt->trx); + innodb_srv_conc_enter_innodb(trx); error = row_update_for_mysql((byte*) old_row, prebuilt); - innodb_srv_conc_exit_innodb(prebuilt->trx); + innodb_srv_conc_exit_innodb(trx); error = convert_error_code_to_mysql(error, user_thd); @@ -3717,19 +3799,18 @@ ha_innobase::delete_row( /* out: error number or 0 */ const mysql_byte* record) /* in: a row in MySQL format */ { - row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt; int error = 0; + trx_t* trx = thd_to_trx(current_thd, ht); DBUG_ENTER("ha_innobase::delete_row"); - ut_a(prebuilt->trx == - (trx_t*) current_thd->ha_data[ht->slot]); + ut_a(prebuilt->trx == trx); if (last_query_id != user_thd->query_id) { prebuilt->sql_stat_start = TRUE; last_query_id = user_thd->query_id; - innobase_release_stat_resources(prebuilt->trx); + innobase_release_stat_resources(trx); } if (!prebuilt->upd_node) { @@ -3740,11 +3821,11 @@ ha_innobase::delete_row( prebuilt->upd_node->is_delete = TRUE; - innodb_srv_conc_enter_innodb(prebuilt->trx); + innodb_srv_conc_enter_innodb(trx); error = row_update_for_mysql((byte*) record, prebuilt); - innodb_srv_conc_exit_innodb(prebuilt->trx); + innodb_srv_conc_exit_innodb(trx); error = convert_error_code_to_mysql(error, user_thd); @@ -3765,8 +3846,6 @@ void ha_innobase::unlock_row(void) /*=========================*/ { - row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt; - DBUG_ENTER("ha_innobase::unlock_row"); if (UNIV_UNLIKELY(last_query_id != user_thd->query_id)) { @@ -3774,7 +3853,7 @@ ha_innobase::unlock_row(void) sql_print_error("last_query_id is %lu != user_thd_query_id is " "%lu", (ulong) last_query_id, (ulong) user_thd->query_id); - mem_analyze_corruption((byte *) prebuilt->trx); + mem_analyze_corruption(prebuilt->trx); ut_error; } @@ -3808,8 +3887,6 @@ bool ha_innobase::was_semi_consistent_read(void) /*=======================================*/ { - row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt; - return(prebuilt->row_read_type == ROW_READ_DID_SEMI_CONSISTENT); } @@ -3818,10 +3895,7 @@ void ha_innobase::try_semi_consistent_read(bool yes) /*===========================================*/ { - row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt; - - ut_a(prebuilt->trx == - (trx_t*) current_thd->ha_data[ht->slot]); + ut_a(prebuilt->trx == thd_to_trx(current_thd, ht)); /* Row read type is set to semi consistent read if this was requested by the MySQL and either innodb_locks_unsafe_for_binlog @@ -3978,7 +4052,6 @@ ha_innobase::index_read( uint key_len,/* in: key value length */ enum ha_rkey_function find_flag)/* in: search flags from my_base.h */ { - row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt; ulint mode; dict_index_t* index; ulint match_mode = 0; @@ -3987,8 +4060,7 @@ ha_innobase::index_read( DBUG_ENTER("index_read"); - ut_a(prebuilt->trx == - (trx_t*) current_thd->ha_data[ht->slot]); + ut_a(prebuilt->trx == thd_to_trx(current_thd, ht)); statistic_increment(current_thd->status_var.ha_read_key_count, &LOCK_status); @@ -4095,15 +4167,13 @@ ha_innobase::change_active_index( index, even if it was internally generated by InnoDB */ { - row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt; KEY* key=0; - statistic_increment(current_thd->status_var.ha_read_key_count, - &LOCK_status); + THD* thd = current_thd; + statistic_increment(thd->status_var.ha_read_key_count, &LOCK_status); DBUG_ENTER("change_active_index"); - ut_ad(user_thd == current_thd); - ut_a(prebuilt->trx == - (trx_t*) current_thd->ha_data[ht->slot]); + ut_ad(user_thd == thd); + ut_a(prebuilt->trx == thd_to_trx(thd, ht)); active_index = keynr; @@ -4186,14 +4256,12 @@ ha_innobase::general_fetch( uint match_mode) /* in: 0, ROW_SEL_EXACT, or ROW_SEL_EXACT_PREFIX */ { - row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt; ulint ret; int error = 0; DBUG_ENTER("general_fetch"); - ut_a(prebuilt->trx == - (trx_t*) current_thd->ha_data[ht->slot]); + ut_a(prebuilt->trx == thd_to_trx(current_thd, ht)); innodb_srv_conc_enter_innodb(prebuilt->trx); @@ -4340,8 +4408,6 @@ ha_innobase::rnd_init( { int err; - row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt; - /* Store the active index value so that we can restore the original value after a scan */ @@ -4419,7 +4485,6 @@ ha_innobase::rnd_pos( the length of data in pos has to be ref_length */ { - row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt; int error; uint keynr = active_index; DBUG_ENTER("rnd_pos"); @@ -4428,8 +4493,7 @@ ha_innobase::rnd_pos( statistic_increment(current_thd->status_var.ha_read_rnd_count, &LOCK_status); - ut_a(prebuilt->trx == - (trx_t*) current_thd->ha_data[ht->slot]); + ut_a(prebuilt->trx == thd_to_trx(current_thd, ht)); if (prebuilt->clust_index_was_generated) { /* No primary key was defined for the table and we @@ -4475,11 +4539,9 @@ ha_innobase::position( /*==================*/ const mysql_byte* record) /* in: row in MySQL format */ { - row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt; uint len; - ut_a(prebuilt->trx == - (trx_t*) current_thd->ha_data[ht->slot]); + ut_a(prebuilt->trx == thd_to_trx(current_thd, ht)); if (prebuilt->clust_index_was_generated) { /* No primary key was defined for the table and we @@ -4970,16 +5032,15 @@ ha_innobase::discard_or_import_tablespace( /* out: 0 == success, -1 == error */ my_bool discard) /* in: TRUE if discard, else import */ { - row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt; dict_table_t* dict_table; trx_t* trx; int err; DBUG_ENTER("ha_innobase::discard_or_import_tablespace"); - ut_a(prebuilt->trx && prebuilt->trx->magic_n == TRX_MAGIC_N); - ut_a(prebuilt->trx == - (trx_t*) current_thd->ha_data[ht->slot]); + ut_a(prebuilt->trx); + ut_a(prebuilt->trx->magic_n == TRX_MAGIC_N); + ut_a(prebuilt->trx == thd_to_trx(current_thd, ht)); dict_table = prebuilt->table; trx = prebuilt->trx; @@ -5003,7 +5064,6 @@ ha_innobase::delete_all_rows(void) /*==============================*/ /* out: error number */ { - row_prebuilt_t* prebuilt = (row_prebuilt_t*)innobase_prebuilt; int error; THD* thd = current_thd; @@ -5121,7 +5181,7 @@ ha_innobase::delete_table( /********************************************************************* Removes all tables in the named database inside InnoDB. */ - +static void innobase_drop_database( /*===================*/ @@ -5288,7 +5348,6 @@ ha_innobase::records_in_range( key_range *max_key) /* in: range end key val, may also be 0 */ { - row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt; KEY* key; dict_index_t* index; mysql_byte* key_val_buff2 = (mysql_byte*) my_malloc( @@ -5307,8 +5366,7 @@ ha_innobase::records_in_range( DBUG_ENTER("records_in_range"); - ut_a(prebuilt->trx == - (trx_t*) current_thd->ha_data[ht->slot]); + ut_a(prebuilt->trx == thd_to_trx(current_thd, ht)); prebuilt->trx->op_info = (char*)"estimating records in index range"; @@ -5382,7 +5440,6 @@ ha_innobase::estimate_rows_upper_bound(void) /*======================================*/ /* out: upper bound of rows */ { - row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt; dict_index_t* index; ulonglong estimate; ulonglong local_data_file_length; @@ -5431,8 +5488,6 @@ ha_innobase::scan_time() /*====================*/ /* out: estimated time measured in disk seeks */ { - row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt; - /* Since MySQL seems to favor table scans too much over index searches, we pretend that a sequential read takes the same time as a random disk read, that is, we do not divide the following @@ -5488,7 +5543,6 @@ ha_innobase::info( /*==============*/ uint flag) /* in: what information MySQL requests */ { - row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt; dict_table_t* ib_table; dict_index_t* index; ha_rows rec_per_key; @@ -5741,12 +5795,10 @@ ha_innobase::check( HA_CHECK_OPT* check_opt) /* in: check options, currently ignored */ { - row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt; ulint ret; ut_a(prebuilt->trx && prebuilt->trx->magic_n == TRX_MAGIC_N); - ut_a(prebuilt->trx == - (trx_t*) current_thd->ha_data[ht->slot]); + ut_a(prebuilt->trx == thd_to_trx(current_thd, ht)); if (prebuilt->mysql_template == NULL) { /* Build the template; we will use a dummy template @@ -5776,9 +5828,8 @@ ha_innobase::update_table_comment( info on foreign keys */ const char* comment)/* in: table comment defined by user */ { - uint length = (uint) strlen(comment); - char* str; - row_prebuilt_t* prebuilt = (row_prebuilt_t*)innobase_prebuilt; + uint length = (uint) strlen(comment); + char* str; long flen; /* We do not know if MySQL can call this function before calling @@ -5851,7 +5902,6 @@ ha_innobase::get_foreign_key_create_info(void) can be inserted to the CREATE TABLE statement, MUST be freed with ::free_foreign_key_create_info */ { - row_prebuilt_t* prebuilt = (row_prebuilt_t*)innobase_prebuilt; char* str = 0; long flen; @@ -5909,7 +5959,6 @@ ha_innobase::get_foreign_key_list(THD *thd, List *f_key_list) dict_foreign_t* foreign; DBUG_ENTER("get_foreign_key_list"); - row_prebuilt_t* prebuilt = (row_prebuilt_t*)innobase_prebuilt; ut_a(prebuilt != NULL); update_thd(current_thd); prebuilt->trx->op_info = (char*)"getting list of foreign keys"; @@ -6042,13 +6091,11 @@ bool ha_innobase::can_switch_engines(void) /*=================================*/ { - row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt; bool can_switch; DBUG_ENTER("ha_innobase::can_switch_engines"); - ut_a(prebuilt->trx == - (trx_t*) current_thd->ha_data[ht->slot]); + ut_a(prebuilt->trx == thd_to_trx(current_thd, ht)); prebuilt->trx->op_info = "determining if there are foreign key constraints"; @@ -6074,8 +6121,6 @@ ha_innobase::referenced_by_foreign_key(void) /*========================================*/ /* out: > 0 if referenced by a FOREIGN KEY */ { - row_prebuilt_t* prebuilt = (row_prebuilt_t*)innobase_prebuilt; - if (dict_table_referenced_by_foreign_key(prebuilt->table)) { return(1); @@ -6108,8 +6153,6 @@ ha_innobase::extra( enum ha_extra_function operation) /* in: HA_EXTRA_FLUSH or some other flag */ { - row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt; - /* Warning: since it is not sure that MySQL calls external_lock before calling this function, the trx field in prebuilt can be obsolete! */ @@ -6142,7 +6185,6 @@ ha_innobase::extra( int ha_innobase::reset() { - row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt; if (prebuilt->blob_heap) { row_mysql_prebuilt_free_blob_heap(prebuilt); } @@ -6161,7 +6203,7 @@ on that table. MySQL-5.0 also calls this before each statement in an execution of a stored procedure. To make the execution more deterministic for binlogging, MySQL-5.0 locks all tables involved in a stored procedure with full explicit table -locks (thd->in_lock_tables is true in ::store_lock()) before executing the +locks (thd_in_lock_tables(thd) holds in store_lock()) before executing the procedure. */ int @@ -6171,7 +6213,6 @@ ha_innobase::start_stmt( THD* thd, /* in: handle to the user thread */ thr_lock_type lock_type) { - row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt; trx_t* trx; update_thd(thd); @@ -6270,7 +6311,6 @@ ha_innobase::external_lock( THD* thd, /* in: handle to the user thread */ int lock_type) /* in: lock type */ { - row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt; trx_t* trx; DBUG_ENTER("ha_innobase::external_lock"); @@ -6336,16 +6376,16 @@ ha_innobase::external_lock( VERY easily deadlocks. We do not set InnoDB table locks if user has not explicitly - requested a table lock. Note that thd->in_lock_tables - can be TRUE on some cases e.g. at the start of a stored + requested a table lock. Note that thd_in_lock_tables(thd) + can hold in some cases, e.g., at the start of a stored procedure call (SQLCOM_CALL). */ if (prebuilt->select_lock_type != LOCK_NONE) { - if (thd->in_lock_tables && - thd->lex->sql_command == SQLCOM_LOCK_TABLES && - thd->variables.innodb_table_locks && - (thd->options & OPTION_NOT_AUTOCOMMIT)) { + if (thd->lex->sql_command == SQLCOM_LOCK_TABLES + && thd->variables.innodb_table_locks + && (thd->options & OPTION_NOT_AUTOCOMMIT) + && thd_in_lock_tables(thd)) { ulint error = row_lock_table_for_mysql( prebuilt, NULL, 0); @@ -6412,7 +6452,6 @@ ha_innobase::transactional_table_lock( THD* thd, /* in: handle to the user thread */ int lock_type) /* in: lock type */ { - row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt; trx_t* trx; DBUG_ENTER("ha_innobase::transactional_table_lock"); @@ -6424,7 +6463,8 @@ ha_innobase::transactional_table_lock( update_thd(thd); - if (prebuilt->table->ibd_file_missing && !current_thd->tablespace_op) { + if (prebuilt->table->ibd_file_missing + && !thd_tablespace_op(current_thd)) { ut_print_timestamp(stderr); fprintf(stderr, " InnoDB error:\n" "MySQL is trying to use a table handle but the .ibd file for\n" @@ -6469,7 +6509,7 @@ ha_innobase::transactional_table_lock( trx->active_trans = 1; } - if (thd->in_lock_tables && thd->variables.innodb_table_locks) { + if (thd->variables.innodb_table_locks && thd_in_lock_tables(thd)) { ulint error = DB_SUCCESS; error = row_lock_table_for_mysql(prebuilt, NULL, 0); @@ -6509,7 +6549,7 @@ innodb_export_status() /**************************************************************************** Implements the SHOW INNODB STATUS command. Sends the output of the InnoDB Monitor to the client. */ - +static bool innodb_show_status( /*===============*/ @@ -6699,6 +6739,7 @@ innodb_mutex_show_status( DBUG_RETURN(FALSE); } +static bool innobase_show_status(handlerton *hton, THD* thd, stat_print_fn* stat_print, enum ha_stat_type stat_type) @@ -6800,7 +6841,6 @@ ha_innobase::store_lock( 'lock'; this may also be TL_IGNORE */ { - row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt; trx_t* trx; /* Note that trx in this function is NOT necessarily prebuilt->trx @@ -6821,16 +6861,28 @@ ha_innobase::store_lock( trx->isolation_level = innobase_map_isolation_level( (enum_tx_isolation) thd->variables.tx_isolation); + + if (trx->isolation_level <= TRX_ISO_READ_COMMITTED + && trx->global_read_view) { + + /* At low transaction isolation levels we let + each consistent read set its own snapshot */ + + read_view_close_for_mysql(trx); + } + } + const bool in_lock_tables = thd_in_lock_tables(thd); + if (thd->lex->sql_command == SQLCOM_DROP_TABLE) { /* MySQL calls this function in DROP TABLE though this table handle may belong to another thd that is running a query. Let us in that case skip any changes to the prebuilt struct. */ - } else if ((lock_type == TL_READ && thd->in_lock_tables) || - (lock_type == TL_READ_HIGH_PRIORITY && thd->in_lock_tables) || + } else if ((lock_type == TL_READ && in_lock_tables) || + (lock_type == TL_READ_HIGH_PRIORITY && in_lock_tables) || lock_type == TL_READ_WITH_SHARED_LOCKS || lock_type == TL_READ_NO_INSERT || (thd->lex->sql_command != SQLCOM_SELECT @@ -6901,7 +6953,7 @@ ha_innobase::store_lock( /* Starting from 5.0.7, we weaken also the table locks set at the start of a MySQL stored procedure call, just like we weaken the locks set at the start of an SQL statement. - MySQL does set thd->in_lock_tables TRUE there, but in reality + MySQL does set in_lock_tables TRUE there, but in reality we do not need table locks to make the execution of a single transaction stored procedure call deterministic (if it does not use a consistent read). */ @@ -6929,14 +6981,14 @@ ha_innobase::store_lock( We especially allow multiple writers if MySQL is at the start of a stored procedure call (SQLCOM_CALL) or a - stored function call (MySQL does have thd->in_lock_tables + stored function call (MySQL does have in_lock_tables TRUE there). */ if ((lock_type >= TL_WRITE_CONCURRENT_INSERT && lock_type <= TL_WRITE) - && !(thd->in_lock_tables + && !(in_lock_tables && thd->lex->sql_command == SQLCOM_LOCK_TABLES) - && !thd->tablespace_op + && !thd_tablespace_op(thd) && thd->lex->sql_command != SQLCOM_TRUNCATE && thd->lex->sql_command != SQLCOM_OPTIMIZE @@ -6963,7 +7015,7 @@ ha_innobase::store_lock( We especially allow concurrent inserts if MySQL is at the start of a stored procedure call (SQLCOM_CALL) - (MySQL does have thd->in_lock_tables TRUE there). */ + (MySQL does have in_lock_tables TRUE there). */ if (lock_type == TL_READ_NO_INSERT && thd->lex->sql_command != SQLCOM_LOCK_TABLES) { @@ -6992,7 +7044,6 @@ ha_innobase::innobase_read_and_init_auto_inc( timeout */ longlong* ret) /* out: auto-inc value */ { - row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt; longlong auto_inc; ulint old_select_lock_type; ibool trx_was_not_started = FALSE; @@ -7172,8 +7223,7 @@ ha_innobase::reset_auto_increment(ulonglong value) { DBUG_ENTER("ha_innobase::reset_auto_increment"); - row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt; - int error; + int error; update_thd(current_thd); @@ -7217,7 +7267,6 @@ ha_innobase::cmp_ref( const mysql_byte* ref2) /* in: an (internal) primary key value in the MySQL key value format */ { - row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt; enum_field_types mysql_type; Field* field; KEY_PART_INFO* key_part; @@ -7408,7 +7457,7 @@ innobase_query_is_update(void) /*********************************************************************** This function is used to prepare X/Open XA distributed transaction */ - +static int innobase_xa_prepare( /*================*/ @@ -7504,7 +7553,7 @@ innobase_xa_prepare( /*********************************************************************** This function is used to recover X/Open XA distributed transactions */ - +static int innobase_xa_recover( /*================*/ @@ -7525,7 +7574,7 @@ innobase_xa_recover( /*********************************************************************** This function is used to commit one X/Open XA distributed transaction which is in the prepared state */ - +static int innobase_commit_by_xid( /*===================*/ @@ -7549,7 +7598,7 @@ innobase_commit_by_xid( /*********************************************************************** This function is used to rollback one X/Open XA distributed transaction which is in the prepared state */ - +static int innobase_rollback_by_xid( /*=====================*/ @@ -7573,9 +7622,10 @@ Create a consistent view for a cursor based on current transaction which is created if the corresponding MySQL thread still lacks one. This consistent view is then used inside of MySQL when accessing records using a cursor. */ - +static void* innobase_create_cursor_view( +/*========================*/ /* out: pointer to cursor view or NULL */ handlerton *hton, /* in: innobase hton */ THD* thd) /* in: user thread handle */ @@ -7588,9 +7638,10 @@ innobase_create_cursor_view( Close the given consistent cursor view of a transaction and restore global read view to a transaction read view. Transaction is created if the corresponding MySQL thread still lacks one. */ - +static void innobase_close_cursor_view( +/*=======================*/ handlerton *hton, THD* thd, /* in: user thread handle */ void* curview)/* in: Consistent read view to be closed */ @@ -7604,7 +7655,7 @@ Set the given consistent cursor view to a transaction which is created if the corresponding MySQL thread still lacks one. If the given consistent cursor view is NULL global read view of a transaction is restored to a transaction read view. */ - +static void innobase_set_cursor_view( /*=====================*/ diff --git a/storage/innobase/handler/ha_innodb.h b/storage/innobase/handler/ha_innodb.h index 339238a584e..eb977ed6bd5 100644 --- a/storage/innobase/handler/ha_innodb.h +++ b/storage/innobase/handler/ha_innodb.h @@ -33,6 +33,7 @@ typedef struct st_innobase_share { struct row_prebuilt_struct; +typedef struct row_prebuilt_struct row_prebuilt_t; my_bool innobase_query_caching_of_table_permitted(THD* thd, char* full_name, uint full_name_len, @@ -41,9 +42,8 @@ my_bool innobase_query_caching_of_table_permitted(THD* thd, char* full_name, /* The class defining a handle to an Innodb table */ class ha_innobase: public handler { - void* innobase_prebuilt;/* (row_prebuilt_t*) prebuilt - struct in InnoDB, used to save - CPU time with prebuilt data + row_prebuilt_t* prebuilt; /* prebuilt struct in InnoDB, used + to save CPU time with prebuilt data structures*/ THD* user_thd; /* the thread handle of the user currently using the handle; this is @@ -238,11 +238,6 @@ extern ulong srv_commit_concurrency; extern ulong srv_flush_log_at_trx_commit; } -int innobase_init(void); -int innobase_end(handlerton *hton, ha_panic_function type); -bool innobase_flush_logs(handlerton *hton); -uint innobase_get_free_space(void); - /* don't delete it - it may be re-enabled later as an optimization for the most common case InnoDB+binlog @@ -256,93 +251,3 @@ int innobase_report_binlog_offset_and_commit( int innobase_commit_complete(void* trx_handle); void innobase_store_binlog_offset_and_flush_log(char *binlog_name,longlong offset); #endif - -void innobase_drop_database(handlerton *hton, char *path); -bool innobase_show_status(handlerton *hton, THD* thd, stat_print_fn*, enum ha_stat_type); - -int innobase_release_temporary_latches(handlerton *hton, THD *thd); - -void innobase_store_binlog_offset_and_flush_log(handlerton *hton, char *binlog_name,longlong offset); - -int innobase_start_trx_and_assign_read_view(handlerton *hton, THD* thd); - -/*********************************************************************** -This function is used to prepare X/Open XA distributed transaction */ - -int innobase_xa_prepare( -/*====================*/ - /* out: 0 or error number */ - handlerton *hton, /* in: innobase hton */ - THD* thd, /* in: handle to the MySQL thread of the user - whose XA transaction should be prepared */ - bool all); /* in: TRUE - commit transaction - FALSE - the current SQL statement ended */ - -/*********************************************************************** -This function is used to recover X/Open XA distributed transactions */ - -int innobase_xa_recover( -/*====================*/ - /* out: number of prepared transactions - stored in xid_list */ - handlerton *hton, /* in: innobase hton */ - XID* xid_list, /* in/out: prepared transactions */ - uint len); /* in: number of slots in xid_list */ - -/*********************************************************************** -This function is used to commit one X/Open XA distributed transaction -which is in the prepared state */ - -int innobase_commit_by_xid( -/*=======================*/ - /* out: 0 or error number */ - handlerton *hton, /* in: innobase hton */ - XID* xid); /* in : X/Open XA Transaction Identification */ - -/*********************************************************************** -This function is used to rollback one X/Open XA distributed transaction -which is in the prepared state */ - -int innobase_rollback_by_xid( - /* out: 0 or error number */ - handlerton *hton, /* in: innobase hton */ - XID *xid); /* in : X/Open XA Transaction Identification */ - - -/*********************************************************************** -Create a consistent view for a cursor based on current transaction -which is created if the corresponding MySQL thread still lacks one. -This consistent view is then used inside of MySQL when accessing records -using a cursor. */ - -void* -innobase_create_cursor_view( - /* out: Pointer to cursor view or NULL */ - handlerton *hton, /* in: innobase hton */ - THD* thd); /* in: user thread handle */ - -/*********************************************************************** -Close the given consistent cursor view of a transaction and restore -global read view to a transaction read view. Transaction is created if the -corresponding MySQL thread still lacks one. */ - -void -innobase_close_cursor_view( -/*=======================*/ - handlerton *hton, /* in: innobase hton */ - THD* thd, /* in: user thread handle */ - void* curview); /* in: Consistent read view to be closed */ - - -/*********************************************************************** -Set the given consistent cursor view to a transaction which is created -if the corresponding MySQL thread still lacks one. If the given -consistent cursor view is NULL global read view of a transaction is -restored to a transaction read view. */ - -void -innobase_set_cursor_view( -/*=====================*/ - handlerton *hton, /* in: innobase hton */ - THD* thd, /* in: user thread handle */ - void* curview); /* in: Consistent read view to be set */ diff --git a/storage/innobase/ibuf/ibuf0ibuf.c b/storage/innobase/ibuf/ibuf0ibuf.c index 96ab928a436..1cbb6003cfc 100644 --- a/storage/innobase/ibuf/ibuf0ibuf.c +++ b/storage/innobase/ibuf/ibuf0ibuf.c @@ -417,9 +417,7 @@ ibuf_data_sizes_update( { ulint old_size; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&ibuf_mutex)); -#endif /* UNIV_SYNC_DEBUG */ old_size = data->size; @@ -1576,9 +1574,7 @@ ibuf_data_enough_free_for_insert( /* out: TRUE if enough free pages in list */ ibuf_data_t* data) /* in: ibuf data for the space */ { -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&ibuf_mutex)); -#endif /* UNIV_SYNC_DEBUG */ /* We want a big margin of free pages, because a B-tree can sometimes grow in size also if records are deleted from it, as the node pointers @@ -1604,16 +1600,9 @@ ibuf_data_too_much_free( /* out: TRUE if enough free pages in list */ ibuf_data_t* data) /* in: ibuf data for the space */ { -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&ibuf_mutex)); -#endif /* UNIV_SYNC_DEBUG */ - if (data->free_list_len >= 3 + data->size / 2 + 3 * data->height) { - - return(TRUE); - } - - return(FALSE); + return(data->free_list_len >= 3 + data->size / 2 + 3 * data->height); } /************************************************************************* @@ -3451,9 +3440,7 @@ ibuf_validate_low(void) ibuf_data_t* data; ulint sum_sizes; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&ibuf_mutex)); -#endif /* UNIV_SYNC_DEBUG */ sum_sizes = 0; diff --git a/storage/innobase/include/buf0buf.ic b/storage/innobase/include/buf0buf.ic index c448c28933a..031bf6c51b4 100644 --- a/storage/innobase/include/buf0buf.ic +++ b/storage/innobase/include/buf0buf.ic @@ -128,9 +128,7 @@ buf_pool_clock_tic(void) /*====================*/ /* out: new clock value */ { -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(buf_pool->mutex))); -#endif /* UNIV_SYNC_DEBUG */ buf_pool->ulint_clock++; @@ -456,7 +454,7 @@ buf_frame_modify_clock_inc( #ifdef UNIV_SYNC_DEBUG ut_ad((mutex_own(&(buf_pool->mutex)) && (block->buf_fix_count == 0)) || rw_lock_own(&(block->lock), RW_LOCK_EXCLUSIVE)); -#endif /*UNIV_SYNC_DEBUG */ +#endif /* UNIV_SYNC_DEBUG */ UT_DULINT_INC(block->modify_clock); @@ -513,14 +511,12 @@ buf_block_buf_fix_inc_debug( const char* file __attribute__ ((unused)), /* in: file name */ ulint line __attribute__ ((unused))) /* in: line */ { -#ifdef UNIV_SYNC_DEBUG ibool ret; ret = rw_lock_s_lock_func_nowait(&(block->debug_latch), file, line); ut_ad(ret == TRUE); ut_ad(mutex_own(&block->mutex)); -#endif block->buf_fix_count++; } #else /* UNIV_SYNC_DEBUG */ @@ -532,9 +528,8 @@ buf_block_buf_fix_inc( /*==================*/ buf_block_t* block) /* in: block to bufferfix */ { -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&block->mutex)); -#endif + block->buf_fix_count++; } #endif /* UNIV_SYNC_DEBUG */ @@ -552,9 +547,7 @@ buf_page_hash_get( ulint fold; ut_ad(buf_pool); -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(buf_pool->mutex))); -#endif /* UNIV_SYNC_DEBUG */ /* Look for the page in the hash table */ diff --git a/storage/innobase/include/buf0flu.ic b/storage/innobase/include/buf0flu.ic index b304673f8be..ae873c42088 100644 --- a/storage/innobase/include/buf0flu.ic +++ b/storage/innobase/include/buf0flu.ic @@ -42,8 +42,8 @@ buf_flush_note_modification( ut_ad(block->buf_fix_count > 0); #ifdef UNIV_SYNC_DEBUG ut_ad(rw_lock_own(&(block->lock), RW_LOCK_EX)); - ut_ad(mutex_own(&(buf_pool->mutex))); #endif /* UNIV_SYNC_DEBUG */ + ut_ad(mutex_own(&(buf_pool->mutex))); ut_ad(ut_dulint_cmp(mtr->start_lsn, ut_dulint_zero) != 0); ut_ad(mtr->modifications); diff --git a/storage/innobase/include/dict0dict.ic b/storage/innobase/include/dict0dict.ic index d59e99277da..4a9afd2f3f5 100644 --- a/storage/innobase/include/dict0dict.ic +++ b/storage/innobase/include/dict0dict.ic @@ -551,9 +551,7 @@ dict_table_check_if_in_cache_low( ulint table_fold; ut_ad(table_name); -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(dict_sys->mutex))); -#endif /* UNIV_SYNC_DEBUG */ /* Look for the table name in the hash table */ table_fold = ut_fold_string(table_name); @@ -576,9 +574,7 @@ dict_table_get_low( dict_table_t* table; ut_ad(table_name); -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(dict_sys->mutex))); -#endif /* UNIV_SYNC_DEBUG */ table = dict_table_check_if_in_cache_low(table_name); @@ -601,9 +597,7 @@ dict_table_get_on_id_low( dict_table_t* table; ulint fold; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(dict_sys->mutex))); -#endif /* UNIV_SYNC_DEBUG */ /* Look for the table name in the hash table */ fold = ut_fold_dulint(table_id); diff --git a/storage/innobase/include/ha0ha.ic b/storage/innobase/include/ha0ha.ic index 1584e1ff4bf..fb264377f28 100644 --- a/storage/innobase/include/ha0ha.ic +++ b/storage/innobase/include/ha0ha.ic @@ -81,9 +81,7 @@ ha_search( { ha_node_t* node; -#ifdef UNIV_SYNC_DEBUG ut_ad(!table->mutexes || mutex_own(hash_get_mutex(table, fold))); -#endif /* UNIV_SYNC_DEBUG */ node = ha_chain_get_first(table, fold); @@ -113,9 +111,7 @@ ha_search_and_get_data( { ha_node_t* node; -#ifdef UNIV_SYNC_DEBUG ut_ad(!table->mutexes || mutex_own(hash_get_mutex(table, fold))); -#endif /* UNIV_SYNC_DEBUG */ node = ha_chain_get_first(table, fold); @@ -145,9 +141,7 @@ ha_search_with_data( { ha_node_t* node; -#ifdef UNIV_SYNC_DEBUG ut_ad(!table->mutexes || mutex_own(hash_get_mutex(table, fold))); -#endif /* UNIV_SYNC_DEBUG */ node = ha_chain_get_first(table, fold); @@ -177,9 +171,7 @@ ha_search_and_delete_if_found( { ha_node_t* node; -#ifdef UNIV_SYNC_DEBUG ut_ad(!table->mutexes || mutex_own(hash_get_mutex(table, fold))); -#endif /* UNIV_SYNC_DEBUG */ node = ha_search_with_data(table, fold, data); diff --git a/storage/innobase/include/lock0lock.ic b/storage/innobase/include/lock0lock.ic index feec460bec8..311623b190b 100644 --- a/storage/innobase/include/lock0lock.ic +++ b/storage/innobase/include/lock0lock.ic @@ -65,9 +65,7 @@ lock_clust_rec_some_has_impl( { dulint trx_id; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ ut_ad(index->type & DICT_CLUSTERED); ut_ad(page_rec_is_user_rec(rec)); diff --git a/storage/innobase/include/log0log.ic b/storage/innobase/include/log0log.ic index 06deff196bc..df0a8baf2d5 100644 --- a/storage/innobase/include/log0log.ic +++ b/storage/innobase/include/log0log.ic @@ -255,9 +255,7 @@ log_block_init( { ulint no; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(log_sys->mutex))); -#endif /* UNIV_SYNC_DEBUG */ no = log_block_convert_lsn_to_no(lsn); @@ -279,9 +277,7 @@ log_block_init_in_old_format( { ulint no; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(log_sys->mutex))); -#endif /* UNIV_SYNC_DEBUG */ no = log_block_convert_lsn_to_no(lsn); diff --git a/storage/innobase/include/mem0mem.h b/storage/innobase/include/mem0mem.h index f68d45d83df..2d5fd1db6c3 100644 --- a/storage/innobase/include/mem0mem.h +++ b/storage/innobase/include/mem0mem.h @@ -279,17 +279,6 @@ mem_strdupl( const char* str, /* in: string to be copied */ ulint len); /* in: length of str, in bytes */ -/************************************************************************** -Makes a NUL-terminated quoted copy of a NUL-terminated string. */ -UNIV_INLINE -char* -mem_strdupq( -/*========*/ - /* out, own: a quoted copy of the string, - must be deallocated with mem_free */ - const char* str, /* in: string to be copied */ - char q); /* in: quote character */ - /************************************************************************** Duplicates a NUL-terminated string, allocated from a memory heap. */ diff --git a/storage/innobase/include/mem0mem.ic b/storage/innobase/include/mem0mem.ic index 069f8de36cb..cb8fbe92cf0 100644 --- a/storage/innobase/include/mem0mem.ic +++ b/storage/innobase/include/mem0mem.ic @@ -589,41 +589,6 @@ mem_strdupl( return(memcpy(s, str, len)); } -/************************************************************************** -Makes a NUL-terminated quoted copy of a NUL-terminated string. */ -UNIV_INLINE -char* -mem_strdupq( -/*========*/ - /* out, own: a quoted copy of the string, - must be deallocated with mem_free */ - const char* str, /* in: string to be copied */ - char q) /* in: quote character */ -{ - char* dst; - char* d; - const char* s = str; - size_t len = strlen(str) + 3; - /* calculate the number of quote characters in the string */ - while((s = strchr(s, q)) != NULL) { - s++; - len++; - } - /* allocate the quoted string, and copy it */ - d = dst = mem_alloc(len); - *d++ = q; - s = str; - while(*s) { - if ((*d++ = *s++) == q) { - *d++ = q; - } - } - *d++ = q; - *d++ = '\0'; - ut_ad((ssize_t) len == d - dst); - return(dst); -} - /************************************************************************** Makes a NUL-terminated copy of a nonterminated string, allocated from a memory heap. */ diff --git a/storage/innobase/include/rem0rec.ic b/storage/innobase/include/rem0rec.ic index ace90247b80..90a35af74dc 100644 --- a/storage/innobase/include/rem0rec.ic +++ b/storage/innobase/include/rem0rec.ic @@ -995,6 +995,9 @@ rec_offs_nth_size( { ut_ad(rec_offs_validate(NULL, NULL, offsets)); ut_ad(n < rec_offs_n_fields(offsets)); + if (!n) { + return(rec_offs_base(offsets)[1 + n] & REC_OFFS_MASK); + } return((rec_offs_base(offsets)[1 + n] - rec_offs_base(offsets)[n]) & REC_OFFS_MASK); } diff --git a/storage/innobase/include/sync0rw.ic b/storage/innobase/include/sync0rw.ic index defe0692aa8..f8b5367739a 100644 --- a/storage/innobase/include/sync0rw.ic +++ b/storage/innobase/include/sync0rw.ic @@ -133,9 +133,8 @@ rw_lock_s_lock_low( const char* file_name, /* in: file name where lock requested */ ulint line) /* in: line where requested */ { -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(rw_lock_get_mutex(lock))); -#endif /* UNIV_SYNC_DEBUG */ + /* Check if the writer field is free */ if (UNIV_LIKELY(lock->writer == RW_LOCK_NOT_LOCKED)) { diff --git a/storage/innobase/include/sync0sync.h b/storage/innobase/include/sync0sync.h index e7e135c0c7e..69c0cd9e39b 100644 --- a/storage/innobase/include/sync0sync.h +++ b/storage/innobase/include/sync0sync.h @@ -114,13 +114,20 @@ mutex_enter_func( mutex_t* mutex, /* in: pointer to mutex */ const char* file_name, /* in: file name where locked */ ulint line); /* in: line where locked */ +/****************************************************************** +NOTE! The following macro should be used in mutex locking, not the +corresponding function. */ + +#define mutex_enter_nowait(M) \ + mutex_enter_nowait_func((M), __FILE__, __LINE__) /************************************************************************ -Tries to lock the mutex for the current thread. If the lock is not acquired -immediately, returns with return value 1. */ +NOTE! Use the corresponding macro in the header file, not this function +directly. Tries to lock the mutex for the current thread. If the lock is not +acquired immediately, returns with return value 1. */ ulint -mutex_enter_nowait( -/*===============*/ +mutex_enter_nowait_func( +/*====================*/ /* out: 0 if succeed, 1 if not */ mutex_t* mutex, /* in: pointer to mutex */ const char* file_name, /* in: file name where mutex @@ -170,7 +177,16 @@ Checks that the mutex has been initialized. */ ibool mutex_validate( /*===========*/ - mutex_t* mutex); + const mutex_t* mutex); +/********************************************************************** +Checks that the current thread owns the mutex. Works only +in the debug version. */ + +ibool +mutex_own( +/*======*/ + /* out: TRUE if owns */ + const mutex_t* mutex); /* in: mutex */ #endif /* UNIV_DEBUG */ #ifdef UNIV_SYNC_DEBUG /********************************************************************** @@ -215,15 +231,6 @@ sync_thread_levels_empty_gen( also purge_is_running mutex is allowed */ /********************************************************************** -Checks that the current thread owns the mutex. Works only -in the debug version. */ - -ibool -mutex_own( -/*======*/ - /* out: TRUE if owns */ - mutex_t* mutex); /* in: mutex */ -/********************************************************************** Gets the debug information for a reserved mutex. */ void @@ -248,7 +255,7 @@ UNIV_INLINE ulint mutex_get_lock_word( /*================*/ - mutex_t* mutex); /* in: mutex */ + const mutex_t* mutex); /* in: mutex */ #ifdef UNIV_SYNC_DEBUG /********************************************************************** NOT to be used outside this module except in debugging! Gets the waiters @@ -258,7 +265,7 @@ ulint mutex_get_waiters( /*==============*/ /* out: value to set */ - mutex_t* mutex); /* in: mutex */ + const mutex_t* mutex); /* in: mutex */ #endif /* UNIV_SYNC_DEBUG */ /* @@ -479,13 +486,13 @@ struct mutex_struct { #ifdef UNIV_SYNC_DEBUG const char* file_name; /* File where the mutex was locked */ ulint line; /* Line where the mutex was locked */ - os_thread_id_t thread_id; /* Debug version: The thread id of the - thread which locked the mutex. */ ulint level; /* Level in the global latching order */ #endif /* UNIV_SYNC_DEBUG */ const char* cfile_name;/* File name where mutex created */ ulint cline; /* Line where created */ #ifdef UNIV_DEBUG + os_thread_id_t thread_id; /* The thread id of the thread + which locked the mutex. */ ulint magic_n; # define MUTEX_MAGIC_N (ulint)979585 #endif /* UNIV_DEBUG */ diff --git a/storage/innobase/include/sync0sync.ic b/storage/innobase/include/sync0sync.ic index 4b48a1469ff..9bd5ac2a518 100644 --- a/storage/innobase/include/sync0sync.ic +++ b/storage/innobase/include/sync0sync.ic @@ -6,6 +6,16 @@ Mutex, the basic synchronization primitive Created 9/5/1995 Heikki Tuuri *******************************************************/ +#if defined(not_defined) && defined(__GNUC__) && defined(UNIV_INTEL_X86) +/* %z0: Use the size of operand %0 which in our case is *m to determine +instruction size, it should end up as xchgl. "1" in the input constraint, +says that "in" has to go in the same place as "out".*/ +#define TAS(m, in, out) \ + asm volatile ("xchg%z0 %2, %0" \ + : "=g" (*(m)), "=r" (out) \ + : "1" (in)) /* Note: "1" here refers to "=r" (out) */ +#endif + /********************************************************************** Sets the waiters field in a mutex. */ @@ -89,20 +99,10 @@ mutex_test_and_set( return(res); #elif defined(not_defined) && defined(__GNUC__) && defined(UNIV_INTEL_X86) - ulint* lw; ulint res; - lw = &(mutex->lock_word); + TAS(&mutex->lock_word, 1, res); - /* In assembly we use the so-called AT & T syntax where - the order of operands is inverted compared to the ordinary Intel - syntax. The 'l' after the mnemonics denotes a 32-bit operation. - The line after the code tells which values come out of the asm - code, and the second line tells the input to the asm code. */ - - asm volatile("movl $1, %%eax; xchgl (%%ecx), %%eax" : - "=eax" (res), "=m" (*lw) : - "ecx" (lw)); return(res); #else ibool ret; @@ -141,20 +141,9 @@ mutex_reset_lock_word( __asm MOV ECX, lw __asm XCHG EDX, DWORD PTR [ECX] #elif defined(not_defined) && defined(__GNUC__) && defined(UNIV_INTEL_X86) - ulint* lw; + ulint res; - lw = &(mutex->lock_word); - - /* In assembly we use the so-called AT & T syntax where - the order of operands is inverted compared to the ordinary Intel - syntax. The 'l' after the mnemonics denotes a 32-bit operation. */ - - asm volatile("movl $0, %%eax; xchgl (%%ecx), %%eax" : - "=m" (*lw) : - "ecx" (lw) : - "eax"); /* gcc does not seem to understand - that our asm code resets eax: tell it - explicitly that after the third ':' */ + TAS(&mutex->lock_word, 0, res); #else mutex->lock_word = 0; @@ -168,9 +157,9 @@ UNIV_INLINE ulint mutex_get_lock_word( /*================*/ - mutex_t* mutex) /* in: mutex */ + const mutex_t* mutex) /* in: mutex */ { - volatile ulint* ptr; /* declared volatile to ensure that + const volatile ulint* ptr; /* declared volatile to ensure that lock_word is loaded from memory */ ut_ad(mutex); @@ -186,9 +175,9 @@ ulint mutex_get_waiters( /*==============*/ /* out: value to set */ - mutex_t* mutex) /* in: mutex */ + const mutex_t* mutex) /* in: mutex */ { - volatile ulint* ptr; /* declared volatile to ensure that + const volatile ulint* ptr; /* declared volatile to ensure that the value is read from memory */ ut_ad(mutex); @@ -206,11 +195,11 @@ mutex_exit( /*=======*/ mutex_t* mutex) /* in: pointer to mutex */ { -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(mutex)); - mutex->thread_id = ULINT_UNDEFINED; + ut_d(mutex->thread_id = ULINT_UNDEFINED); +#ifdef UNIV_SYNC_DEBUG sync_thread_reset_level(mutex); #endif mutex_reset_lock_word(mutex); @@ -250,6 +239,7 @@ mutex_enter_func( ulint line) /* in: line where locked */ { ut_ad(mutex_validate(mutex)); + ut_ad(!mutex_own(mutex)); /* Note that we do not peek at the value of lock_word before trying the atomic test_and_set; we could peek, and possibly save time. */ @@ -259,6 +249,7 @@ mutex_enter_func( #endif /* UNIV_DEBUG && !UNIV_HOTBACKUP */ if (!mutex_test_and_set(mutex)) { + ut_d(mutex->thread_id = os_thread_get_curr_id()); #ifdef UNIV_SYNC_DEBUG mutex_set_debug_info(mutex, file_name, line); #endif diff --git a/storage/innobase/include/trx0sys.ic b/storage/innobase/include/trx0sys.ic index 9c950be09f0..86b71df08d6 100644 --- a/storage/innobase/include/trx0sys.ic +++ b/storage/innobase/include/trx0sys.ic @@ -62,9 +62,7 @@ trx_sys_get_nth_rseg( trx_sys_t* sys, /* in: trx system */ ulint n) /* in: index of slot */ { -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(kernel_mutex))); -#endif /* UNIV_SYNC_DEBUG */ ut_ad(n < TRX_SYS_N_RSEGS); return(sys->rseg_array[n]); @@ -121,9 +119,7 @@ trx_sysf_rseg_get_space( ulint i, /* in: slot index == rseg id */ mtr_t* mtr) /* in: mtr */ { -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(kernel_mutex))); -#endif /* UNIV_SYNC_DEBUG */ ut_ad(sys_header); ut_ad(i < TRX_SYS_N_RSEGS); @@ -146,9 +142,7 @@ trx_sysf_rseg_get_page_no( mtr_t* mtr) /* in: mtr */ { ut_ad(sys_header); -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(kernel_mutex))); -#endif /* UNIV_SYNC_DEBUG */ ut_ad(i < TRX_SYS_N_RSEGS); return(mtr_read_ulint(sys_header + TRX_SYS_RSEGS @@ -168,9 +162,7 @@ trx_sysf_rseg_set_space( ulint space, /* in: space id */ mtr_t* mtr) /* in: mtr */ { -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(kernel_mutex))); -#endif /* UNIV_SYNC_DEBUG */ ut_ad(sys_header); ut_ad(i < TRX_SYS_N_RSEGS); @@ -194,9 +186,7 @@ trx_sysf_rseg_set_page_no( slot is reset to unused */ mtr_t* mtr) /* in: mtr */ { -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(kernel_mutex))); -#endif /* UNIV_SYNC_DEBUG */ ut_ad(sys_header); ut_ad(i < TRX_SYS_N_RSEGS); @@ -250,9 +240,7 @@ trx_get_on_id( { trx_t* trx; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(kernel_mutex))); -#endif /* UNIV_SYNC_DEBUG */ trx = UT_LIST_GET_FIRST(trx_sys->trx_list); @@ -282,9 +270,7 @@ trx_list_get_min_trx_id(void) { trx_t* trx; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(kernel_mutex))); -#endif /* UNIV_SYNC_DEBUG */ trx = UT_LIST_GET_LAST(trx_sys->trx_list); @@ -307,9 +293,7 @@ trx_is_active( { trx_t* trx; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(kernel_mutex))); -#endif /* UNIV_SYNC_DEBUG */ if (ut_dulint_cmp(trx_id, trx_list_get_min_trx_id()) < 0) { @@ -346,9 +330,7 @@ trx_sys_get_new_trx_id(void) { dulint id; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ /* VERY important: after the database is started, max_trx_id value is divisible by TRX_SYS_TRX_ID_WRITE_MARGIN, and the following if @@ -378,9 +360,7 @@ trx_sys_get_new_trx_no(void) /*========================*/ /* out: new, allocated trx number */ { -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ return(trx_sys_get_new_trx_id()); } diff --git a/storage/innobase/include/univ.i b/storage/innobase/include/univ.i index 7a5cb21f07a..957baa0391f 100644 --- a/storage/innobase/include/univ.i +++ b/storage/innobase/include/univ.i @@ -40,9 +40,9 @@ if we are compiling on Windows. */ # undef VERSION /* Include the header file generated by GNU autoconf */ -#ifndef __WIN__ -# include "config.h" -#endif +# ifndef __WIN__ +# include "config.h" +# endif # ifdef HAVE_SCHED_H # include @@ -51,9 +51,9 @@ if we are compiling on Windows. */ /* When compiling for Itanium IA64, undefine the flag below to prevent use of the 32-bit x86 assembler in mutex operations. */ -#if defined(__WIN__) && !defined(WIN64) && !defined(_WIN64) -#define UNIV_CAN_USE_X86_ASSEMBLER -#endif +# if defined(__WIN__) && !defined(WIN64) && !defined(_WIN64) +# define UNIV_CAN_USE_X86_ASSEMBLER +# endif /* We only try to do explicit inlining of functions with gcc and Microsoft Visual C++ */ diff --git a/storage/innobase/include/ut0lst.h b/storage/innobase/include/ut0lst.h index 9735bf315c6..ebe2803fe23 100644 --- a/storage/innobase/include/ut0lst.h +++ b/storage/innobase/include/ut0lst.h @@ -74,6 +74,7 @@ the pointer to the node to be added to the list. NAME is the list name. */ ((N)->NAME).next = (BASE).start;\ ((N)->NAME).prev = NULL;\ if ((BASE).start != NULL) {\ + ut_ad((BASE).start != (N));\ (((BASE).start)->NAME).prev = (N);\ }\ (BASE).start = (N);\ @@ -94,6 +95,7 @@ the pointer to the node to be added to the list. NAME is the list name. */ ((N)->NAME).prev = (BASE).end;\ ((N)->NAME).next = NULL;\ if ((BASE).end != NULL) {\ + ut_ad((BASE).end != (N));\ (((BASE).end)->NAME).next = (N);\ }\ (BASE).end = (N);\ @@ -111,6 +113,7 @@ name, NODE1 and NODE2 are pointers to nodes. */ {\ ut_ad(NODE1);\ ut_ad(NODE2);\ + ut_ad((NODE1) != (NODE2));\ ((BASE).count)++;\ ((NODE2)->NAME).prev = (NODE1);\ ((NODE2)->NAME).next = ((NODE1)->NAME).next;\ diff --git a/storage/innobase/lock/lock0lock.c b/storage/innobase/lock/lock0lock.c index 84b64b146dc..93a43d9a30f 100644 --- a/storage/innobase/lock/lock0lock.c +++ b/storage/innobase/lock/lock0lock.c @@ -1162,9 +1162,7 @@ lock_rec_get_next_on_page( ulint space; ulint page_no; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ ut_ad(lock_get_type(lock) == LOCK_REC); space = lock->un_member.rec_lock.space; @@ -1201,9 +1199,7 @@ lock_rec_get_first_on_page_addr( { lock_t* lock; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ lock = HASH_GET_FIRST(lock_sys->rec_hash, lock_rec_hash(space, page_no)); @@ -1261,9 +1257,7 @@ lock_rec_get_first_on_page( ulint space; ulint page_no; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ hash = buf_frame_get_lock_hash_val(ptr); @@ -1295,9 +1289,7 @@ lock_rec_get_next( rec_t* rec, /* in: record on a page */ lock_t* lock) /* in: lock */ { -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ ut_ad(lock_get_type(lock) == LOCK_REC); if (page_rec_is_comp(rec)) { @@ -1326,9 +1318,7 @@ lock_rec_get_first( { lock_t* lock; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ lock = lock_rec_get_first_on_page(rec); if (UNIV_LIKELY_NULL(lock)) { @@ -1414,9 +1404,7 @@ lock_rec_get_prev( ulint page_no; lock_t* found_lock = NULL; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ ut_ad(lock_get_type(in_lock) == LOCK_REC); space = in_lock->un_member.rec_lock.space; @@ -1456,9 +1444,7 @@ lock_table_has( { lock_t* lock; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ /* Look for stronger locks the same trx already has on the table */ @@ -1502,9 +1488,7 @@ lock_rec_has_expl( { lock_t* lock; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ ut_ad((precise_mode & LOCK_MODE_MASK) == LOCK_S || (precise_mode & LOCK_MODE_MASK) == LOCK_X); ut_ad(!(precise_mode & LOCK_INSERT_INTENTION)); @@ -1552,9 +1536,7 @@ lock_rec_other_has_expl_req( { lock_t* lock; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ ut_ad(mode == LOCK_X || mode == LOCK_S); ut_ad(gap == 0 || gap == LOCK_GAP); ut_ad(wait == 0 || wait == LOCK_WAIT); @@ -1594,9 +1576,8 @@ lock_rec_other_has_conflicting( trx_t* trx) /* in: our transaction */ { lock_t* lock; -#ifdef UNIV_SYNC_DEBUG + ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ lock = lock_rec_get_first(rec); @@ -1629,9 +1610,7 @@ lock_rec_find_similar_on_page( lock_t* lock; ulint heap_no; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ heap_no = rec_get_heap_no(rec, page_rec_is_comp(rec)); lock = lock_rec_get_first_on_page(rec); @@ -1665,9 +1644,7 @@ lock_sec_rec_some_has_impl_off_kernel( { page_t* page; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ ut_ad(!(index->type & DICT_CLUSTERED)); ut_ad(page_rec_is_user_rec(rec)); ut_ad(rec_offs_validate(rec, index, offsets)); @@ -1760,9 +1737,7 @@ lock_rec_create( ulint n_bits; ulint n_bytes; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ page = buf_frame_align(rec); space = buf_frame_get_space_id(page); @@ -1842,9 +1817,7 @@ lock_rec_enqueue_waiting( lock_t* lock; trx_t* trx; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ /* Test if there already is some other reason to suspend thread: we do not enqueue a lock request if the query thread should be @@ -1934,9 +1907,7 @@ lock_rec_add_to_queue( ulint heap_no; ibool somebody_waits = FALSE; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ ut_ad((type_mode & (LOCK_WAIT | LOCK_GAP)) || ((type_mode & LOCK_MODE_MASK) != LOCK_S) || !lock_rec_other_has_expl_req(LOCK_X, 0, LOCK_WAIT, @@ -2017,9 +1988,7 @@ lock_rec_lock_fast( ulint heap_no; trx_t* trx; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ ut_ad((LOCK_MODE_MASK & mode) != LOCK_S || lock_table_has(thr_get_trx(thr), index->table, LOCK_IS)); ut_ad((LOCK_MODE_MASK & mode) != LOCK_X @@ -2102,9 +2071,7 @@ lock_rec_lock_slow( trx_t* trx; ulint err; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ ut_ad((LOCK_MODE_MASK & mode) != LOCK_S || lock_table_has(thr_get_trx(thr), index->table, LOCK_IS)); ut_ad((LOCK_MODE_MASK & mode) != LOCK_X @@ -2176,9 +2143,7 @@ lock_rec_lock( { ulint err; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ ut_ad((LOCK_MODE_MASK & mode) != LOCK_S || lock_table_has(thr_get_trx(thr), index->table, LOCK_IS)); ut_ad((LOCK_MODE_MASK & mode) != LOCK_X @@ -2216,9 +2181,7 @@ lock_rec_has_to_wait_in_queue( ulint page_no; ulint heap_no; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ ut_ad(lock_get_wait(wait_lock)); ut_ad(lock_get_type(wait_lock) == LOCK_REC); @@ -2251,9 +2214,7 @@ lock_grant( /*=======*/ lock_t* lock) /* in: waiting lock request */ { -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ lock_reset_lock_and_trx_wait(lock); @@ -2298,9 +2259,7 @@ lock_rec_cancel( /*============*/ lock_t* lock) /* in: waiting record lock request */ { -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ ut_ad(lock_get_type(lock) == LOCK_REC); /* Reset the bit (there can be only one set bit) in the lock bitmap */ @@ -2333,9 +2292,7 @@ lock_rec_dequeue_from_page( lock_t* lock; trx_t* trx; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ ut_ad(lock_get_type(in_lock) == LOCK_REC); trx = in_lock->trx; @@ -2378,9 +2335,7 @@ lock_rec_discard( ulint page_no; trx_t* trx; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ ut_ad(lock_get_type(in_lock) == LOCK_REC); trx = in_lock->trx; @@ -2409,9 +2364,7 @@ lock_rec_free_all_from_discard_page( lock_t* lock; lock_t* next_lock; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ space = buf_frame_get_space_id(page); page_no = buf_frame_get_page_no(page); @@ -2444,9 +2397,7 @@ lock_rec_reset_and_release_wait( lock_t* lock; ulint heap_no; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ heap_no = rec_get_heap_no(rec, page_rec_is_comp(rec)); @@ -2477,9 +2428,8 @@ lock_rec_inherit_to_gap( the locks on this record */ { lock_t* lock; -#ifdef UNIV_SYNC_DEBUG + ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ lock = lock_rec_get_first(rec); @@ -2518,9 +2468,8 @@ lock_rec_inherit_to_gap_if_gap_lock( the locks on this record */ { lock_t* lock; -#ifdef UNIV_SYNC_DEBUG + ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ lock = lock_rec_get_first(rec); @@ -2554,9 +2503,7 @@ lock_rec_move( ulint heap_no; ulint type_mode; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ heap_no = rec_get_heap_no(donator, comp); @@ -3228,9 +3175,7 @@ lock_deadlock_occurs( ulint cost = 0; ut_ad(trx && lock); -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ retry: /* We check that adding this trx to the waits-for graph does not produce a cycle. First mark all active transactions @@ -3302,9 +3247,7 @@ lock_deadlock_recursive( ulint ret; ut_a(trx && start && wait_lock); -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ if (trx->deadlock_mark == 1) { /* We have already exhaustively searched the subtree starting @@ -3315,12 +3258,6 @@ lock_deadlock_recursive( *cost = *cost + 1; - if ((depth > LOCK_MAX_DEPTH_IN_DEADLOCK_CHECK) - || (*cost > LOCK_MAX_N_STEPS_IN_DEADLOCK_CHECK)) { - - return(LOCK_VICTIM_IS_START); - } - lock = wait_lock; if (lock_get_type(wait_lock) == LOCK_REC) { @@ -3353,11 +3290,18 @@ lock_deadlock_recursive( if (lock_has_to_wait(wait_lock, lock)) { + ibool too_far + = depth > LOCK_MAX_DEPTH_IN_DEADLOCK_CHECK + || *cost > LOCK_MAX_N_STEPS_IN_DEADLOCK_CHECK; + lock_trx = lock->trx; - if (lock_trx == start) { + if (lock_trx == start || too_far) { + /* We came back to the recursion starting - point: a deadlock detected */ + point: a deadlock detected; or we have + searched the waits-for graph too long */ + FILE* ef = lock_latest_err_file; rewind(ef); @@ -3399,9 +3343,20 @@ lock_deadlock_recursive( } #ifdef UNIV_DEBUG if (lock_print_waits) { - fputs("Deadlock detected\n", stderr); + fputs("Deadlock detected" + " or too long search\n", + stderr); } #endif /* UNIV_DEBUG */ + if (too_far) { + + fputs("TOO DEEP OR LONG SEARCH" + " IN THE LOCK TABLE" + " WAITS-FOR GRAPH\n", ef); + + return(LOCK_VICTIM_IS_START); + } + if (ut_dulint_cmp(wait_lock->trx->undo_no, start->undo_no) >= 0) { /* Our recursion starting point @@ -3472,9 +3427,7 @@ lock_table_create( lock_t* lock; ut_ad(table && trx); -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ if (type_mode == LOCK_AUTO_INC) { /* Only one trx can have the lock on the table @@ -3519,9 +3472,7 @@ lock_table_remove_low( dict_table_t* table; trx_t* trx; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ table = lock->un_member.tab_lock.table; trx = lock->trx; @@ -3555,9 +3506,7 @@ lock_table_enqueue_waiting( lock_t* lock; trx_t* trx; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ /* Test if there already is some other reason to suspend thread: we do not enqueue a lock request if the query thread should be @@ -3630,9 +3579,7 @@ lock_table_other_has_incompatible( { lock_t* lock; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ lock = UT_LIST_GET_LAST(table->locks); @@ -3786,9 +3733,7 @@ lock_table_dequeue( { lock_t* lock; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ ut_a(lock_get_type(in_lock) == LOCK_TABLE); lock = UT_LIST_GET_NEXT(un_member.tab_lock.locks, in_lock); @@ -3930,9 +3875,7 @@ lock_release_off_kernel( ulint count; lock_t* lock; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ lock = UT_LIST_GET_LAST(trx->trx_locks); @@ -3993,9 +3936,7 @@ lock_cancel_waiting_and_release( /*============================*/ lock_t* lock) /* in: waiting lock request */ { -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ if (lock_get_type(lock) == LOCK_REC) { @@ -4028,9 +3969,7 @@ lock_reset_all_on_table_for_trx( lock_t* lock; lock_t* prev_lock; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ lock = UT_LIST_GET_LAST(trx->trx_locks); @@ -4091,9 +4030,7 @@ lock_table_print( FILE* file, /* in: file where to print */ lock_t* lock) /* in: table type lock */ { -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ ut_a(lock_get_type(lock) == LOCK_TABLE); fputs("TABLE LOCK table ", file); @@ -4143,9 +4080,7 @@ lock_rec_print( ulint* offsets = offsets_; *offsets_ = (sizeof offsets_) / sizeof *offsets_; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ ut_a(lock_get_type(lock) == LOCK_REC); space = lock->un_member.rec_lock.space; @@ -4250,9 +4185,7 @@ lock_get_n_rec_locks(void) ulint n_locks = 0; ulint i; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ for (i = 0; i < hash_get_n_cells(lock_sys->rec_hash); i++) { @@ -4492,9 +4425,7 @@ lock_table_queue_validate( lock_t* lock; ibool is_waiting; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ is_waiting = FALSE; @@ -4665,9 +4596,7 @@ lock_rec_validate_page( ulint* offsets = offsets_; *offsets_ = (sizeof offsets_) / sizeof *offsets_; -#ifdef UNIV_SYNC_DEBUG ut_ad(!mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ mtr_start(&mtr); @@ -4943,9 +4872,7 @@ lock_rec_convert_impl_to_expl( { trx_t* impl_trx; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ ut_ad(page_rec_is_user_rec(rec)); ut_ad(rec_offs_validate(rec, index, offsets)); ut_ad(!page_rec_is_comp(rec) == !rec_offs_comp(offsets)); diff --git a/storage/innobase/log/log0log.c b/storage/innobase/log/log0log.c index 5d8875f1bd0..e9dedf6aac4 100644 --- a/storage/innobase/log/log0log.c +++ b/storage/innobase/log/log0log.c @@ -165,9 +165,7 @@ log_buf_pool_get_oldest_modification(void) { dulint lsn; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(log_sys->mutex))); -#endif /* UNIV_SYNC_DEBUG */ lsn = buf_pool_get_oldest_modification(); @@ -269,9 +267,7 @@ log_write_low( ulint data_len; byte* log_block; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(log->mutex))); -#endif /* UNIV_SYNC_DEBUG */ part_loop: /* Calculate a part length */ @@ -340,9 +336,7 @@ log_close(void) log_t* log = log_sys; ulint checkpoint_age; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(log->mutex))); -#endif /* UNIV_SYNC_DEBUG */ lsn = log->lsn; @@ -464,9 +458,7 @@ log_group_get_capacity( /* out: capacity in bytes */ log_group_t* group) /* in: log group */ { -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(log_sys->mutex))); -#endif /* UNIV_SYNC_DEBUG */ return((group->file_size - LOG_FILE_HDR_SIZE) * group->n_files); } @@ -482,9 +474,7 @@ log_group_calc_size_offset( ulint offset, /* in: real offset within the log group */ log_group_t* group) /* in: log group */ { -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(log_sys->mutex))); -#endif /* UNIV_SYNC_DEBUG */ return(offset - LOG_FILE_HDR_SIZE * (1 + offset / group->file_size)); } @@ -500,9 +490,7 @@ log_group_calc_real_offset( ulint offset, /* in: size offset within the log group */ log_group_t* group) /* in: log group */ { -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(log_sys->mutex))); -#endif /* UNIV_SYNC_DEBUG */ return(offset + LOG_FILE_HDR_SIZE * (1 + offset / (group->file_size - LOG_FILE_HDR_SIZE))); @@ -525,9 +513,7 @@ log_group_calc_lsn_offset( ib_longlong group_size; ib_longlong offset; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(log_sys->mutex))); -#endif /* UNIV_SYNC_DEBUG */ /* If total log file size is > 2 GB we can easily get overflows with 32-bit integers. Use 64-bit integers instead. */ @@ -642,9 +628,7 @@ log_calc_max_ages(void) ulint archive_margin; ulint smallest_archive_margin; -#ifdef UNIV_SYNC_DEBUG ut_ad(!mutex_own(&(log_sys->mutex))); -#endif /* UNIV_SYNC_DEBUG */ mutex_enter(&(log_sys->mutex)); @@ -942,9 +926,7 @@ log_flush_do_unlocks( ulint code) /* in: any ORed combination of LOG_UNLOCK_FLUSH_LOCK and LOG_UNLOCK_NONE_FLUSHED_LOCK */ { -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(log_sys->mutex))); -#endif /* UNIV_SYNC_DEBUG */ /* NOTE that we must own the log mutex when doing the setting of the events: this is because transactions will wait for these events to @@ -976,9 +958,7 @@ log_group_check_flush_completion( /* out: LOG_UNLOCK_NONE_FLUSHED_LOCK or 0 */ log_group_t* group) /* in: log group */ { -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(log_sys->mutex))); -#endif /* UNIV_SYNC_DEBUG */ if (!log_sys->one_flushed && group->n_pending_writes == 0) { #ifdef UNIV_DEBUG @@ -1015,9 +995,7 @@ log_sys_check_flush_completion(void) ulint move_start; ulint move_end; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(log_sys->mutex))); -#endif /* UNIV_SYNC_DEBUG */ if (log_sys->n_pending_writes == 0) { @@ -1129,10 +1107,8 @@ log_group_file_header_flush( { byte* buf; ulint dest_offset; -#ifdef UNIV_SYNC_DEBUG - ut_ad(mutex_own(&(log_sys->mutex))); -#endif /* UNIV_SYNC_DEBUG */ + ut_ad(mutex_own(&(log_sys->mutex))); ut_a(nth_file < group->n_files); buf = *(group->file_header_bufs + nth_file); @@ -1203,9 +1179,7 @@ log_group_write_buf( ulint next_offset; ulint i; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(log_sys->mutex))); -#endif /* UNIV_SYNC_DEBUG */ ut_a(len % OS_FILE_LOG_BLOCK_SIZE == 0); ut_a(ut_dulint_get_low(start_lsn) % OS_FILE_LOG_BLOCK_SIZE == 0); @@ -1626,9 +1600,7 @@ void log_complete_checkpoint(void) /*=========================*/ { -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(log_sys->mutex))); -#endif /* UNIV_SYNC_DEBUG */ ut_ad(log_sys->n_pending_checkpoint_writes == 0); log_sys->next_checkpoint_no @@ -1715,9 +1687,7 @@ log_group_checkpoint( byte* buf; ulint i; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(log_sys->mutex))); -#endif /* UNIV_SYNC_DEBUG */ #if LOG_CHECKPOINT_SIZE > OS_FILE_LOG_BLOCK_SIZE # error "LOG_CHECKPOINT_SIZE > OS_FILE_LOG_BLOCK_SIZE" #endif @@ -1882,9 +1852,7 @@ log_group_read_checkpoint_info( log_group_t* group, /* in: log group */ ulint field) /* in: LOG_CHECKPOINT_1 or LOG_CHECKPOINT_2 */ { -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(log_sys->mutex))); -#endif /* UNIV_SYNC_DEBUG */ log_sys->n_log_ios++; @@ -1902,9 +1870,7 @@ log_groups_write_checkpoint_info(void) { log_group_t* group; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(log_sys->mutex))); -#endif /* UNIV_SYNC_DEBUG */ group = UT_LIST_GET_FIRST(log_sys->log_groups); @@ -2162,9 +2128,7 @@ log_group_read_log_seg( ulint source_offset; ibool sync; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(log_sys->mutex))); -#endif /* UNIV_SYNC_DEBUG */ sync = FALSE; @@ -2237,9 +2201,7 @@ log_group_archive_file_header_write( byte* buf; ulint dest_offset; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(log_sys->mutex))); -#endif /* UNIV_SYNC_DEBUG */ ut_a(nth_file < group->n_files); @@ -2276,9 +2238,7 @@ log_group_archive_completed_header_write( byte* buf; ulint dest_offset; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(log_sys->mutex))); -#endif /* UNIV_SYNC_DEBUG */ ut_a(nth_file < group->n_files); buf = *(group->archive_file_header_bufs + nth_file); @@ -2317,9 +2277,7 @@ log_group_archive( ulint n_files; ulint open_mode; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(log_sys->mutex))); -#endif /* UNIV_SYNC_DEBUG */ start_lsn = log_sys->archived_lsn; @@ -2452,9 +2410,7 @@ log_archive_groups(void) { log_group_t* group; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(log_sys->mutex))); -#endif /* UNIV_SYNC_DEBUG */ group = UT_LIST_GET_FIRST(log_sys->log_groups); @@ -2477,9 +2433,7 @@ log_archive_write_complete_groups(void) dulint end_lsn; ulint i; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(log_sys->mutex))); -#endif /* UNIV_SYNC_DEBUG */ group = UT_LIST_GET_FIRST(log_sys->log_groups); @@ -2546,9 +2500,7 @@ void log_archive_check_completion_low(void) /*==================================*/ { -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(log_sys->mutex))); -#endif /* UNIV_SYNC_DEBUG */ if (log_sys->n_pending_archive_ios == 0 && log_sys->archiving_phase == LOG_ARCHIVE_READ) { @@ -2784,9 +2736,7 @@ log_archive_close_groups( log_group_t* group; ulint trunc_len; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(log_sys->mutex))); -#endif /* UNIV_SYNC_DEBUG */ if (log_sys->archiving_state == LOG_ARCH_OFF) { @@ -3278,9 +3228,7 @@ log_check_log_recs( byte* buf1; byte* scan_buf; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(log_sys->mutex))); -#endif /* UNIV_SYNC_DEBUG */ if (len == 0) { @@ -3322,7 +3270,7 @@ log_peek_lsn( log system mutex */ dulint* lsn) /* out: if returns TRUE, current lsn is here */ { - if (0 == mutex_enter_nowait(&(log_sys->mutex), __FILE__, __LINE__)) { + if (0 == mutex_enter_nowait(&(log_sys->mutex))) { *lsn = log_sys->lsn; mutex_exit(&(log_sys->mutex)); diff --git a/storage/innobase/log/log0recv.c b/storage/innobase/log/log0recv.c index 41e2b921664..ab5f42e3a13 100644 --- a/storage/innobase/log/log0recv.c +++ b/storage/innobase/log/log0recv.c @@ -171,9 +171,8 @@ void recv_sys_empty_hash(void) /*=====================*/ { -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(recv_sys->mutex))); -#endif /* UNIV_SYNC_DEBUG */ + if (recv_sys->n_addrs != 0) { fprintf(stderr, "InnoDB: Error: %lu pages with log records" @@ -1396,9 +1395,8 @@ loop: goto loop; } -#ifdef UNIV_SYNC_DEBUG ut_ad(!allow_ibuf == mutex_own(&log_sys->mutex)); -#endif /* UNIV_SYNC_DEBUG */ + if (!allow_ibuf) { recv_no_ibuf_operations = TRUE; } @@ -1842,9 +1840,7 @@ recv_parse_log_recs( byte* body; ulint n_recs; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(log_sys->mutex))); -#endif /* UNIV_SYNC_DEBUG */ ut_ad(!ut_dulint_is_zero(recv_sys->parse_start_lsn)); loop: ptr = recv_sys->buf + recv_sys->recovered_offset; @@ -2894,9 +2890,8 @@ recv_reset_logs( { log_group_t* group; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(log_sys->mutex))); -#endif /* UNIV_SYNC_DEBUG */ + log_sys->lsn = ut_dulint_align_up(lsn, OS_FILE_LOG_BLOCK_SIZE); group = UT_LIST_GET_FIRST(log_sys->log_groups); diff --git a/storage/innobase/mem/mem0pool.c b/storage/innobase/mem/mem0pool.c index a7acd331e16..c010ae61160 100644 --- a/storage/innobase/mem/mem0pool.c +++ b/storage/innobase/mem/mem0pool.c @@ -257,9 +257,7 @@ mem_pool_fill_free_list( mem_area_t* area2; ibool ret; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(pool->mutex))); -#endif /* UNIV_SYNC_DEBUG */ if (i >= 63) { /* We come here when we have run out of space in the diff --git a/storage/innobase/pars/pars0pars.c b/storage/innobase/pars/pars0pars.c index 6861844870c..16530494a96 100644 --- a/storage/innobase/pars/pars0pars.c +++ b/storage/innobase/pars/pars0pars.c @@ -1859,10 +1859,9 @@ pars_sql( heap = mem_heap_create(256); -#ifdef UNIV_SYNC_DEBUG /* Currently, the parser is not reentrant: */ ut_ad(mutex_own(&(dict_sys->mutex))); -#endif /* UNIV_SYNC_DEBUG */ + pars_sym_tab_global = sym_tab_create(heap); pars_sym_tab_global->string_len = strlen(str); diff --git a/storage/innobase/que/que0que.c b/storage/innobase/que/que0que.c index f5a63ae6ffa..bf83f28f04e 100644 --- a/storage/innobase/que/que0que.c +++ b/storage/innobase/que/que0que.c @@ -127,9 +127,7 @@ que_graph_publish( que_t* graph, /* in: graph */ sess_t* sess) /* in: session */ { -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ UT_LIST_ADD_LAST(graphs, sess->graphs, graph); } @@ -238,9 +236,7 @@ que_thr_end_wait( { ibool was_active; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ ut_ad(thr); ut_ad((thr->state == QUE_THR_LOCK_WAIT) || (thr->state == QUE_THR_PROCEDURE_WAIT) @@ -280,9 +276,7 @@ que_thr_end_wait_no_next_thr( ut_a(thr->state == QUE_THR_LOCK_WAIT); /* In MySQL this is the only possible state here */ -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ ut_ad(thr); ut_ad((thr->state == QUE_THR_LOCK_WAIT) || (thr->state == QUE_THR_PROCEDURE_WAIT) @@ -419,9 +413,7 @@ que_fork_error_handle( { que_thr_t* thr; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ ut_ad(trx->sess->state == SESS_ERROR); ut_ad(UT_LIST_GET_LEN(trx->reply_signals) == 0); ut_ad(UT_LIST_GET_LEN(trx->wait_thrs) == 0); @@ -698,9 +690,7 @@ que_graph_try_free( { sess_t* sess; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ sess = (graph->trx)->sess; @@ -931,9 +921,7 @@ que_thr_stop( que_t* graph; ibool ret = TRUE; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ graph = thr->graph; trx = graph->trx; @@ -1309,10 +1297,7 @@ que_run_threads_low( ut_ad(thr->state == QUE_THR_RUNNING); ut_a(thr_get_trx(thr)->error_state == DB_SUCCESS); - -#ifdef UNIV_SYNC_DEBUG ut_ad(!mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ /* cumul_resource counts how much resources the OS thread (NOT the query thread) has spent in this function */ diff --git a/storage/innobase/read/read0read.c b/storage/innobase/read/read0read.c index 2375c35190a..10a6e07e96a 100644 --- a/storage/innobase/read/read0read.c +++ b/storage/innobase/read/read0read.c @@ -162,9 +162,8 @@ read_view_oldest_copy_or_open_new( ulint n; ulint i; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ + old_view = UT_LIST_GET_LAST(trx_sys->view_list); if (old_view == NULL) { @@ -245,9 +244,9 @@ read_view_open_now( read_view_t* view; trx_t* trx; ulint n; -#ifdef UNIV_SYNC_DEBUG + ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ + view = read_view_create_low(UT_LIST_GET_LEN(trx_sys->trx_list), heap); view->creator_trx_id = cr_trx_id; @@ -313,9 +312,8 @@ read_view_close( /*============*/ read_view_t* view) /* in: read view */ { -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ + UT_LIST_REMOVE(view_list, trx_sys->view_list, view); } diff --git a/storage/innobase/row/row0mysql.c b/storage/innobase/row/row0mysql.c index 78851c7b4f9..7c9427db0d2 100644 --- a/storage/innobase/row/row0mysql.c +++ b/storage/innobase/row/row0mysql.c @@ -1748,8 +1748,8 @@ row_create_table_for_mysql( ut_ad(trx->mysql_thread_id == os_thread_get_curr_id()); #ifdef UNIV_SYNC_DEBUG ut_ad(rw_lock_own(&dict_operation_lock, RW_LOCK_EX)); - ut_ad(mutex_own(&(dict_sys->mutex))); #endif /* UNIV_SYNC_DEBUG */ + ut_ad(mutex_own(&(dict_sys->mutex))); ut_ad(trx->dict_operation_lock_mode == RW_X_LATCH); if (srv_created_new_raw) { @@ -1964,8 +1964,8 @@ row_create_index_for_mysql( #ifdef UNIV_SYNC_DEBUG ut_ad(rw_lock_own(&dict_operation_lock, RW_LOCK_EX)); - ut_ad(mutex_own(&(dict_sys->mutex))); #endif /* UNIV_SYNC_DEBUG */ + ut_ad(mutex_own(&(dict_sys->mutex))); ut_ad(trx->mysql_thread_id == os_thread_get_curr_id()); trx->op_info = "creating index"; @@ -2080,8 +2080,8 @@ row_table_add_foreign_constraints( { ulint err; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(dict_sys->mutex))); +#ifdef UNIV_SYNC_DEBUG ut_ad(rw_lock_own(&dict_operation_lock, RW_LOCK_EX)); #endif /* UNIV_SYNC_DEBUG */ ut_a(sql_string); @@ -2246,9 +2246,7 @@ row_get_background_drop_list_len_low(void) /*======================================*/ /* out: how many tables in list */ { -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ if (!row_mysql_drop_list_inited) { @@ -2726,8 +2724,8 @@ row_truncate_table_for_mysql( row_mysql_lock_data_dictionary(trx); -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(dict_sys->mutex))); +#ifdef UNIV_SYNC_DEBUG ut_ad(rw_lock_own(&dict_operation_lock, RW_LOCK_EX)); #endif /* UNIV_SYNC_DEBUG */ @@ -3001,8 +2999,8 @@ row_drop_table_for_mysql( locked_dictionary = TRUE; } -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(dict_sys->mutex))); +#ifdef UNIV_SYNC_DEBUG ut_ad(rw_lock_own(&dict_operation_lock, RW_LOCK_EX)); #endif /* UNIV_SYNC_DEBUG */ diff --git a/storage/innobase/row/row0vers.c b/storage/innobase/row/row0vers.c index c8b71965f75..03d9a2f1203 100644 --- a/storage/innobase/row/row0vers.c +++ b/storage/innobase/row/row0vers.c @@ -63,8 +63,8 @@ row_vers_impl_x_locked_off_kernel( mtr_t mtr; ulint comp; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); +#ifdef UNIV_SYNC_DEBUG ut_ad(!rw_lock_own(&(purge_sys->latch), RW_LOCK_SHARED)); #endif /* UNIV_SYNC_DEBUG */ diff --git a/storage/innobase/srv/srv0que.c b/storage/innobase/srv/srv0que.c index 9c261cbb00e..e2b4e217980 100644 --- a/storage/innobase/srv/srv0que.c +++ b/storage/innobase/srv/srv0que.c @@ -82,10 +82,7 @@ srv_que_task_enqueue_low( que_thr_t* thr) /* in: query thread */ { ut_ad(thr); - -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ UT_LIST_ADD_LAST(queue, srv_sys->tasks, thr); diff --git a/storage/innobase/srv/srv0srv.c b/storage/innobase/srv/srv0srv.c index 2a177ed26cd..72e8fe751d0 100644 --- a/storage/innobase/srv/srv0srv.c +++ b/storage/innobase/srv/srv0srv.c @@ -726,9 +726,7 @@ srv_suspend_thread(void) ulint slot_no; ulint type; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ slot_no = thr_local_get_slot_no(os_thread_get_curr_id()); @@ -780,9 +778,7 @@ srv_release_threads( ut_ad(type >= SRV_WORKER); ut_ad(type <= SRV_MASTER); ut_ad(n > 0); -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ for (i = 0; i < OS_THREAD_MAX_N; i++) { @@ -1305,9 +1301,7 @@ srv_table_reserve_slot_for_mysql(void) srv_slot_t* slot; ulint i; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ i = 0; slot = srv_mysql_table + i; @@ -1387,9 +1381,7 @@ srv_suspend_mysql_thread( ulint sec; ulint ms; -#ifdef UNIV_SYNC_DEBUG ut_ad(!mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ trx = thr_get_trx(thr); @@ -1535,9 +1527,7 @@ srv_release_mysql_thread_if_suspended( srv_slot_t* slot; ulint i; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ for (i = 0; i < OS_THREAD_MAX_N; i++) { @@ -1830,15 +1820,15 @@ srv_export_innodb_status(void) export_vars.innodb_row_lock_waits = srv_n_lock_wait_count; export_vars.innodb_row_lock_current_waits = srv_n_lock_wait_current_count; - export_vars.innodb_row_lock_time = srv_n_lock_wait_time / 10000; + export_vars.innodb_row_lock_time = srv_n_lock_wait_time / 1000; if (srv_n_lock_wait_count > 0) { export_vars.innodb_row_lock_time_avg = (ulint) - (srv_n_lock_wait_time / 10000 / srv_n_lock_wait_count); + (srv_n_lock_wait_time / 1000 / srv_n_lock_wait_count); } else { export_vars.innodb_row_lock_time_avg = 0; } export_vars.innodb_row_lock_time_max - = srv_n_lock_max_wait_time / 10000; + = srv_n_lock_max_wait_time / 1000; export_vars.innodb_rows_read = srv_n_rows_read; export_vars.innodb_rows_inserted = srv_n_rows_inserted; export_vars.innodb_rows_updated = srv_n_rows_updated; diff --git a/storage/innobase/sync/sync0rw.c b/storage/innobase/sync/sync0rw.c index f06db577bad..34b45e2c1c3 100644 --- a/storage/innobase/sync/sync0rw.c +++ b/storage/innobase/sync/sync0rw.c @@ -339,9 +339,8 @@ rw_lock_x_lock_low( const char* file_name,/* in: file name where lock requested */ ulint line) /* in: line where requested */ { -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(rw_lock_get_mutex(lock))); -#endif /* UNIV_SYNC_DEBUG */ + if (rw_lock_get_writer(lock) == RW_LOCK_NOT_LOCKED) { if (rw_lock_get_reader_count(lock) == 0) { @@ -564,8 +563,7 @@ rw_lock_debug_mutex_enter(void) /*==========================*/ { loop: - if (0 == mutex_enter_nowait(&rw_lock_debug_mutex, - __FILE__, __LINE__)) { + if (0 == mutex_enter_nowait(&rw_lock_debug_mutex)) { return; } @@ -573,8 +571,7 @@ loop: rw_lock_debug_waiters = TRUE; - if (0 == mutex_enter_nowait(&rw_lock_debug_mutex, - __FILE__, __LINE__)) { + if (0 == mutex_enter_nowait(&rw_lock_debug_mutex)) { return; } diff --git a/storage/innobase/sync/sync0sync.c b/storage/innobase/sync/sync0sync.c index c0198469491..672e1f93aad 100644 --- a/storage/innobase/sync/sync0sync.c +++ b/storage/innobase/sync/sync0sync.c @@ -311,12 +311,13 @@ mutex_free( } /************************************************************************ -Tries to lock the mutex for the current thread. If the lock is not acquired -immediately, returns with return value 1. */ +NOTE! Use the corresponding macro in the header file, not this function +directly. Tries to lock the mutex for the current thread. If the lock is not +acquired immediately, returns with return value 1. */ ulint -mutex_enter_nowait( -/*===============*/ +mutex_enter_nowait_func( +/*====================*/ /* out: 0 if succeed, 1 if not */ mutex_t* mutex, /* in: pointer to mutex */ const char* file_name __attribute__((unused)), @@ -329,6 +330,7 @@ mutex_enter_nowait( if (!mutex_test_and_set(mutex)) { + ut_d(mutex->thread_id = os_thread_get_curr_id()); #ifdef UNIV_SYNC_DEBUG mutex_set_debug_info(mutex, file_name, line); #endif @@ -346,13 +348,29 @@ Checks that the mutex has been initialized. */ ibool mutex_validate( /*===========*/ - mutex_t* mutex) + const mutex_t* mutex) { ut_a(mutex); ut_a(mutex->magic_n == MUTEX_MAGIC_N); return(TRUE); } + +/********************************************************************** +Checks that the current thread owns the mutex. Works only in the debug +version. */ + +ibool +mutex_own( +/*======*/ + /* out: TRUE if owns */ + const mutex_t* mutex) /* in: mutex */ +{ + ut_ad(mutex_validate(mutex)); + + return(mutex_get_lock_word(mutex) == 1 + && os_thread_eq(mutex->thread_id, os_thread_get_curr_id())); +} #endif /* UNIV_DEBUG */ /********************************************************************** @@ -451,6 +469,7 @@ spin_loop: if (mutex_test_and_set(mutex) == 0) { /* Succeeded! */ + ut_d(mutex->thread_id = os_thread_get_curr_id()); #ifdef UNIV_SYNC_DEBUG mutex_set_debug_info(mutex, file_name, line); #endif @@ -492,6 +511,7 @@ spin_loop: sync_array_free_cell_protected(sync_primary_wait_array, index); + ut_d(mutex->thread_id = os_thread_get_curr_id()); #ifdef UNIV_SYNC_DEBUG mutex_set_debug_info(mutex, file_name, line); #endif @@ -592,7 +612,6 @@ mutex_set_debug_info( mutex->file_name = file_name; mutex->line = line; - mutex->thread_id = os_thread_get_curr_id(); } /********************************************************************** @@ -614,31 +633,6 @@ mutex_get_debug_info( *thread_id = mutex->thread_id; } -/********************************************************************** -Checks that the current thread owns the mutex. Works only in the debug -version. */ - -ibool -mutex_own( -/*======*/ - /* out: TRUE if owns */ - mutex_t* mutex) /* in: mutex */ -{ - ut_ad(mutex_validate(mutex)); - - if (mutex_get_lock_word(mutex) != 1) { - - return(FALSE); - } - - if (!os_thread_eq(mutex->thread_id, os_thread_get_curr_id())) { - - return(FALSE); - } - - return(TRUE); -} - /********************************************************************** Prints debug info of currently reserved mutexes. */ static diff --git a/storage/innobase/thr/thr0loc.c b/storage/innobase/thr/thr0loc.c index f22e909f392..b803bd53101 100644 --- a/storage/innobase/thr/thr0loc.c +++ b/storage/innobase/thr/thr0loc.c @@ -64,9 +64,7 @@ thr_local_get( try_again: ut_ad(thr_local_hash); -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&thr_local_mutex)); -#endif /* UNIV_SYNC_DEBUG */ /* Look for the local struct in the hash table */ diff --git a/storage/innobase/trx/trx0purge.c b/storage/innobase/trx/trx0purge.c index 11e089ac90e..25519a09a1d 100644 --- a/storage/innobase/trx/trx0purge.c +++ b/storage/innobase/trx/trx0purge.c @@ -197,9 +197,7 @@ void trx_purge_sys_create(void) /*======================*/ { -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ purge_sys = mem_alloc(sizeof(trx_purge_t)); @@ -260,9 +258,8 @@ trx_purge_add_update_undo_to_history( ut_ad(undo); rseg = undo->rseg; -#ifdef UNIV_SYNC_DEBUG + ut_ad(mutex_own(&(rseg->mutex))); -#endif /* UNIV_SYNC_DEBUG */ rseg_header = trx_rsegf_get(rseg->space, rseg->page_no, mtr); @@ -341,9 +338,7 @@ trx_purge_free_segment( /* fputs("Freeing an update undo log segment\n", stderr); */ -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(purge_sys->mutex))); -#endif /* UNIV_SYNC_DEBUG */ loop: mtr_start(&mtr); mutex_enter(&(rseg->mutex)); @@ -445,9 +440,7 @@ trx_purge_truncate_rseg_history( ulint n_removed_logs = 0; mtr_t mtr; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(purge_sys->mutex))); -#endif /* UNIV_SYNC_DEBUG */ mtr_start(&mtr); mutex_enter(&(rseg->mutex)); @@ -537,9 +530,7 @@ trx_purge_truncate_history(void) dulint limit_trx_no; dulint limit_undo_no; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(purge_sys->mutex))); -#endif /* UNIV_SYNC_DEBUG */ trx_purge_arr_get_biggest(purge_sys->arr, &limit_trx_no, &limit_undo_no); @@ -579,9 +570,7 @@ trx_purge_truncate_if_arr_empty(void) /*=================================*/ /* out: TRUE if array empty */ { -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(purge_sys->mutex))); -#endif /* UNIV_SYNC_DEBUG */ if (purge_sys->arr->n_used == 0) { @@ -610,9 +599,7 @@ trx_purge_rseg_get_next_history_log( ibool del_marks; mtr_t mtr; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(purge_sys->mutex))); -#endif /* UNIV_SYNC_DEBUG */ mutex_enter(&(rseg->mutex)); @@ -715,9 +702,7 @@ trx_purge_choose_next_log(void) ulint offset = 0; /* remove warning (??? bug ???) */ mtr_t mtr; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(purge_sys->mutex))); -#endif /* UNIV_SYNC_DEBUG */ ut_ad(purge_sys->next_stored == FALSE); rseg = UT_LIST_GET_FIRST(trx_sys->rseg_list); @@ -818,9 +803,7 @@ trx_purge_get_next_rec( ulint cmpl_info; mtr_t mtr; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(purge_sys->mutex))); -#endif /* UNIV_SYNC_DEBUG */ ut_ad(purge_sys->next_stored); space = purge_sys->rseg->space; diff --git a/storage/innobase/trx/trx0roll.c b/storage/innobase/trx/trx0roll.c index 201d1be3656..91dcf035f96 100644 --- a/storage/innobase/trx/trx0roll.c +++ b/storage/innobase/trx/trx0roll.c @@ -785,10 +785,8 @@ trx_roll_try_truncate( dulint limit; dulint biggest; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(trx->undo_mutex))); ut_ad(mutex_own(&((trx->rseg)->mutex))); -#endif /* UNIV_SYNC_DEBUG */ trx->pages_undone = 0; @@ -831,9 +829,7 @@ trx_roll_pop_top_rec( trx_undo_rec_t* prev_rec; page_t* prev_rec_page; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(trx->undo_mutex))); -#endif /* UNIV_SYNC_DEBUG */ undo_page = trx_undo_page_get_s_latched(undo->space, undo->top_page_no, mtr); @@ -1060,9 +1056,7 @@ trx_rollback( que_thr_t* thr; /* que_thr_t* thr2; */ -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ ut_ad((trx->undo_no_arr == NULL) || ((trx->undo_no_arr)->n_used == 0)); /* Initialize the rollback field in the transaction */ @@ -1131,9 +1125,7 @@ trx_roll_graph_build( que_thr_t* thr; /* que_thr_t* thr2; */ -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ heap = mem_heap_create(512); fork = que_fork_create(NULL, NULL, QUE_FORK_ROLLBACK, heap); @@ -1160,9 +1152,7 @@ trx_finish_error_processing( trx_sig_t* sig; trx_sig_t* next_sig; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ sig = UT_LIST_GET_FIRST(trx->signals); @@ -1195,9 +1185,7 @@ trx_finish_partial_rollback_off_kernel( { trx_sig_t* sig; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ sig = UT_LIST_GET_FIRST(trx->signals); @@ -1228,9 +1216,7 @@ trx_finish_rollback_off_kernel( trx_sig_t* sig; trx_sig_t* next_sig; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ ut_a(trx->undo_no_arr == NULL || trx->undo_no_arr->n_used == 0); diff --git a/storage/innobase/trx/trx0rseg.c b/storage/innobase/trx/trx0rseg.c index 7a6989c7b4f..020f217c90b 100644 --- a/storage/innobase/trx/trx0rseg.c +++ b/storage/innobase/trx/trx0rseg.c @@ -60,9 +60,7 @@ trx_rseg_header_create( page_t* page; ut_ad(mtr); -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ ut_ad(mtr_memo_contains(mtr, fil_space_get_latch(space), MTR_MEMO_X_LOCK)); sys_header = trx_sysf_get(mtr); @@ -138,9 +136,7 @@ trx_rseg_mem_create( ulint sum_of_undo_sizes; ulint len; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ rseg = mem_alloc(sizeof(trx_rseg_t)); diff --git a/storage/innobase/trx/trx0sys.c b/storage/innobase/trx/trx0sys.c index b87f3d5e090..307a03bfbc3 100644 --- a/storage/innobase/trx/trx0sys.c +++ b/storage/innobase/trx/trx0sys.c @@ -547,9 +547,7 @@ trx_in_trx_list( { trx_t* trx; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(kernel_mutex))); -#endif /* UNIV_SYNC_DEBUG */ trx = UT_LIST_GET_FIRST(trx_sys->trx_list); @@ -576,9 +574,7 @@ trx_sys_flush_max_trx_id(void) trx_sysf_t* sys_header; mtr_t mtr; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ mtr_start(&mtr); @@ -799,9 +795,7 @@ trx_sysf_rseg_find_free( ulint page_no; ulint i; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(kernel_mutex))); -#endif /* UNIV_SYNC_DEBUG */ sys_header = trx_sysf_get(mtr); diff --git a/storage/innobase/trx/trx0trx.c b/storage/innobase/trx/trx0trx.c index 6f59d2659ec..2f0c25c323a 100644 --- a/storage/innobase/trx/trx0trx.c +++ b/storage/innobase/trx/trx0trx.c @@ -101,9 +101,7 @@ trx_create( { trx_t* trx; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ trx = mem_alloc(sizeof(trx_t)); @@ -280,9 +278,7 @@ trx_free( /*=====*/ trx_t* trx) /* in, own: trx object */ { -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ if (trx->declared_to_be_inside_innodb) { ut_print_timestamp(stderr); @@ -406,9 +402,7 @@ trx_list_insert_ordered( { trx_t* trx2; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ trx2 = UT_LIST_GET_FIRST(trx_sys->trx_list); @@ -633,9 +627,7 @@ trx_assign_rseg(void) { trx_rseg_t* rseg = trx_sys->latest_rseg; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ loop: /* Get next rseg in a round-robin fashion */ @@ -672,9 +664,7 @@ trx_start_low( { trx_rseg_t* rseg; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ ut_ad(trx->rseg == NULL); if (trx->type == TRX_PURGE) { @@ -749,9 +739,7 @@ trx_commit_off_kernel( ibool must_flush_log = FALSE; mtr_t mtr; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ trx->must_flush_log_later = FALSE; @@ -851,9 +839,7 @@ trx_commit_off_kernel( ut_ad(trx->conc_state == TRX_ACTIVE || trx->conc_state == TRX_PREPARED); -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ /* The following assignment makes the transaction committed in memory and makes its changes to data visible to other transactions. @@ -1036,9 +1022,7 @@ trx_handle_commit_sig_off_kernel( trx_sig_t* sig; trx_sig_t* next_sig; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ trx->que_state = TRX_QUE_COMMITTING; @@ -1078,9 +1062,7 @@ trx_end_lock_wait( { que_thr_t* thr; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ ut_ad(trx->que_state == TRX_QUE_LOCK_WAIT); thr = UT_LIST_GET_FIRST(trx->wait_thrs); @@ -1107,9 +1089,7 @@ trx_lock_wait_to_suspended( { que_thr_t* thr; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ ut_ad(trx->que_state == TRX_QUE_LOCK_WAIT); thr = UT_LIST_GET_FIRST(trx->wait_thrs); @@ -1137,9 +1117,7 @@ trx_sig_reply_wait_to_suspended( trx_sig_t* sig; que_thr_t* thr; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ sig = UT_LIST_GET_FIRST(trx->reply_signals); @@ -1172,9 +1150,7 @@ trx_sig_is_compatible( { trx_sig_t* sig; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ if (UT_LIST_GET_LEN(trx->signals) == 0) { @@ -1260,9 +1236,7 @@ trx_sig_send( trx_t* receiver_trx; ut_ad(trx); -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ if (!trx_sig_is_compatible(trx, type, sender)) { /* The signal is not compatible with the other signals in @@ -1332,9 +1306,7 @@ trx_end_signal_handling( /*====================*/ trx_t* trx) /* in: trx */ { -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ ut_ad(trx->handling_signals == TRUE); trx->handling_signals = FALSE; @@ -1368,9 +1340,7 @@ loop: we can process immediately */ ut_ad(trx); -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ if (trx->handling_signals && (UT_LIST_GET_LEN(trx->signals) == 0)) { @@ -1471,9 +1441,7 @@ trx_sig_reply( trx_t* receiver_trx; ut_ad(sig); -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ if (sig->receiver != NULL) { ut_ad((sig->receiver)->state == QUE_THR_SIG_REPLY_WAIT); @@ -1501,9 +1469,7 @@ trx_sig_remove( trx_sig_t* sig) /* in, own: signal */ { ut_ad(trx && sig); -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ ut_ad(sig->receiver == NULL); @@ -1820,9 +1786,7 @@ trx_prepare_off_kernel( dulint lsn; mtr_t mtr; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ rseg = trx->rseg; @@ -1868,9 +1832,7 @@ trx_prepare_off_kernel( mutex_enter(&kernel_mutex); } -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ /*--------------------------------------*/ trx->conc_state = TRX_PREPARED; diff --git a/storage/innobase/trx/trx0undo.c b/storage/innobase/trx/trx0undo.c index fbcfab38f01..831e337f513 100644 --- a/storage/innobase/trx/trx0undo.c +++ b/storage/innobase/trx/trx0undo.c @@ -395,9 +395,7 @@ trx_undo_seg_create( ibool success; ut_ad(mtr && id && rseg_hdr); -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(rseg->mutex))); -#endif /* UNIV_SYNC_DEBUG */ /* fputs(type == TRX_UNDO_INSERT ? "Creating insert undo log segment\n" @@ -836,11 +834,9 @@ trx_undo_add_page( ulint n_reserved; ibool success; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(trx->undo_mutex))); ut_ad(!mutex_own(&kernel_mutex)); ut_ad(mutex_own(&(trx->rseg->mutex))); -#endif /* UNIV_SYNC_DEBUG */ rseg = trx->rseg; @@ -911,10 +907,8 @@ trx_undo_free_page( ulint hist_size; ut_a(hdr_page_no != page_no); -#ifdef UNIV_SYNC_DEBUG ut_ad(!mutex_own(&kernel_mutex)); ut_ad(mutex_own(&(rseg->mutex))); -#endif /* UNIV_SYNC_DEBUG */ undo_page = trx_undo_page_get(space, page_no, mtr); @@ -961,9 +955,7 @@ trx_undo_free_page_in_rollback( ulint last_page_no; ut_ad(undo->hdr_page_no != page_no); -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(trx->undo_mutex))); -#endif /* UNIV_SYNC_DEBUG */ last_page_no = trx_undo_free_page(undo->rseg, FALSE, undo->space, undo->hdr_page_no, page_no, mtr); @@ -1016,10 +1008,8 @@ trx_undo_truncate_end( trx_rseg_t* rseg; mtr_t mtr; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(trx->undo_mutex))); ut_ad(mutex_own(&(trx->rseg->mutex))); -#endif /* UNIV_SYNC_DEBUG */ rseg = trx->rseg; @@ -1096,9 +1086,7 @@ trx_undo_truncate_start( ulint page_no; mtr_t mtr; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(rseg->mutex))); -#endif /* UNIV_SYNC_DEBUG */ if (0 == ut_dulint_cmp(limit, ut_dulint_zero)) { @@ -1164,9 +1152,9 @@ trx_undo_seg_free( while (!finished) { mtr_start(&mtr); -#ifdef UNIV_SYNC_DEBUG + ut_ad(!mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ + mutex_enter(&(rseg->mutex)); seg_header = trx_undo_page_get(undo->space, undo->hdr_page_no, @@ -1389,9 +1377,7 @@ trx_undo_mem_create( { trx_undo_t* undo; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(rseg->mutex))); -#endif /* UNIV_SYNC_DEBUG */ if (id >= TRX_RSEG_N_SLOTS) { fprintf(stderr, @@ -1437,11 +1423,9 @@ trx_undo_mem_init_for_reuse( XID* xid, /* in: X/Open XA transaction identification*/ ulint offset) /* in: undo log header byte offset on page */ { -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&((undo->rseg)->mutex))); -#endif /* UNIV_SYNC_DEBUG */ - if (undo->id >= TRX_RSEG_N_SLOTS) { + if (UNIV_UNLIKELY(undo->id >= TRX_RSEG_N_SLOTS)) { fprintf(stderr, "InnoDB: Error: undo->id is %lu\n", (ulong) undo->id); @@ -1501,9 +1485,7 @@ trx_undo_create( trx_undo_t* undo; page_t* undo_page; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(rseg->mutex))); -#endif /* UNIV_SYNC_DEBUG */ if (rseg->curr_size == rseg->max_size) { @@ -1561,9 +1543,7 @@ trx_undo_reuse_cached( page_t* undo_page; ulint offset; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(rseg->mutex))); -#endif /* UNIV_SYNC_DEBUG */ if (type == TRX_UNDO_INSERT) { @@ -1671,15 +1651,12 @@ trx_undo_assign_undo( rseg = trx->rseg; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(trx->undo_mutex))); -#endif /* UNIV_SYNC_DEBUG */ mtr_start(&mtr); -#ifdef UNIV_SYNC_DEBUG ut_ad(!mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ + mutex_enter(&(rseg->mutex)); undo = trx_undo_reuse_cached(trx, rseg, type, trx->id, &trx->xid, @@ -1836,9 +1813,8 @@ trx_undo_update_cleanup( undo = trx->update_undo; rseg = trx->rseg; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(rseg->mutex))); -#endif /* UNIV_SYNC_DEBUG */ + trx_purge_add_update_undo_to_history(trx, undo_page, mtr); UT_LIST_REMOVE(undo_list, rseg->update_undo_list, undo); diff --git a/storage/innobase/usr/usr0sess.c b/storage/innobase/usr/usr0sess.c index ca97ea23e95..3740c05eaab 100644 --- a/storage/innobase/usr/usr0sess.c +++ b/storage/innobase/usr/usr0sess.c @@ -32,9 +32,8 @@ sess_open(void) { sess_t* sess; -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ + sess = mem_alloc(sizeof(sess_t)); sess->state = SESS_ACTIVE; @@ -54,9 +53,7 @@ sess_close( /*=======*/ sess_t* sess) /* in, own: session object */ { -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ ut_ad(sess->trx == NULL); mem_free(sess); @@ -72,9 +69,8 @@ sess_try_close( /* out: TRUE if closed */ sess_t* sess) /* in, own: session object */ { -#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); -#endif /* UNIV_SYNC_DEBUG */ + if (UT_LIST_GET_LEN(sess->graphs) == 0) { sess_close(sess); diff --git a/storage/innobase/ut/ut0ut.c b/storage/innobase/ut/ut0ut.c index d805cc3b4b2..bc6778f4c2f 100644 --- a/storage/innobase/ut/ut0ut.c +++ b/storage/innobase/ut/ut0ut.c @@ -20,6 +20,55 @@ Created 5/11/1994 Heikki Tuuri ibool ut_always_false = FALSE; +#ifdef __WIN__ +/********************************************************************* +NOTE: The Windows epoch starts from 1601/01/01 whereas the Unix +epoch starts from 1970/1/1. For selection of constant see: +http://support.microsoft.com/kb/167296/ */ +#define WIN_TO_UNIX_DELTA_USEC ((ib_longlong) 11644473600000000ULL) + + +/********************************************************************* +This is the Windows version of gettimeofday(2).*/ +static +int +ut_gettimeofday( +/*============*/ + /* out: 0 if all OK else -1 */ + struct timeval* tv, /* out: Values are relative to Unix epoch */ + void* tz) /* in: not used */ +{ + FILETIME ft; + ib_longlong tm; + + if (!tv) { + errno = EINVAL; + return(-1); + } + + GetSystemTimeAsFileTime(&ft); + + tm = (ib_longlong) ft.dwHighDateTime << 32; + tm |= ft.dwLowDateTime; + + ut_a(tm >= 0); /* If tm wraps over to negative, the quotient / 10 + does not work */ + + tm /= 10; /* Convert from 100 nsec periods to usec */ + + /* If we don't convert to the Unix epoch the value for + struct timeval::tv_sec will overflow.*/ + tm -= WIN_TO_UNIX_DELTA_USEC; + + tv->tv_sec = (long) (tm / 1000000L); + tv->tv_usec = (long) (tm % 1000000L); + + return(0); +} +#else +#define ut_gettimeofday gettimeofday +#endif + #ifndef UNIV_HOTBACKUP /********************************************************************* Display an SQL identifier. @@ -85,17 +134,11 @@ ut_usectime( ulint* sec, /* out: seconds since the Epoch */ ulint* ms) /* out: microseconds since the Epoch+*sec */ { -#ifdef __WIN__ - SYSTEMTIME st; - GetLocalTime(&st); - *sec = (ulint) st.wSecond; - *ms = (ulint) st.wMilliseconds; -#else struct timeval tv; - gettimeofday(&tv,NULL); + + ut_gettimeofday(&tv, NULL); *sec = (ulint) tv.tv_sec; *ms = (ulint) tv.tv_usec; -#endif } /**************************************************************