mirror of
https://github.com/MariaDB/server.git
synced 2026-05-15 03:17:20 +02:00
Merge siva.hindu.god:/home/tsmith/m/inno/jan04/51
into siva.hindu.god:/home/tsmith/m/bk/51-build storage/innobase/buf/buf0buf.c: Auto merged storage/innobase/dict/dict0dict.c: Auto merged storage/innobase/ha/ha0ha.c: Auto merged storage/innobase/ha/hash0hash.c: Auto merged storage/innobase/include/hash0hash.h: Auto merged storage/innobase/lock/lock0lock.c: Auto merged storage/innobase/log/log0recv.c: Auto merged
This commit is contained in:
commit
0e4155835c
27 changed files with 336 additions and 268 deletions
|
|
@ -1755,22 +1755,22 @@ buf_page_init_for_read(
|
||||||
if (*err == DB_TABLESPACE_DELETED
|
if (*err == DB_TABLESPACE_DELETED
|
||||||
|| NULL != buf_page_hash_get(space, offset)) {
|
|| NULL != buf_page_hash_get(space, offset)) {
|
||||||
|
|
||||||
/* The page belongs to a space which has been
|
/* The page belongs to a space which has been
|
||||||
deleted or is being deleted, or the page is
|
deleted or is being deleted, or the page is
|
||||||
already in buf_pool, return */
|
already in buf_pool, return */
|
||||||
|
|
||||||
mutex_exit(&block->mutex);
|
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);
|
ut_ad(block);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -854,8 +854,10 @@ buf_flush_batch(
|
||||||
|
|
||||||
ut_ad((flush_type == BUF_FLUSH_LRU)
|
ut_ad((flush_type == BUF_FLUSH_LRU)
|
||||||
|| (flush_type == BUF_FLUSH_LIST));
|
|| (flush_type == BUF_FLUSH_LIST));
|
||||||
|
#ifdef UNIV_SYNC_DEBUG
|
||||||
ut_ad((flush_type != BUF_FLUSH_LIST)
|
ut_ad((flush_type != BUF_FLUSH_LIST)
|
||||||
|| sync_thread_levels_empty_gen(TRUE));
|
|| sync_thread_levels_empty_gen(TRUE));
|
||||||
|
#endif /* UNIV_SYNC_DEBUG */
|
||||||
mutex_enter(&(buf_pool->mutex));
|
mutex_enter(&(buf_pool->mutex));
|
||||||
|
|
||||||
if ((buf_pool->n_flush[flush_type] > 0)
|
if ((buf_pool->n_flush[flush_type] > 0)
|
||||||
|
|
|
||||||
|
|
@ -801,16 +801,20 @@ dict_init(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
Returns a table object. NOTE! This is a high-level function to be used
|
Returns a table object and optionally increment its MySQL open handle count.
|
||||||
mainly from outside the 'dict' directory. Inside this directory
|
NOTE! This is a high-level function to be used mainly from outside the
|
||||||
dict_table_get_low is usually the appropriate function. */
|
'dict' directory. Inside this directory dict_table_get_low is usually the
|
||||||
|
appropriate function. */
|
||||||
|
|
||||||
dict_table_t*
|
dict_table_t*
|
||||||
dict_table_get(
|
dict_table_get(
|
||||||
/*===========*/
|
/*===========*/
|
||||||
/* out: table, NULL if
|
/* out: table, NULL if
|
||||||
does not exist */
|
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;
|
dict_table_t* table;
|
||||||
|
|
||||||
|
|
@ -818,42 +822,17 @@ dict_table_get(
|
||||||
|
|
||||||
table = dict_table_get_low(table_name);
|
table = dict_table_get_low(table_name);
|
||||||
|
|
||||||
mutex_exit(&(dict_sys->mutex));
|
if (inc_mysql_count && table) {
|
||||||
|
|
||||||
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 */
|
|
||||||
{
|
|
||||||
dict_table_t* table;
|
|
||||||
|
|
||||||
mutex_enter(&(dict_sys->mutex));
|
|
||||||
|
|
||||||
table = dict_table_get_low(table_name);
|
|
||||||
|
|
||||||
if (table != NULL) {
|
|
||||||
|
|
||||||
table->n_mysql_handles_opened++;
|
table->n_mysql_handles_opened++;
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_exit(&(dict_sys->mutex));
|
mutex_exit(&(dict_sys->mutex));
|
||||||
|
|
||||||
if (table != NULL) {
|
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);
|
dict_update_statistics(table);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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. */
|
chosen to be a prime number slightly bigger than n. */
|
||||||
|
|
||||||
hash_table_t*
|
hash_table_t*
|
||||||
ha_create(
|
ha_create_func(
|
||||||
/*======*/
|
/*===========*/
|
||||||
/* out, own: created table */
|
/* out, own: created table */
|
||||||
ibool in_btr_search, /* in: TRUE if the hash table is used in
|
ibool in_btr_search, /* in: TRUE if the hash table is used in
|
||||||
the btr_search module */
|
the btr_search module */
|
||||||
ulint n, /* in: number of array cells */
|
ulint n, /* in: number of array cells */
|
||||||
ulint n_mutexes, /* in: number of mutexes to protect the
|
#ifdef UNIV_SYNC_DEBUG
|
||||||
hash table: must be a power of 2, or 0 */
|
ulint mutex_level, /* in: level of the mutexes in the latching
|
||||||
ulint mutex_level) /* in: level of the mutexes in the latching
|
|
||||||
order: this is used in the debug version */
|
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;
|
hash_table_t* table;
|
||||||
ulint i;
|
ulint i;
|
||||||
|
|
|
||||||
|
|
@ -129,13 +129,15 @@ hash_table_free(
|
||||||
Creates a mutex array to protect a hash table. */
|
Creates a mutex array to protect a hash table. */
|
||||||
|
|
||||||
void
|
void
|
||||||
hash_create_mutexes(
|
hash_create_mutexes_func(
|
||||||
/*================*/
|
/*=====================*/
|
||||||
hash_table_t* table, /* in: hash table */
|
hash_table_t* table, /* in: hash table */
|
||||||
ulint n_mutexes, /* in: number of mutexes, must be a
|
#ifdef UNIV_SYNC_DEBUG
|
||||||
power of 2 */
|
ulint sync_level, /* in: latching order level of the
|
||||||
ulint sync_level) /* in: latching order level of the
|
|
||||||
mutexes: used in the debug version */
|
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;
|
ulint i;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -39,9 +39,6 @@ have disables the InnoDB inlining in this file. */
|
||||||
#include <myisampack.h>
|
#include <myisampack.h>
|
||||||
#include <mysys_err.h>
|
#include <mysys_err.h>
|
||||||
#include <my_sys.h>
|
#include <my_sys.h>
|
||||||
|
|
||||||
#define MAX_ULONG_BIT ((ulong) 1 << (sizeof(ulong)*8-1))
|
|
||||||
|
|
||||||
#include "ha_innodb.h"
|
#include "ha_innodb.h"
|
||||||
|
|
||||||
pthread_mutex_t innobase_share_mutex, /* to protect innobase_open_files */
|
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);
|
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 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
|
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 */
|
/* 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) {
|
if (NULL == ib_table) {
|
||||||
ut_print_timestamp(stderr);
|
ut_print_timestamp(stderr);
|
||||||
|
|
@ -4451,7 +4436,7 @@ ha_innobase::rnd_pos(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
DBUG_PRINT("error", ("Got error: %d", error));
|
DBUG_PRINT("error", ("Got error: %d", error));
|
||||||
DBUG_RETURN(error);
|
DBUG_RETURN(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -4932,7 +4917,7 @@ ha_innobase::create(
|
||||||
|
|
||||||
log_buffer_flush_to_disk();
|
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);
|
DBUG_ASSERT(innobase_table != 0);
|
||||||
|
|
||||||
|
|
@ -5543,16 +5528,10 @@ ha_innobase::info(
|
||||||
prebuilt->trx->op_info = (char*)
|
prebuilt->trx->op_info = (char*)
|
||||||
"returning various info to MySQL";
|
"returning various info to MySQL";
|
||||||
|
|
||||||
if (ib_table->space != 0) {
|
my_snprintf(path, sizeof(path), "%s/%s%s",
|
||||||
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",
|
|
||||||
mysql_data_home, ib_table->name, reg_ext);
|
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,
|
/* Note that we do not know the access time of the table,
|
||||||
nor the CHECK TABLE time, nor the UPDATE or INSERT time. */
|
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];
|
char buf1[IO_SIZE], buf2[IO_SIZE];
|
||||||
mutex_t* mutex;
|
mutex_t* mutex;
|
||||||
|
#ifdef UNIV_DEBUG
|
||||||
ulint rw_lock_count= 0;
|
ulint rw_lock_count= 0;
|
||||||
ulint rw_lock_count_spin_loop= 0;
|
ulint rw_lock_count_spin_loop= 0;
|
||||||
ulint rw_lock_count_spin_rounds= 0;
|
ulint rw_lock_count_spin_rounds= 0;
|
||||||
ulint rw_lock_count_os_wait= 0;
|
ulint rw_lock_count_os_wait= 0;
|
||||||
ulint rw_lock_count_os_yield= 0;
|
ulint rw_lock_count_os_yield= 0;
|
||||||
ulonglong rw_lock_wait_time= 0;
|
ulonglong rw_lock_wait_time= 0;
|
||||||
|
#endif /* UNIV_DEBUG */
|
||||||
uint hton_name_len= strlen(innobase_hton_name), buf1len, buf2len;
|
uint hton_name_len= strlen(innobase_hton_name), buf1len, buf2len;
|
||||||
DBUG_ENTER("innodb_mutex_show_status");
|
DBUG_ENTER("innodb_mutex_show_status");
|
||||||
|
|
||||||
#ifdef MUTEX_PROTECT_TO_BE_ADDED_LATER
|
mutex_enter_noninline(&mutex_list_mutex);
|
||||||
mutex_enter(&mutex_list_mutex);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
mutex = UT_LIST_GET_FIRST(mutex_list);
|
mutex = UT_LIST_GET_FIRST(mutex_list);
|
||||||
|
|
||||||
while (mutex != NULL) {
|
while (mutex != NULL) {
|
||||||
|
#ifdef UNIV_DEBUG
|
||||||
if (mutex->mutex_type != 1) {
|
if (mutex->mutex_type != 1) {
|
||||||
if (mutex->count_using > 0) {
|
if (mutex->count_using > 0) {
|
||||||
buf1len= my_snprintf(buf1, sizeof(buf1),
|
buf1len= my_snprintf(buf1, sizeof(buf1),
|
||||||
|
|
@ -6636,14 +6616,13 @@ innodb_mutex_show_status(
|
||||||
mutex->count_spin_rounds,
|
mutex->count_spin_rounds,
|
||||||
mutex->count_os_wait,
|
mutex->count_os_wait,
|
||||||
mutex->count_os_yield,
|
mutex->count_os_yield,
|
||||||
(ulong) (mutex->lspent_time/1000));
|
(ulong) (mutex->lspent_time/1000));
|
||||||
|
|
||||||
if (stat_print(thd, innobase_hton_name,
|
if (stat_print(thd, innobase_hton_name,
|
||||||
hton_name_len, buf1, buf1len,
|
hton_name_len, buf1, buf1len,
|
||||||
buf2, buf2len)) {
|
buf2, buf2len)) {
|
||||||
#ifdef MUTEX_PROTECT_TO_BE_ADDED_LATER
|
mutex_exit_noninline(
|
||||||
mutex_exit(&mutex_list_mutex);
|
&mutex_list_mutex);
|
||||||
#endif
|
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -6656,26 +6635,39 @@ innodb_mutex_show_status(
|
||||||
rw_lock_count_os_yield += mutex->count_os_yield;
|
rw_lock_count_os_yield += mutex->count_os_yield;
|
||||||
rw_lock_wait_time += mutex->lspent_time;
|
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 = UT_LIST_GET_NEXT(list, mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mutex_exit_noninline(&mutex_list_mutex);
|
||||||
|
|
||||||
|
#ifdef UNIV_DEBUG
|
||||||
buf2len= my_snprintf(buf2, sizeof(buf2),
|
buf2len= my_snprintf(buf2, sizeof(buf2),
|
||||||
"count=%lu, spin_waits=%lu, spin_rounds=%lu, "
|
"count=%lu, spin_waits=%lu, spin_rounds=%lu, "
|
||||||
"os_waits=%lu, os_yields=%lu, os_wait_times=%lu",
|
"os_waits=%lu, os_yields=%lu, os_wait_times=%lu",
|
||||||
rw_lock_count, rw_lock_count_spin_loop,
|
rw_lock_count, rw_lock_count_spin_loop,
|
||||||
rw_lock_count_spin_rounds,
|
rw_lock_count_spin_rounds,
|
||||||
rw_lock_count_os_wait, rw_lock_count_os_yield,
|
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,
|
if (stat_print(thd, innobase_hton_name, hton_name_len,
|
||||||
STRING_WITH_LEN("rw_lock_mutexes"), buf2, buf2len)) {
|
STRING_WITH_LEN("rw_lock_mutexes"), buf2, buf2len)) {
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
}
|
}
|
||||||
|
#endif /* UNIV_DEBUG */
|
||||||
#ifdef MUTEX_PROTECT_TO_BE_ADDED_LATER
|
|
||||||
mutex_exit(&mutex_list_mutex);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
DBUG_RETURN(FALSE);
|
DBUG_RETURN(FALSE);
|
||||||
}
|
}
|
||||||
|
|
@ -7348,7 +7340,6 @@ innobase_get_at_most_n_mbchars(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
This function returns true if
|
This function returns true if
|
||||||
|
|
||||||
|
|
@ -7358,33 +7349,34 @@ is either REPLACE or LOAD DATA INFILE REPLACE.
|
||||||
2) SQL-query in the current thread
|
2) SQL-query in the current thread
|
||||||
is INSERT ON DUPLICATE KEY UPDATE.
|
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 ! */
|
prototype for this function ! */
|
||||||
|
extern "C"
|
||||||
ibool
|
ibool
|
||||||
innobase_query_is_update(void)
|
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 ||
|
return(FALSE);
|
||||||
thd->lex->sql_command == SQLCOM_REPLACE_SELECT ||
|
|
||||||
(thd->lex->sql_command == SQLCOM_LOAD &&
|
|
||||||
thd->lex->duplicates == DUP_REPLACE)) {
|
|
||||||
|
|
||||||
return(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (thd->lex->sql_command == SQLCOM_INSERT &&
|
switch (thd->lex->sql_command) {
|
||||||
thd->lex->duplicates == DUP_UPDATE) {
|
case SQLCOM_REPLACE:
|
||||||
|
case SQLCOM_REPLACE_SELECT:
|
||||||
return(1);
|
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
|
|
|
||||||
|
|
@ -160,7 +160,7 @@ struct btr_search_struct{
|
||||||
number of full fields */
|
number of full fields */
|
||||||
ulint n_bytes; /* recommended prefix: number of bytes in
|
ulint n_bytes; /* recommended prefix: number of bytes in
|
||||||
an incomplete field;
|
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
|
ibool left_side; /* TRUE or FALSE, depending on whether
|
||||||
the leftmost record of several records with
|
the leftmost record of several records with
|
||||||
the same prefix should be indexed in the
|
the same prefix should be indexed in the
|
||||||
|
|
|
||||||
|
|
@ -625,8 +625,6 @@ buf_page_release(
|
||||||
RW_NO_LATCH */
|
RW_NO_LATCH */
|
||||||
mtr_t* mtr) /* in: mtr */
|
mtr_t* mtr) /* in: mtr */
|
||||||
{
|
{
|
||||||
ulint buf_fix_count;
|
|
||||||
|
|
||||||
ut_ad(block);
|
ut_ad(block);
|
||||||
|
|
||||||
ut_a(block->state == BUF_BLOCK_FILE_PAGE);
|
ut_a(block->state == BUF_BLOCK_FILE_PAGE);
|
||||||
|
|
@ -643,8 +641,7 @@ buf_page_release(
|
||||||
#ifdef UNIV_SYNC_DEBUG
|
#ifdef UNIV_SYNC_DEBUG
|
||||||
rw_lock_s_unlock(&(block->debug_latch));
|
rw_lock_s_unlock(&(block->debug_latch));
|
||||||
#endif
|
#endif
|
||||||
buf_fix_count = block->buf_fix_count;
|
block->buf_fix_count--;
|
||||||
block->buf_fix_count = buf_fix_count - 1;
|
|
||||||
|
|
||||||
mutex_exit(&block->mutex);
|
mutex_exit(&block->mutex);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -65,8 +65,8 @@ dtype_get_mblen(
|
||||||
innobase_get_cset_width(dtype_get_charset_coll(prtype),
|
innobase_get_cset_width(dtype_get_charset_coll(prtype),
|
||||||
mbminlen, mbmaxlen);
|
mbminlen, mbmaxlen);
|
||||||
ut_ad(*mbminlen <= *mbmaxlen);
|
ut_ad(*mbminlen <= *mbmaxlen);
|
||||||
ut_ad(*mbminlen <= 2); /* cf. the bit-field in dtype_t */
|
ut_ad(*mbminlen <= 2); /* mbminlen in dtype_t is 0..3 */
|
||||||
ut_ad(*mbmaxlen < 1 << 3); /* cf. the bit-field in dtype_t */
|
ut_ad(*mbmaxlen < 1 << 3); /* mbmaxlen in dtype_t is 0..7 */
|
||||||
#else /* !UNIV_HOTBACKUP */
|
#else /* !UNIV_HOTBACKUP */
|
||||||
ut_a(mtype <= DATA_BINARY);
|
ut_a(mtype <= DATA_BINARY);
|
||||||
*mbminlen = *mbmaxlen = 1;
|
*mbminlen = *mbmaxlen = 1;
|
||||||
|
|
|
||||||
|
|
@ -326,26 +326,20 @@ dict_foreign_parse_drop_constraints(
|
||||||
const char*** constraints_to_drop); /* out: id's of the
|
const char*** constraints_to_drop); /* out: id's of the
|
||||||
constraints to drop */
|
constraints to drop */
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
Returns a table object. NOTE! This is a high-level function to be used
|
Returns a table object and optionally increment its MySQL open handle count.
|
||||||
mainly from outside the 'dict' directory. Inside this directory
|
NOTE! This is a high-level function to be used mainly from outside the
|
||||||
dict_table_get_low is usually the appropriate function. */
|
'dict' directory. Inside this directory dict_table_get_low is usually the
|
||||||
|
appropriate function. */
|
||||||
|
|
||||||
dict_table_t*
|
dict_table_t*
|
||||||
dict_table_get(
|
dict_table_get(
|
||||||
/*===========*/
|
/*===========*/
|
||||||
/* out: table, NULL if
|
/* out: table, NULL if
|
||||||
does not exist */
|
does not exist */
|
||||||
const char* table_name); /* in: table name */
|
const char* table_name, /* in: table name */
|
||||||
/**************************************************************************
|
ibool inc_mysql_count);
|
||||||
Returns a table object and increments MySQL open handle count on the table.
|
/* in: whether to increment the 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 */
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
Returns a table object based on table id. */
|
Returns a table object based on table id. */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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. */
|
chosen to be a prime number slightly bigger than n. */
|
||||||
|
|
||||||
hash_table_t*
|
hash_table_t*
|
||||||
ha_create(
|
ha_create_func(
|
||||||
/*======*/
|
/*===========*/
|
||||||
/* out, own: created table */
|
/* out, own: created table */
|
||||||
ibool in_btr_search, /* in: TRUE if the hash table is used in
|
ibool in_btr_search, /* in: TRUE if the hash table is used in
|
||||||
the btr_search module */
|
the btr_search module */
|
||||||
ulint n, /* in: number of array cells */
|
ulint n, /* in: number of array cells */
|
||||||
ulint n_mutexes, /* in: number of mutexes to protect the
|
#ifdef UNIV_SYNC_DEBUG
|
||||||
hash table: must be a power of 2 */
|
ulint mutex_level, /* in: level of the mutexes in the latching
|
||||||
ulint mutex_level); /* in: level of the mutexes in the latching
|
|
||||||
order: this is used in the debug version */
|
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
|
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
|
is found, its node is updated to point to the new data, and no new node
|
||||||
|
|
|
||||||
|
|
@ -31,12 +31,20 @@ hash0_create(
|
||||||
Creates a mutex array to protect a hash table. */
|
Creates a mutex array to protect a hash table. */
|
||||||
|
|
||||||
void
|
void
|
||||||
hash_create_mutexes(
|
hash_create_mutexes_func(
|
||||||
/*================*/
|
/*=====================*/
|
||||||
hash_table_t* table, /* in: hash table */
|
hash_table_t* table, /* in: hash table */
|
||||||
ulint n_mutexes, /* in: number of mutexes */
|
#ifdef UNIV_SYNC_DEBUG
|
||||||
ulint sync_level); /* in: latching order level of the
|
ulint sync_level, /* in: latching order level of the
|
||||||
mutexes: used in the debug version */
|
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. */
|
Frees a hash table. */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
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
|
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. */
|
is necessary only if the memory block containing it is freed. */
|
||||||
#define rw_lock_create(L, level) \
|
#ifdef UNIV_DEBUG
|
||||||
rw_lock_create_func((L), (level), __FILE__, __LINE__, #L)
|
# 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
|
Creates, or rather, initializes an rw-lock object in a specified memory
|
||||||
|
|
@ -74,10 +84,14 @@ void
|
||||||
rw_lock_create_func(
|
rw_lock_create_func(
|
||||||
/*================*/
|
/*================*/
|
||||||
rw_lock_t* lock, /* in: pointer to memory */
|
rw_lock_t* lock, /* in: pointer to memory */
|
||||||
|
#ifdef UNIV_DEBUG
|
||||||
|
# ifdef UNIV_SYNC_DEBUG
|
||||||
ulint level, /* in: level */
|
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 */
|
const char* cfile_name, /* in: file name where created */
|
||||||
ulint cline, /* in: file line where created */
|
ulint cline); /* in: file line where created */
|
||||||
const char* cmutex_name); /* in: mutex name */
|
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
Calling this function is obligatory only if the memory buffer containing
|
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
|
the rw-lock is freed. Removes an rw-lock object from the global list. The
|
||||||
|
|
|
||||||
|
|
@ -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
|
in the reset state. Explicit freeing of the mutex with mutex_free is
|
||||||
necessary only if the memory block containing it is freed. */
|
necessary only if the memory block containing it is freed. */
|
||||||
|
|
||||||
#define mutex_create(M, level) \
|
#ifdef UNIV_DEBUG
|
||||||
mutex_create_func((M), (level), __FILE__, __LINE__, #M)
|
# 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
|
Creates, or rather, initializes a mutex object in a specified memory
|
||||||
|
|
@ -52,10 +62,14 @@ void
|
||||||
mutex_create_func(
|
mutex_create_func(
|
||||||
/*==============*/
|
/*==============*/
|
||||||
mutex_t* mutex, /* in: pointer to memory */
|
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 */
|
ulint level, /* in: level */
|
||||||
|
# endif /* UNIV_SYNC_DEBUG */
|
||||||
|
#endif /* UNIV_DEBUG */
|
||||||
const char* cfile_name, /* in: file name where created */
|
const char* cfile_name, /* in: file name where created */
|
||||||
ulint cline, /* in: file line where created */
|
ulint cline); /* in: file line where created */
|
||||||
const char* cmutex_name); /* in: mutex name */
|
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
Calling this function is obligatory only if the memory buffer containing
|
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
|
the mutex is freed. Removes a mutex object from the mutex list. The mutex
|
||||||
|
|
@ -149,6 +163,7 @@ void
|
||||||
sync_print(
|
sync_print(
|
||||||
/*=======*/
|
/*=======*/
|
||||||
FILE* file); /* in: file where to print */
|
FILE* file); /* in: file where to print */
|
||||||
|
#ifdef UNIV_DEBUG
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
Checks that the mutex has been initialized. */
|
Checks that the mutex has been initialized. */
|
||||||
|
|
||||||
|
|
@ -156,6 +171,8 @@ ibool
|
||||||
mutex_validate(
|
mutex_validate(
|
||||||
/*===========*/
|
/*===========*/
|
||||||
mutex_t* mutex);
|
mutex_t* mutex);
|
||||||
|
#endif /* UNIV_DEBUG */
|
||||||
|
#ifdef UNIV_SYNC_DEBUG
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
Adds a latch and its level in the thread level array. Allocates the memory
|
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
|
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,
|
allowed to be owned by the thread,
|
||||||
also purge_is_running mutex is
|
also purge_is_running mutex is
|
||||||
allowed */
|
allowed */
|
||||||
#ifdef UNIV_SYNC_DEBUG
|
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
Checks that the current thread owns the mutex. Works only
|
Checks that the current thread owns the mutex. Works only
|
||||||
in the debug version. */
|
in the debug version. */
|
||||||
|
|
@ -465,26 +481,29 @@ struct mutex_struct {
|
||||||
ulint line; /* Line 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
|
os_thread_id_t thread_id; /* Debug version: The thread id of the
|
||||||
thread which locked the mutex. */
|
thread which locked the mutex. */
|
||||||
#endif /* UNIV_SYNC_DEBUG */
|
|
||||||
ulint level; /* Level in the global latching order */
|
ulint level; /* Level in the global latching order */
|
||||||
|
#endif /* UNIV_SYNC_DEBUG */
|
||||||
const char* cfile_name;/* File name where mutex created */
|
const char* cfile_name;/* File name where mutex created */
|
||||||
ulint cline; /* Line where created */
|
ulint cline; /* Line where created */
|
||||||
ulint magic_n;
|
#ifdef UNIV_DEBUG
|
||||||
|
ulint magic_n;
|
||||||
|
# define MUTEX_MAGIC_N (ulint)979585
|
||||||
|
#endif /* UNIV_DEBUG */
|
||||||
#ifndef UNIV_HOTBACKUP
|
#ifndef UNIV_HOTBACKUP
|
||||||
ulong count_using; /* count of times mutex used */
|
ulong count_os_wait; /* count of os_wait */
|
||||||
ulong count_spin_loop; /* count of spin loops */
|
# ifdef UNIV_DEBUG
|
||||||
ulong count_spin_rounds; /* count of spin rounds */
|
ulong count_using; /* count of times mutex used */
|
||||||
ulong count_os_wait; /* count of os_wait */
|
ulong count_spin_loop; /* count of spin loops */
|
||||||
ulong count_os_yield; /* count of os_wait */
|
ulong count_spin_rounds; /* count of spin rounds */
|
||||||
ulonglong lspent_time; /* mutex os_wait timer msec */
|
ulong count_os_yield; /* count of os_wait */
|
||||||
ulonglong lmax_spent_time; /* mutex os_wait timer msec */
|
ulonglong lspent_time; /* mutex os_wait timer msec */
|
||||||
const char* cmutex_name;/* mutex name */
|
ulonglong lmax_spent_time; /* mutex os_wait timer msec */
|
||||||
ulint mutex_type;/* 0 - usual mutex 1 - rw_lock mutex */
|
const char* cmutex_name;/* mutex name */
|
||||||
|
ulint mutex_type;/* 0 - usual mutex 1 - rw_lock mutex */
|
||||||
|
# endif /* UNIV_DEBUG */
|
||||||
#endif /* !UNIV_HOTBACKUP */
|
#endif /* !UNIV_HOTBACKUP */
|
||||||
};
|
};
|
||||||
|
|
||||||
#define MUTEX_MAGIC_N (ulint)979585
|
|
||||||
|
|
||||||
/* The global array of wait cells for implementation of the databases own
|
/* The global array of wait cells for implementation of the databases own
|
||||||
mutexes and read-write locks. Appears here for debugging purposes only! */
|
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_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
|
/* The number of system calls made in this module. Intended for performance
|
||||||
monitoring. */
|
monitoring. */
|
||||||
|
|
||||||
extern ulint mutex_system_call_count;
|
extern ulint mutex_system_call_count;
|
||||||
extern ulint mutex_exit_count;
|
extern ulint mutex_exit_count;
|
||||||
|
|
||||||
|
#ifdef UNIV_SYNC_DEBUG
|
||||||
/* Latching order checks start when this is set TRUE */
|
/* Latching order checks start when this is set TRUE */
|
||||||
extern ibool sync_order_checks_on;
|
extern ibool sync_order_checks_on;
|
||||||
|
#endif /* UNIV_SYNC_DEBUG */
|
||||||
|
|
||||||
/* This variable is set to TRUE when sync_init is called */
|
/* This variable is set to TRUE when sync_init is called */
|
||||||
extern ibool sync_initialized;
|
extern ibool sync_initialized;
|
||||||
|
|
|
||||||
|
|
@ -254,9 +254,9 @@ mutex_enter_func(
|
||||||
/* Note that we do not peek at the value of lock_word before trying
|
/* 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. */
|
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++;
|
mutex->count_using++;
|
||||||
#endif /* UNIV_HOTBACKUP */
|
#endif /* UNIV_DEBUG && !UNIV_HOTBACKUP */
|
||||||
|
|
||||||
if (!mutex_test_and_set(mutex)) {
|
if (!mutex_test_and_set(mutex)) {
|
||||||
#ifdef UNIV_SYNC_DEBUG
|
#ifdef UNIV_SYNC_DEBUG
|
||||||
|
|
|
||||||
|
|
@ -83,19 +83,27 @@ memory is read outside the allocated blocks. */
|
||||||
/* Make a non-inline debug version */
|
/* Make a non-inline debug version */
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
#define UNIV_DEBUG
|
#define UNIV_DEBUG /* Enable ut_ad() assertions */
|
||||||
#define UNIV_MEM_DEBUG
|
#define UNIV_LIST_DEBUG /* debug UT_LIST_ macros */
|
||||||
#define UNIV_IBUF_DEBUG
|
#define UNIV_MEM_DEBUG /* detect memory leaks etc */
|
||||||
#define UNIV_SYNC_DEBUG
|
#define UNIV_IBUF_DEBUG /* debug the insert buffer;
|
||||||
#define UNIV_SEARCH_DEBUG
|
this limits the database to IBUF_COUNT_N_SPACES and IBUF_COUNT_N_PAGES,
|
||||||
#define UNIV_SYNC_PERF_STAT
|
and the insert buffer must be empty when the database is started */
|
||||||
#define UNIV_SEARCH_PERF_STAT
|
#define UNIV_SYNC_DEBUG /* debug mutex and latch
|
||||||
#define UNIV_SRV_PRINT_LATCH_WAITS
|
operations (very slow); also UNIV_DEBUG must be defined */
|
||||||
#define UNIV_BTR_PRINT
|
#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
|
#endif
|
||||||
|
|
||||||
#define UNIV_BTR_DEBUG
|
#define UNIV_BTR_DEBUG /* check B-tree links */
|
||||||
#define UNIV_LIGHT_MEM_DEBUG
|
#define UNIV_LIGHT_MEM_DEBUG /* light memory debugging */
|
||||||
|
|
||||||
#ifdef HAVE_purify
|
#ifdef HAVE_purify
|
||||||
/* The following sets all new allocated memory to zero before use:
|
/* The following sets all new allocated memory to zero before use:
|
||||||
|
|
|
||||||
|
|
@ -124,7 +124,7 @@ name, NODE1 and NODE2 are pointers to nodes. */
|
||||||
}\
|
}\
|
||||||
|
|
||||||
/* Invalidate the pointers in a list node. */
|
/* Invalidate the pointers in a list node. */
|
||||||
#ifdef UNIV_DEBUG
|
#ifdef UNIV_LIST_DEBUG
|
||||||
# define UT_LIST_REMOVE_CLEAR(NAME, N) \
|
# define UT_LIST_REMOVE_CLEAR(NAME, N) \
|
||||||
((N)->NAME.prev = (N)->NAME.next = (void*) -1)
|
((N)->NAME.prev = (N)->NAME.next = (void*) -1)
|
||||||
#else
|
#else
|
||||||
|
|
|
||||||
|
|
@ -4391,10 +4391,6 @@ loop:
|
||||||
trx->read_view->up_limit_id));
|
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) {
|
if (trx->que_state == TRX_QUE_LOCK_WAIT) {
|
||||||
fprintf(file,
|
fprintf(file,
|
||||||
"------- TRX HAS BEEN WAITING %lu SEC"
|
"------- TRX HAS BEEN WAITING %lu SEC"
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,7 @@ Created 9/20/1997 Heikki Tuuri
|
||||||
#include "btr0cur.h"
|
#include "btr0cur.h"
|
||||||
#include "dict0boot.h"
|
#include "dict0boot.h"
|
||||||
#include "fil0fil.h"
|
#include "fil0fil.h"
|
||||||
|
#include "sync0sync.h"
|
||||||
|
|
||||||
#ifdef UNIV_HOTBACKUP
|
#ifdef UNIV_HOTBACKUP
|
||||||
/* This is set to FALSE if the backup was originally taken with the
|
/* 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 = hash0_create(buf_pool_get_curr_size() / 256);
|
recv_sys->addr_hash = hash0_create(buf_pool_get_curr_size() / 256);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef UNIV_LOG_DEBUG
|
||||||
/************************************************************
|
/************************************************************
|
||||||
Frees the recovery system. */
|
Frees the recovery system. */
|
||||||
static
|
static
|
||||||
|
|
@ -209,6 +211,7 @@ recv_sys_free(void)
|
||||||
|
|
||||||
mutex_exit(&(recv_sys->mutex));
|
mutex_exit(&(recv_sys->mutex));
|
||||||
}
|
}
|
||||||
|
#endif /* UNIV_LOG_DEBUG */
|
||||||
|
|
||||||
/************************************************************
|
/************************************************************
|
||||||
Truncates possible corrupted or extra records from a log group. */
|
Truncates possible corrupted or extra records from a log group. */
|
||||||
|
|
@ -2855,6 +2858,15 @@ recv_recovery_from_checkpoint_finish(void)
|
||||||
#ifndef UNIV_LOG_DEBUG
|
#ifndef UNIV_LOG_DEBUG
|
||||||
recv_sys_free();
|
recv_sys_free();
|
||||||
#endif
|
#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) {
|
if (srv_force_recovery < SRV_FORCE_NO_TRX_UNDO) {
|
||||||
/* Rollback the uncommitted transactions which have no user
|
/* Rollback the uncommitted transactions which have no user
|
||||||
session */
|
session */
|
||||||
|
|
|
||||||
|
|
@ -1524,7 +1524,8 @@ row_ins_check_foreign_constraints(
|
||||||
if (foreign->foreign_index == index) {
|
if (foreign->foreign_index == index) {
|
||||||
|
|
||||||
if (foreign->referenced_table == NULL) {
|
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) {
|
if (0 == trx->dict_operation_lock_mode) {
|
||||||
|
|
|
||||||
|
|
@ -1831,7 +1831,9 @@ stop_for_a_while:
|
||||||
|
|
||||||
mtr_commit(&mtr);
|
mtr_commit(&mtr);
|
||||||
|
|
||||||
|
#ifdef UNIV_SYNC_DEBUG
|
||||||
ut_ad(sync_thread_levels_empty_gen(TRUE));
|
ut_ad(sync_thread_levels_empty_gen(TRUE));
|
||||||
|
#endif /* UNIV_SYNC_DEBUG */
|
||||||
err = DB_SUCCESS;
|
err = DB_SUCCESS;
|
||||||
goto func_exit;
|
goto func_exit;
|
||||||
|
|
||||||
|
|
@ -1850,7 +1852,9 @@ commit_mtr_for_a_while:
|
||||||
leaf_contains_updates = FALSE;
|
leaf_contains_updates = FALSE;
|
||||||
mtr_has_extra_clust_latch = FALSE;
|
mtr_has_extra_clust_latch = FALSE;
|
||||||
|
|
||||||
|
#ifdef UNIV_SYNC_DEBUG
|
||||||
ut_ad(sync_thread_levels_empty_gen(TRUE));
|
ut_ad(sync_thread_levels_empty_gen(TRUE));
|
||||||
|
#endif /* UNIV_SYNC_DEBUG */
|
||||||
|
|
||||||
goto table_loop;
|
goto table_loop;
|
||||||
|
|
||||||
|
|
@ -1866,7 +1870,9 @@ lock_wait_or_error:
|
||||||
|
|
||||||
mtr_commit(&mtr);
|
mtr_commit(&mtr);
|
||||||
|
|
||||||
|
#ifdef UNIV_SYNC_DEBUG
|
||||||
ut_ad(sync_thread_levels_empty_gen(TRUE));
|
ut_ad(sync_thread_levels_empty_gen(TRUE));
|
||||||
|
#endif /* UNIV_SYNC_DEBUG */
|
||||||
|
|
||||||
func_exit:
|
func_exit:
|
||||||
if (UNIV_LIKELY_NULL(heap)) {
|
if (UNIV_LIKELY_NULL(heap)) {
|
||||||
|
|
@ -4447,7 +4453,7 @@ row_search_check_if_query_cache_permitted(
|
||||||
dict_table_t* table;
|
dict_table_t* table;
|
||||||
ibool ret = FALSE;
|
ibool ret = FALSE;
|
||||||
|
|
||||||
table = dict_table_get(norm_name);
|
table = dict_table_get(norm_name, FALSE);
|
||||||
|
|
||||||
if (table == NULL) {
|
if (table == NULL) {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -202,7 +202,8 @@ row_upd_check_references_constraints(
|
||||||
foreign->n_fields))) {
|
foreign->n_fields))) {
|
||||||
|
|
||||||
if (foreign->foreign_table == NULL) {
|
if (foreign->foreign_table == NULL) {
|
||||||
dict_table_get(foreign->foreign_table_name);
|
dict_table_get(foreign->foreign_table_name,
|
||||||
|
FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (foreign->foreign_table) {
|
if (foreign->foreign_table) {
|
||||||
|
|
|
||||||
|
|
@ -1601,17 +1601,6 @@ innobase_start_or_create_for_mysql(void)
|
||||||
srv_was_started = TRUE;
|
srv_was_started = TRUE;
|
||||||
srv_is_being_started = FALSE;
|
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) {
|
if (trx_doublewrite == NULL) {
|
||||||
/* Create the doublewrite buffer to a new tablespace */
|
/* Create the doublewrite buffer to a new tablespace */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -89,11 +89,14 @@ void
|
||||||
rw_lock_create_func(
|
rw_lock_create_func(
|
||||||
/*================*/
|
/*================*/
|
||||||
rw_lock_t* lock, /* in: pointer to memory */
|
rw_lock_t* lock, /* in: pointer to memory */
|
||||||
ulint level __attribute__((unused)),
|
#ifdef UNIV_DEBUG
|
||||||
/* in: level */
|
# 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 */
|
const char* cfile_name, /* in: file name where created */
|
||||||
ulint cline, /* in: file line where created */
|
ulint cline) /* in: file line where created */
|
||||||
const char* cmutex_name) /* in: mutex name */
|
|
||||||
{
|
{
|
||||||
/* If this is the very first time a synchronization object is
|
/* If this is the very first time a synchronization object is
|
||||||
created, then the following call initializes the sync system. */
|
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.cfile_name = cfile_name;
|
||||||
lock->mutex.cline = cline;
|
lock->mutex.cline = cline;
|
||||||
|
|
||||||
#ifndef UNIV_HOTBACKUP
|
#if defined UNIV_DEBUG && !defined UNIV_HOTBACKUP
|
||||||
lock->mutex.cmutex_name = cmutex_name;
|
lock->mutex.cmutex_name = cmutex_name;
|
||||||
lock->mutex.mutex_type = 1;
|
lock->mutex.mutex_type = 1;
|
||||||
#endif /* !UNIV_HOTBACKUP */
|
#endif /* UNIV_DEBUG && !UNIV_HOTBACKUP */
|
||||||
|
|
||||||
rw_lock_set_waiters(lock, 0);
|
rw_lock_set_waiters(lock, 0);
|
||||||
rw_lock_set_writer(lock, RW_LOCK_NOT_LOCKED);
|
rw_lock_set_writer(lock, RW_LOCK_NOT_LOCKED);
|
||||||
|
|
|
||||||
|
|
@ -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.
|
sync_array_signal_object with the mutex as an argument.
|
||||||
Q.E.D. */
|
Q.E.D. */
|
||||||
|
|
||||||
ulint sync_dummy = 0;
|
|
||||||
|
|
||||||
/* The number of system calls made in this module. Intended for performance
|
/* The number of system calls made in this module. Intended for performance
|
||||||
monitoring. */
|
monitoring. */
|
||||||
|
|
||||||
|
|
@ -133,6 +131,7 @@ ibool sync_initialized = FALSE;
|
||||||
typedef struct sync_level_struct sync_level_t;
|
typedef struct sync_level_struct sync_level_t;
|
||||||
typedef struct sync_thread_struct sync_thread_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
|
/* The latch levels currently owned by threads are stored in this data
|
||||||
structure; the size of this array is OS_THREAD_MAX_N */
|
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 protecting sync_thread_level_arrays */
|
||||||
mutex_t sync_thread_mutex;
|
mutex_t sync_thread_mutex;
|
||||||
|
#endif /* UNIV_SYNC_DEBUG */
|
||||||
|
|
||||||
/* Global list of database mutexes (not OS mutexes) created. */
|
/* Global list of database mutexes (not OS mutexes) created. */
|
||||||
ut_list_base_node_t mutex_list;
|
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 protecting the mutex_list variable */
|
||||||
mutex_t mutex_list_mutex;
|
mutex_t mutex_list_mutex;
|
||||||
|
|
||||||
|
#ifdef UNIV_SYNC_DEBUG
|
||||||
/* Latching order checks start when this is set TRUE */
|
/* Latching order checks start when this is set TRUE */
|
||||||
ibool sync_order_checks_on = FALSE;
|
ibool sync_order_checks_on = FALSE;
|
||||||
|
#endif /* UNIV_SYNC_DEBUG */
|
||||||
/* Dummy mutex used to implement mutex_fence */
|
|
||||||
mutex_t dummy_mutex_for_fence;
|
|
||||||
|
|
||||||
struct sync_thread_struct{
|
struct sync_thread_struct{
|
||||||
os_thread_id_t id; /* OS thread id */
|
os_thread_id_t id; /* OS thread id */
|
||||||
|
|
@ -202,10 +201,14 @@ void
|
||||||
mutex_create_func(
|
mutex_create_func(
|
||||||
/*==============*/
|
/*==============*/
|
||||||
mutex_t* mutex, /* in: pointer to memory */
|
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 */
|
ulint level, /* in: level */
|
||||||
|
# endif /* UNIV_SYNC_DEBUG */
|
||||||
|
#endif /* UNIV_DEBUG */
|
||||||
const char* cfile_name, /* in: file name where created */
|
const char* cfile_name, /* in: file name where created */
|
||||||
ulint cline, /* in: file line where created */
|
ulint cline) /* in: file line where created */
|
||||||
const char* cmutex_name) /* in: mutex name */
|
|
||||||
{
|
{
|
||||||
#if defined(_WIN32) && defined(UNIV_CAN_USE_X86_ASSEMBLER)
|
#if defined(_WIN32) && defined(UNIV_CAN_USE_X86_ASSEMBLER)
|
||||||
mutex_reset_lock_word(mutex);
|
mutex_reset_lock_word(mutex);
|
||||||
|
|
@ -214,15 +217,19 @@ mutex_create_func(
|
||||||
mutex->lock_word = 0;
|
mutex->lock_word = 0;
|
||||||
#endif
|
#endif
|
||||||
mutex_set_waiters(mutex, 0);
|
mutex_set_waiters(mutex, 0);
|
||||||
|
#ifdef UNIV_DEBUG
|
||||||
mutex->magic_n = MUTEX_MAGIC_N;
|
mutex->magic_n = MUTEX_MAGIC_N;
|
||||||
|
#endif /* UNIV_DEBUG */
|
||||||
#ifdef UNIV_SYNC_DEBUG
|
#ifdef UNIV_SYNC_DEBUG
|
||||||
mutex->line = 0;
|
mutex->line = 0;
|
||||||
mutex->file_name = "not yet reserved";
|
mutex->file_name = "not yet reserved";
|
||||||
#endif /* UNIV_SYNC_DEBUG */
|
|
||||||
mutex->level = level;
|
mutex->level = level;
|
||||||
|
#endif /* UNIV_SYNC_DEBUG */
|
||||||
mutex->cfile_name = cfile_name;
|
mutex->cfile_name = cfile_name;
|
||||||
mutex->cline = cline;
|
mutex->cline = cline;
|
||||||
#ifndef UNIV_HOTBACKUP
|
#ifndef UNIV_HOTBACKUP
|
||||||
|
mutex->count_os_wait = 0;
|
||||||
|
# ifdef UNIV_DEBUG
|
||||||
mutex->cmutex_name= cmutex_name;
|
mutex->cmutex_name= cmutex_name;
|
||||||
mutex->count_using= 0;
|
mutex->count_using= 0;
|
||||||
mutex->mutex_type= 0;
|
mutex->mutex_type= 0;
|
||||||
|
|
@ -230,8 +237,8 @@ mutex_create_func(
|
||||||
mutex->lmax_spent_time= 0;
|
mutex->lmax_spent_time= 0;
|
||||||
mutex->count_spin_loop= 0;
|
mutex->count_spin_loop= 0;
|
||||||
mutex->count_spin_rounds= 0;
|
mutex->count_spin_rounds= 0;
|
||||||
mutex->count_os_wait= 0;
|
|
||||||
mutex->count_os_yield= 0;
|
mutex->count_os_yield= 0;
|
||||||
|
# endif /* UNIV_DEBUG */
|
||||||
#endif /* !UNIV_HOTBACKUP */
|
#endif /* !UNIV_HOTBACKUP */
|
||||||
|
|
||||||
/* Check that lock_word is aligned; this is important on Intel */
|
/* 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 */
|
/* 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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_enter(&mutex_list_mutex);
|
mutex_enter(&mutex_list_mutex);
|
||||||
|
|
||||||
if (UT_LIST_GET_LEN(mutex_list) > 0) {
|
ut_ad(UT_LIST_GET_LEN(mutex_list) == 0
|
||||||
ut_a(UT_LIST_GET_FIRST(mutex_list)->magic_n == MUTEX_MAGIC_N);
|
|| UT_LIST_GET_FIRST(mutex_list)->magic_n == MUTEX_MAGIC_N);
|
||||||
}
|
|
||||||
|
|
||||||
UT_LIST_ADD_FIRST(list, mutex_list, mutex);
|
UT_LIST_ADD_FIRST(list, mutex_list, mutex);
|
||||||
|
|
||||||
|
|
@ -265,24 +275,24 @@ mutex_free(
|
||||||
/*=======*/
|
/*=======*/
|
||||||
mutex_t* mutex) /* in: mutex */
|
mutex_t* mutex) /* in: mutex */
|
||||||
{
|
{
|
||||||
#ifdef UNIV_DEBUG
|
ut_ad(mutex_validate(mutex));
|
||||||
ut_a(mutex_validate(mutex));
|
|
||||||
#endif /* UNIV_DEBUG */
|
|
||||||
ut_a(mutex_get_lock_word(mutex) == 0);
|
ut_a(mutex_get_lock_word(mutex) == 0);
|
||||||
ut_a(mutex_get_waiters(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);
|
mutex_enter(&mutex_list_mutex);
|
||||||
|
|
||||||
if (UT_LIST_GET_PREV(list, mutex)) {
|
ut_ad(!UT_LIST_GET_PREV(list, mutex)
|
||||||
ut_a(UT_LIST_GET_PREV(list, mutex)->magic_n
|
|| UT_LIST_GET_PREV(list, mutex)->magic_n
|
||||||
== MUTEX_MAGIC_N);
|
== MUTEX_MAGIC_N);
|
||||||
}
|
ut_ad(!UT_LIST_GET_NEXT(list, mutex)
|
||||||
if (UT_LIST_GET_NEXT(list, mutex)) {
|
|| UT_LIST_GET_NEXT(list, mutex)->magic_n
|
||||||
ut_a(UT_LIST_GET_NEXT(list, mutex)->magic_n
|
== MUTEX_MAGIC_N);
|
||||||
== MUTEX_MAGIC_N);
|
|
||||||
}
|
|
||||||
|
|
||||||
UT_LIST_REMOVE(list, mutex_list, mutex);
|
UT_LIST_REMOVE(list, mutex_list, mutex);
|
||||||
|
|
||||||
|
|
@ -295,8 +305,9 @@ mutex_free(
|
||||||
/* If we free the mutex protecting the mutex list (freeing is
|
/* If we free the mutex protecting the mutex list (freeing is
|
||||||
not necessary), we have to reset the magic number AFTER removing
|
not necessary), we have to reset the magic number AFTER removing
|
||||||
it from the list. */
|
it from the list. */
|
||||||
|
#ifdef UNIV_DEBUG
|
||||||
mutex->magic_n = 0;
|
mutex->magic_n = 0;
|
||||||
|
#endif /* UNIV_DEBUG */
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
|
|
@ -328,6 +339,7 @@ mutex_enter_nowait(
|
||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef UNIV_DEBUG
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
Checks that the mutex has been initialized. */
|
Checks that the mutex has been initialized. */
|
||||||
|
|
||||||
|
|
@ -341,6 +353,7 @@ mutex_validate(
|
||||||
|
|
||||||
return(TRUE);
|
return(TRUE);
|
||||||
}
|
}
|
||||||
|
#endif /* UNIV_DEBUG */
|
||||||
|
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
Sets the waiters field in a mutex. */
|
Sets the waiters field in a mutex. */
|
||||||
|
|
@ -376,13 +389,13 @@ mutex_spin_wait(
|
||||||
{
|
{
|
||||||
ulint index; /* index of the reserved wait cell */
|
ulint index; /* index of the reserved wait cell */
|
||||||
ulint i; /* spin round count */
|
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 */
|
ib_longlong lstart_time = 0, lfinish_time; /* for timing os_wait */
|
||||||
ulint ltime_diff;
|
ulint ltime_diff;
|
||||||
ulint sec;
|
ulint sec;
|
||||||
ulint ms;
|
ulint ms;
|
||||||
uint timer_started = 0;
|
uint timer_started = 0;
|
||||||
#endif /* !UNIV_HOTBACKUP */
|
#endif /* UNIV_DEBUG && !UNIV_HOTBACKUP */
|
||||||
ut_ad(mutex);
|
ut_ad(mutex);
|
||||||
|
|
||||||
mutex_loop:
|
mutex_loop:
|
||||||
|
|
@ -396,10 +409,10 @@ mutex_loop:
|
||||||
a memory word. */
|
a memory word. */
|
||||||
|
|
||||||
spin_loop:
|
spin_loop:
|
||||||
#ifndef UNIV_HOTBACKUP
|
#if defined UNIV_DEBUG && !defined UNIV_HOTBACKUP
|
||||||
mutex_spin_wait_count++;
|
mutex_spin_wait_count++;
|
||||||
mutex->count_spin_loop++;
|
mutex->count_spin_loop++;
|
||||||
#endif /* !UNIV_HOTBACKUP */
|
#endif /* UNIV_DEBUG && !UNIV_HOTBACKUP */
|
||||||
|
|
||||||
while (mutex_get_lock_word(mutex) != 0 && i < SYNC_SPIN_ROUNDS) {
|
while (mutex_get_lock_word(mutex) != 0 && i < SYNC_SPIN_ROUNDS) {
|
||||||
if (srv_spin_wait_delay) {
|
if (srv_spin_wait_delay) {
|
||||||
|
|
@ -410,14 +423,14 @@ spin_loop:
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i == SYNC_SPIN_ROUNDS) {
|
if (i == SYNC_SPIN_ROUNDS) {
|
||||||
#ifndef UNIV_HOTBACKUP
|
#if defined UNIV_DEBUG && !defined UNIV_HOTBACKUP
|
||||||
mutex->count_os_yield++;
|
mutex->count_os_yield++;
|
||||||
if (timed_mutexes == 1 && timer_started==0) {
|
if (timed_mutexes == 1 && timer_started==0) {
|
||||||
ut_usectime(&sec, &ms);
|
ut_usectime(&sec, &ms);
|
||||||
lstart_time= (ib_longlong)sec * 1000000 + ms;
|
lstart_time= (ib_longlong)sec * 1000000 + ms;
|
||||||
timer_started = 1;
|
timer_started = 1;
|
||||||
}
|
}
|
||||||
#endif /* !UNIV_HOTBACKUP */
|
#endif /* UNIV_DEBUG && !UNIV_HOTBACKUP */
|
||||||
os_thread_yield();
|
os_thread_yield();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -431,9 +444,9 @@ spin_loop:
|
||||||
|
|
||||||
mutex_spin_round_count += i;
|
mutex_spin_round_count += i;
|
||||||
|
|
||||||
#ifndef UNIV_HOTBACKUP
|
#if defined UNIV_DEBUG && !defined UNIV_HOTBACKUP
|
||||||
mutex->count_spin_rounds += i;
|
mutex->count_spin_rounds += i;
|
||||||
#endif /* !UNIV_HOTBACKUP */
|
#endif /* UNIV_DEBUG && !UNIV_HOTBACKUP */
|
||||||
|
|
||||||
if (mutex_test_and_set(mutex) == 0) {
|
if (mutex_test_and_set(mutex) == 0) {
|
||||||
/* Succeeded! */
|
/* Succeeded! */
|
||||||
|
|
@ -514,6 +527,7 @@ spin_loop:
|
||||||
|
|
||||||
#ifndef UNIV_HOTBACKUP
|
#ifndef UNIV_HOTBACKUP
|
||||||
mutex->count_os_wait++;
|
mutex->count_os_wait++;
|
||||||
|
# ifdef UNIV_DEBUG
|
||||||
/* !!!!! Sometimes os_wait can be called without os_thread_yield */
|
/* !!!!! Sometimes os_wait can be called without os_thread_yield */
|
||||||
|
|
||||||
if (timed_mutexes == 1 && timer_started==0) {
|
if (timed_mutexes == 1 && timer_started==0) {
|
||||||
|
|
@ -521,13 +535,14 @@ spin_loop:
|
||||||
lstart_time= (ib_longlong)sec * 1000000 + ms;
|
lstart_time= (ib_longlong)sec * 1000000 + ms;
|
||||||
timer_started = 1;
|
timer_started = 1;
|
||||||
}
|
}
|
||||||
|
# endif /* UNIV_DEBUG */
|
||||||
#endif /* !UNIV_HOTBACKUP */
|
#endif /* !UNIV_HOTBACKUP */
|
||||||
|
|
||||||
sync_array_wait_event(sync_primary_wait_array, index);
|
sync_array_wait_event(sync_primary_wait_array, index);
|
||||||
goto mutex_loop;
|
goto mutex_loop;
|
||||||
|
|
||||||
finish_timing:
|
finish_timing:
|
||||||
#ifndef UNIV_HOTBACKUP
|
#if defined UNIV_DEBUG && !defined UNIV_HOTBACKUP
|
||||||
if (timed_mutexes == 1 && timer_started==1) {
|
if (timed_mutexes == 1 && timer_started==1) {
|
||||||
ut_usectime(&sec, &ms);
|
ut_usectime(&sec, &ms);
|
||||||
lfinish_time= (ib_longlong)sec * 1000000 + ms;
|
lfinish_time= (ib_longlong)sec * 1000000 + ms;
|
||||||
|
|
@ -539,7 +554,7 @@ finish_timing:
|
||||||
mutex->lmax_spent_time= ltime_diff;
|
mutex->lmax_spent_time= ltime_diff;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* !UNIV_HOTBACKUP */
|
#endif /* UNIV_DEBUG && !UNIV_HOTBACKUP */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -598,9 +613,7 @@ mutex_get_debug_info(
|
||||||
*line = mutex->line;
|
*line = mutex->line;
|
||||||
*thread_id = mutex->thread_id;
|
*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
|
Checks that the current thread owns the mutex. Works only in the debug
|
||||||
version. */
|
version. */
|
||||||
|
|
@ -611,7 +624,7 @@ mutex_own(
|
||||||
/* out: TRUE if owns */
|
/* out: TRUE if owns */
|
||||||
mutex_t* mutex) /* in: mutex */
|
mutex_t* mutex) /* in: mutex */
|
||||||
{
|
{
|
||||||
ut_a(mutex_validate(mutex));
|
ut_ad(mutex_validate(mutex));
|
||||||
|
|
||||||
if (mutex_get_lock_word(mutex) != 1) {
|
if (mutex_get_lock_word(mutex) != 1) {
|
||||||
|
|
||||||
|
|
@ -710,7 +723,6 @@ sync_all_freed(void)
|
||||||
{
|
{
|
||||||
return(mutex_n_reserved() + rw_lock_n_locked() == 0);
|
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. */
|
Gets the value in the nth slot in the thread level arrays. */
|
||||||
|
|
@ -834,7 +846,6 @@ sync_thread_levels_g(
|
||||||
(ulong) mutex->cline);
|
(ulong) mutex->cline);
|
||||||
|
|
||||||
if (mutex_get_lock_word(mutex) != 0) {
|
if (mutex_get_lock_word(mutex) != 0) {
|
||||||
#ifdef UNIV_SYNC_DEBUG
|
|
||||||
const char* file_name;
|
const char* file_name;
|
||||||
ulint line;
|
ulint line;
|
||||||
os_thread_id_t thread_id;
|
os_thread_id_t thread_id;
|
||||||
|
|
@ -852,19 +863,11 @@ sync_thread_levels_g(
|
||||||
thread_id),
|
thread_id),
|
||||||
file_name,
|
file_name,
|
||||||
(ulong) line);
|
(ulong) line);
|
||||||
#else /* UNIV_SYNC_DEBUG */
|
|
||||||
fprintf(stderr,
|
|
||||||
"InnoDB: Locked mutex:"
|
|
||||||
" addr %p\n",
|
|
||||||
(void*) mutex);
|
|
||||||
#endif /* UNIV_SYNC_DEBUG */
|
|
||||||
} else {
|
} else {
|
||||||
fputs("Not locked\n", stderr);
|
fputs("Not locked\n", stderr);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
#ifdef UNIV_SYNC_DEBUG
|
|
||||||
rw_lock_print(lock);
|
rw_lock_print(lock);
|
||||||
#endif /* UNIV_SYNC_DEBUG */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return(FALSE);
|
return(FALSE);
|
||||||
|
|
@ -996,9 +999,7 @@ sync_thread_add_level(
|
||||||
|
|
||||||
if ((latch == (void*)&sync_thread_mutex)
|
if ((latch == (void*)&sync_thread_mutex)
|
||||||
|| (latch == (void*)&mutex_list_mutex)
|
|| (latch == (void*)&mutex_list_mutex)
|
||||||
#ifdef UNIV_SYNC_DEBUG
|
|
||||||
|| (latch == (void*)&rw_lock_debug_mutex)
|
|| (latch == (void*)&rw_lock_debug_mutex)
|
||||||
#endif /* UNIV_SYNC_DEBUG */
|
|
||||||
|| (latch == (void*)&rw_lock_list_mutex)) {
|
|| (latch == (void*)&rw_lock_list_mutex)) {
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
@ -1219,9 +1220,7 @@ sync_thread_reset_level(
|
||||||
|
|
||||||
if ((latch == (void*)&sync_thread_mutex)
|
if ((latch == (void*)&sync_thread_mutex)
|
||||||
|| (latch == (void*)&mutex_list_mutex)
|
|| (latch == (void*)&mutex_list_mutex)
|
||||||
#ifdef UNIV_SYNC_DEBUG
|
|
||||||
|| (latch == (void*)&rw_lock_debug_mutex)
|
|| (latch == (void*)&rw_lock_debug_mutex)
|
||||||
#endif /* UNIV_SYNC_DEBUG */
|
|
||||||
|| (latch == (void*)&rw_lock_list_mutex)) {
|
|| (latch == (void*)&rw_lock_list_mutex)) {
|
||||||
|
|
||||||
return(FALSE);
|
return(FALSE);
|
||||||
|
|
@ -1260,6 +1259,7 @@ sync_thread_reset_level(
|
||||||
|
|
||||||
return(FALSE);
|
return(FALSE);
|
||||||
}
|
}
|
||||||
|
#endif /* UNIV_SYNC_DEBUG */
|
||||||
|
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
Initializes the synchronization data structures. */
|
Initializes the synchronization data structures. */
|
||||||
|
|
@ -1268,8 +1268,10 @@ void
|
||||||
sync_init(void)
|
sync_init(void)
|
||||||
/*===========*/
|
/*===========*/
|
||||||
{
|
{
|
||||||
|
#ifdef UNIV_SYNC_DEBUG
|
||||||
sync_thread_t* thread_slot;
|
sync_thread_t* thread_slot;
|
||||||
ulint i;
|
ulint i;
|
||||||
|
#endif /* UNIV_SYNC_DEBUG */
|
||||||
|
|
||||||
ut_a(sync_initialized == FALSE);
|
ut_a(sync_initialized == FALSE);
|
||||||
|
|
||||||
|
|
@ -1280,7 +1282,7 @@ sync_init(void)
|
||||||
|
|
||||||
sync_primary_wait_array = sync_array_create(OS_THREAD_MAX_N,
|
sync_primary_wait_array = sync_array_create(OS_THREAD_MAX_N,
|
||||||
SYNC_ARRAY_OS_MUTEX);
|
SYNC_ARRAY_OS_MUTEX);
|
||||||
|
#ifdef UNIV_SYNC_DEBUG
|
||||||
/* Create the thread latch level array where the latch levels
|
/* Create the thread latch level array where the latch levels
|
||||||
are stored for each OS thread */
|
are stored for each OS thread */
|
||||||
|
|
||||||
|
|
@ -1291,13 +1293,14 @@ sync_init(void)
|
||||||
thread_slot = sync_thread_level_arrays_get_nth(i);
|
thread_slot = sync_thread_level_arrays_get_nth(i);
|
||||||
thread_slot->levels = NULL;
|
thread_slot->levels = NULL;
|
||||||
}
|
}
|
||||||
|
#endif /* UNIV_SYNC_DEBUG */
|
||||||
/* Init the mutex list and create the mutex to protect it. */
|
/* Init the mutex list and create the mutex to protect it. */
|
||||||
|
|
||||||
UT_LIST_INIT(mutex_list);
|
UT_LIST_INIT(mutex_list);
|
||||||
mutex_create(&mutex_list_mutex, SYNC_NO_ORDER_CHECK);
|
mutex_create(&mutex_list_mutex, SYNC_NO_ORDER_CHECK);
|
||||||
|
#ifdef UNIV_SYNC_DEBUG
|
||||||
mutex_create(&sync_thread_mutex, SYNC_NO_ORDER_CHECK);
|
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. */
|
/* Init the rw-lock list and create the mutex to protect it. */
|
||||||
|
|
||||||
|
|
@ -1332,7 +1335,9 @@ sync_close(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_free(&mutex_list_mutex);
|
mutex_free(&mutex_list_mutex);
|
||||||
|
#ifdef UNIV_SYNC_DEBUG
|
||||||
mutex_free(&sync_thread_mutex);
|
mutex_free(&sync_thread_mutex);
|
||||||
|
#endif /* UNIV_SYNC_DEBUG */
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
|
|
|
||||||
|
|
@ -131,8 +131,26 @@ trx_rollback_for_mysql(
|
||||||
|
|
||||||
trx->op_info = "rollback";
|
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 = "";
|
trx->op_info = "";
|
||||||
|
|
||||||
return(err);
|
return(err);
|
||||||
|
|
|
||||||
|
|
@ -1598,6 +1598,24 @@ trx_commit_for_mysql(
|
||||||
|
|
||||||
trx->op_info = "committing";
|
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);
|
trx_start_if_not_started(trx);
|
||||||
|
|
||||||
mutex_enter(&kernel_mutex);
|
mutex_enter(&kernel_mutex);
|
||||||
|
|
@ -1761,11 +1779,10 @@ trx_print(
|
||||||
|| mem_heap_get_size(trx->lock_heap) > 400) {
|
|| mem_heap_get_size(trx->lock_heap) > 400) {
|
||||||
newline = TRUE;
|
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) UT_LIST_GET_LEN(trx->trx_locks),
|
||||||
(ulong) mem_heap_get_size(trx->lock_heap));
|
(ulong) mem_heap_get_size(trx->lock_heap),
|
||||||
|
|
||||||
fprintf(f, "%lu row lock(s)",
|
|
||||||
(ulong) lock_number_of_rows_locked(trx));
|
(ulong) lock_number_of_rows_locked(trx));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue