diff options
author | unknown <tsmith@siva.hindu.god> | 2007-01-04 19:51:34 -0700 |
---|---|---|
committer | unknown <tsmith@siva.hindu.god> | 2007-01-04 19:51:34 -0700 |
commit | a5868736ff8c1c314e7c72a2fac9d138b69d56b1 (patch) | |
tree | 336e5a6b476fbb75a7fdaaf8e6dd18958a4ec637 /storage/innobase | |
parent | 4dabfa5de70c59c4f7ea1e4a33224c5a3f798d66 (diff) | |
download | mariadb-git-a5868736ff8c1c314e7c72a2fac9d138b69d56b1.tar.gz |
Applied innodb-5.1-ss1039 and innodb-5.1-ss1134 snapshots.
Fixes:
- Bug #24712: SHOW TABLE STATUS for file-per-table showing incorrect time fields
- Bug #24386: Performance degradation caused by instrumentation in mutex_struct
- Bug #24190: many exportable definitions of field_in_record_is_null
- Bug #21468: InnoDB crash during recovery with corrupted data pages: XA bug?
storage/innobase/buf/buf0buf.c:
Applied innodb-5.1-ss1039 and innodb-5.1-ss1134 snapshots.
Revision r1045:
buf_page_init_for_read(): Correct the indentation.
storage/innobase/buf/buf0flu.c:
Applied innodb-5.1-ss1039 and innodb-5.1-ss1134 snapshots.
Revision r1038:
Port r983 from branches/zip: Enclose some more debug code in
#ifdef UNIV_SYNC_DEBUG to allow the code to be built
with UNIV_DEBUG but without UNIV_SYNC_DEBUG.
storage/innobase/dict/dict0dict.c:
Applied innodb-5.1-ss1039 and innodb-5.1-ss1134 snapshots.
Revision r1124:
Unify dict_table_get_and_increment_handle_count() with dict_table_get() by
adding a second parameter, adjust callers.
storage/innobase/ha/ha0ha.c:
Applied innodb-5.1-ss1039 and innodb-5.1-ss1134 snapshots.
Revision r1039:
Port r1034 from branches/zip: Remove some instrumentation and reduce
the output of SHOW MUTEX STATUS in non-debug builds. (Bug #24386)
storage/innobase/ha/hash0hash.c:
Applied innodb-5.1-ss1039 and innodb-5.1-ss1134 snapshots.
Revision r1039:
Port r1034 from branches/zip: Remove some instrumentation and reduce
the output of SHOW MUTEX STATUS in non-debug builds. (Bug #24386)
storage/innobase/handler/ha_innodb.cc:
Applied innodb-5.1-ss1039 and innodb-5.1-ss1134 snapshots.
Revision r1028:
Merge a change from MySQL AB.
ChangeSet
2006/11/10 17:22:43+02:00 aelkin@dsl-hkibras-fe30f900-107.dhcp.inet.fi
Bug #24190 many exportable definitions of field_in_record_is_null
mysql had several(2) exportable definitions of field_in_record_is_null function.
Fixed with adding static.
storage/innobase/handler/ha_innodb.cc
2006/11/10 17:22:36+02:00 aelkin@dsl-hkibras-fe30f900-107.dhcp.inet.fi +1 -1
made static
Revision r1008:
Minor cleanup.
ha_innobase::rnd_pos(): Use correct format in DBUG_PRINT statements.
buf_page_release(): Remove the local variable buf_fix_count.
Revision r1039:
Port r1034 from branches/zip: Remove some instrumentation and reduce
the output of SHOW MUTEX STATUS in non-debug builds. (Bug #24386)
Revision r1124:
Unify dict_table_get_and_increment_handle_count() with dict_table_get() by
adding a second parameter, adjust callers.
Revision r1134:
Fix a potential bug in ha_innodb.cc:innobase_query_is_update() where the
function can be called with "current_thd == NULL". Minor non-functional fix
in log0recv.c
Revision r1098:
Fix bug #24712: SHOW TABLE STATUS for file-per-table showing incorrect
time fields
Revision r1109:
ha_innodb.cc: Remove unused define MAX_ULONG_BIT.
storage/innobase/include/btr0sea.h:
Applied innodb-5.1-ss1039 and innodb-5.1-ss1134 snapshots.
Revision r1088:
Replace the Latin abbreviation "cf." in comments.
storage/innobase/include/buf0buf.ic:
Applied innodb-5.1-ss1039 and innodb-5.1-ss1134 snapshots.
Revision r1008:
Minor cleanup.
ha_innobase::rnd_pos(): Use correct format in DBUG_PRINT statements.
buf_page_release(): Remove the local variable buf_fix_count.
storage/innobase/include/data0type.ic:
Applied innodb-5.1-ss1039 and innodb-5.1-ss1134 snapshots.
Revision r1088:
Replace the Latin abbreviation "cf." in comments.
storage/innobase/include/dict0dict.h:
Applied innodb-5.1-ss1039 and innodb-5.1-ss1134 snapshots.
Revision r1124:
Unify dict_table_get_and_increment_handle_count() with dict_table_get() by
adding a second parameter, adjust callers.
storage/innobase/include/ha0ha.h:
Applied innodb-5.1-ss1039 and innodb-5.1-ss1134 snapshots.
Revision r1039:
Port r1034 from branches/zip: Remove some instrumentation and reduce
the output of SHOW MUTEX STATUS in non-debug builds. (Bug #24386)
storage/innobase/include/hash0hash.h:
Applied innodb-5.1-ss1039 and innodb-5.1-ss1134 snapshots.
Revision r1039:
Port r1034 from branches/zip: Remove some instrumentation and reduce
the output of SHOW MUTEX STATUS in non-debug builds. (Bug #24386)
storage/innobase/include/sync0rw.h:
Applied innodb-5.1-ss1039 and innodb-5.1-ss1134 snapshots.
Revision r1039:
Port r1034 from branches/zip: Remove some instrumentation and reduce
the output of SHOW MUTEX STATUS in non-debug builds. (Bug #24386)
storage/innobase/include/sync0sync.h:
Applied innodb-5.1-ss1039 and innodb-5.1-ss1134 snapshots.
Revision r1038:
Port r983 from branches/zip: Enclose some more debug code in
#ifdef UNIV_SYNC_DEBUG to allow the code to be built
with UNIV_DEBUG but without UNIV_SYNC_DEBUG.
Revision r1037:
Port r972 from branches/zip: Enclose some debug code in #ifdef UNIV_SYNC_DEBUG.
The code was previously unused in non-debug builds.
Revision r1039:
Port r1034 from branches/zip: Remove some instrumentation and reduce
the output of SHOW MUTEX STATUS in non-debug builds. (Bug #24386)
Revision r1084:
Remove the unused constants SYNC_INFINITE_TIME and SYNC_TIME_EXCEEDED.
storage/innobase/include/sync0sync.ic:
Applied innodb-5.1-ss1039 and innodb-5.1-ss1134 snapshots.
Revision r1039:
Port r1034 from branches/zip: Remove some instrumentation and reduce
the output of SHOW MUTEX STATUS in non-debug builds. (Bug #24386)
storage/innobase/include/univ.i:
Applied innodb-5.1-ss1039 and innodb-5.1-ss1134 snapshots.
Revision r1006:
Introduce #define UNIV_LIST_DEBUG for enabling the debug code in
UT_LIST_REMOVE_CLEAR().
Revision r1088:
Replace the Latin abbreviation "cf." in comments.
Revision r1083:
univ.i: Document the debug flags (UNIV_DEBUG et al).
storage/innobase/include/ut0lst.h:
Applied innodb-5.1-ss1039 and innodb-5.1-ss1134 snapshots.
Revision r1006:
Introduce #define UNIV_LIST_DEBUG for enabling the debug code in
UT_LIST_REMOVE_CLEAR().
storage/innobase/lock/lock0lock.c:
Applied innodb-5.1-ss1039 and innodb-5.1-ss1134 snapshots.
Revision r1009:
Remove duplicate printing of row lock counts in SHOW INNODB STATUS, and in
the remaining print, add a comma so it doesn't get combined with the heap
size. Both problems were introduced in r383.
storage/innobase/log/log0recv.c:
Applied innodb-5.1-ss1039 and innodb-5.1-ss1134 snapshots.
Revision r1134:
Fix a potential bug in ha_innodb.cc:innobase_query_is_update() where the
function can be called with "current_thd == NULL". Minor non-functional fix
in log0recv.c
Revision r1078:
Merge r1067:1077 from branches/5.0:
innobase_start_or_create_for_mysql(): Remove unnecessary delay now that
we moved the setting sync_order_checks_on=TRUE to log0recv.c,
to the start of the rollback phase in crash recovery.
Fix assertion failure sync0sync.c line 1239
(the latter ut_error in sync_thread_reset_level())
in crash recovery when UNIV_SYNC_DEBUG is enabled.
Revision r1080:
Merge r1079 from branches/5.0:
recv_recovery_from_checkpoint_finish(): Add 1 sec delay
before switching on the sync order checks in crash recovery, so that
file I/O threads have time to suspend themselves.
storage/innobase/row/row0ins.c:
Applied innodb-5.1-ss1039 and innodb-5.1-ss1134 snapshots.
Revision r1124:
Unify dict_table_get_and_increment_handle_count() with dict_table_get() by
adding a second parameter, adjust callers.
storage/innobase/row/row0sel.c:
Applied innodb-5.1-ss1039 and innodb-5.1-ss1134 snapshots.
Revision r1038:
Port r983 from branches/zip: Enclose some more debug code in
#ifdef UNIV_SYNC_DEBUG to allow the code to be built
with UNIV_DEBUG but without UNIV_SYNC_DEBUG.
Revision r1124:
Unify dict_table_get_and_increment_handle_count() with dict_table_get() by
adding a second parameter, adjust callers.
storage/innobase/row/row0upd.c:
Applied innodb-5.1-ss1039 and innodb-5.1-ss1134 snapshots.
Revision r1124:
Unify dict_table_get_and_increment_handle_count() with dict_table_get() by
adding a second parameter, adjust callers.
storage/innobase/srv/srv0start.c:
Applied innodb-5.1-ss1039 and innodb-5.1-ss1134 snapshots.
Revision r1038:
Port r983 from branches/zip: Enclose some more debug code in
#ifdef UNIV_SYNC_DEBUG to allow the code to be built
with UNIV_DEBUG but without UNIV_SYNC_DEBUG.
Revision r1078:
Merge r1067:1077 from branches/5.0:
innobase_start_or_create_for_mysql(): Remove unnecessary delay now that
we moved the setting sync_order_checks_on=TRUE to log0recv.c,
to the start of the rollback phase in crash recovery.
Fix assertion failure sync0sync.c line 1239
(the latter ut_error in sync_thread_reset_level())
in crash recovery when UNIV_SYNC_DEBUG is enabled.
Revision r1070:
Remove another accidentally committed change to srv0start.c.
The change was accidentally committed with the merge in r1068.
This revision corresponds to r1051 with a properly merged
r1067 of branches/5.0.
Revision r1068:
Merge r1067 from branches/5.0:
trx_rollback_for_mysql(), trx_commit_for_mysql():
Protect the creation of trx_dummy_sess with kernel_mutex.
This error was introduced in r1046 and r1050.
Revision r1069:
Remove an accidentally committed change to srv0start.c.
The change was accidentally committed with the merge in r1068.
storage/innobase/sync/sync0rw.c:
Applied innodb-5.1-ss1039 and innodb-5.1-ss1134 snapshots.
Revision r1039:
Port r1034 from branches/zip: Remove some instrumentation and reduce
the output of SHOW MUTEX STATUS in non-debug builds. (Bug #24386)
storage/innobase/sync/sync0sync.c:
Applied innodb-5.1-ss1039 and innodb-5.1-ss1134 snapshots.
Revision r1038:
Port r983 from branches/zip: Enclose some more debug code in
#ifdef UNIV_SYNC_DEBUG to allow the code to be built
with UNIV_DEBUG but without UNIV_SYNC_DEBUG.
Revision r1037:
Port r972 from branches/zip: Enclose some debug code in #ifdef UNIV_SYNC_DEBUG.
The code was previously unused in non-debug builds.
Revision r1039:
Port r1034 from branches/zip: Remove some instrumentation and reduce
the output of SHOW MUTEX STATUS in non-debug builds. (Bug #24386)
storage/innobase/trx/trx0roll.c:
Applied innodb-5.1-ss1039 and innodb-5.1-ss1134 snapshots.
Revision r1049:
Merge r1048 from branches/5.0:
trx_rollback_for_mysql(): Do not set trx->sess back to NULL.
This bug was introduced in r1046.
Revision r1047:
Merge r1046 from branches/5.0:
branches/5.0: trx_rollback_for_mysql(): Ensure that trx->sess is non-NULL
when calling trx_general_rollback_for_mysql(). This removes a segmentation
fault when rolling back a prepared transaction in XA recovery. (Bug #21468)
Revision r1068:
Merge r1067 from branches/5.0:
trx_rollback_for_mysql(), trx_commit_for_mysql():
Protect the creation of trx_dummy_sess with kernel_mutex.
This error was introduced in r1046 and r1050.
Revision r1051:
Merge r1050 from branches/5.0:
trx_rollback_for_mysql(): Fix the comment introduced in r1046.
trx_commit_for_mysql(): Use the dummy trx->sess also for committing a prepared
transaction in XA recovery, just in case our code would need the session
object also in that case (does not seem to need it right now).
storage/innobase/trx/trx0trx.c:
Applied innodb-5.1-ss1039 and innodb-5.1-ss1134 snapshots.
Revision r1009:
Remove duplicate printing of row lock counts in SHOW INNODB STATUS, and in
the remaining print, add a comma so it doesn't get combined with the heap
size. Both problems were introduced in r383.
Revision r1068:
Merge r1067 from branches/5.0:
trx_rollback_for_mysql(), trx_commit_for_mysql():
Protect the creation of trx_dummy_sess with kernel_mutex.
This error was introduced in r1046 and r1050.
Revision r1051:
Merge r1050 from branches/5.0:
trx_rollback_for_mysql(): Fix the comment introduced in r1046.
trx_commit_for_mysql(): Use the dummy trx->sess also for committing a prepared
transaction in XA recovery, just in case our code would need the session
object also in that case (does not seem to need it right now).
Diffstat (limited to 'storage/innobase')
27 files changed, 336 insertions, 268 deletions
diff --git a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c index 99e365d6129..ad775fbd6d5 100644 --- a/storage/innobase/buf/buf0buf.c +++ b/storage/innobase/buf/buf0buf.c @@ -1755,22 +1755,22 @@ buf_page_init_for_read( if (*err == DB_TABLESPACE_DELETED || NULL != buf_page_hash_get(space, offset)) { - /* The page belongs to a space which has been - deleted or is being deleted, or the page is - already in buf_pool, return */ + /* The page belongs to a space which has been + deleted or is being deleted, or the page is + already in buf_pool, return */ mutex_exit(&block->mutex); - mutex_exit(&(buf_pool->mutex)); + mutex_exit(&(buf_pool->mutex)); - buf_block_free(block); + buf_block_free(block); - if (mode == BUF_READ_IBUF_PAGES_ONLY) { + if (mode == BUF_READ_IBUF_PAGES_ONLY) { - mtr_commit(&mtr); - } + mtr_commit(&mtr); + } - return(NULL); - } + return(NULL); + } ut_ad(block); diff --git a/storage/innobase/buf/buf0flu.c b/storage/innobase/buf/buf0flu.c index 49b81196a64..64060dab8ae 100644 --- a/storage/innobase/buf/buf0flu.c +++ b/storage/innobase/buf/buf0flu.c @@ -854,8 +854,10 @@ buf_flush_batch( ut_ad((flush_type == BUF_FLUSH_LRU) || (flush_type == BUF_FLUSH_LIST)); +#ifdef UNIV_SYNC_DEBUG ut_ad((flush_type != BUF_FLUSH_LIST) || sync_thread_levels_empty_gen(TRUE)); +#endif /* UNIV_SYNC_DEBUG */ mutex_enter(&(buf_pool->mutex)); if ((buf_pool->n_flush[flush_type] > 0) diff --git a/storage/innobase/dict/dict0dict.c b/storage/innobase/dict/dict0dict.c index 7c2fc18accd..2b3cfdba27d 100644 --- a/storage/innobase/dict/dict0dict.c +++ b/storage/innobase/dict/dict0dict.c @@ -801,43 +801,20 @@ dict_init(void) } /************************************************************************** -Returns a table object. NOTE! This is a high-level function to be used -mainly from outside the 'dict' directory. Inside this directory -dict_table_get_low is usually the appropriate function. */ +Returns a table object and optionally increment its MySQL open handle count. +NOTE! This is a high-level function to be used mainly from outside the +'dict' directory. Inside this directory dict_table_get_low is usually the +appropriate function. */ dict_table_t* dict_table_get( /*===========*/ /* out: table, NULL if does not exist */ - const char* table_name) /* in: table name */ -{ - dict_table_t* table; - - mutex_enter(&(dict_sys->mutex)); - - table = dict_table_get_low(table_name); - - mutex_exit(&(dict_sys->mutex)); - - if (table != NULL) { - if (!table->stat_initialized) { - dict_update_statistics(table); - } - } - - return(table); -} - -/************************************************************************** -Returns a table object and increments MySQL open handle count on the table. */ - -dict_table_t* -dict_table_get_and_increment_handle_count( -/*======================================*/ - /* out: table, NULL if - does not exist */ - const char* table_name) /* in: table name */ + const char* table_name, /* in: table name */ + ibool inc_mysql_count) + /* in: whether to increment the open + handle count on the table */ { dict_table_t* table; @@ -845,15 +822,17 @@ dict_table_get_and_increment_handle_count( table = dict_table_get_low(table_name); - if (table != NULL) { - + if (inc_mysql_count && table) { table->n_mysql_handles_opened++; } mutex_exit(&(dict_sys->mutex)); if (table != NULL) { - if (!table->stat_initialized && !table->ibd_file_missing) { + if (!table->stat_initialized) { + /* If table->ibd_file_missing == TRUE, this will + print an error message and return without doing + anything. */ dict_update_statistics(table); } } diff --git a/storage/innobase/ha/ha0ha.c b/storage/innobase/ha/ha0ha.c index 23ea2554f01..07dfb66afa8 100644 --- a/storage/innobase/ha/ha0ha.c +++ b/storage/innobase/ha/ha0ha.c @@ -18,16 +18,18 @@ Creates a hash table with >= n array cells. The actual number of cells is chosen to be a prime number slightly bigger than n. */ hash_table_t* -ha_create( -/*======*/ +ha_create_func( +/*===========*/ /* out, own: created table */ ibool in_btr_search, /* in: TRUE if the hash table is used in the btr_search module */ ulint n, /* in: number of array cells */ - ulint n_mutexes, /* in: number of mutexes to protect the - hash table: must be a power of 2, or 0 */ - ulint mutex_level) /* in: level of the mutexes in the latching +#ifdef UNIV_SYNC_DEBUG + ulint mutex_level, /* in: level of the mutexes in the latching order: this is used in the debug version */ +#endif /* UNIV_SYNC_DEBUG */ + ulint n_mutexes) /* in: number of mutexes to protect the + hash table: must be a power of 2, or 0 */ { hash_table_t* table; ulint i; diff --git a/storage/innobase/ha/hash0hash.c b/storage/innobase/ha/hash0hash.c index 6084a19fa27..4807015eee5 100644 --- a/storage/innobase/ha/hash0hash.c +++ b/storage/innobase/ha/hash0hash.c @@ -129,13 +129,15 @@ hash_table_free( Creates a mutex array to protect a hash table. */ void -hash_create_mutexes( -/*================*/ +hash_create_mutexes_func( +/*=====================*/ hash_table_t* table, /* in: hash table */ - ulint n_mutexes, /* in: number of mutexes, must be a - power of 2 */ - ulint sync_level) /* in: latching order level of the +#ifdef UNIV_SYNC_DEBUG + ulint sync_level, /* in: latching order level of the mutexes: used in the debug version */ +#endif /* UNIV_SYNC_DEBUG */ + ulint n_mutexes) /* in: number of mutexes, must be a + power of 2 */ { ulint i; diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 4d835b41863..90d1701a565 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -39,9 +39,6 @@ have disables the InnoDB inlining in this file. */ #include <myisampack.h> #include <mysys_err.h> #include <my_sys.h> - -#define MAX_ULONG_BIT ((ulong) 1 << (sizeof(ulong)*8-1)) - #include "ha_innodb.h" pthread_mutex_t innobase_share_mutex, /* to protect innobase_open_files */ @@ -1261,18 +1258,6 @@ trx_is_interrupted( return(trx && trx->mysql_thd && ((THD*) trx->mysql_thd)->killed); } -/************************************************************************** -Obtain a pointer to the MySQL THD object, as in current_thd(). This -definition must match the one in sql/ha_innodb.cc! */ -extern "C" -void* -innobase_current_thd(void) -/*======================*/ - /* out: MySQL THD object */ -{ - return(current_thd); -} - /********************************************************************* Call this when you have opened a new table handle in HANDLER, before you call index_read_idx() etc. Actually, we can let the cursor stay open even @@ -2354,7 +2339,7 @@ ha_innobase::open( /* Get pointer to a table object in InnoDB dictionary cache */ - ib_table = dict_table_get_and_increment_handle_count(norm_name); + ib_table = dict_table_get(norm_name, TRUE); if (NULL == ib_table) { ut_print_timestamp(stderr); @@ -4451,7 +4436,7 @@ ha_innobase::rnd_pos( } if (error) { - DBUG_PRINT("error", ("Got error: %d", error)); + DBUG_PRINT("error", ("Got error: %d", error)); DBUG_RETURN(error); } @@ -4932,7 +4917,7 @@ ha_innobase::create( log_buffer_flush_to_disk(); - innobase_table = dict_table_get(norm_name); + innobase_table = dict_table_get(norm_name, FALSE); DBUG_ASSERT(innobase_table != 0); @@ -5543,16 +5528,10 @@ ha_innobase::info( prebuilt->trx->op_info = (char*) "returning various info to MySQL"; - if (ib_table->space != 0) { - my_snprintf(path, sizeof(path), "%s/%s%s", - mysql_data_home, ib_table->name, ".ibd"); - unpack_filename(path,path); - } else { - my_snprintf(path, sizeof(path), "%s/%s%s", + my_snprintf(path, sizeof(path), "%s/%s%s", mysql_data_home, ib_table->name, reg_ext); - unpack_filename(path,path); - } + unpack_filename(path,path); /* Note that we do not know the access time of the table, nor the CHECK TABLE time, nor the UPDATE or INSERT time. */ @@ -6605,22 +6584,23 @@ innodb_mutex_show_status( { char buf1[IO_SIZE], buf2[IO_SIZE]; mutex_t* mutex; +#ifdef UNIV_DEBUG ulint rw_lock_count= 0; ulint rw_lock_count_spin_loop= 0; ulint rw_lock_count_spin_rounds= 0; ulint rw_lock_count_os_wait= 0; ulint rw_lock_count_os_yield= 0; ulonglong rw_lock_wait_time= 0; +#endif /* UNIV_DEBUG */ uint hton_name_len= strlen(innobase_hton_name), buf1len, buf2len; DBUG_ENTER("innodb_mutex_show_status"); -#ifdef MUTEX_PROTECT_TO_BE_ADDED_LATER - mutex_enter(&mutex_list_mutex); -#endif + mutex_enter_noninline(&mutex_list_mutex); mutex = UT_LIST_GET_FIRST(mutex_list); while (mutex != NULL) { +#ifdef UNIV_DEBUG if (mutex->mutex_type != 1) { if (mutex->count_using > 0) { buf1len= my_snprintf(buf1, sizeof(buf1), @@ -6636,14 +6616,13 @@ innodb_mutex_show_status( mutex->count_spin_rounds, mutex->count_os_wait, mutex->count_os_yield, - (ulong) (mutex->lspent_time/1000)); + (ulong) (mutex->lspent_time/1000)); if (stat_print(thd, innobase_hton_name, hton_name_len, buf1, buf1len, buf2, buf2len)) { -#ifdef MUTEX_PROTECT_TO_BE_ADDED_LATER - mutex_exit(&mutex_list_mutex); -#endif + mutex_exit_noninline( + &mutex_list_mutex); DBUG_RETURN(1); } } @@ -6656,26 +6635,39 @@ innodb_mutex_show_status( rw_lock_count_os_yield += mutex->count_os_yield; rw_lock_wait_time += mutex->lspent_time; } +#else /* UNIV_DEBUG */ + buf1len= my_snprintf(buf1, sizeof(buf1), "%s:%lu", + mutex->cfile_name, (ulong) mutex->cline); + buf2len= my_snprintf(buf2, sizeof(buf2), "os_waits=%lu", + mutex->count_os_wait); + + if (stat_print(thd, innobase_hton_name, + hton_name_len, buf1, buf1len, + buf2, buf2len)) { + mutex_exit_noninline(&mutex_list_mutex); + DBUG_RETURN(1); + } +#endif /* UNIV_DEBUG */ mutex = UT_LIST_GET_NEXT(list, mutex); } + mutex_exit_noninline(&mutex_list_mutex); + +#ifdef UNIV_DEBUG buf2len= my_snprintf(buf2, sizeof(buf2), "count=%lu, spin_waits=%lu, spin_rounds=%lu, " "os_waits=%lu, os_yields=%lu, os_wait_times=%lu", rw_lock_count, rw_lock_count_spin_loop, rw_lock_count_spin_rounds, rw_lock_count_os_wait, rw_lock_count_os_yield, - (ulong) (rw_lock_wait_time/1000)); + (ulong) (rw_lock_wait_time/1000)); if (stat_print(thd, innobase_hton_name, hton_name_len, STRING_WITH_LEN("rw_lock_mutexes"), buf2, buf2len)) { DBUG_RETURN(1); } - -#ifdef MUTEX_PROTECT_TO_BE_ADDED_LATER - mutex_exit(&mutex_list_mutex); -#endif +#endif /* UNIV_DEBUG */ DBUG_RETURN(FALSE); } @@ -7348,7 +7340,6 @@ innobase_get_at_most_n_mbchars( } } -extern "C" { /********************************************************************** This function returns true if @@ -7358,33 +7349,34 @@ is either REPLACE or LOAD DATA INFILE REPLACE. 2) SQL-query in the current thread is INSERT ON DUPLICATE KEY UPDATE. -NOTE that /mysql/innobase/row/row0ins.c must contain the +NOTE that storage/innobase/row/row0ins.c must contain the prototype for this function ! */ - +extern "C" ibool innobase_query_is_update(void) /*==========================*/ { - THD* thd; + THD* thd = current_thd; - thd = (THD *)innobase_current_thd(); + if (!thd) { + /* InnoDB's internal threads may run InnoDB stored procedures + that call this function. Then current_thd is not defined + (it is probably NULL). */ - if (thd->lex->sql_command == SQLCOM_REPLACE || - thd->lex->sql_command == SQLCOM_REPLACE_SELECT || - (thd->lex->sql_command == SQLCOM_LOAD && - thd->lex->duplicates == DUP_REPLACE)) { - - return(1); + return(FALSE); } - if (thd->lex->sql_command == SQLCOM_INSERT && - thd->lex->duplicates == DUP_UPDATE) { - - return(1); + switch (thd->lex->sql_command) { + case SQLCOM_REPLACE: + case SQLCOM_REPLACE_SELECT: + return(TRUE); + case SQLCOM_LOAD: + return(thd->lex->duplicates == DUP_REPLACE); + case SQLCOM_INSERT: + return(thd->lex->duplicates == DUP_UPDATE); + default: + return(FALSE); } - - return(0); -} } /*********************************************************************** diff --git a/storage/innobase/include/btr0sea.h b/storage/innobase/include/btr0sea.h index 8b4408ef852..281587ad060 100644 --- a/storage/innobase/include/btr0sea.h +++ b/storage/innobase/include/btr0sea.h @@ -160,7 +160,7 @@ struct btr_search_struct{ number of full fields */ ulint n_bytes; /* recommended prefix: number of bytes in an incomplete field; - cf. BTR_PAGE_MAX_REC_SIZE */ + see also BTR_PAGE_MAX_REC_SIZE */ ibool left_side; /* TRUE or FALSE, depending on whether the leftmost record of several records with the same prefix should be indexed in the diff --git a/storage/innobase/include/buf0buf.ic b/storage/innobase/include/buf0buf.ic index 43895295734..c448c28933a 100644 --- a/storage/innobase/include/buf0buf.ic +++ b/storage/innobase/include/buf0buf.ic @@ -625,8 +625,6 @@ buf_page_release( RW_NO_LATCH */ mtr_t* mtr) /* in: mtr */ { - ulint buf_fix_count; - ut_ad(block); ut_a(block->state == BUF_BLOCK_FILE_PAGE); @@ -643,8 +641,7 @@ buf_page_release( #ifdef UNIV_SYNC_DEBUG rw_lock_s_unlock(&(block->debug_latch)); #endif - buf_fix_count = block->buf_fix_count; - block->buf_fix_count = buf_fix_count - 1; + block->buf_fix_count--; mutex_exit(&block->mutex); diff --git a/storage/innobase/include/data0type.ic b/storage/innobase/include/data0type.ic index b447c9c39c2..b8c24bb074a 100644 --- a/storage/innobase/include/data0type.ic +++ b/storage/innobase/include/data0type.ic @@ -65,8 +65,8 @@ dtype_get_mblen( innobase_get_cset_width(dtype_get_charset_coll(prtype), mbminlen, mbmaxlen); ut_ad(*mbminlen <= *mbmaxlen); - ut_ad(*mbminlen <= 2); /* cf. the bit-field in dtype_t */ - ut_ad(*mbmaxlen < 1 << 3); /* cf. the bit-field in dtype_t */ + ut_ad(*mbminlen <= 2); /* mbminlen in dtype_t is 0..3 */ + ut_ad(*mbmaxlen < 1 << 3); /* mbmaxlen in dtype_t is 0..7 */ #else /* !UNIV_HOTBACKUP */ ut_a(mtype <= DATA_BINARY); *mbminlen = *mbmaxlen = 1; diff --git a/storage/innobase/include/dict0dict.h b/storage/innobase/include/dict0dict.h index 2582effbb29..836a6290498 100644 --- a/storage/innobase/include/dict0dict.h +++ b/storage/innobase/include/dict0dict.h @@ -326,26 +326,20 @@ dict_foreign_parse_drop_constraints( const char*** constraints_to_drop); /* out: id's of the constraints to drop */ /************************************************************************** -Returns a table object. NOTE! This is a high-level function to be used -mainly from outside the 'dict' directory. Inside this directory -dict_table_get_low is usually the appropriate function. */ +Returns a table object and optionally increment its MySQL open handle count. +NOTE! This is a high-level function to be used mainly from outside the +'dict' directory. Inside this directory dict_table_get_low is usually the +appropriate function. */ dict_table_t* dict_table_get( /*===========*/ /* out: table, NULL if does not exist */ - const char* table_name); /* in: table name */ -/************************************************************************** -Returns a table object and increments MySQL open handle count on the table. -*/ - -dict_table_t* -dict_table_get_and_increment_handle_count( -/*======================================*/ - /* out: table, NULL if - does not exist */ - const char* table_name); /* in: table name */ + const char* table_name, /* in: table name */ + ibool inc_mysql_count); + /* in: whether to increment the open + handle count on the table */ /************************************************************************** Returns a table object based on table id. */ diff --git a/storage/innobase/include/ha0ha.h b/storage/innobase/include/ha0ha.h index 9fc80ed301c..beaa06ae755 100644 --- a/storage/innobase/include/ha0ha.h +++ b/storage/innobase/include/ha0ha.h @@ -41,16 +41,23 @@ Creates a hash table with >= n array cells. The actual number of cells is chosen to be a prime number slightly bigger than n. */ hash_table_t* -ha_create( -/*======*/ +ha_create_func( +/*===========*/ /* out, own: created table */ ibool in_btr_search, /* in: TRUE if the hash table is used in the btr_search module */ ulint n, /* in: number of array cells */ - ulint n_mutexes, /* in: number of mutexes to protect the - hash table: must be a power of 2 */ - ulint mutex_level); /* in: level of the mutexes in the latching +#ifdef UNIV_SYNC_DEBUG + ulint mutex_level, /* in: level of the mutexes in the latching order: this is used in the debug version */ +#endif /* UNIV_SYNC_DEBUG */ + ulint n_mutexes); /* in: number of mutexes to protect the + hash table: must be a power of 2 */ +#ifdef UNIV_SYNC_DEBUG +# define ha_create(b,n_c,n_m,level) ha_create_func(b,n_c,level,n_m) +#else /* UNIV_SYNC_DEBUG */ +# define ha_create(b,n_c,n_m,level) ha_create_func(b,n_c,n_m) +#endif /* UNIV_SYNC_DEBUG */ /***************************************************************** Inserts an entry into a hash table. If an entry with the same fold number is found, its node is updated to point to the new data, and no new node diff --git a/storage/innobase/include/hash0hash.h b/storage/innobase/include/hash0hash.h index 31c5c57ae35..0ab02801fd1 100644 --- a/storage/innobase/include/hash0hash.h +++ b/storage/innobase/include/hash0hash.h @@ -31,12 +31,20 @@ hash_create( Creates a mutex array to protect a hash table. */ void -hash_create_mutexes( -/*================*/ +hash_create_mutexes_func( +/*=====================*/ hash_table_t* table, /* in: hash table */ - ulint n_mutexes, /* in: number of mutexes */ - ulint sync_level); /* in: latching order level of the +#ifdef UNIV_SYNC_DEBUG + ulint sync_level, /* in: latching order level of the mutexes: used in the debug version */ +#endif /* UNIV_SYNC_DEBUG */ + ulint n_mutexes); /* in: number of mutexes */ +#ifdef UNIV_SYNC_DEBUG +# define hash_create_mutexes(t,n,level) hash_create_mutexes_func(t,level,n) +#else /* UNIV_SYNC_DEBUG */ +# define hash_create_mutexes(t,n,level) hash_create_mutexes_func(t,n) +#endif /* UNIV_SYNC_DEBUG */ + /***************************************************************** Frees a hash table. */ diff --git a/storage/innobase/include/sync0rw.h b/storage/innobase/include/sync0rw.h index 7c0241f2e02..abf04253141 100644 --- a/storage/innobase/include/sync0rw.h +++ b/storage/innobase/include/sync0rw.h @@ -61,8 +61,18 @@ Creates, or rather, initializes an rw-lock object in a specified memory location (which must be appropriately aligned). The rw-lock is initialized to the non-locked state. Explicit freeing of the rw-lock with rw_lock_free is necessary only if the memory block containing it is freed. */ -#define rw_lock_create(L, level) \ - rw_lock_create_func((L), (level), __FILE__, __LINE__, #L) +#ifdef UNIV_DEBUG +# ifdef UNIV_SYNC_DEBUG +# define rw_lock_create(L, level) \ + rw_lock_create_func((L), (level), #L, __FILE__, __LINE__) +# else /* UNIV_SYNC_DEBUG */ +# define rw_lock_create(L, level) \ + rw_lock_create_func((L), #L, __FILE__, __LINE__) +# endif /* UNIV_SYNC_DEBUG */ +#else /* UNIV_DEBUG */ +# define rw_lock_create(L, level) \ + rw_lock_create_func((L), __FILE__, __LINE__) +#endif /* UNIV_DEBUG */ /********************************************************************** Creates, or rather, initializes an rw-lock object in a specified memory @@ -74,10 +84,14 @@ void rw_lock_create_func( /*================*/ rw_lock_t* lock, /* in: pointer to memory */ +#ifdef UNIV_DEBUG +# ifdef UNIV_SYNC_DEBUG ulint level, /* in: level */ +# endif /* UNIV_SYNC_DEBUG */ + const char* cmutex_name, /* in: mutex name */ +#endif /* UNIV_DEBUG */ const char* cfile_name, /* in: file name where created */ - ulint cline, /* in: file line where created */ - const char* cmutex_name); /* in: mutex name */ + ulint cline); /* in: file line where created */ /********************************************************************** Calling this function is obligatory only if the memory buffer containing the rw-lock is freed. Removes an rw-lock object from the global list. The diff --git a/storage/innobase/include/sync0sync.h b/storage/innobase/include/sync0sync.h index a1184d44257..e7e135c0c7e 100644 --- a/storage/innobase/include/sync0sync.h +++ b/storage/innobase/include/sync0sync.h @@ -39,8 +39,18 @@ location (which must be appropriately aligned). The mutex is initialized in the reset state. Explicit freeing of the mutex with mutex_free is necessary only if the memory block containing it is freed. */ -#define mutex_create(M, level) \ - mutex_create_func((M), (level), __FILE__, __LINE__, #M) +#ifdef UNIV_DEBUG +# ifdef UNIV_SYNC_DEBUG +# define mutex_create(M, level) \ + mutex_create_func((M), #M, (level), __FILE__, __LINE__) +# else +# define mutex_create(M, level) \ + mutex_create_func((M), #M, __FILE__, __LINE__) +# endif +#else +# define mutex_create(M, level) \ + mutex_create_func((M), __FILE__, __LINE__) +#endif /********************************************************************** Creates, or rather, initializes a mutex object in a specified memory @@ -52,10 +62,14 @@ void mutex_create_func( /*==============*/ mutex_t* mutex, /* in: pointer to memory */ +#ifdef UNIV_DEBUG + const char* cmutex_name, /* in: mutex name */ +# ifdef UNIV_SYNC_DEBUG ulint level, /* in: level */ +# endif /* UNIV_SYNC_DEBUG */ +#endif /* UNIV_DEBUG */ const char* cfile_name, /* in: file name where created */ - ulint cline, /* in: file line where created */ - const char* cmutex_name); /* in: mutex name */ + ulint cline); /* in: file line where created */ /********************************************************************** Calling this function is obligatory only if the memory buffer containing the mutex is freed. Removes a mutex object from the mutex list. The mutex @@ -149,6 +163,7 @@ void sync_print( /*=======*/ FILE* file); /* in: file where to print */ +#ifdef UNIV_DEBUG /********************************************************************** Checks that the mutex has been initialized. */ @@ -156,6 +171,8 @@ ibool mutex_validate( /*===========*/ mutex_t* mutex); +#endif /* UNIV_DEBUG */ +#ifdef UNIV_SYNC_DEBUG /********************************************************************** Adds a latch and its level in the thread level array. Allocates the memory for the array if called first time for this OS thread. Makes the checks @@ -197,7 +214,6 @@ sync_thread_levels_empty_gen( allowed to be owned by the thread, also purge_is_running mutex is allowed */ -#ifdef UNIV_SYNC_DEBUG /********************************************************************** Checks that the current thread owns the mutex. Works only in the debug version. */ @@ -465,26 +481,29 @@ struct mutex_struct { 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. */ -#endif /* UNIV_SYNC_DEBUG */ 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 */ - ulint magic_n; + ulint cline; /* Line where created */ +#ifdef UNIV_DEBUG + ulint magic_n; +# define MUTEX_MAGIC_N (ulint)979585 +#endif /* UNIV_DEBUG */ #ifndef UNIV_HOTBACKUP - ulong count_using; /* count of times mutex used */ - ulong count_spin_loop; /* count of spin loops */ - ulong count_spin_rounds; /* count of spin rounds */ - ulong count_os_wait; /* count of os_wait */ - ulong count_os_yield; /* count of os_wait */ - ulonglong lspent_time; /* mutex os_wait timer msec */ - ulonglong lmax_spent_time; /* mutex os_wait timer msec */ - const char* cmutex_name;/* mutex name */ - ulint mutex_type;/* 0 - usual mutex 1 - rw_lock mutex */ + ulong count_os_wait; /* count of os_wait */ +# ifdef UNIV_DEBUG + ulong count_using; /* count of times mutex used */ + ulong count_spin_loop; /* count of spin loops */ + ulong count_spin_rounds; /* count of spin rounds */ + ulong count_os_yield; /* count of os_wait */ + ulonglong lspent_time; /* mutex os_wait timer msec */ + ulonglong lmax_spent_time; /* mutex os_wait timer msec */ + const char* cmutex_name;/* mutex name */ + ulint mutex_type;/* 0 - usual mutex 1 - rw_lock mutex */ +# endif /* UNIV_DEBUG */ #endif /* !UNIV_HOTBACKUP */ }; -#define MUTEX_MAGIC_N (ulint)979585 - /* The global array of wait cells for implementation of the databases own mutexes and read-write locks. Appears here for debugging purposes only! */ @@ -496,20 +515,16 @@ to 20 microseconds. */ #define SYNC_SPIN_ROUNDS srv_n_spin_wait_rounds -#define SYNC_INFINITE_TIME ((ulint)(-1)) - -/* Means that a timeout elapsed when waiting */ - -#define SYNC_TIME_EXCEEDED (ulint)1 - /* The number of system calls made in this module. Intended for performance monitoring. */ extern ulint mutex_system_call_count; extern ulint mutex_exit_count; +#ifdef UNIV_SYNC_DEBUG /* Latching order checks start when this is set TRUE */ extern ibool sync_order_checks_on; +#endif /* UNIV_SYNC_DEBUG */ /* This variable is set to TRUE when sync_init is called */ extern ibool sync_initialized; diff --git a/storage/innobase/include/sync0sync.ic b/storage/innobase/include/sync0sync.ic index bcecc3478b3..4b48a1469ff 100644 --- a/storage/innobase/include/sync0sync.ic +++ b/storage/innobase/include/sync0sync.ic @@ -254,9 +254,9 @@ mutex_enter_func( /* 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. */ -#ifndef UNIV_HOTBACKUP +#if defined UNIV_DEBUG && !defined UNIV_HOTBACKUP mutex->count_using++; -#endif /* UNIV_HOTBACKUP */ +#endif /* UNIV_DEBUG && !UNIV_HOTBACKUP */ if (!mutex_test_and_set(mutex)) { #ifdef UNIV_SYNC_DEBUG diff --git a/storage/innobase/include/univ.i b/storage/innobase/include/univ.i index f471fe136b0..7a5cb21f07a 100644 --- a/storage/innobase/include/univ.i +++ b/storage/innobase/include/univ.i @@ -83,19 +83,27 @@ memory is read outside the allocated blocks. */ /* Make a non-inline debug version */ #if 0 -#define UNIV_DEBUG -#define UNIV_MEM_DEBUG -#define UNIV_IBUF_DEBUG -#define UNIV_SYNC_DEBUG -#define UNIV_SEARCH_DEBUG -#define UNIV_SYNC_PERF_STAT -#define UNIV_SEARCH_PERF_STAT -#define UNIV_SRV_PRINT_LATCH_WAITS -#define UNIV_BTR_PRINT +#define UNIV_DEBUG /* Enable ut_ad() assertions */ +#define UNIV_LIST_DEBUG /* debug UT_LIST_ macros */ +#define UNIV_MEM_DEBUG /* detect memory leaks etc */ +#define UNIV_IBUF_DEBUG /* debug the insert buffer; +this limits the database to IBUF_COUNT_N_SPACES and IBUF_COUNT_N_PAGES, +and the insert buffer must be empty when the database is started */ +#define UNIV_SYNC_DEBUG /* debug mutex and latch +operations (very slow); also UNIV_DEBUG must be defined */ +#define UNIV_SEARCH_DEBUG /* debug B-tree comparisons */ +#define UNIV_SYNC_PERF_STAT /* operation counts for + rw-locks and mutexes */ +#define UNIV_SEARCH_PERF_STAT /* statistics for the + adaptive hash index */ +#define UNIV_SRV_PRINT_LATCH_WAITS /* enable diagnostic output + in sync0sync.c */ +#define UNIV_BTR_PRINT /* enable functions for + printing B-trees */ #endif -#define UNIV_BTR_DEBUG -#define UNIV_LIGHT_MEM_DEBUG +#define UNIV_BTR_DEBUG /* check B-tree links */ +#define UNIV_LIGHT_MEM_DEBUG /* light memory debugging */ #ifdef HAVE_purify /* The following sets all new allocated memory to zero before use: diff --git a/storage/innobase/include/ut0lst.h b/storage/innobase/include/ut0lst.h index d19885d6edc..9735bf315c6 100644 --- a/storage/innobase/include/ut0lst.h +++ b/storage/innobase/include/ut0lst.h @@ -124,7 +124,7 @@ name, NODE1 and NODE2 are pointers to nodes. */ }\ /* Invalidate the pointers in a list node. */ -#ifdef UNIV_DEBUG +#ifdef UNIV_LIST_DEBUG # define UT_LIST_REMOVE_CLEAR(NAME, N) \ ((N)->NAME.prev = (N)->NAME.next = (void*) -1) #else diff --git a/storage/innobase/lock/lock0lock.c b/storage/innobase/lock/lock0lock.c index 551470f49b6..84b64b146dc 100644 --- a/storage/innobase/lock/lock0lock.c +++ b/storage/innobase/lock/lock0lock.c @@ -4391,10 +4391,6 @@ loop: trx->read_view->up_limit_id)); } - fprintf(file, - "Trx has approximately %lu row locks\n", - (ulong) lock_number_of_rows_locked(trx)); - if (trx->que_state == TRX_QUE_LOCK_WAIT) { fprintf(file, "------- TRX HAS BEEN WAITING %lu SEC" diff --git a/storage/innobase/log/log0recv.c b/storage/innobase/log/log0recv.c index 280ebbb6bf2..41e2b921664 100644 --- a/storage/innobase/log/log0recv.c +++ b/storage/innobase/log/log0recv.c @@ -33,6 +33,7 @@ Created 9/20/1997 Heikki Tuuri #include "btr0cur.h" #include "dict0boot.h" #include "fil0fil.h" +#include "sync0sync.h" #ifdef UNIV_HOTBACKUP /* This is set to FALSE if the backup was originally taken with the @@ -190,6 +191,7 @@ recv_sys_empty_hash(void) recv_sys->addr_hash = hash_create(buf_pool_get_curr_size() / 256); } +#ifndef UNIV_LOG_DEBUG /************************************************************ Frees the recovery system. */ static @@ -209,6 +211,7 @@ recv_sys_free(void) mutex_exit(&(recv_sys->mutex)); } +#endif /* UNIV_LOG_DEBUG */ /************************************************************ Truncates possible corrupted or extra records from a log group. */ @@ -2855,6 +2858,15 @@ recv_recovery_from_checkpoint_finish(void) #ifndef UNIV_LOG_DEBUG recv_sys_free(); #endif + +#ifdef UNIV_SYNC_DEBUG + /* Wait for a while so that created threads have time to suspend + themselves before we switch the latching order checks on */ + os_thread_sleep(1000000); + + /* Switch latching order checks on in sync0sync.c */ + sync_order_checks_on = TRUE; +#endif if (srv_force_recovery < SRV_FORCE_NO_TRX_UNDO) { /* Rollback the uncommitted transactions which have no user session */ diff --git a/storage/innobase/row/row0ins.c b/storage/innobase/row/row0ins.c index aeaa83daa4d..1fba0abcdaf 100644 --- a/storage/innobase/row/row0ins.c +++ b/storage/innobase/row/row0ins.c @@ -1524,7 +1524,8 @@ row_ins_check_foreign_constraints( if (foreign->foreign_index == index) { if (foreign->referenced_table == NULL) { - dict_table_get(foreign->referenced_table_name); + dict_table_get(foreign->referenced_table_name, + FALSE); } if (0 == trx->dict_operation_lock_mode) { diff --git a/storage/innobase/row/row0sel.c b/storage/innobase/row/row0sel.c index c6b117cdafa..bee9f1472ce 100644 --- a/storage/innobase/row/row0sel.c +++ b/storage/innobase/row/row0sel.c @@ -1831,7 +1831,9 @@ stop_for_a_while: mtr_commit(&mtr); +#ifdef UNIV_SYNC_DEBUG ut_ad(sync_thread_levels_empty_gen(TRUE)); +#endif /* UNIV_SYNC_DEBUG */ err = DB_SUCCESS; goto func_exit; @@ -1850,7 +1852,9 @@ commit_mtr_for_a_while: leaf_contains_updates = FALSE; mtr_has_extra_clust_latch = FALSE; +#ifdef UNIV_SYNC_DEBUG ut_ad(sync_thread_levels_empty_gen(TRUE)); +#endif /* UNIV_SYNC_DEBUG */ goto table_loop; @@ -1866,7 +1870,9 @@ lock_wait_or_error: mtr_commit(&mtr); +#ifdef UNIV_SYNC_DEBUG ut_ad(sync_thread_levels_empty_gen(TRUE)); +#endif /* UNIV_SYNC_DEBUG */ func_exit: if (UNIV_LIKELY_NULL(heap)) { @@ -4447,7 +4453,7 @@ row_search_check_if_query_cache_permitted( dict_table_t* table; ibool ret = FALSE; - table = dict_table_get(norm_name); + table = dict_table_get(norm_name, FALSE); if (table == NULL) { diff --git a/storage/innobase/row/row0upd.c b/storage/innobase/row/row0upd.c index 6533ac93d7d..c91cc449b96 100644 --- a/storage/innobase/row/row0upd.c +++ b/storage/innobase/row/row0upd.c @@ -202,7 +202,8 @@ row_upd_check_references_constraints( foreign->n_fields))) { if (foreign->foreign_table == NULL) { - dict_table_get(foreign->foreign_table_name); + dict_table_get(foreign->foreign_table_name, + FALSE); } if (foreign->foreign_table) { diff --git a/storage/innobase/srv/srv0start.c b/storage/innobase/srv/srv0start.c index 5eaea26b75d..25f6f05e878 100644 --- a/storage/innobase/srv/srv0start.c +++ b/storage/innobase/srv/srv0start.c @@ -1601,17 +1601,6 @@ innobase_start_or_create_for_mysql(void) srv_was_started = TRUE; srv_is_being_started = FALSE; -#ifdef UNIV_DEBUG - /* Wait a while so that the created threads have time to suspend - themselves before we switch sync debugging on; otherwise a thread may - execute mutex_enter() before the checks are on, and mutex_exit() after - the checks are on, which will cause an assertion failure in sync - debug. */ - - os_thread_sleep(3000000); -#endif - sync_order_checks_on = TRUE; - if (trx_doublewrite == NULL) { /* Create the doublewrite buffer to a new tablespace */ diff --git a/storage/innobase/sync/sync0rw.c b/storage/innobase/sync/sync0rw.c index 441933843d7..549ad36271b 100644 --- a/storage/innobase/sync/sync0rw.c +++ b/storage/innobase/sync/sync0rw.c @@ -89,11 +89,14 @@ void rw_lock_create_func( /*================*/ rw_lock_t* lock, /* in: pointer to memory */ - ulint level __attribute__((unused)), - /* in: level */ +#ifdef UNIV_DEBUG +# ifdef UNIV_SYNC_DEBUG + ulint level, /* in: level */ +# endif /* UNIV_SYNC_DEBUG */ + const char* cmutex_name, /* in: mutex name */ +#endif /* UNIV_DEBUG */ const char* cfile_name, /* in: file name where created */ - ulint cline, /* in: file line where created */ - const char* cmutex_name) /* in: mutex name */ + ulint cline) /* in: file line where created */ { /* If this is the very first time a synchronization object is created, then the following call initializes the sync system. */ @@ -103,10 +106,10 @@ rw_lock_create_func( lock->mutex.cfile_name = cfile_name; lock->mutex.cline = cline; -#ifndef UNIV_HOTBACKUP +#if defined UNIV_DEBUG && !defined UNIV_HOTBACKUP lock->mutex.cmutex_name = cmutex_name; lock->mutex.mutex_type = 1; -#endif /* !UNIV_HOTBACKUP */ +#endif /* UNIV_DEBUG && !UNIV_HOTBACKUP */ rw_lock_set_waiters(lock, 0); rw_lock_set_writer(lock, RW_LOCK_NOT_LOCKED); diff --git a/storage/innobase/sync/sync0sync.c b/storage/innobase/sync/sync0sync.c index ff7056b0afe..c0198469491 100644 --- a/storage/innobase/sync/sync0sync.c +++ b/storage/innobase/sync/sync0sync.c @@ -108,8 +108,6 @@ will set the waiters field to 0 in mutex_exit, and then call sync_array_signal_object with the mutex as an argument. Q.E.D. */ -ulint sync_dummy = 0; - /* The number of system calls made in this module. Intended for performance monitoring. */ @@ -133,6 +131,7 @@ ibool sync_initialized = FALSE; typedef struct sync_level_struct sync_level_t; typedef struct sync_thread_struct sync_thread_t; +#ifdef UNIV_SYNC_DEBUG /* The latch levels currently owned by threads are stored in this data structure; the size of this array is OS_THREAD_MAX_N */ @@ -140,6 +139,7 @@ sync_thread_t* sync_thread_level_arrays; /* Mutex protecting sync_thread_level_arrays */ mutex_t sync_thread_mutex; +#endif /* UNIV_SYNC_DEBUG */ /* Global list of database mutexes (not OS mutexes) created. */ ut_list_base_node_t mutex_list; @@ -147,11 +147,10 @@ ut_list_base_node_t mutex_list; /* Mutex protecting the mutex_list variable */ mutex_t mutex_list_mutex; +#ifdef UNIV_SYNC_DEBUG /* Latching order checks start when this is set TRUE */ ibool sync_order_checks_on = FALSE; - -/* Dummy mutex used to implement mutex_fence */ -mutex_t dummy_mutex_for_fence; +#endif /* UNIV_SYNC_DEBUG */ struct sync_thread_struct{ os_thread_id_t id; /* OS thread id */ @@ -202,10 +201,14 @@ void mutex_create_func( /*==============*/ mutex_t* mutex, /* in: pointer to memory */ +#ifdef UNIV_DEBUG + const char* cmutex_name, /* in: mutex name */ +# ifdef UNIV_SYNC_DEBUG ulint level, /* in: level */ +# endif /* UNIV_SYNC_DEBUG */ +#endif /* UNIV_DEBUG */ const char* cfile_name, /* in: file name where created */ - ulint cline, /* in: file line where created */ - const char* cmutex_name) /* in: mutex name */ + ulint cline) /* in: file line where created */ { #if defined(_WIN32) && defined(UNIV_CAN_USE_X86_ASSEMBLER) mutex_reset_lock_word(mutex); @@ -214,15 +217,19 @@ mutex_create_func( mutex->lock_word = 0; #endif mutex_set_waiters(mutex, 0); +#ifdef UNIV_DEBUG mutex->magic_n = MUTEX_MAGIC_N; +#endif /* UNIV_DEBUG */ #ifdef UNIV_SYNC_DEBUG mutex->line = 0; mutex->file_name = "not yet reserved"; -#endif /* UNIV_SYNC_DEBUG */ mutex->level = level; +#endif /* UNIV_SYNC_DEBUG */ mutex->cfile_name = cfile_name; mutex->cline = cline; #ifndef UNIV_HOTBACKUP + mutex->count_os_wait = 0; +# ifdef UNIV_DEBUG mutex->cmutex_name= cmutex_name; mutex->count_using= 0; mutex->mutex_type= 0; @@ -230,8 +237,8 @@ mutex_create_func( mutex->lmax_spent_time= 0; mutex->count_spin_loop= 0; mutex->count_spin_rounds= 0; - mutex->count_os_wait= 0; mutex->count_os_yield= 0; +# endif /* UNIV_DEBUG */ #endif /* !UNIV_HOTBACKUP */ /* Check that lock_word is aligned; this is important on Intel */ @@ -239,16 +246,19 @@ mutex_create_func( /* NOTE! The very first mutexes are not put to the mutex list */ - if ((mutex == &mutex_list_mutex) || (mutex == &sync_thread_mutex)) { + if ((mutex == &mutex_list_mutex) +#ifdef UNIV_SYNC_DEBUG + || (mutex == &sync_thread_mutex) +#endif /* UNIV_SYNC_DEBUG */ + ) { return; } mutex_enter(&mutex_list_mutex); - if (UT_LIST_GET_LEN(mutex_list) > 0) { - ut_a(UT_LIST_GET_FIRST(mutex_list)->magic_n == MUTEX_MAGIC_N); - } + ut_ad(UT_LIST_GET_LEN(mutex_list) == 0 + || UT_LIST_GET_FIRST(mutex_list)->magic_n == MUTEX_MAGIC_N); UT_LIST_ADD_FIRST(list, mutex_list, mutex); @@ -265,24 +275,24 @@ mutex_free( /*=======*/ mutex_t* mutex) /* in: mutex */ { -#ifdef UNIV_DEBUG - ut_a(mutex_validate(mutex)); -#endif /* UNIV_DEBUG */ + ut_ad(mutex_validate(mutex)); ut_a(mutex_get_lock_word(mutex) == 0); ut_a(mutex_get_waiters(mutex) == 0); - if (mutex != &mutex_list_mutex && mutex != &sync_thread_mutex) { + if (mutex != &mutex_list_mutex +#ifdef UNIV_SYNC_DEBUG + && mutex != &sync_thread_mutex +#endif /* UNIV_SYNC_DEBUG */ + ) { mutex_enter(&mutex_list_mutex); - if (UT_LIST_GET_PREV(list, mutex)) { - ut_a(UT_LIST_GET_PREV(list, mutex)->magic_n - == MUTEX_MAGIC_N); - } - if (UT_LIST_GET_NEXT(list, mutex)) { - ut_a(UT_LIST_GET_NEXT(list, mutex)->magic_n - == MUTEX_MAGIC_N); - } + ut_ad(!UT_LIST_GET_PREV(list, mutex) + || UT_LIST_GET_PREV(list, mutex)->magic_n + == MUTEX_MAGIC_N); + ut_ad(!UT_LIST_GET_NEXT(list, mutex) + || UT_LIST_GET_NEXT(list, mutex)->magic_n + == MUTEX_MAGIC_N); UT_LIST_REMOVE(list, mutex_list, mutex); @@ -295,8 +305,9 @@ mutex_free( /* If we free the mutex protecting the mutex list (freeing is not necessary), we have to reset the magic number AFTER removing it from the list. */ - +#ifdef UNIV_DEBUG mutex->magic_n = 0; +#endif /* UNIV_DEBUG */ } /************************************************************************ @@ -328,6 +339,7 @@ mutex_enter_nowait( return(1); } +#ifdef UNIV_DEBUG /********************************************************************** Checks that the mutex has been initialized. */ @@ -341,6 +353,7 @@ mutex_validate( return(TRUE); } +#endif /* UNIV_DEBUG */ /********************************************************************** Sets the waiters field in a mutex. */ @@ -376,13 +389,13 @@ mutex_spin_wait( { ulint index; /* index of the reserved wait cell */ ulint i; /* spin round count */ -#ifndef UNIV_HOTBACKUP +#if defined UNIV_DEBUG && !defined UNIV_HOTBACKUP ib_longlong lstart_time = 0, lfinish_time; /* for timing os_wait */ ulint ltime_diff; ulint sec; ulint ms; uint timer_started = 0; -#endif /* !UNIV_HOTBACKUP */ +#endif /* UNIV_DEBUG && !UNIV_HOTBACKUP */ ut_ad(mutex); mutex_loop: @@ -396,10 +409,10 @@ mutex_loop: a memory word. */ spin_loop: -#ifndef UNIV_HOTBACKUP +#if defined UNIV_DEBUG && !defined UNIV_HOTBACKUP mutex_spin_wait_count++; mutex->count_spin_loop++; -#endif /* !UNIV_HOTBACKUP */ +#endif /* UNIV_DEBUG && !UNIV_HOTBACKUP */ while (mutex_get_lock_word(mutex) != 0 && i < SYNC_SPIN_ROUNDS) { if (srv_spin_wait_delay) { @@ -410,14 +423,14 @@ spin_loop: } if (i == SYNC_SPIN_ROUNDS) { -#ifndef UNIV_HOTBACKUP +#if defined UNIV_DEBUG && !defined UNIV_HOTBACKUP mutex->count_os_yield++; if (timed_mutexes == 1 && timer_started==0) { ut_usectime(&sec, &ms); lstart_time= (ib_longlong)sec * 1000000 + ms; timer_started = 1; } -#endif /* !UNIV_HOTBACKUP */ +#endif /* UNIV_DEBUG && !UNIV_HOTBACKUP */ os_thread_yield(); } @@ -431,9 +444,9 @@ spin_loop: mutex_spin_round_count += i; -#ifndef UNIV_HOTBACKUP +#if defined UNIV_DEBUG && !defined UNIV_HOTBACKUP mutex->count_spin_rounds += i; -#endif /* !UNIV_HOTBACKUP */ +#endif /* UNIV_DEBUG && !UNIV_HOTBACKUP */ if (mutex_test_and_set(mutex) == 0) { /* Succeeded! */ @@ -514,6 +527,7 @@ spin_loop: #ifndef UNIV_HOTBACKUP mutex->count_os_wait++; +# ifdef UNIV_DEBUG /* !!!!! Sometimes os_wait can be called without os_thread_yield */ if (timed_mutexes == 1 && timer_started==0) { @@ -521,13 +535,14 @@ spin_loop: lstart_time= (ib_longlong)sec * 1000000 + ms; timer_started = 1; } +# endif /* UNIV_DEBUG */ #endif /* !UNIV_HOTBACKUP */ sync_array_wait_event(sync_primary_wait_array, index); goto mutex_loop; finish_timing: -#ifndef UNIV_HOTBACKUP +#if defined UNIV_DEBUG && !defined UNIV_HOTBACKUP if (timed_mutexes == 1 && timer_started==1) { ut_usectime(&sec, &ms); lfinish_time= (ib_longlong)sec * 1000000 + ms; @@ -539,7 +554,7 @@ finish_timing: mutex->lmax_spent_time= ltime_diff; } } -#endif /* !UNIV_HOTBACKUP */ +#endif /* UNIV_DEBUG && !UNIV_HOTBACKUP */ return; } @@ -598,9 +613,7 @@ mutex_get_debug_info( *line = mutex->line; *thread_id = mutex->thread_id; } -#endif /* UNIV_SYNC_DEBUG */ -#ifdef UNIV_SYNC_DEBUG /********************************************************************** Checks that the current thread owns the mutex. Works only in the debug version. */ @@ -611,7 +624,7 @@ mutex_own( /* out: TRUE if owns */ mutex_t* mutex) /* in: mutex */ { - ut_a(mutex_validate(mutex)); + ut_ad(mutex_validate(mutex)); if (mutex_get_lock_word(mutex) != 1) { @@ -710,7 +723,6 @@ sync_all_freed(void) { return(mutex_n_reserved() + rw_lock_n_locked() == 0); } -#endif /* UNIV_SYNC_DEBUG */ /********************************************************************** Gets the value in the nth slot in the thread level arrays. */ @@ -834,7 +846,6 @@ sync_thread_levels_g( (ulong) mutex->cline); if (mutex_get_lock_word(mutex) != 0) { -#ifdef UNIV_SYNC_DEBUG const char* file_name; ulint line; os_thread_id_t thread_id; @@ -852,19 +863,11 @@ sync_thread_levels_g( thread_id), file_name, (ulong) line); -#else /* UNIV_SYNC_DEBUG */ - fprintf(stderr, - "InnoDB: Locked mutex:" - " addr %p\n", - (void*) mutex); -#endif /* UNIV_SYNC_DEBUG */ } else { fputs("Not locked\n", stderr); } } else { -#ifdef UNIV_SYNC_DEBUG rw_lock_print(lock); -#endif /* UNIV_SYNC_DEBUG */ } return(FALSE); @@ -996,9 +999,7 @@ sync_thread_add_level( if ((latch == (void*)&sync_thread_mutex) || (latch == (void*)&mutex_list_mutex) -#ifdef UNIV_SYNC_DEBUG || (latch == (void*)&rw_lock_debug_mutex) -#endif /* UNIV_SYNC_DEBUG */ || (latch == (void*)&rw_lock_list_mutex)) { return; @@ -1219,9 +1220,7 @@ sync_thread_reset_level( if ((latch == (void*)&sync_thread_mutex) || (latch == (void*)&mutex_list_mutex) -#ifdef UNIV_SYNC_DEBUG || (latch == (void*)&rw_lock_debug_mutex) -#endif /* UNIV_SYNC_DEBUG */ || (latch == (void*)&rw_lock_list_mutex)) { return(FALSE); @@ -1260,6 +1259,7 @@ sync_thread_reset_level( return(FALSE); } +#endif /* UNIV_SYNC_DEBUG */ /********************************************************************** Initializes the synchronization data structures. */ @@ -1268,8 +1268,10 @@ void sync_init(void) /*===========*/ { +#ifdef UNIV_SYNC_DEBUG sync_thread_t* thread_slot; ulint i; +#endif /* UNIV_SYNC_DEBUG */ ut_a(sync_initialized == FALSE); @@ -1280,7 +1282,7 @@ sync_init(void) sync_primary_wait_array = sync_array_create(OS_THREAD_MAX_N, SYNC_ARRAY_OS_MUTEX); - +#ifdef UNIV_SYNC_DEBUG /* Create the thread latch level array where the latch levels are stored for each OS thread */ @@ -1291,13 +1293,14 @@ sync_init(void) thread_slot = sync_thread_level_arrays_get_nth(i); thread_slot->levels = NULL; } - +#endif /* UNIV_SYNC_DEBUG */ /* Init the mutex list and create the mutex to protect it. */ UT_LIST_INIT(mutex_list); mutex_create(&mutex_list_mutex, SYNC_NO_ORDER_CHECK); - +#ifdef UNIV_SYNC_DEBUG mutex_create(&sync_thread_mutex, SYNC_NO_ORDER_CHECK); +#endif /* UNIV_SYNC_DEBUG */ /* Init the rw-lock list and create the mutex to protect it. */ @@ -1332,7 +1335,9 @@ sync_close(void) } mutex_free(&mutex_list_mutex); +#ifdef UNIV_SYNC_DEBUG mutex_free(&sync_thread_mutex); +#endif /* UNIV_SYNC_DEBUG */ } /*********************************************************************** diff --git a/storage/innobase/trx/trx0roll.c b/storage/innobase/trx/trx0roll.c index 1b00ae63ecd..201d1be3656 100644 --- a/storage/innobase/trx/trx0roll.c +++ b/storage/innobase/trx/trx0roll.c @@ -131,8 +131,26 @@ trx_rollback_for_mysql( trx->op_info = "rollback"; - err = trx_general_rollback_for_mysql(trx, FALSE, NULL); + /* If we are doing the XA recovery of prepared transactions, then + the transaction object does not have an InnoDB session object, and we + set a dummy session that we use for all MySQL transactions. */ + + mutex_enter(&kernel_mutex); + + if (trx->sess == NULL) { + /* Open a dummy session */ + + if (!trx_dummy_sess) { + trx_dummy_sess = sess_open(); + } + trx->sess = trx_dummy_sess; + } + + mutex_exit(&kernel_mutex); + + err = trx_general_rollback_for_mysql(trx, FALSE, NULL); + trx->op_info = ""; return(err); diff --git a/storage/innobase/trx/trx0trx.c b/storage/innobase/trx/trx0trx.c index 4d0a26b5757..cfa2b01f406 100644 --- a/storage/innobase/trx/trx0trx.c +++ b/storage/innobase/trx/trx0trx.c @@ -1598,6 +1598,24 @@ trx_commit_for_mysql( trx->op_info = "committing"; + /* If we are doing the XA recovery of prepared transactions, then + the transaction object does not have an InnoDB session object, and we + set the dummy session that we use for all MySQL transactions. */ + + mutex_enter(&kernel_mutex); + + if (trx->sess == NULL) { + /* Open a dummy session */ + + if (!trx_dummy_sess) { + trx_dummy_sess = sess_open(); + } + + trx->sess = trx_dummy_sess; + } + + mutex_exit(&kernel_mutex); + trx_start_if_not_started(trx); mutex_enter(&kernel_mutex); @@ -1761,11 +1779,10 @@ trx_print( || mem_heap_get_size(trx->lock_heap) > 400) { newline = TRUE; - fprintf(f, "%lu lock struct(s), heap size %lu", + fprintf(f, "%lu lock struct(s), heap size %lu," + " %lu row lock(s)", (ulong) UT_LIST_GET_LEN(trx->trx_locks), - (ulong) mem_heap_get_size(trx->lock_heap)); - - fprintf(f, "%lu row lock(s)", + (ulong) mem_heap_get_size(trx->lock_heap), (ulong) lock_number_of_rows_locked(trx)); } |