mirror of
https://github.com/MariaDB/server.git
synced 2025-05-13 01:01:44 +03:00
Merge mysql.com:/home/pz/mysql/mysql-4.0-root
into mysql.com:/home/pz/mysql/mysql-4.0
This commit is contained in:
commit
21601b51c3
@ -23510,17 +23510,21 @@ will be logged in the execution order.
|
||||
Updates to non-transactional tables are stored in the binary log
|
||||
immediately after execution. For transactional tables such as @code{BDB}
|
||||
or @code{InnoDB} tables, all updates (@code{UPDATE}, @code{DELETE}
|
||||
or @code{INSERT}) that change tables are cached until a @code{COMMIT}.
|
||||
or @code{INSERT}) that change tables are cached until a @code{COMMIT} command
|
||||
is sent to the server. At this point mysqld writes the whole transaction to
|
||||
the binary log before the @code{COMMIT} is executed.
|
||||
Every thread will, on start, allocate a buffer of @code{binlog_cache_size}
|
||||
to buffer queries. If a query is bigger than this, the thread will open
|
||||
a temporary file to handle the bigger cache. The temporary file will
|
||||
a temporary file to store the transcation. The temporary file will
|
||||
be deleted when the thread ends.
|
||||
|
||||
The @code{max_binlog_cache_size} can be used to restrict the total size used
|
||||
to cache a multi-query transaction.
|
||||
The @code{max_binlog_cache_size} (default 4G) can be used to restrict
|
||||
the total size used to cache a multi-query transaction. If a transaction is
|
||||
bigger than this it will fail and roll back.
|
||||
|
||||
If you are using the update or binary log, concurrent inserts will
|
||||
not work together with @code{CREATE ... SELECT} and @code{INSERT ... SELECT}.
|
||||
be converted to normal inserts when using @code{CREATE ... SELECT} and
|
||||
@code{INSERT ... SELECT}.
|
||||
This is to ensure that you can recreate an exact copy of your tables by
|
||||
applying the log on a backup.
|
||||
|
||||
|
@ -1041,7 +1041,7 @@ dict_create_or_check_foreign_constraint_tables(void)
|
||||
que_t* graph;
|
||||
ulint error;
|
||||
trx_t* trx;
|
||||
char* str;
|
||||
char* str;
|
||||
|
||||
mutex_enter(&(dict_sys->mutex));
|
||||
|
||||
@ -1060,20 +1060,24 @@ dict_create_or_check_foreign_constraint_tables(void)
|
||||
return(DB_SUCCESS);
|
||||
}
|
||||
|
||||
mutex_exit(&(dict_sys->mutex));
|
||||
|
||||
trx = trx_allocate_for_mysql();
|
||||
|
||||
trx->op_info = (char *) "creating foreign key sys tables";
|
||||
|
||||
row_mysql_lock_data_dictionary(trx);
|
||||
|
||||
if (table1) {
|
||||
fprintf(stderr,
|
||||
"InnoDB: dropping incompletely created SYS_FOREIGN table\n");
|
||||
row_drop_table_for_mysql((char *) "SYS_FOREIGN", trx, TRUE);
|
||||
row_drop_table_for_mysql((char *) "SYS_FOREIGN", trx);
|
||||
}
|
||||
|
||||
if (table2) {
|
||||
fprintf(stderr,
|
||||
"InnoDB: dropping incompletely created SYS_FOREIGN_COLS table\n");
|
||||
row_drop_table_for_mysql((char *) "SYS_FOREIGN_COLS",trx,TRUE);
|
||||
row_drop_table_for_mysql((char *) "SYS_FOREIGN_COLS", trx);
|
||||
}
|
||||
|
||||
fprintf(stderr,
|
||||
@ -1122,8 +1126,8 @@ dict_create_or_check_foreign_constraint_tables(void)
|
||||
fprintf(stderr,
|
||||
"InnoDB: dropping incompletely created SYS_FOREIGN tables\n");
|
||||
|
||||
row_drop_table_for_mysql((char *) "SYS_FOREIGN", trx, TRUE);
|
||||
row_drop_table_for_mysql((char *) "SYS_FOREIGN_COLS",trx,TRUE);
|
||||
row_drop_table_for_mysql((char *) "SYS_FOREIGN", trx);
|
||||
row_drop_table_for_mysql((char *) "SYS_FOREIGN_COLS", trx);
|
||||
|
||||
error = DB_MUST_GET_MORE_FILE_SPACE;
|
||||
}
|
||||
@ -1132,6 +1136,8 @@ dict_create_or_check_foreign_constraint_tables(void)
|
||||
|
||||
trx->op_info = (char *) "";
|
||||
|
||||
row_mysql_unlock_data_dictionary(trx);
|
||||
|
||||
trx_free_for_mysql(trx);
|
||||
|
||||
if (error == DB_SUCCESS) {
|
||||
@ -1139,8 +1145,6 @@ dict_create_or_check_foreign_constraint_tables(void)
|
||||
"InnoDB: Foreign key constraint system tables created\n");
|
||||
}
|
||||
|
||||
mutex_exit(&(dict_sys->mutex));
|
||||
|
||||
return(error);
|
||||
}
|
||||
|
||||
|
@ -30,13 +30,16 @@ Created 1/8/1996 Heikki Tuuri
|
||||
dict_sys_t* dict_sys = NULL; /* the dictionary system */
|
||||
|
||||
rw_lock_t dict_operation_lock; /* table create, drop, etc. reserve
|
||||
this in X-mode, implicit or backround
|
||||
this in X-mode; implicit or backround
|
||||
operations purge, rollback, foreign
|
||||
key checks reserve this in S-mode; we
|
||||
cannot trust that MySQL protects
|
||||
implicit or background operations
|
||||
from dropping a table: this is our
|
||||
mechanism */
|
||||
a table drop since MySQL does not
|
||||
know of them; therefore we need this;
|
||||
NOTE: a transaction which reserves
|
||||
this must keep book on the mode in
|
||||
trx->dict_operation_lock_mode */
|
||||
|
||||
#define DICT_HEAP_SIZE 100 /* initial memory heap size when
|
||||
creating a table or index object */
|
||||
@ -182,6 +185,58 @@ dict_foreign_free(
|
||||
/*==============*/
|
||||
dict_foreign_t* foreign); /* in, own: foreign key struct */
|
||||
|
||||
/************************************************************************
|
||||
Checks if the database name in two table names is the same. */
|
||||
static
|
||||
ibool
|
||||
dict_tables_have_same_db(
|
||||
/*=====================*/
|
||||
/* out: TRUE if same db name */
|
||||
char* name1, /* in: table name in the form dbname '/' tablename */
|
||||
char* name2) /* in: table name in the form dbname '/' tablename */
|
||||
{
|
||||
ulint i;
|
||||
|
||||
for (i = 0; i < 100000; i++) {
|
||||
if (name1[i] == '/' && name2[i] == '/') {
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
if (name1[i] != name2[i]) {
|
||||
|
||||
return(FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
ut_a(0);
|
||||
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
Return the end of table name where we have removed dbname and '/'. */
|
||||
static
|
||||
char*
|
||||
dict_remove_db_name(
|
||||
/*================*/
|
||||
/* out: table name */
|
||||
char* name) /* in: table name in the form dbname '/' tablename */
|
||||
{
|
||||
ulint i;
|
||||
|
||||
for (i = 0; i < 100000 ; i++) {
|
||||
if (name[i] == '/') {
|
||||
|
||||
return(name + i + 1);
|
||||
}
|
||||
}
|
||||
|
||||
ut_a(0);
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
Reserves the dictionary system mutex for MySQL. */
|
||||
|
||||
@ -1926,7 +1981,8 @@ dict_scan_col(
|
||||
|
||||
old_ptr = ptr;
|
||||
|
||||
while (!isspace(*ptr) && *ptr != ',' && *ptr != ')' && *ptr != '`') {
|
||||
while (!isspace(*ptr) && *ptr != ',' && *ptr != ')' && *ptr != '`'
|
||||
&& *ptr != '\0') {
|
||||
|
||||
ptr++;
|
||||
}
|
||||
@ -2000,7 +2056,7 @@ dict_scan_table_name(
|
||||
|
||||
old_ptr = ptr;
|
||||
|
||||
while (!isspace(*ptr) && *ptr != '(' && *ptr != '`') {
|
||||
while (!isspace(*ptr) && *ptr != '(' && *ptr != '`' && *ptr != '\0') {
|
||||
if (*ptr == '.') {
|
||||
dot_ptr = ptr;
|
||||
}
|
||||
@ -2023,17 +2079,28 @@ dict_scan_table_name(
|
||||
}
|
||||
#ifdef __WIN__
|
||||
ut_cpy_in_lower_case(second_table_name + i, old_ptr,
|
||||
ptr - old_ptr);
|
||||
ptr - old_ptr);
|
||||
#else
|
||||
ut_memcpy(second_table_name + i, old_ptr, ptr - old_ptr);
|
||||
if (srv_lower_case_table_names) {
|
||||
ut_cpy_in_lower_case(second_table_name + i, old_ptr,
|
||||
ptr - old_ptr);
|
||||
} else {
|
||||
ut_memcpy(second_table_name + i, old_ptr,
|
||||
ptr - old_ptr);
|
||||
}
|
||||
#endif
|
||||
second_table_name[i + (ptr - old_ptr)] = '\0';
|
||||
} else {
|
||||
#ifdef __WIN__
|
||||
ut_cpy_in_lower_case(second_table_name, old_ptr,
|
||||
ptr - old_ptr);
|
||||
ptr - old_ptr);
|
||||
#else
|
||||
ut_memcpy(second_table_name, old_ptr, ptr - old_ptr);
|
||||
if (srv_lower_case_table_names) {
|
||||
ut_cpy_in_lower_case(second_table_name, old_ptr,
|
||||
ptr - old_ptr);
|
||||
} else {
|
||||
ut_memcpy(second_table_name, old_ptr, ptr - old_ptr);
|
||||
}
|
||||
#endif
|
||||
second_table_name[dot_ptr - old_ptr] = '/';
|
||||
second_table_name[ptr - old_ptr] = '\0';
|
||||
@ -2050,6 +2117,44 @@ dict_scan_table_name(
|
||||
return(ptr);
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
Skips one 'word', like an id. For the lexical definition of 'word', see the
|
||||
code below. */
|
||||
static
|
||||
char*
|
||||
dict_skip_word(
|
||||
/*===========*/
|
||||
/* out: scanned to */
|
||||
char* ptr, /* in: scanned to */
|
||||
ibool* success)/* out: TRUE if success, FALSE if just spaces left in
|
||||
string */
|
||||
{
|
||||
*success = FALSE;
|
||||
|
||||
while (isspace(*ptr)) {
|
||||
ptr++;
|
||||
}
|
||||
|
||||
if (*ptr == '\0') {
|
||||
|
||||
return(ptr);
|
||||
}
|
||||
|
||||
if (*ptr == '`') {
|
||||
ptr++;
|
||||
}
|
||||
|
||||
while (!isspace(*ptr) && *ptr != ',' && *ptr != '(' && *ptr != '`'
|
||||
&& *ptr != '\0') {
|
||||
|
||||
ptr++;
|
||||
}
|
||||
|
||||
*success = TRUE;
|
||||
|
||||
return(ptr);
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
Returns the number of opening brackets '(' subtracted by the number
|
||||
of closing brackets ')' between string and ptr. */
|
||||
@ -2119,7 +2224,6 @@ dict_create_foreign_constraints(
|
||||
if (table == NULL) {
|
||||
return(DB_ERROR);
|
||||
}
|
||||
|
||||
loop:
|
||||
ptr = dict_scan_to(ptr, (char *) "FOREIGN");
|
||||
|
||||
@ -2148,7 +2252,19 @@ loop:
|
||||
ptr = dict_accept(ptr, (char *) "(", &success);
|
||||
|
||||
if (!success) {
|
||||
goto loop;
|
||||
/* MySQL allows also an index id before the '('; we
|
||||
skip it */
|
||||
ptr = dict_skip_word(ptr, &success);
|
||||
|
||||
if (!success) {
|
||||
return(DB_CANNOT_ADD_CONSTRAINT);
|
||||
}
|
||||
|
||||
ptr = dict_accept(ptr, (char *) "(", &success);
|
||||
|
||||
if (!success) {
|
||||
return(DB_CANNOT_ADD_CONSTRAINT);
|
||||
}
|
||||
}
|
||||
|
||||
i = 0;
|
||||
@ -2223,6 +2339,7 @@ col_loop1:
|
||||
|
||||
if (!success) {
|
||||
dict_foreign_free(foreign);
|
||||
|
||||
return(DB_CANNOT_ADD_CONSTRAINT);
|
||||
}
|
||||
|
||||
@ -2236,6 +2353,7 @@ col_loop2:
|
||||
|
||||
if (!success) {
|
||||
dict_foreign_free(foreign);
|
||||
|
||||
return(DB_CANNOT_ADD_CONSTRAINT);
|
||||
}
|
||||
|
||||
@ -2263,14 +2381,20 @@ col_loop2:
|
||||
ptr = dict_accept(ptr, "DELETE", &success);
|
||||
|
||||
if (!success) {
|
||||
dict_foreign_free(foreign);
|
||||
|
||||
return(DB_CANNOT_ADD_CONSTRAINT);
|
||||
}
|
||||
|
||||
ptr = dict_accept(ptr, "RESTRICT", &success);
|
||||
|
||||
if (success) {
|
||||
goto try_find_index;
|
||||
}
|
||||
|
||||
ptr = dict_accept(ptr, "CASCADE", &success);
|
||||
|
||||
if (success) {
|
||||
|
||||
foreign->type = DICT_FOREIGN_ON_DELETE_CASCADE;
|
||||
|
||||
goto try_find_index;
|
||||
@ -2279,32 +2403,47 @@ col_loop2:
|
||||
ptr = dict_accept(ptr, "SET", &success);
|
||||
|
||||
if (!success) {
|
||||
|
||||
goto try_find_index;
|
||||
dict_foreign_free(foreign);
|
||||
|
||||
return(DB_CANNOT_ADD_CONSTRAINT);
|
||||
}
|
||||
|
||||
ptr = dict_accept(ptr, "NULL", &success);
|
||||
|
||||
if (success) {
|
||||
for (j = 0; j < foreign->n_fields; j++) {
|
||||
if ((dict_index_get_nth_type(
|
||||
if (!success) {
|
||||
dict_foreign_free(foreign);
|
||||
|
||||
return(DB_CANNOT_ADD_CONSTRAINT);
|
||||
}
|
||||
|
||||
for (j = 0; j < foreign->n_fields; j++) {
|
||||
if ((dict_index_get_nth_type(
|
||||
foreign->foreign_index, j)->prtype)
|
||||
& DATA_NOT_NULL) {
|
||||
|
||||
/* It is not sensible to define SET NULL
|
||||
if the column is not allowed to be NULL! */
|
||||
/* It is not sensible to define SET NULL
|
||||
if the column is not allowed to be NULL! */
|
||||
|
||||
dict_foreign_free(foreign);
|
||||
return(DB_CANNOT_ADD_CONSTRAINT);
|
||||
}
|
||||
dict_foreign_free(foreign);
|
||||
|
||||
return(DB_CANNOT_ADD_CONSTRAINT);
|
||||
}
|
||||
|
||||
foreign->type = DICT_FOREIGN_ON_DELETE_SET_NULL;
|
||||
|
||||
goto try_find_index;
|
||||
}
|
||||
|
||||
foreign->type = DICT_FOREIGN_ON_DELETE_SET_NULL;
|
||||
|
||||
try_find_index:
|
||||
/* We check that there are no superfluous words like 'ON UPDATE ...'
|
||||
which we do not support yet. */
|
||||
|
||||
ptr = dict_accept(ptr, (char *) "ON", &success);
|
||||
|
||||
if (success) {
|
||||
dict_foreign_free(foreign);
|
||||
|
||||
return(DB_CANNOT_ADD_CONSTRAINT);
|
||||
}
|
||||
|
||||
/* Try to find an index which contains the columns as the first fields
|
||||
and in the right order, and the types are the same as in
|
||||
foreign->foreign_index */
|
||||
@ -2351,6 +2490,7 @@ try_find_index:
|
||||
referenced_table->referenced_list,
|
||||
foreign);
|
||||
}
|
||||
|
||||
goto loop;
|
||||
}
|
||||
|
||||
@ -2849,6 +2989,14 @@ dict_update_statistics_low(
|
||||
ulint size;
|
||||
ulint sum_of_index_sizes = 0;
|
||||
|
||||
/* If we have set a high innodb_force_recovery level, do not calculate
|
||||
statistics, as a badly corrupted index can cause a crash in it. */
|
||||
|
||||
if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE) {
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Find out the sizes of the indexes and how many different values
|
||||
for the key they approximately have */
|
||||
|
||||
@ -3152,16 +3300,25 @@ dict_print_info_on_foreign_keys_in_create_format(
|
||||
}
|
||||
}
|
||||
|
||||
buf2 += sprintf(buf2, ") REFERENCES `%s` (",
|
||||
if (dict_tables_have_same_db(table->name,
|
||||
foreign->referenced_table_name)) {
|
||||
/* Do not print the database name of the referenced
|
||||
table */
|
||||
buf2 += sprintf(buf2, ") REFERENCES `%s` (",
|
||||
dict_remove_db_name(
|
||||
foreign->referenced_table_name));
|
||||
} else {
|
||||
buf2 += sprintf(buf2, ") REFERENCES `%s` (",
|
||||
foreign->referenced_table_name);
|
||||
/* Change the '/' in the table name to '.' */
|
||||
/* Change the '/' in the table name to '.' */
|
||||
|
||||
for (i = ut_strlen(buf); i > 0; i--) {
|
||||
if (buf[i] == '/') {
|
||||
for (i = ut_strlen(buf); i > 0; i--) {
|
||||
if (buf[i] == '/') {
|
||||
|
||||
buf[i] = '.';
|
||||
buf[i] = '.';
|
||||
|
||||
break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -334,6 +334,7 @@ extern ibool recv_no_ibuf_operations;
|
||||
extern ibool recv_needed_recovery;
|
||||
|
||||
extern ibool recv_is_making_a_backup;
|
||||
extern ulint recv_max_parsed_page_no;
|
||||
|
||||
/* Size of the parsing buffer; it must accommodate RECV_SCAN_SIZE many
|
||||
times! */
|
||||
|
@ -230,18 +230,35 @@ row_update_cascade_for_mysql(
|
||||
or set null operation */
|
||||
dict_table_t* table); /* in: table where we do the operation */
|
||||
/*************************************************************************
|
||||
Locks the data dictionary exclusively for performing a table create
|
||||
operation. */
|
||||
Locks the data dictionary exclusively for performing a table create or other
|
||||
data dictionary modification operation. */
|
||||
|
||||
void
|
||||
row_mysql_lock_data_dictionary(void);
|
||||
/*================================*/
|
||||
row_mysql_lock_data_dictionary(
|
||||
/*===========================*/
|
||||
trx_t* trx); /* in: transaction */
|
||||
/*************************************************************************
|
||||
Unlocks the data dictionary exclusively lock. */
|
||||
Unlocks the data dictionary exclusive lock. */
|
||||
|
||||
void
|
||||
row_mysql_unlock_data_dictionary(void);
|
||||
/*==================================*/
|
||||
row_mysql_unlock_data_dictionary(
|
||||
/*=============================*/
|
||||
trx_t* trx); /* in: transaction */
|
||||
/*************************************************************************
|
||||
Locks the data dictionary in shared mode from modifications, for performing
|
||||
foreign key check, rollback, or other operation invisible to MySQL. */
|
||||
|
||||
void
|
||||
row_mysql_freeze_data_dictionary(
|
||||
/*=============================*/
|
||||
trx_t* trx); /* in: transaction */
|
||||
/*************************************************************************
|
||||
Unlocks the data dictionary shared lock. */
|
||||
|
||||
void
|
||||
row_mysql_unfreeze_data_dictionary(
|
||||
/*===============================*/
|
||||
trx_t* trx); /* in: transaction */
|
||||
/*************************************************************************
|
||||
Does a table creation operation for MySQL. If the name of the created
|
||||
table ends to characters INNODB_MONITOR, then this also starts
|
||||
@ -310,11 +327,9 @@ output by the master thread. */
|
||||
int
|
||||
row_drop_table_for_mysql(
|
||||
/*=====================*/
|
||||
/* out: error code or DB_SUCCESS */
|
||||
char* name, /* in: table name */
|
||||
trx_t* trx, /* in: transaction handle */
|
||||
ibool has_dict_mutex);/* in: TRUE if the caller already owns the
|
||||
dictionary system mutex */
|
||||
/* out: error code or DB_SUCCESS */
|
||||
char* name, /* in: table name */
|
||||
trx_t* trx); /* in: transaction handle */
|
||||
/*************************************************************************
|
||||
Drops a database for MySQL. */
|
||||
|
||||
|
@ -28,6 +28,9 @@ extern os_event_t srv_lock_timeout_thread_event;
|
||||
at a time */
|
||||
#define SRV_AUTO_EXTEND_INCREMENT (8 * ((1024 * 1024) / UNIV_PAGE_SIZE))
|
||||
|
||||
/* This is set to TRUE if the MySQL user has set it in MySQL */
|
||||
extern ibool srv_lower_case_table_names;
|
||||
|
||||
/* Server parameters which are read from the initfile */
|
||||
|
||||
extern char* srv_data_home;
|
||||
|
@ -386,9 +386,10 @@ struct trx_struct{
|
||||
/* how many tables the current SQL
|
||||
statement uses, except those
|
||||
in consistent read */
|
||||
ibool has_dict_operation_lock;
|
||||
/* TRUE if the trx currently holds
|
||||
an s-lock on dict_operation_lock */
|
||||
ibool dict_operation_lock_mode;
|
||||
/* 0, RW_S_LATCH, or RW_X_LATCH:
|
||||
the latch mode trx currently holds
|
||||
on dict_operation_lock */
|
||||
ibool has_search_latch;
|
||||
/* TRUE if this trx has latched the
|
||||
search system latch in S-mode */
|
||||
@ -427,34 +428,6 @@ struct trx_struct{
|
||||
mysql_trx_list; /* list of transactions created for
|
||||
MySQL */
|
||||
/*------------------------------*/
|
||||
mutex_t undo_mutex; /* mutex protecting the fields in this
|
||||
section (down to undo_no_arr), EXCEPT
|
||||
last_sql_stat_start, which can be
|
||||
accessed only when we know that there
|
||||
cannot be any activity in the undo
|
||||
logs! */
|
||||
dulint undo_no; /* next undo log record number to
|
||||
assign */
|
||||
trx_savept_t last_sql_stat_start;
|
||||
/* undo_no when the last sql statement
|
||||
was started: in case of an error, trx
|
||||
is rolled back down to this undo
|
||||
number; see note at undo_mutex! */
|
||||
trx_rseg_t* rseg; /* rollback segment assigned to the
|
||||
transaction, or NULL if not assigned
|
||||
yet */
|
||||
trx_undo_t* insert_undo; /* pointer to the insert undo log, or
|
||||
NULL if no inserts performed yet */
|
||||
trx_undo_t* update_undo; /* pointer to the update undo log, or
|
||||
NULL if no update performed yet */
|
||||
dulint roll_limit; /* least undo number to undo during
|
||||
a rollback */
|
||||
ulint pages_undone; /* number of undo log pages undone
|
||||
since the last undo log truncation */
|
||||
trx_undo_arr_t* undo_no_arr; /* array of undo numbers of undo log
|
||||
records which are currently processed
|
||||
by a rollback operation */
|
||||
/*------------------------------*/
|
||||
ulint error_state; /* 0 if no error, otherwise error
|
||||
number */
|
||||
void* error_info; /* if the error number indicates a
|
||||
@ -508,6 +481,34 @@ struct trx_struct{
|
||||
/*------------------------------*/
|
||||
mem_heap_t* read_view_heap; /* memory heap for the read view */
|
||||
read_view_t* read_view; /* consistent read view or NULL */
|
||||
/*------------------------------*/
|
||||
mutex_t undo_mutex; /* mutex protecting the fields in this
|
||||
section (down to undo_no_arr), EXCEPT
|
||||
last_sql_stat_start, which can be
|
||||
accessed only when we know that there
|
||||
cannot be any activity in the undo
|
||||
logs! */
|
||||
dulint undo_no; /* next undo log record number to
|
||||
assign */
|
||||
trx_savept_t last_sql_stat_start;
|
||||
/* undo_no when the last sql statement
|
||||
was started: in case of an error, trx
|
||||
is rolled back down to this undo
|
||||
number; see note at undo_mutex! */
|
||||
trx_rseg_t* rseg; /* rollback segment assigned to the
|
||||
transaction, or NULL if not assigned
|
||||
yet */
|
||||
trx_undo_t* insert_undo; /* pointer to the insert undo log, or
|
||||
NULL if no inserts performed yet */
|
||||
trx_undo_t* update_undo; /* pointer to the update undo log, or
|
||||
NULL if no update performed yet */
|
||||
dulint roll_limit; /* least undo number to undo during
|
||||
a rollback */
|
||||
ulint pages_undone; /* number of undo log pages undone
|
||||
since the last undo log truncation */
|
||||
trx_undo_arr_t* undo_no_arr; /* array of undo numbers of undo log
|
||||
records which are currently processed
|
||||
by a rollback operation */
|
||||
};
|
||||
|
||||
#define TRX_MAX_N_THREADS 32 /* maximum number of concurrent
|
||||
|
@ -69,6 +69,8 @@ ulint recv_previous_parsed_rec_type = 999999;
|
||||
ulint recv_previous_parsed_rec_offset = 0;
|
||||
ulint recv_previous_parsed_rec_is_multi = 0;
|
||||
|
||||
ulint recv_max_parsed_page_no = 0;
|
||||
|
||||
/************************************************************
|
||||
Creates the recovery system. */
|
||||
|
||||
@ -141,7 +143,13 @@ recv_sys_empty_hash(void)
|
||||
/*=====================*/
|
||||
{
|
||||
ut_ad(mutex_own(&(recv_sys->mutex)));
|
||||
ut_a(recv_sys->n_addrs == 0);
|
||||
if (recv_sys->n_addrs != 0) {
|
||||
fprintf(stderr,
|
||||
"InnoDB: Error: %lu pages with log records were left unprocessed!\n"
|
||||
"InnoDB: Maximum page number with log records on it %lu\n",
|
||||
recv_sys->n_addrs, recv_max_parsed_page_no);
|
||||
ut_a(0);
|
||||
}
|
||||
|
||||
hash_table_free(recv_sys->addr_hash);
|
||||
mem_heap_empty(recv_sys->heap);
|
||||
@ -1361,6 +1369,12 @@ recv_apply_log_recs_for_backup(
|
||||
n_pages_total += file_sizes[i];
|
||||
}
|
||||
|
||||
if (recv_max_parsed_page_no >= n_pages_total) {
|
||||
printf(
|
||||
"InnoDB: Error: tablespace size %lu pages, but a log record on page %lu!\n",
|
||||
n_pages_total, recv_max_parsed_page_no);
|
||||
}
|
||||
|
||||
printf(
|
||||
"InnoDB: Starting an apply batch of log records to the database...\n"
|
||||
"InnoDB: Progress in percents: ");
|
||||
@ -1701,6 +1715,10 @@ recv_parse_log_rec(
|
||||
return(0);
|
||||
}
|
||||
|
||||
if (*page_no > recv_max_parsed_page_no) {
|
||||
recv_max_parsed_page_no = *page_no;
|
||||
}
|
||||
|
||||
return(new_ptr - ptr);
|
||||
}
|
||||
|
||||
|
@ -66,8 +66,12 @@ os_event_create(
|
||||
event = ut_malloc(sizeof(struct os_event_struct));
|
||||
|
||||
os_fast_mutex_init(&(event->os_mutex));
|
||||
pthread_cond_init(&(event->cond_var), NULL);
|
||||
|
||||
#if defined(UNIV_HOTBACKUP) && defined(UNIV_HPUX10)
|
||||
pthread_cond_init(&(event->cond_var), pthread_condattr_default);
|
||||
#else
|
||||
pthread_cond_init(&(event->cond_var), NULL);
|
||||
#endif
|
||||
event->is_set = FALSE;
|
||||
|
||||
return(event);
|
||||
@ -440,9 +444,13 @@ os_fast_mutex_init(
|
||||
ut_a(fast_mutex);
|
||||
|
||||
InitializeCriticalSection((LPCRITICAL_SECTION) fast_mutex);
|
||||
#else
|
||||
#if defined(UNIV_HOTBACKUP) && defined(UNIV_HPUX10)
|
||||
pthread_mutex_init(fast_mutex, pthread_mutexattr_default);
|
||||
#else
|
||||
pthread_mutex_init(fast_mutex, MY_MUTEX_INIT_FAST);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
/**************************************************************
|
||||
|
@ -126,8 +126,10 @@ os_thread_create(
|
||||
os_thread_t pthread;
|
||||
pthread_attr_t attr;
|
||||
|
||||
#if !(defined(UNIV_HOTBACKUP) && defined(UNIV_HPUX10))
|
||||
pthread_attr_init(&attr);
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef UNIV_AIX
|
||||
/* We must make sure a thread stack is at least 32 kB, otherwise
|
||||
InnoDB might crash; we do not know if the default stack size on
|
||||
@ -142,16 +144,21 @@ os_thread_create(
|
||||
exit(1);
|
||||
}
|
||||
#endif
|
||||
ret = pthread_create(&pthread, &attr, start_f, arg);
|
||||
|
||||
#if defined(UNIV_HOTBACKUP) && defined(UNIV_HPUX10)
|
||||
ret = pthread_create(&pthread, pthread_attr_default, start_f, arg);
|
||||
#else
|
||||
ret = pthread_create(&pthread, &attr, start_f, arg);
|
||||
#endif
|
||||
if (ret) {
|
||||
fprintf(stderr,
|
||||
"InnoDB: Error: pthread_create returned %d\n", ret);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
#if !(defined(UNIV_HOTBACKUP) && defined(UNIV_HPUX10))
|
||||
pthread_attr_destroy(&attr);
|
||||
|
||||
#endif
|
||||
if (srv_set_thread_priorities) {
|
||||
|
||||
my_pthread_setprio(pthread, srv_query_thread_priority);
|
||||
|
@ -643,7 +643,7 @@ row_ins_check_foreign_constraint(
|
||||
|
||||
run_again:
|
||||
ut_ad(rw_lock_own(&dict_operation_lock, RW_LOCK_SHARED));
|
||||
|
||||
|
||||
err = DB_SUCCESS;
|
||||
|
||||
if (thr_get_trx(thr)->check_foreigns == FALSE) {
|
||||
@ -880,21 +880,16 @@ row_ins_check_foreign_constraints(
|
||||
trx);
|
||||
}
|
||||
|
||||
if (!trx->has_dict_operation_lock) {
|
||||
if (0 == trx->dict_operation_lock_mode) {
|
||||
got_s_lock = TRUE;
|
||||
|
||||
rw_lock_s_lock(&dict_operation_lock);
|
||||
|
||||
trx->has_dict_operation_lock = TRUE;
|
||||
row_mysql_freeze_data_dictionary(trx);
|
||||
}
|
||||
|
||||
err = row_ins_check_foreign_constraint(TRUE, foreign,
|
||||
table, index, entry, thr);
|
||||
if (got_s_lock) {
|
||||
|
||||
rw_lock_s_unlock(&dict_operation_lock);
|
||||
|
||||
trx->has_dict_operation_lock = FALSE;
|
||||
row_mysql_unfreeze_data_dictionary(trx);
|
||||
}
|
||||
|
||||
if (err != DB_SUCCESS) {
|
||||
|
@ -1134,32 +1134,73 @@ row_mysql_recover_tmp_table(
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
Locks the data dictionary exclusively for performing a table create
|
||||
operation. */
|
||||
Locks the data dictionary in shared mode from modifications, for performing
|
||||
foreign key check, rollback, or other operation invisible to MySQL. */
|
||||
|
||||
void
|
||||
row_mysql_lock_data_dictionary(void)
|
||||
/*================================*/
|
||||
row_mysql_freeze_data_dictionary(
|
||||
/*=============================*/
|
||||
trx_t* trx) /* in: transaction */
|
||||
{
|
||||
ut_a(trx->dict_operation_lock_mode == 0);
|
||||
|
||||
rw_lock_s_lock(&dict_operation_lock);
|
||||
|
||||
trx->dict_operation_lock_mode = RW_S_LATCH;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
Unlocks the data dictionary shared lock. */
|
||||
|
||||
void
|
||||
row_mysql_unfreeze_data_dictionary(
|
||||
/*===============================*/
|
||||
trx_t* trx) /* in: transaction */
|
||||
{
|
||||
ut_a(trx->dict_operation_lock_mode == RW_S_LATCH);
|
||||
|
||||
rw_lock_s_unlock(&dict_operation_lock);
|
||||
|
||||
trx->dict_operation_lock_mode = 0;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
Locks the data dictionary exclusively for performing a table create or other
|
||||
data dictionary modification operation. */
|
||||
|
||||
void
|
||||
row_mysql_lock_data_dictionary(
|
||||
/*===========================*/
|
||||
trx_t* trx) /* in: transaction */
|
||||
{
|
||||
ut_a(trx->dict_operation_lock_mode == 0);
|
||||
|
||||
/* Serialize data dictionary operations with dictionary mutex:
|
||||
no deadlocks or lock waits can occur then in these operations */
|
||||
|
||||
rw_lock_x_lock(&dict_operation_lock);
|
||||
trx->dict_operation_lock_mode = RW_X_LATCH;
|
||||
|
||||
mutex_enter(&(dict_sys->mutex));
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
Unlocks the data dictionary exclusively lock. */
|
||||
Unlocks the data dictionary exclusive lock. */
|
||||
|
||||
void
|
||||
row_mysql_unlock_data_dictionary(void)
|
||||
/*==================================*/
|
||||
row_mysql_unlock_data_dictionary(
|
||||
/*=============================*/
|
||||
trx_t* trx) /* in: transaction */
|
||||
{
|
||||
ut_a(trx->dict_operation_lock_mode == RW_X_LATCH);
|
||||
|
||||
/* Serialize data dictionary operations with dictionary mutex:
|
||||
no deadlocks can occur then in these operations */
|
||||
|
||||
mutex_exit(&(dict_sys->mutex));
|
||||
rw_lock_x_unlock(&dict_operation_lock);
|
||||
|
||||
trx->dict_operation_lock_mode = 0;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
@ -1183,6 +1224,7 @@ row_create_table_for_mysql(
|
||||
|
||||
ut_ad(trx->mysql_thread_id == os_thread_get_curr_id());
|
||||
ut_ad(rw_lock_own(&dict_operation_lock, RW_LOCK_EX));
|
||||
ut_ad(trx->dict_operation_lock_mode == RW_X_LATCH);
|
||||
ut_ad(mutex_own(&(dict_sys->mutex)));
|
||||
|
||||
if (srv_created_new_raw) {
|
||||
@ -1331,7 +1373,7 @@ row_create_table_for_mysql(
|
||||
fprintf(stderr,
|
||||
"InnoDB: Warning: cannot create table %s because tablespace full\n",
|
||||
table->name);
|
||||
row_drop_table_for_mysql(table->name, trx, TRUE);
|
||||
row_drop_table_for_mysql(table->name, trx);
|
||||
} else {
|
||||
ut_a(err == DB_DUPLICATE_KEY);
|
||||
|
||||
@ -1425,7 +1467,7 @@ row_create_index_for_mysql(
|
||||
|
||||
trx_general_rollback_for_mysql(trx, FALSE, NULL);
|
||||
|
||||
row_drop_table_for_mysql(index->table_name, trx, TRUE);
|
||||
row_drop_table_for_mysql(index->table_name, trx);
|
||||
|
||||
trx->error_state = DB_SUCCESS;
|
||||
}
|
||||
@ -1499,7 +1541,7 @@ row_table_add_foreign_constraints(
|
||||
|
||||
trx_general_rollback_for_mysql(trx, FALSE, NULL);
|
||||
|
||||
row_drop_table_for_mysql(name, trx, TRUE);
|
||||
row_drop_table_for_mysql(name, trx);
|
||||
|
||||
trx->error_state = DB_SUCCESS;
|
||||
}
|
||||
@ -1530,7 +1572,7 @@ row_drop_table_for_mysql_in_background(
|
||||
name); */
|
||||
/* Drop the table in InnoDB */
|
||||
|
||||
error = row_drop_table_for_mysql(name, trx, FALSE);
|
||||
error = row_drop_table_for_mysql(name, trx);
|
||||
|
||||
if (error != DB_SUCCESS) {
|
||||
fprintf(stderr,
|
||||
@ -1689,9 +1731,7 @@ row_drop_table_for_mysql(
|
||||
/*=====================*/
|
||||
/* out: error code or DB_SUCCESS */
|
||||
char* name, /* in: table name */
|
||||
trx_t* trx, /* in: transaction handle */
|
||||
ibool has_dict_mutex) /* in: TRUE if the caller already owns the
|
||||
dictionary system mutex */
|
||||
trx_t* trx) /* in: transaction handle */
|
||||
{
|
||||
dict_table_t* table;
|
||||
que_thr_t* thr;
|
||||
@ -1703,6 +1743,7 @@ row_drop_table_for_mysql(
|
||||
ulint namelen;
|
||||
ulint keywordlen;
|
||||
ulint rounds = 0;
|
||||
ibool locked_dictionary = FALSE;
|
||||
char buf[10000];
|
||||
|
||||
ut_ad(trx->mysql_thread_id == os_thread_get_curr_id());
|
||||
@ -1846,12 +1887,13 @@ row_drop_table_for_mysql(
|
||||
/* Serialize data dictionary operations with dictionary mutex:
|
||||
no deadlocks can occur then in these operations */
|
||||
|
||||
if (!has_dict_mutex) {
|
||||
if (trx->dict_operation_lock_mode != RW_X_LATCH) {
|
||||
/* Prevent foreign key checks etc. while we are dropping the
|
||||
table */
|
||||
rw_lock_x_lock(&dict_operation_lock);
|
||||
|
||||
mutex_enter(&(dict_sys->mutex));
|
||||
row_mysql_lock_data_dictionary(trx);
|
||||
|
||||
locked_dictionary = TRUE;
|
||||
}
|
||||
|
||||
ut_ad(mutex_own(&(dict_sys->mutex)));
|
||||
@ -1948,9 +1990,8 @@ row_drop_table_for_mysql(
|
||||
}
|
||||
funct_exit:
|
||||
|
||||
if (!has_dict_mutex) {
|
||||
mutex_exit(&(dict_sys->mutex));
|
||||
rw_lock_x_unlock(&dict_operation_lock);
|
||||
if (locked_dictionary) {
|
||||
row_mysql_unlock_data_dictionary(trx);
|
||||
}
|
||||
|
||||
que_graph_free(graph);
|
||||
@ -1986,8 +2027,7 @@ row_drop_database_for_mysql(
|
||||
|
||||
trx_start_if_not_started(trx);
|
||||
loop:
|
||||
rw_lock_x_lock(&dict_operation_lock);
|
||||
mutex_enter(&(dict_sys->mutex));
|
||||
row_mysql_lock_data_dictionary(trx);
|
||||
|
||||
while ((table_name = dict_get_first_table_name_in_db(name))) {
|
||||
ut_a(memcmp(table_name, name, strlen(name)) == 0);
|
||||
@ -2000,8 +2040,7 @@ loop:
|
||||
the table */
|
||||
|
||||
if (table->n_mysql_handles_opened > 0) {
|
||||
mutex_exit(&(dict_sys->mutex));
|
||||
rw_lock_x_unlock(&dict_operation_lock);
|
||||
row_mysql_unlock_data_dictionary(trx);
|
||||
|
||||
ut_print_timestamp(stderr);
|
||||
fprintf(stderr,
|
||||
@ -2016,7 +2055,7 @@ loop:
|
||||
goto loop;
|
||||
}
|
||||
|
||||
err = row_drop_table_for_mysql(table_name, trx, TRUE);
|
||||
err = row_drop_table_for_mysql(table_name, trx);
|
||||
|
||||
mem_free(table_name);
|
||||
|
||||
@ -2028,8 +2067,7 @@ loop:
|
||||
}
|
||||
}
|
||||
|
||||
mutex_exit(&(dict_sys->mutex));
|
||||
rw_lock_x_unlock(&dict_operation_lock);
|
||||
row_mysql_unlock_data_dictionary(trx);
|
||||
|
||||
trx_commit_for_mysql(trx);
|
||||
|
||||
@ -2166,8 +2204,7 @@ row_rename_table_for_mysql(
|
||||
/* Serialize data dictionary operations with dictionary mutex:
|
||||
no deadlocks can occur then in these operations */
|
||||
|
||||
rw_lock_x_lock(&dict_operation_lock);
|
||||
mutex_enter(&(dict_sys->mutex));
|
||||
row_mysql_lock_data_dictionary(trx);
|
||||
|
||||
table = dict_table_get_low(old_name);
|
||||
|
||||
@ -2249,8 +2286,7 @@ row_rename_table_for_mysql(
|
||||
}
|
||||
}
|
||||
funct_exit:
|
||||
mutex_exit(&(dict_sys->mutex));
|
||||
rw_lock_x_unlock(&dict_operation_lock);
|
||||
row_mysql_unlock_data_dictionary(trx);
|
||||
|
||||
que_graph_free(graph);
|
||||
|
||||
|
@ -24,6 +24,7 @@ Created 3/14/1997 Heikki Tuuri
|
||||
#include "row0row.h"
|
||||
#include "row0upd.h"
|
||||
#include "row0vers.h"
|
||||
#include "row0mysql.h"
|
||||
#include "log0log.h"
|
||||
|
||||
/************************************************************************
|
||||
@ -454,8 +455,8 @@ ibool
|
||||
row_purge_parse_undo_rec(
|
||||
/*=====================*/
|
||||
/* out: TRUE if purge operation required:
|
||||
NOTE that then the CALLER must s-unlock
|
||||
dict_operation_lock! */
|
||||
NOTE that then the CALLER must unfreeze
|
||||
data dictionary! */
|
||||
purge_node_t* node, /* in: row undo node */
|
||||
ibool* updated_extern,
|
||||
/* out: TRUE if an externally stored field
|
||||
@ -464,6 +465,7 @@ row_purge_parse_undo_rec(
|
||||
{
|
||||
dict_index_t* clust_index;
|
||||
byte* ptr;
|
||||
trx_t* trx;
|
||||
dulint undo_no;
|
||||
dulint table_id;
|
||||
dulint trx_id;
|
||||
@ -473,6 +475,8 @@ row_purge_parse_undo_rec(
|
||||
ulint cmpl_info;
|
||||
|
||||
ut_ad(node && thr);
|
||||
|
||||
trx = thr_get_trx(thr);
|
||||
|
||||
ptr = trx_undo_rec_get_pars(node->undo_rec, &type, &cmpl_info,
|
||||
updated_extern, &undo_no, &table_id);
|
||||
@ -498,17 +502,18 @@ row_purge_parse_undo_rec(
|
||||
/* Prevent DROP TABLE etc. from running when we are doing the purge
|
||||
for this row */
|
||||
|
||||
rw_lock_s_lock(&dict_operation_lock);
|
||||
mutex_enter(&(dict_sys->mutex));
|
||||
row_mysql_freeze_data_dictionary(trx);
|
||||
|
||||
mutex_enter(&(dict_sys->mutex));
|
||||
|
||||
node->table = dict_table_get_on_id_low(table_id, thr_get_trx(thr));
|
||||
|
||||
mutex_exit(&(dict_sys->mutex));
|
||||
|
||||
mutex_exit(&(dict_sys->mutex));
|
||||
|
||||
if (node->table == NULL) {
|
||||
/* The table has been dropped: no need to do purge */
|
||||
|
||||
rw_lock_s_unlock(&dict_operation_lock);
|
||||
row_mysql_unfreeze_data_dictionary(trx);
|
||||
|
||||
return(FALSE);
|
||||
}
|
||||
@ -518,7 +523,7 @@ row_purge_parse_undo_rec(
|
||||
if (clust_index == NULL) {
|
||||
/* The table was corrupt in the data dictionary */
|
||||
|
||||
rw_lock_s_unlock(&dict_operation_lock);
|
||||
row_mysql_unfreeze_data_dictionary(trx);
|
||||
|
||||
return(FALSE);
|
||||
}
|
||||
@ -556,9 +561,12 @@ row_purge(
|
||||
dulint roll_ptr;
|
||||
ibool purge_needed;
|
||||
ibool updated_extern;
|
||||
trx_t* trx;
|
||||
|
||||
ut_ad(node && thr);
|
||||
|
||||
trx = thr_get_trx(thr);
|
||||
|
||||
node->undo_rec = trx_purge_fetch_next_rec(&roll_ptr,
|
||||
&(node->reservation),
|
||||
node->heap);
|
||||
@ -577,8 +585,8 @@ row_purge(
|
||||
} else {
|
||||
purge_needed = row_purge_parse_undo_rec(node, &updated_extern,
|
||||
thr);
|
||||
/* If purge_needed == TRUE, we must also remember to unlock
|
||||
dict_operation_lock! */
|
||||
/* If purge_needed == TRUE, we must also remember to unfreeze
|
||||
data dictionary! */
|
||||
}
|
||||
|
||||
if (purge_needed) {
|
||||
@ -600,7 +608,7 @@ row_purge(
|
||||
btr_pcur_close(&(node->pcur));
|
||||
}
|
||||
|
||||
rw_lock_s_unlock(&dict_operation_lock);
|
||||
row_mysql_unfreeze_data_dictionary(trx);
|
||||
}
|
||||
|
||||
/* Do some cleanup */
|
||||
|
@ -24,6 +24,7 @@ Created 1/8/1997 Heikki Tuuri
|
||||
#include "row0row.h"
|
||||
#include "row0uins.h"
|
||||
#include "row0umod.h"
|
||||
#include "row0mysql.h"
|
||||
#include "srv0srv.h"
|
||||
|
||||
/* How to undo row operations?
|
||||
@ -204,6 +205,7 @@ row_undo(
|
||||
ulint err;
|
||||
trx_t* trx;
|
||||
dulint roll_ptr;
|
||||
ibool froze_data_dict = FALSE;
|
||||
|
||||
ut_ad(node && thr);
|
||||
|
||||
@ -256,13 +258,13 @@ row_undo(
|
||||
/* Prevent DROP TABLE etc. while we are rolling back this row.
|
||||
If we are doing a TABLE CREATE or some other dictionary operation,
|
||||
then we already have dict_operation_lock locked in x-mode. Do not
|
||||
try to lock again in s-mode, because that would cause a hang.
|
||||
|
||||
TODO: keep track when trx exactly has the latch locked!!!
|
||||
TODO: trx->dict_operation tells it only in some cases!!! */
|
||||
|
||||
if (!trx->dict_operation) {
|
||||
rw_lock_s_lock(&dict_operation_lock);
|
||||
try to lock again in s-mode, because that would cause a hang. */
|
||||
|
||||
if (trx->dict_operation_lock_mode == 0) {
|
||||
|
||||
row_mysql_freeze_data_dictionary(trx);
|
||||
|
||||
froze_data_dict = TRUE;
|
||||
}
|
||||
|
||||
if (node->state == UNDO_NODE_INSERT) {
|
||||
@ -275,9 +277,9 @@ row_undo(
|
||||
err = row_undo_mod(node, thr);
|
||||
}
|
||||
|
||||
if (!trx->dict_operation) {
|
||||
if (froze_data_dict) {
|
||||
|
||||
rw_lock_s_unlock(&dict_operation_lock);
|
||||
row_mysql_unfreeze_data_dictionary(trx);
|
||||
}
|
||||
|
||||
/* Do some cleanup */
|
||||
|
@ -89,14 +89,16 @@ row_upd_index_is_referenced(
|
||||
{
|
||||
dict_table_t* table = index->table;
|
||||
dict_foreign_t* foreign;
|
||||
ibool froze_data_dict = FALSE;
|
||||
|
||||
if (!UT_LIST_GET_FIRST(table->referenced_list)) {
|
||||
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
if (!trx->has_dict_operation_lock) {
|
||||
rw_lock_s_lock(&dict_operation_lock);
|
||||
if (trx->dict_operation_lock_mode == 0) {
|
||||
row_mysql_freeze_data_dictionary(trx);
|
||||
froze_data_dict = TRUE;
|
||||
}
|
||||
|
||||
foreign = UT_LIST_GET_FIRST(table->referenced_list);
|
||||
@ -104,8 +106,8 @@ row_upd_index_is_referenced(
|
||||
while (foreign) {
|
||||
if (foreign->referenced_index == index) {
|
||||
|
||||
if (!trx->has_dict_operation_lock) {
|
||||
rw_lock_s_unlock(&dict_operation_lock);
|
||||
if (froze_data_dict) {
|
||||
row_mysql_unfreeze_data_dictionary(trx);
|
||||
}
|
||||
|
||||
return(TRUE);
|
||||
@ -114,8 +116,8 @@ row_upd_index_is_referenced(
|
||||
foreign = UT_LIST_GET_NEXT(referenced_list, foreign);
|
||||
}
|
||||
|
||||
if (!trx->has_dict_operation_lock) {
|
||||
rw_lock_s_unlock(&dict_operation_lock);
|
||||
if (froze_data_dict) {
|
||||
row_mysql_unfreeze_data_dictionary(trx);
|
||||
}
|
||||
|
||||
return(FALSE);
|
||||
@ -162,12 +164,10 @@ row_upd_check_references_constraints(
|
||||
|
||||
mtr_start(mtr);
|
||||
|
||||
if (!trx->has_dict_operation_lock) {
|
||||
if (trx->dict_operation_lock_mode == 0) {
|
||||
got_s_lock = TRUE;
|
||||
|
||||
rw_lock_s_lock(&dict_operation_lock);
|
||||
|
||||
trx->has_dict_operation_lock = TRUE;
|
||||
row_mysql_freeze_data_dictionary(trx);
|
||||
}
|
||||
|
||||
foreign = UT_LIST_GET_FIRST(table->referenced_list);
|
||||
@ -211,10 +211,7 @@ row_upd_check_references_constraints(
|
||||
|
||||
if (err != DB_SUCCESS) {
|
||||
if (got_s_lock) {
|
||||
rw_lock_s_unlock(
|
||||
&dict_operation_lock);
|
||||
trx->has_dict_operation_lock
|
||||
= FALSE;
|
||||
row_mysql_unfreeze_data_dictionary(trx);
|
||||
}
|
||||
|
||||
mem_heap_free(heap);
|
||||
@ -227,8 +224,7 @@ row_upd_check_references_constraints(
|
||||
}
|
||||
|
||||
if (got_s_lock) {
|
||||
rw_lock_s_unlock(&dict_operation_lock);
|
||||
trx->has_dict_operation_lock = FALSE;
|
||||
row_mysql_unfreeze_data_dictionary(trx);
|
||||
}
|
||||
|
||||
mem_heap_free(heap);
|
||||
|
@ -51,6 +51,10 @@ Created 10/8/1995 Heikki Tuuri
|
||||
#include "srv0start.h"
|
||||
#include "row0mysql.h"
|
||||
|
||||
/* This is set to TRUE if the MySQL user has set it in MySQL; currently
|
||||
affects only FOREIGN KEY definition parsing */
|
||||
ibool srv_lower_case_table_names = FALSE;
|
||||
|
||||
/* Buffer which can be used in printing fatal error messages */
|
||||
char srv_fatal_errbuf[5000];
|
||||
|
||||
@ -2064,6 +2068,7 @@ srv_suspend_mysql_thread(
|
||||
os_event_t event;
|
||||
double wait_time;
|
||||
trx_t* trx;
|
||||
ibool had_dict_lock = FALSE;
|
||||
|
||||
ut_ad(!mutex_own(&kernel_mutex));
|
||||
|
||||
@ -2107,18 +2112,22 @@ srv_suspend_mysql_thread(
|
||||
srv_conc_force_exit_innodb(thr_get_trx(thr));
|
||||
|
||||
/* Release possible foreign key check latch */
|
||||
if (trx->has_dict_operation_lock) {
|
||||
if (trx->dict_operation_lock_mode == RW_S_LATCH) {
|
||||
|
||||
rw_lock_s_unlock(&dict_operation_lock);
|
||||
had_dict_lock = TRUE;
|
||||
|
||||
row_mysql_unfreeze_data_dictionary(trx);
|
||||
}
|
||||
|
||||
ut_a(trx->dict_operation_lock_mode == 0);
|
||||
|
||||
/* Wait for the release */
|
||||
|
||||
os_event_wait(event);
|
||||
|
||||
if (trx->has_dict_operation_lock) {
|
||||
if (had_dict_lock) {
|
||||
|
||||
rw_lock_s_lock(&dict_operation_lock);
|
||||
row_mysql_freeze_data_dictionary(trx);
|
||||
}
|
||||
|
||||
/* Return back inside InnoDB */
|
||||
|
@ -1380,7 +1380,7 @@ innobase_start_or_create_for_mysql(void)
|
||||
if (0 != os_fast_mutex_trylock(&srv_os_test_mutex)) {
|
||||
fprintf(stderr,
|
||||
"InnoDB: Error: pthread_mutex_trylock returns an unexpected value on\n"
|
||||
"InnoDB: success! Cannot continue.\n");
|
||||
"InnoDB: success! Cannot continue.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@ -1390,11 +1390,17 @@ innobase_start_or_create_for_mysql(void)
|
||||
|
||||
os_fast_mutex_unlock(&srv_os_test_mutex);
|
||||
|
||||
if (srv_print_verbose_log)
|
||||
{
|
||||
ut_print_timestamp(stderr);
|
||||
fprintf(stderr, " InnoDB: Started\n");
|
||||
if (srv_print_verbose_log) {
|
||||
ut_print_timestamp(stderr);
|
||||
fprintf(stderr, " InnoDB: Started\n");
|
||||
}
|
||||
|
||||
if (srv_force_recovery > 0) {
|
||||
fprintf(stderr,
|
||||
"InnoDB: !!! innodb_force_recovery is set to %lu !!!\n",
|
||||
srv_force_recovery);
|
||||
}
|
||||
|
||||
return((int) DB_SUCCESS);
|
||||
}
|
||||
|
||||
|
@ -254,7 +254,7 @@ loop:
|
||||
mutex_exit(&kernel_mutex);
|
||||
|
||||
if (trx->dict_operation) {
|
||||
mutex_enter(&(dict_sys->mutex));
|
||||
row_mysql_lock_data_dictionary(trx);
|
||||
}
|
||||
|
||||
que_run_threads(thr);
|
||||
@ -290,14 +290,14 @@ loop:
|
||||
fprintf(stderr,
|
||||
"InnoDB: Table found: dropping table %s in recovery\n", table->name);
|
||||
|
||||
err = row_drop_table_for_mysql(table->name, trx,
|
||||
TRUE);
|
||||
err = row_drop_table_for_mysql(table->name, trx);
|
||||
|
||||
ut_a(err == (int) DB_SUCCESS);
|
||||
}
|
||||
}
|
||||
|
||||
if (trx->dict_operation) {
|
||||
mutex_exit(&(dict_sys->mutex));
|
||||
row_mysql_unlock_data_dictionary(trx);
|
||||
}
|
||||
|
||||
fprintf(stderr, "InnoDB: Rolling back of trx id %lu %lu completed\n",
|
||||
|
@ -134,7 +134,7 @@ trx_create(
|
||||
trx->lock_heap = mem_heap_create_in_buffer(256);
|
||||
UT_LIST_INIT(trx->trx_locks);
|
||||
|
||||
trx->has_dict_operation_lock = FALSE;
|
||||
trx->dict_operation_lock_mode = 0;
|
||||
trx->has_search_latch = FALSE;
|
||||
trx->search_latch_timeout = BTR_SEA_TIMEOUT;
|
||||
|
||||
@ -261,6 +261,8 @@ trx_free(
|
||||
ut_a(!trx->has_search_latch);
|
||||
ut_a(!trx->auto_inc_lock);
|
||||
|
||||
ut_a(trx->dict_operation_lock_mode == 0);
|
||||
|
||||
if (trx->lock_heap) {
|
||||
mem_heap_free(trx->lock_heap);
|
||||
}
|
||||
|
@ -468,7 +468,7 @@ fi
|
||||
|
||||
MYSQL_TEST_ARGS="--no-defaults --socket=$MASTER_MYSOCK --database=$DB \
|
||||
--user=$DBUSER --password=$DBPASSWD --silent -v --skip-safemalloc \
|
||||
--tmpdir=$MYSQL_TMP_DIR"
|
||||
--tmpdir=$MYSQL_TMP_DIR --port=$MASTER_MYPORT"
|
||||
MYSQL_TEST_BIN=$MYSQL_TEST
|
||||
MYSQL_TEST="$MYSQL_TEST $MYSQL_TEST_ARGS"
|
||||
GDB_CLIENT_INIT=$MYSQL_TMP_DIR/gdbinit.client
|
||||
|
100
mysql-test/r/bdb_cache.result
Normal file
100
mysql-test/r/bdb_cache.result
Normal file
@ -0,0 +1,100 @@
|
||||
drop table if exists t1, t2, t3;
|
||||
flush status;
|
||||
set autocommit=0;
|
||||
create table t1 (a int not null) type=bdb;
|
||||
insert into t1 values (1),(2),(3);
|
||||
select * from t1;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 0
|
||||
drop table t1;
|
||||
commit;
|
||||
set autocommit=1;
|
||||
begin;
|
||||
create table t1 (a int not null) type=bdb;
|
||||
insert into t1 values (1),(2),(3);
|
||||
select * from t1;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 0
|
||||
drop table t1;
|
||||
commit;
|
||||
create table t1 (a int not null) type=bdb;
|
||||
create table t2 (a int not null) type=bdb;
|
||||
create table t3 (a int not null) type=bdb;
|
||||
insert into t1 values (1),(2);
|
||||
insert into t2 values (1),(2);
|
||||
insert into t3 values (1),(2);
|
||||
select * from t1;
|
||||
a
|
||||
1
|
||||
2
|
||||
select * from t2;
|
||||
a
|
||||
1
|
||||
2
|
||||
select * from t3;
|
||||
a
|
||||
1
|
||||
2
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 3
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 0
|
||||
begin;
|
||||
select * from t1;
|
||||
a
|
||||
1
|
||||
2
|
||||
select * from t2;
|
||||
a
|
||||
1
|
||||
2
|
||||
select * from t3;
|
||||
a
|
||||
1
|
||||
2
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 3
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 0
|
||||
insert into t1 values (3);
|
||||
insert into t2 values (3);
|
||||
insert into t1 values (4);
|
||||
select * from t1;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
select * from t2;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
select * from t3;
|
||||
a
|
||||
1
|
||||
2
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 3
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 0
|
||||
commit;
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 1
|
@ -46,20 +46,6 @@ select 3 ^ 11, 1 ^ 1, 1 ^ 0, 1 ^ NULL, NULL ^ 1;
|
||||
select 1 XOR 1, 1 XOR 0, 0 XOR 1, 0 XOR 0, NULL XOR 1, 1 XOR NULL, 0 XOR NULL;
|
||||
1 XOR 1 1 XOR 0 0 XOR 1 0 XOR 0 NULL XOR 1 1 XOR NULL 0 XOR NULL
|
||||
0 1 1 0 NULL NULL NULL
|
||||
drop table if exists t1,t2;
|
||||
CREATE TABLE t1 ( start datetime default NULL) TYPE=MyISAM;
|
||||
INSERT INTO t1 VALUES ('2002-10-21 00:00:00');
|
||||
INSERT INTO t1 VALUES ('2002-10-28 00:00:00');
|
||||
INSERT INTO t1 VALUES ('2002-11-04 00:00:00');
|
||||
CREATE TABLE t2 ( ctime1 timestamp(14) NOT NULL, ctime2 timestamp(14) NOT NULL) TYPE=MyISAM;
|
||||
INSERT INTO t2 VALUES (20021029165106,20021105164731);
|
||||
select * from t1, t2 where t1.start between t2.ctime1 and t2.ctime2;
|
||||
start ctime1 ctime2
|
||||
2002-11-04 00:00:00 20021029165106 20021105164731
|
||||
select * from t1, t2 where t1.start >= t2.ctime1 and t1.start <= t2.ctime2;
|
||||
start ctime1 ctime2
|
||||
2002-11-04 00:00:00 20021029165106 20021105164731
|
||||
drop table if exists t1,t2;
|
||||
select 5 between 0 and 10 between 0 and 1,(5 between 0 and 10) between 0 and 1;
|
||||
5 between 0 and 10 between 0 and 1 (5 between 0 and 10) between 0 and 1
|
||||
0 1
|
||||
|
@ -1,4 +1,4 @@
|
||||
drop table if exists t1,t2;
|
||||
drop table if exists t1,t2,t3;
|
||||
select from_days(to_days("960101")),to_days(960201)-to_days("19960101"),to_days(date_add(curdate(), interval 1 day))-to_days(curdate()),weekday("1997-11-29");
|
||||
from_days(to_days("960101")) to_days(960201)-to_days("19960101") to_days(date_add(curdate(), interval 1 day))-to_days(curdate()) weekday("1997-11-29")
|
||||
1996-01-01 31 1 5
|
||||
@ -372,3 +372,18 @@ select extract(MONTH FROM "0000-00-00"),extract(MONTH FROM d),extract(MONTH FROM
|
||||
extract(MONTH FROM "0000-00-00") extract(MONTH FROM d) extract(MONTH FROM dt) extract(MONTH FROM t) extract(MONTH FROM c)
|
||||
0 0 0 0 0
|
||||
drop table t1;
|
||||
CREATE TABLE t1 ( start datetime default NULL);
|
||||
INSERT INTO t1 VALUES ('2002-10-21 00:00:00'),('2002-10-28 00:00:00'),('2002-11-04 00:00:00');
|
||||
CREATE TABLE t2 ( ctime1 timestamp(14) NOT NULL, ctime2 timestamp(14) NOT NULL);
|
||||
INSERT INTO t2 VALUES (20021029165106,20021105164731);
|
||||
CREATE TABLE t3 (ctime1 char(19) NOT NULL, ctime2 char(19) NOT NULL);
|
||||
INSERT INTO t3 VALUES ("2002-10-29 16:51:06","2002-11-05 16:47:31");
|
||||
select * from t1, t2 where t1.start between t2.ctime1 and t2.ctime2;
|
||||
start ctime1 ctime2
|
||||
select * from t1, t2 where t1.start >= t2.ctime1 and t1.start <= t2.ctime2;
|
||||
start ctime1 ctime2
|
||||
2002-11-04 00:00:00 20021029165106 20021105164731
|
||||
select * from t1, t3 where t1.start between t3.ctime1 and t3.ctime2;
|
||||
start ctime1 ctime2
|
||||
2002-11-04 00:00:00 2002-10-29 16:51:06 2002-11-05 16:47:31
|
||||
drop table t1,t2,t3;
|
||||
|
1
mysql-test/t/bdb_cache-master.opt
Normal file
1
mysql-test/t/bdb_cache-master.opt
Normal file
@ -0,0 +1 @@
|
||||
--set-variable=query_cache_size=1M
|
50
mysql-test/t/bdb_cache.test
Normal file
50
mysql-test/t/bdb_cache.test
Normal file
@ -0,0 +1,50 @@
|
||||
-- source include/have_bdb.inc
|
||||
-- source include/have_query_cache.inc
|
||||
|
||||
#
|
||||
# Without auto_commit.
|
||||
#
|
||||
drop table if exists t1, t2, t3;
|
||||
flush status;
|
||||
set autocommit=0;
|
||||
create table t1 (a int not null) type=bdb;
|
||||
insert into t1 values (1),(2),(3);
|
||||
select * from t1;
|
||||
show status like "Qcache_queries_in_cache";
|
||||
drop table t1;
|
||||
commit;
|
||||
set autocommit=1;
|
||||
begin;
|
||||
create table t1 (a int not null) type=bdb;
|
||||
insert into t1 values (1),(2),(3);
|
||||
select * from t1;
|
||||
show status like "Qcache_queries_in_cache";
|
||||
drop table t1;
|
||||
commit;
|
||||
create table t1 (a int not null) type=bdb;
|
||||
create table t2 (a int not null) type=bdb;
|
||||
create table t3 (a int not null) type=bdb;
|
||||
insert into t1 values (1),(2);
|
||||
insert into t2 values (1),(2);
|
||||
insert into t3 values (1),(2);
|
||||
select * from t1;
|
||||
select * from t2;
|
||||
select * from t3;
|
||||
show status like "Qcache_queries_in_cache";
|
||||
show status like "Qcache_hits";
|
||||
begin;
|
||||
select * from t1;
|
||||
select * from t2;
|
||||
select * from t3;
|
||||
show status like "Qcache_queries_in_cache";
|
||||
show status like "Qcache_hits";
|
||||
insert into t1 values (3);
|
||||
insert into t2 values (3);
|
||||
insert into t1 values (4);
|
||||
select * from t1;
|
||||
select * from t2;
|
||||
select * from t3;
|
||||
show status like "Qcache_queries_in_cache";
|
||||
show status like "Qcache_hits";
|
||||
commit;
|
||||
show status like "Qcache_queries_in_cache";
|
@ -17,16 +17,6 @@ select 2 in (3,2,5,9,5,1),"monty" in ("david","monty","allan"), 1.2 in (1.4,1.2,
|
||||
select -1.49 or -1.49,0.6 or 0.6;
|
||||
select 3 ^ 11, 1 ^ 1, 1 ^ 0, 1 ^ NULL, NULL ^ 1;
|
||||
select 1 XOR 1, 1 XOR 0, 0 XOR 1, 0 XOR 0, NULL XOR 1, 1 XOR NULL, 0 XOR NULL;
|
||||
drop table if exists t1,t2;
|
||||
CREATE TABLE t1 ( start datetime default NULL) TYPE=MyISAM;
|
||||
INSERT INTO t1 VALUES ('2002-10-21 00:00:00');
|
||||
INSERT INTO t1 VALUES ('2002-10-28 00:00:00');
|
||||
INSERT INTO t1 VALUES ('2002-11-04 00:00:00');
|
||||
CREATE TABLE t2 ( ctime1 timestamp(14) NOT NULL, ctime2 timestamp(14) NOT NULL) TYPE=MyISAM;
|
||||
INSERT INTO t2 VALUES (20021029165106,20021105164731);
|
||||
select * from t1, t2 where t1.start between t2.ctime1 and t2.ctime2;
|
||||
select * from t1, t2 where t1.start >= t2.ctime1 and t1.start <= t2.ctime2;
|
||||
drop table if exists t1,t2;
|
||||
|
||||
#
|
||||
# Wrong usage of functions
|
||||
|
@ -1,7 +1,7 @@
|
||||
#
|
||||
# time functions
|
||||
#
|
||||
drop table if exists t1,t2;
|
||||
drop table if exists t1,t2,t3;
|
||||
|
||||
select from_days(to_days("960101")),to_days(960201)-to_days("19960101"),to_days(date_add(curdate(), interval 1 day))-to_days(curdate()),weekday("1997-11-29");
|
||||
select period_add("9602",-12),period_diff(199505,"9404") ;
|
||||
@ -160,3 +160,20 @@ select yearweek("0000-00-00"),yearweek(d),yearweek(dt),yearweek(t),yearweek(c) f
|
||||
select to_days("0000-00-00"),to_days(d),to_days(dt),to_days(t),to_days(c) from t1;
|
||||
select extract(MONTH FROM "0000-00-00"),extract(MONTH FROM d),extract(MONTH FROM dt),extract(MONTH FROM t),extract(MONTH FROM c) from t1;
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# Test problem with TIMESTAMP and BETWEEN
|
||||
#
|
||||
|
||||
CREATE TABLE t1 ( start datetime default NULL);
|
||||
INSERT INTO t1 VALUES ('2002-10-21 00:00:00'),('2002-10-28 00:00:00'),('2002-11-04 00:00:00');
|
||||
CREATE TABLE t2 ( ctime1 timestamp(14) NOT NULL, ctime2 timestamp(14) NOT NULL);
|
||||
INSERT INTO t2 VALUES (20021029165106,20021105164731);
|
||||
CREATE TABLE t3 (ctime1 char(19) NOT NULL, ctime2 char(19) NOT NULL);
|
||||
INSERT INTO t3 VALUES ("2002-10-29 16:51:06","2002-11-05 16:47:31");
|
||||
|
||||
# The following statement should be fixed to return a row in 4.1
|
||||
select * from t1, t2 where t1.start between t2.ctime1 and t2.ctime2;
|
||||
select * from t1, t2 where t1.start >= t2.ctime1 and t1.start <= t2.ctime2;
|
||||
select * from t1, t3 where t1.start between t3.ctime1 and t3.ctime2;
|
||||
drop table t1,t2,t3;
|
||||
|
@ -544,7 +544,6 @@ public:
|
||||
enum Item_result result_type () const { return field_length == 8 || field_length == 14 ? INT_RESULT : STRING_RESULT; }
|
||||
enum_field_types type() const { return FIELD_TYPE_TIMESTAMP;}
|
||||
enum ha_base_keytype key_type() const { return HA_KEYTYPE_ULONG_INT; }
|
||||
enum Item_result cmp_type () const { return INT_RESULT; }
|
||||
void store(const char *to,uint length);
|
||||
void store(double nr);
|
||||
void store(longlong nr);
|
||||
|
@ -1153,15 +1153,15 @@ ha_innobase::open(
|
||||
ib_table = dict_table_get_and_increment_handle_count(
|
||||
norm_name, NULL);
|
||||
if (NULL == ib_table) {
|
||||
|
||||
sql_print_error("InnoDB error:\n\
|
||||
Cannot find table %s from the internal data dictionary\n\
|
||||
of InnoDB though the .frm file for the table exists. Maybe you\n\
|
||||
have deleted and recreated InnoDB data files but have forgotten\n\
|
||||
to delete the corresponding .frm files of InnoDB tables, or you\n\
|
||||
have moved .frm files to another database?\n\
|
||||
Look from section 15.1 of http://www.innodb.com/ibman.html\n\
|
||||
how you can resolve the problem.\n",
|
||||
ut_print_timestamp(stderr);
|
||||
fprintf(stderr, " InnoDB error:\n"
|
||||
"Cannot find table %s from the internal data dictionary\n"
|
||||
"of InnoDB though the .frm file for the table exists. Maybe you\n"
|
||||
"have deleted and recreated InnoDB data files but have forgotten\n"
|
||||
"to delete the corresponding .frm files of InnoDB tables, or you\n"
|
||||
"have moved .frm files to another database?\n"
|
||||
"Look from section 15.1 of http://www.innodb.com/ibman.html\n"
|
||||
"how you can resolve the problem.\n",
|
||||
norm_name);
|
||||
|
||||
free_share(share);
|
||||
@ -2961,16 +2961,21 @@ ha_innobase::create(
|
||||
trx->check_unique_secondary = FALSE;
|
||||
}
|
||||
|
||||
if (lower_case_table_names) {
|
||||
srv_lower_case_table_names = TRUE;
|
||||
} else {
|
||||
srv_lower_case_table_names = FALSE;
|
||||
}
|
||||
|
||||
fn_format(name2, name, "", "",2); // Remove the .frm extension
|
||||
|
||||
normalize_table_name(norm_name, name2);
|
||||
|
||||
/* Latch the InnoDB data dictionary exclusive so that no deadlocks
|
||||
/* Latch the InnoDB data dictionary exclusively so that no deadlocks
|
||||
or lock waits can happen in it during a table create operation.
|
||||
(Drop table etc. do this latching in row0mysql.c.) */
|
||||
Drop table etc. do this latching in row0mysql.c. */
|
||||
|
||||
row_mysql_lock_data_dictionary();
|
||||
row_mysql_lock_data_dictionary(trx);
|
||||
|
||||
/* Create the table definition in InnoDB */
|
||||
|
||||
@ -2979,7 +2984,7 @@ ha_innobase::create(
|
||||
if (error) {
|
||||
innobase_commit_low(trx);
|
||||
|
||||
row_mysql_unlock_data_dictionary();
|
||||
row_mysql_unlock_data_dictionary(trx);
|
||||
|
||||
trx_free_for_mysql(trx);
|
||||
|
||||
@ -3009,7 +3014,7 @@ ha_innobase::create(
|
||||
if (error) {
|
||||
innobase_commit_low(trx);
|
||||
|
||||
row_mysql_unlock_data_dictionary();
|
||||
row_mysql_unlock_data_dictionary(trx);
|
||||
|
||||
trx_free_for_mysql(trx);
|
||||
|
||||
@ -3024,7 +3029,7 @@ ha_innobase::create(
|
||||
(uint) primary_key_no))) {
|
||||
innobase_commit_low(trx);
|
||||
|
||||
row_mysql_unlock_data_dictionary();
|
||||
row_mysql_unlock_data_dictionary(trx);
|
||||
|
||||
trx_free_for_mysql(trx);
|
||||
|
||||
@ -3040,7 +3045,7 @@ ha_innobase::create(
|
||||
|
||||
innobase_commit_low(trx);
|
||||
|
||||
row_mysql_unlock_data_dictionary();
|
||||
row_mysql_unlock_data_dictionary(trx);
|
||||
|
||||
trx_free_for_mysql(trx);
|
||||
|
||||
@ -3057,7 +3062,7 @@ ha_innobase::create(
|
||||
if (error) {
|
||||
innobase_commit_low(trx);
|
||||
|
||||
row_mysql_unlock_data_dictionary();
|
||||
row_mysql_unlock_data_dictionary(trx);
|
||||
|
||||
trx_free_for_mysql(trx);
|
||||
|
||||
@ -3066,7 +3071,7 @@ ha_innobase::create(
|
||||
|
||||
innobase_commit_low(trx);
|
||||
|
||||
row_mysql_unlock_data_dictionary();
|
||||
row_mysql_unlock_data_dictionary(trx);
|
||||
|
||||
/* Flush the log to reduce probability that the .frm files and
|
||||
the InnoDB data dictionary get out-of-sync if the user runs
|
||||
@ -3108,6 +3113,12 @@ ha_innobase::delete_table(
|
||||
|
||||
DBUG_ENTER("ha_innobase::delete_table");
|
||||
|
||||
if (lower_case_table_names) {
|
||||
srv_lower_case_table_names = TRUE;
|
||||
} else {
|
||||
srv_lower_case_table_names = FALSE;
|
||||
}
|
||||
|
||||
trx = trx_allocate_for_mysql();
|
||||
|
||||
name_len = strlen(name);
|
||||
@ -3121,7 +3132,7 @@ ha_innobase::delete_table(
|
||||
|
||||
/* Drop the table in InnoDB */
|
||||
|
||||
error = row_drop_table_for_mysql(norm_name, trx, FALSE);
|
||||
error = row_drop_table_for_mysql(norm_name, trx);
|
||||
|
||||
/* Flush the log to reduce probability that the .frm files and
|
||||
the InnoDB data dictionary get out-of-sync if the user runs
|
||||
@ -3218,6 +3229,12 @@ ha_innobase::rename_table(
|
||||
|
||||
DBUG_ENTER("ha_innobase::rename_table");
|
||||
|
||||
if (lower_case_table_names) {
|
||||
srv_lower_case_table_names = TRUE;
|
||||
} else {
|
||||
srv_lower_case_table_names = FALSE;
|
||||
}
|
||||
|
||||
trx = trx_allocate_for_mysql();
|
||||
|
||||
name_len1 = strlen(from);
|
||||
@ -3406,6 +3423,15 @@ ha_innobase::info(
|
||||
|
||||
DBUG_ENTER("info");
|
||||
|
||||
/* If we are forcing recovery at a high level, we will suppress
|
||||
statistics calculation on tables, because that may crash the
|
||||
server if an index is badly corrupted. */
|
||||
|
||||
if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE) {
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Warning: since it is not sure that MySQL calls external_lock
|
||||
before calling this function, the trx field in prebuilt can be
|
||||
obsolete! */
|
||||
|
@ -294,7 +294,8 @@ int ha_commit_trans(THD *thd, THD_TRANS* trans)
|
||||
error=1;
|
||||
}
|
||||
else
|
||||
transaction_commited= 1;
|
||||
if (!(thd->options & OPTION_BEGIN))
|
||||
transaction_commited= 1;
|
||||
trans->bdb_tid=0;
|
||||
}
|
||||
#endif
|
||||
|
@ -360,7 +360,6 @@ void Item_func_between::fix_length_and_dec()
|
||||
if (args[0]->type() == FIELD_ITEM)
|
||||
{
|
||||
Field *field=((Item_field*) args[0])->field;
|
||||
cmp_type=field->cmp_type();
|
||||
if (field->store_for_compare())
|
||||
{
|
||||
if (convert_constant_item(field,&args[1]))
|
||||
|
@ -74,7 +74,7 @@ extern HASH open_cache;
|
||||
|
||||
static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table,uint count,
|
||||
bool unlock, TABLE **write_locked);
|
||||
static int lock_external(TABLE **table,uint count);
|
||||
static int lock_external(THD *thd, TABLE **table,uint count);
|
||||
static int unlock_external(THD *thd, TABLE **table,uint count);
|
||||
static void print_lock_error(int error);
|
||||
|
||||
@ -110,7 +110,7 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd,TABLE **tables,uint count)
|
||||
}
|
||||
|
||||
thd->proc_info="System lock";
|
||||
if (lock_external(tables,count))
|
||||
if (lock_external(thd, tables, count))
|
||||
{
|
||||
my_free((gptr) sql_lock,MYF(0));
|
||||
sql_lock=0;
|
||||
@ -159,11 +159,10 @@ retry:
|
||||
}
|
||||
|
||||
|
||||
static int lock_external(TABLE **tables,uint count)
|
||||
static int lock_external(THD *thd, TABLE **tables, uint count)
|
||||
{
|
||||
reg1 uint i;
|
||||
int lock_type,error;
|
||||
THD *thd=current_thd;
|
||||
DBUG_ENTER("lock_external");
|
||||
|
||||
for (i=1 ; i <= count ; i++, tables++)
|
||||
|
@ -502,7 +502,9 @@ struct show_var_st init_vars[]= {
|
||||
{"skip_networking", (char*) &opt_disable_networking, SHOW_BOOL},
|
||||
{"skip_show_database", (char*) &opt_skip_show_db, SHOW_BOOL},
|
||||
{sys_slow_launch_time.name, (char*) &sys_slow_launch_time, SHOW_SYS},
|
||||
#ifdef HAVE_SYS_UN_H
|
||||
{"socket", (char*) &mysql_unix_port, SHOW_CHAR_PTR},
|
||||
#endif
|
||||
{sys_sort_buffer.name, (char*) &sys_sort_buffer, SHOW_SYS},
|
||||
{"sql_mode", (char*) &opt_sql_mode, SHOW_LONG},
|
||||
{"table_cache", (char*) &table_cache_size, SHOW_LONG},
|
||||
|
@ -1275,7 +1275,7 @@ static int open_unireg_entry(THD *thd, TABLE *entry, const char *db,
|
||||
int error;
|
||||
DBUG_ENTER("open_unireg_entry");
|
||||
|
||||
(void) sprintf(path,"%s/%s/%s",mysql_data_home,db,name);
|
||||
strxmov(path, mysql_data_home, "/", db, "/", name, NullS);
|
||||
if (openfrm(path,alias,
|
||||
(uint) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE | HA_GET_INDEX |
|
||||
HA_TRY_READ_ONLY),
|
||||
|
Loading…
x
Reference in New Issue
Block a user