manual merge

client/mysql.cc:
  Auto merged
client/mysqlbinlog.cc:
  Auto merged
include/my_global.h:
  Auto merged
innobase/include/row0mysql.h:
  Auto merged
mysql-test/r/ps_1general.result:
  Auto merged
mysql-test/r/subselect.result:
  Auto merged
mysql-test/r/system_mysql_db.result:
  Auto merged
mysql-test/t/subselect.test:
  Auto merged
sql/ha_innodb.cc:
  Auto merged
sql/ha_myisam.cc:
  Auto merged
sql/handler.cc:
  Auto merged
sql/item_subselect.h:
  Auto merged
sql/sql_load.cc:
  Auto merged
sql/sql_table.cc:
  Auto merged
This commit is contained in:
unknown 2004-07-20 15:34:57 +02:00
commit e2d25910f8
48 changed files with 416 additions and 186 deletions

View file

@ -2717,8 +2717,11 @@ btr_estimate_number_of_different_key_vals(
rec = page_rec_get_next(rec);
}
if (n_cols == dict_index_get_n_unique_in_tree(index)) {
/* We add one because we know that the first record
/* If there is more than one leaf page in the tree,
we add one because we know that the first record
on the page certainly had a different prefix than the
last record on the previous index page in the
alphabetical order. Before this fix, if there was
@ -2726,7 +2729,11 @@ btr_estimate_number_of_different_key_vals(
algorithm grossly underestimated the number of rows
in the table. */
n_diff[n_cols]++;
if (btr_page_get_prev(page, &mtr) != FIL_NULL
|| btr_page_get_next(page, &mtr) != FIL_NULL) {
n_diff[n_cols]++;
}
}
total_external_size +=

View file

@ -418,7 +418,8 @@ lock_release_off_kernel(
/*====================*/
trx_t* trx); /* in: transaction */
/*************************************************************************
Releases table locks, and releases possible other transactions waiting
Releases table locks explicitly requested with LOCK TABLES (indicated by
lock type LOCK_TABLE_EXP), and releases possible other transactions waiting
because of these locks. */
void
@ -548,7 +549,7 @@ extern lock_sys_t* lock_sys;
/* Lock types */
#define LOCK_TABLE 16 /* these type values should be so high that */
#define LOCK_REC 32 /* they can be ORed to the lock mode */
#define LOCK_TABLE_EXP 80 /* explicit table lock */
#define LOCK_TABLE_EXP 80 /* explicit table lock (80 = 16 + 64) */
#define LOCK_TYPE_MASK 0xF0UL /* mask used to extract lock type from the
type_mode field in a lock */
/* Waiting lock flag */

View file

@ -161,11 +161,12 @@ row_lock_table_autoinc_for_mysql(
row_prebuilt_t* prebuilt); /* in: prebuilt struct in the MySQL
table handle */
/*************************************************************************
Unlocks a table lock possibly reserved by trx. */
Unlocks all table locks explicitly requested by trx (with LOCK TABLES,
lock type LOCK_TABLE_EXP). */
void
row_unlock_table_for_mysql(
/*=======================*/
row_unlock_tables_for_mysql(
/*========================*/
trx_t* trx); /* in: transaction */
/*************************************************************************
Sets a table lock on the table mentioned in prebuilt. */

View file

@ -157,6 +157,7 @@ extern ulint srv_test_n_mutexes;
extern ulint srv_test_array_size;
extern ulint srv_activity_count;
extern ulint srv_fatal_semaphore_wait_threshold;
extern mutex_t* kernel_mutex_temp;/* mutex protecting the server, trx structs,
query threads, and lock table: we allocate

View file

@ -95,7 +95,7 @@ void
sync_arr_wake_threads_if_sema_free(void);
/*====================================*/
/**************************************************************************
Prints warnings of long semaphore waits to stderr. Currently > 120 sec. */
Prints warnings of long semaphore waits to stderr. */
void
sync_array_print_long_waits(void);

View file

@ -423,8 +423,9 @@ struct trx_struct{
lock_t* auto_inc_lock; /* possible auto-inc lock reserved by
the transaction; note that it is also
in the lock list trx_locks */
ulint n_tables_locked;/* number of table locks reserved by
the transaction, stored in trx_locks */
ulint n_lock_table_exp;/* number of explicit table locks
(LOCK TABLES) reserved by the
transaction, stored in trx_locks */
UT_LIST_NODE_T(trx_t)
trx_list; /* list of transactions */
UT_LIST_NODE_T(trx_t)

View file

@ -2023,9 +2023,8 @@ lock_grant(
lock->trx->auto_inc_lock = lock;
} else if (lock_get_type(lock) == LOCK_TABLE_EXP) {
ut_ad(lock_get_mode(lock) == LOCK_S
ut_a(lock_get_mode(lock) == LOCK_S
|| lock_get_mode(lock) == LOCK_X);
lock->trx->n_tables_locked++;
}
if (lock_print_waits) {
@ -3203,6 +3202,10 @@ lock_table_create(
lock->type_mode = type_mode | LOCK_TABLE;
lock->trx = trx;
if (lock_get_type(lock) == LOCK_TABLE_EXP) {
lock->trx->n_lock_table_exp++;
}
lock->un_member.tab_lock.table = table;
UT_LIST_ADD_LAST(un_member.tab_lock.locks, table->locks, lock);
@ -3238,7 +3241,11 @@ lock_table_remove_low(
if (lock == trx->auto_inc_lock) {
trx->auto_inc_lock = NULL;
}
if (lock_get_type(lock) == LOCK_TABLE_EXP) {
lock->trx->n_lock_table_exp--;
}
UT_LIST_REMOVE(trx_locks, trx->trx_locks, lock);
UT_LIST_REMOVE(un_member.tab_lock.locks, table->locks, lock);
}
@ -3386,7 +3393,7 @@ lock_table(
return(DB_SUCCESS);
}
ut_ad(flags == 0 || flags == LOCK_TABLE_EXP);
ut_a(flags == 0 || flags == LOCK_TABLE_EXP);
trx = thr_get_trx(thr);
@ -3418,10 +3425,7 @@ lock_table(
lock_table_create(table, mode | flags, trx);
if (flags) {
ut_ad(mode == LOCK_S || mode == LOCK_X);
trx->n_tables_locked++;
}
ut_a(!flags || mode == LOCK_S || mode == LOCK_X);
lock_mutex_exit_kernel();
@ -3502,13 +3506,13 @@ lock_table_dequeue(
#ifdef UNIV_SYNC_DEBUG
ut_ad(mutex_own(&kernel_mutex));
#endif /* UNIV_SYNC_DEBUG */
ut_ad(lock_get_type(in_lock) == LOCK_TABLE ||
ut_a(lock_get_type(in_lock) == LOCK_TABLE ||
lock_get_type(in_lock) == LOCK_TABLE_EXP);
lock = UT_LIST_GET_NEXT(un_member.tab_lock.locks, in_lock);
lock_table_remove_low(in_lock);
/* Check if waiting locks in the queue can now be granted: grant
locks if there are no conflicting locks ahead. */
@ -3608,9 +3612,8 @@ lock_release_off_kernel(
lock_table_dequeue(lock);
if (lock_get_type(lock) == LOCK_TABLE_EXP) {
ut_ad(lock_get_mode(lock) == LOCK_S
ut_a(lock_get_mode(lock) == LOCK_S
|| lock_get_mode(lock) == LOCK_X);
trx->n_tables_locked--;
}
}
@ -3631,11 +3634,12 @@ lock_release_off_kernel(
mem_heap_empty(trx->lock_heap);
ut_a(trx->auto_inc_lock == NULL);
ut_a(trx->n_tables_locked == 0);
ut_a(trx->n_lock_table_exp == 0);
}
/*************************************************************************
Releases table locks, and releases possible other transactions waiting
Releases table locks explicitly requested with LOCK TABLES (indicated by
lock type LOCK_TABLE_EXP), and releases possible other transactions waiting
because of these locks. */
void
@ -3660,7 +3664,7 @@ lock_release_tables_off_kernel(
count++;
if (lock_get_type(lock) == LOCK_TABLE_EXP) {
ut_ad(lock_get_mode(lock) == LOCK_S
ut_a(lock_get_mode(lock) == LOCK_S
|| lock_get_mode(lock) == LOCK_X);
if (trx->insert_undo || trx->update_undo) {
@ -3676,7 +3680,7 @@ lock_release_tables_off_kernel(
}
lock_table_dequeue(lock);
trx->n_tables_locked--;
lock = UT_LIST_GET_LAST(trx->trx_locks);
continue;
}
@ -3695,9 +3699,7 @@ lock_release_tables_off_kernel(
lock = UT_LIST_GET_PREV(trx_locks, lock);
}
mem_heap_empty(trx->lock_heap);
ut_a(trx->n_tables_locked == 0);
ut_a(trx->n_lock_table_exp == 0);
}
/*************************************************************************

View file

@ -370,6 +370,32 @@ row_ins_cascade_ancestor_updates_table(
return(FALSE);
}
/*************************************************************************
Returns the number of ancestor UPDATE or DELETE nodes of a
cascaded update/delete node. */
static
ulint
row_ins_cascade_n_ancestors(
/*========================*/
/* out: number of ancestors */
que_node_t* node) /* in: node in a query graph */
{
que_node_t* parent;
ulint n_ancestors = 0;
parent = que_node_get_parent(node);
while (que_node_get_type(parent) == QUE_NODE_UPDATE) {
n_ancestors++;
parent = que_node_get_parent(parent);
ut_a(parent);
}
return(n_ancestors);
}
/**********************************************************************
Calculates the update vector node->cascade->update for a child table in
a cascaded update. */
@ -615,6 +641,34 @@ row_ins_foreign_report_add_err(
mutex_exit(&dict_foreign_err_mutex);
}
/*************************************************************************
Invalidate the query cache for the given table. */
static
void
row_ins_invalidate_query_cache(
/*===========================*/
que_thr_t* thr, /* in: query thread whose run_node
is an update node */
const char* name) /* in: table name prefixed with
database name and a '/' character */
{
char* buf;
char* ptr;
ulint len = strlen(name) + 1;
buf = mem_strdupl(name, len);
ptr = strchr(buf, '/');
ut_a(ptr);
*ptr = '\0';
/* We call a function in ha_innodb.cc */
#ifndef UNIV_HOTBACKUP
innobase_invalidate_query_cache(thr_get_trx(thr), buf, len);
#endif
mem_free(buf);
}
/*************************************************************************
Perform referential actions or checks when a parent row is deleted or updated
and the constraint had an ON DELETE or ON UPDATE condition which was not
@ -650,26 +704,15 @@ row_ins_foreign_check_on_constraint(
ulint n_to_update;
ulint err;
ulint i;
char* ptr;
char* table_name_buf;
ut_a(thr && foreign && pcur && mtr);
/* Since we are going to delete or update a row, we have to invalidate
the MySQL query cache for table */
table_name_buf = mem_strdup(table->name);
ptr = strchr(table_name_buf, '/');
ut_a(ptr);
*ptr = '\0';
#ifndef UNIV_HOTBACKUP
/* We call a function in ha_innodb.cc */
innobase_invalidate_query_cache(thr_get_trx(thr), table_name_buf,
strlen(table->name) + 1);
#endif
mem_free(table_name_buf);
row_ins_invalidate_query_cache(thr, table->name);
node = thr->run_node;
@ -757,6 +800,16 @@ row_ins_foreign_check_on_constraint(
goto nonstandard_exit_func;
}
if (row_ins_cascade_n_ancestors(cascade) >= 15) {
err = DB_ROW_IS_REFERENCED;
row_ins_foreign_report_err(
(char*)"Trying a too deep cascaded delete or update\n",
thr, foreign, btr_pcur_get_rec(pcur), entry);
goto nonstandard_exit_func;
}
index = btr_pcur_get_btr_cur(pcur)->index;
ut_a(index == foreign->foreign_index);

View file

@ -741,14 +741,15 @@ run_again:
}
/*************************************************************************
Unlocks a table lock possibly reserved by trx. */
Unlocks all table locks explicitly requested by trx (with LOCK TABLES,
lock type LOCK_TABLE_EXP). */
void
row_unlock_table_for_mysql(
/*=======================*/
row_unlock_tables_for_mysql(
/*========================*/
trx_t* trx) /* in: transaction */
{
if (!trx->n_tables_locked) {
if (!trx->n_lock_table_exp) {
return;
}
@ -3175,7 +3176,12 @@ row_check_table_for_mysql(
REPEATABLE READ here */
prebuilt->trx->isolation_level = TRX_ISO_REPEATABLE_READ;
/* Enlarge the fatal lock wait timeout during CHECK TABLE. */
mutex_enter(&kernel_mutex);
srv_fatal_semaphore_wait_threshold += 7200; /* 2 hours */
mutex_exit(&kernel_mutex);
index = dict_table_get_first_index(table);
while (index != NULL) {
@ -3223,6 +3229,11 @@ row_check_table_for_mysql(
ret = DB_ERROR;
}
/* Restore the fatal lock wait timeout after CHECK TABLE. */
mutex_enter(&kernel_mutex);
srv_fatal_semaphore_wait_threshold -= 7200; /* 2 hours */
mutex_exit(&kernel_mutex);
prebuilt->trx->op_info = "";
return(ret);

View file

@ -55,6 +55,9 @@ ibool srv_lower_case_table_names = FALSE;
in the server */
ulint srv_activity_count = 0;
/* The following is the maximum allowed duration of a lock wait. */
ulint srv_fatal_semaphore_wait_threshold = 600;
ibool srv_lock_timeout_and_monitor_active = FALSE;
ibool srv_error_monitor_active = FALSE;

View file

@ -1115,7 +1115,7 @@ NetWare. */
srv_monitor_file_name = mem_alloc(
strlen(fil_path_to_mysql_datadir) +
20 + sizeof "/innodb_status.");
sprintf(srv_monitor_file_name, "%s/innodb.status.%lu",
sprintf(srv_monitor_file_name, "%s/innodb_status.%lu",
fil_path_to_mysql_datadir, os_proc_get_number());
srv_monitor_file = fopen(srv_monitor_file_name, "w+");
if (!srv_monitor_file) {

View file

@ -895,7 +895,7 @@ sync_arr_wake_threads_if_sema_free(void)
}
/**************************************************************************
Prints warnings of long semaphore waits to stderr. Currently > 120 sec. */
Prints warnings of long semaphore waits to stderr. */
void
sync_array_print_long_waits(void)
@ -905,6 +905,7 @@ sync_array_print_long_waits(void)
ibool old_val;
ibool noticed = FALSE;
ulint i;
ulint fatal_timeout = srv_fatal_semaphore_wait_threshold;
for (i = 0; i < sync_primary_wait_array->n_cells; i++) {
@ -919,12 +920,13 @@ sync_array_print_long_waits(void)
}
if (cell->wait_object != NULL
&& difftime(time(NULL), cell->reservation_time) > 600) {
&& difftime(time(NULL), cell->reservation_time)
> fatal_timeout) {
fputs(
"InnoDB: Error: semaphore wait has lasted > 600 seconds\n"
fprintf(stderr,
"InnoDB: Error: semaphore wait has lasted > %lu seconds\n"
"InnoDB: We intentionally crash the server, because it appears to be hung.\n",
stderr);
fatal_timeout);
ut_error;
}

View file

@ -151,7 +151,7 @@ trx_create(
trx->n_tickets_to_enter_innodb = 0;
trx->auto_inc_lock = NULL;
trx->n_tables_locked = 0;
trx->n_lock_table_exp = 0;
trx->read_view_heap = mem_heap_create(256);
trx->read_view = NULL;
@ -279,7 +279,7 @@ trx_free(
ut_a(!trx->has_search_latch);
ut_a(!trx->auto_inc_lock);
ut_a(!trx->n_tables_locked);
ut_a(!trx->n_lock_table_exp);
ut_a(trx->dict_operation_lock_mode == 0);