Below is the list of changes that have just been commited into a local
3.23. repository of heikki. When heikki does a push, they will be
propogaged to the main repository and within 24 hours after the push into
the public repository. For information on how to access
the public repository see
http://www.mysql.com/doc/I/n/Installing_source_tree.html
ChangeSet
1.1057 02/06/22 20:11:01 heikki@xxxxxxxxxxxxxxx +1 -0
ha_innobase.cc:
Merge 3.23.52
sql/ha_innobase.cc
1.75 02/06/22 20:10:52 heikki@xxxxxxxxxxxxxxx +149 -39
Merge 3.23.52
# This is a BitKeeper patch. What follows are the unified diffs for the
# set of deltas contained in the patch. The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User: heikki
# Host: hundin.mysql.fi
# Root: /home/heikki/mysql
--- 1.74/sql/ha_innobase.cc Wed May 29 14:00:10 2002
+++ 1.75/sql/ha_innobase.cc Sat Jun 22 20:10:52 2002
@@ -27,6 +27,7 @@
#endif
#include "mysql_priv.h"
+#include "slave.h"
#ifdef HAVE_INNOBASE_DB
#include <m_ctype.h>
#include <assert.h>
@@ -53,10 +54,12 @@
/* Include necessary InnoDB headers */
extern "C" {
#include "../innobase/include/univ.i"
+#include "../innobase/include/os0file.h"
#include "../innobase/include/srv0start.h"
#include "../innobase/include/srv0srv.h"
#include "../innobase/include/trx0roll.h"
#include "../innobase/include/trx0trx.h"
+#include "../innobase/include/trx0sys.h"
#include "../innobase/include/row0ins.h"
#include "../innobase/include/row0mysql.h"
#include "../innobase/include/row0sel.h"
@@ -180,7 +183,8 @@
convert_error_code_to_mysql(
/*========================*/
/* out: MySQL error code */
- int error) /* in: InnoDB error code */
+ int error, /* in: InnoDB error code */
+ THD* thd) /* in: user thread handle or NULL */
{
if (error == DB_SUCCESS) {
@@ -199,11 +203,27 @@
return(HA_ERR_NO_ACTIVE_RECORD);
} else if (error == (int) DB_DEADLOCK) {
+ /* Since we roll back the whole transaction, we must
+ tell it also to MySQL so that MySQL knows to empty the
+ cached binlog for this transaction */
+
+ if (thd) {
+ ha_rollback(thd);
+ }
return(HA_ERR_LOCK_DEADLOCK);
} else if (error == (int) DB_LOCK_WAIT_TIMEOUT) {
+ /* Since we roll back the whole transaction, we must
+ tell it also to MySQL so that MySQL knows to empty the
+ cached binlog for this transaction */
+
+
+ if (thd) {
+ ha_rollback(thd);
+ }
+
return(HA_ERR_LOCK_WAIT_TIMEOUT);
} else if (error == (int) DB_NO_REFERENCED_ROW) {
@@ -313,7 +333,23 @@
thd->transaction.stmt.innobase_tid =
(void*)&innodb_dummy_stmt_trx_handle;
} else {
- ut_a(trx->magic_n == TRX_MAGIC_N);
+ if (trx->magic_n != TRX_MAGIC_N) {
+ mem_analyze_corruption((byte*)trx);
+
+ ut_a(0);
+ }
+ }
+
+ if (thd->options & OPTION_NO_FOREIGN_KEY_CHECKS) {
+ trx->check_foreigns = FALSE;
+ } else {
+ trx->check_foreigns = TRUE;
+ }
+
+ if (thd->options & OPTION_RELAXED_UNIQUE_CHECKS) {
+ trx->check_unique_secondary = FALSE;
+ } else {
+ trx->check_unique_secondary = TRUE;
}
return(trx);
@@ -359,6 +395,8 @@
DBUG_ENTER("innobase_init");
+ os_innodb_umask = (ulint)my_umask;
+
if (specialflag & SPECIAL_NO_PRIOR) {
srv_set_thread_priorities = FALSE;
} else {
@@ -435,7 +473,7 @@
srv_log_archive_on = (ulint) innobase_log_archive;
srv_log_buffer_size = (ulint) innobase_log_buffer_size;
- srv_flush_log_at_trx_commit = (ibool) innobase_flush_log_at_trx_commit;
+ srv_flush_log_at_trx_commit = (ulint) innobase_flush_log_at_trx_commit;
srv_use_native_aio = 0;
@@ -470,6 +508,22 @@
(void) hash_init(&innobase_open_tables,32,0,0,
(hash_get_key) innobase_get_key,0,0);
pthread_mutex_init(&innobase_mutex,MY_MUTEX_INIT_FAST);
+
+ /* If this is a replication slave and we needed to do a crash recovery,
+ set the master binlog position to what InnoDB internally knew about
+ how far we got transactions durable inside InnoDB. There is a
+ problem here: if the user used also MyISAM tables, InnoDB might not
+ know the right position for them.
+
+ THIS DOES NOT WORK CURRENTLY because replication seems to initialize
+ glob_mi also after innobase_init. */
+
+/* if (trx_sys_mysql_master_log_pos != -1) {
+ ut_memcpy(glob_mi.log_file_name, trx_sys_mysql_master_log_name,
+ 1 + ut_strlen(trx_sys_mysql_master_log_name));
+ glob_mi.pos = trx_sys_mysql_master_log_pos;
+ }
+*/
DBUG_RETURN(0);
}
@@ -528,6 +582,17 @@
/*********************************************************************
Commits a transaction in an InnoDB database. */
+void
+innobase_commit_low(
+/*================*/
+ trx_t* trx) /* in: transaction handle */
+{
+ trx_commit_for_mysql(trx);
+}
+
+/*********************************************************************
+Commits a transaction in an InnoDB database. */
+
int
innobase_commit(
/*============*/
@@ -547,8 +612,21 @@
trx = check_trx_exists(thd);
if (trx_handle != (void*)&innodb_dummy_stmt_trx_handle) {
+ if (thd->slave_thread) {
- trx_commit_for_mysql(trx);
+ /* Update the replication position info inside
+ InnoDB. Note that we cannot presently do this for
+ CREATE TABLE etc. because MySQL does not tell us the
+ thd associated with those operations! */
+
+ trx->mysql_master_log_file_name =
+ glob_mi.log_file_name;
+ trx->mysql_master_log_pos = (ib_longlong)
+ (glob_mi.pos + glob_mi.event_len
+ + glob_mi.pending);
+ }
+
+ innobase_commit_low(trx);
}
/* Release possible statement level resources */
@@ -589,6 +667,8 @@
trx = (trx_t*)trx_handle;
+ ut_a(trx != NULL);
+
trx->mysql_log_file_name = log_file_name;
trx->mysql_log_offset = (ib_longlong)end_offset;
@@ -629,7 +709,7 @@
trx_mark_sql_stat_end(trx);
- DBUG_RETURN(convert_error_code_to_mysql(error));
+ DBUG_RETURN(convert_error_code_to_mysql(error, NULL));
}
/*********************************************************************
@@ -791,10 +871,9 @@
ib_table = dict_table_get_and_increment_handle_count(
norm_name, NULL);
-
if (NULL == ib_table) {
- fprintf(stderr,
+ fprintf(stderr,
"InnoDB: Error: cannot find table %s from the internal data dictionary\n"
"InnoDB: of InnoDB though the .frm file for the table exists. Maybe you\n"
"InnoDB: have deleted and recreated InnoDB data files but have forgotten\n"
@@ -846,6 +925,9 @@
auto_inc_counter_for_this_stat = 0;
+ block_size = 16 * 1024; /* Index block size in InnoDB: used by MySQL
+ in query optimization */
+
/* Init table lock structure */
thr_lock_data_init(&share->lock,&lock,(void*) 0);
@@ -1365,7 +1447,8 @@
if (error != DB_SUCCESS) {
- error = convert_error_code_to_mysql(error);
+ error = convert_error_code_to_mysql(error,
+ user_thd);
goto func_exit;
}
@@ -1381,7 +1464,7 @@
srv_conc_exit_innodb(prebuilt->trx);
error = convert_error_code_to_mysql(
- error);
+ error, user_thd);
goto func_exit;
}
}
@@ -1412,7 +1495,8 @@
if (error != DB_SUCCESS) {
- error = convert_error_code_to_mysql(error);
+ error = convert_error_code_to_mysql(error,
+ user_thd);
goto func_exit;
}
@@ -1452,7 +1536,7 @@
prebuilt->trx->ignore_duplicates_in_insert = FALSE;
- error = convert_error_code_to_mysql(error);
+ error = convert_error_code_to_mysql(error, user_thd);
/* Tell InnoDB server that there might be work for
utility threads: */
@@ -1669,7 +1753,7 @@
srv_conc_exit_innodb(prebuilt->trx);
- error = convert_error_code_to_mysql(error);
+ error = convert_error_code_to_mysql(error, user_thd);
/* Tell InnoDB server that there might be work for
utility threads: */
@@ -1714,7 +1798,7 @@
srv_conc_exit_innodb(prebuilt->trx);
- error = convert_error_code_to_mysql(error);
+ error = convert_error_code_to_mysql(error, user_thd);
/* Tell the InnoDB server that there might be work for
utility threads: */
@@ -1872,7 +1956,7 @@
error = HA_ERR_KEY_NOT_FOUND;
table->status = STATUS_NOT_FOUND;
} else {
- error = convert_error_code_to_mysql(ret);
+ error = convert_error_code_to_mysql(ret, user_thd);
table->status = STATUS_NOT_FOUND;
}
@@ -1891,7 +1975,7 @@
InnoDB */
{
row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
- KEY* key=0;
+ KEY* key;
statistic_increment(ha_read_key_count, &LOCK_status);
@@ -1912,10 +1996,9 @@
if (!prebuilt->index) {
fprintf(stderr,
"InnoDB: Could not find key n:o %u with name %s from dict cache\n"
- "InnoDB: for table %s\n", keynr, key ? key->name : "NULL",
- prebuilt->table->name);
+ "InnoDB: for table %s\n", keynr, key->name, prebuilt->table->name);
- DBUG_RETURN(1);
+ return(1);
}
assert(prebuilt->search_tuple);
@@ -1931,7 +2014,7 @@
build_template(prebuilt, user_thd, table, ROW_MYSQL_WHOLE_ROW);
- DBUG_RETURN(0);
+ return(0);
}
/**************************************************************************
@@ -1999,7 +2082,7 @@
error = HA_ERR_END_OF_FILE;
table->status = STATUS_NOT_FOUND;
} else {
- error = convert_error_code_to_mysql(ret);
+ error = convert_error_code_to_mysql(ret, user_thd);
table->status = STATUS_NOT_FOUND;
}
@@ -2301,7 +2384,7 @@
error = row_create_table_for_mysql(table, trx);
- error = convert_error_code_to_mysql(error);
+ error = convert_error_code_to_mysql(error, NULL);
DBUG_RETURN(error);
}
@@ -2358,7 +2441,7 @@
error = row_create_index_for_mysql(index, trx);
- error = convert_error_code_to_mysql(error);
+ error = convert_error_code_to_mysql(error, NULL);
DBUG_RETURN(error);
}
@@ -2384,7 +2467,7 @@
0, DICT_CLUSTERED, 0);
error = row_create_index_for_mysql(index, trx);
- error = convert_error_code_to_mysql(error);
+ error = convert_error_code_to_mysql(error, NULL);
return(error);
}
@@ -2414,19 +2497,36 @@
DBUG_ENTER("ha_innobase::create");
+ assert(current_thd != NULL);
+
trx = trx_allocate_for_mysql();
+ if (current_thd->options & OPTION_NO_FOREIGN_KEY_CHECKS) {
+ trx->check_foreigns = FALSE;
+ }
+
+ if (current_thd->options & OPTION_RELAXED_UNIQUE_CHECKS) {
+ trx->check_unique_secondary = FALSE;
+ }
+
fn_format(name2, name, "", "",2); // Remove the .frm extension
normalize_table_name(norm_name, name2);
- /* Create the table definition in InnoDB */
+ /* Latch the InnoDB data dictionary exclusive 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.) */
+
+ row_mysql_lock_data_dictionary();
+
+ /* Create the table definition in InnoDB */
error = create_table_def(trx, form, norm_name);
if (error) {
+ innobase_commit_low(trx);
- trx_commit_for_mysql(trx);
+ row_mysql_unlock_data_dictionary();
trx_free_for_mysql(trx);
@@ -2458,7 +2558,9 @@
error = create_clustered_index_when_no_primary(trx,
norm_name);
if (error) {
- trx_commit_for_mysql(trx);
+ innobase_commit_low(trx);
+
+ row_mysql_unlock_data_dictionary();
trx_free_for_mysql(trx);
@@ -2471,7 +2573,9 @@
first */
if ((error = create_index(trx, form, norm_name,
(uint) primary_key_no))) {
- trx_commit_for_mysql(trx);
+ innobase_commit_low(trx);
+
+ row_mysql_unlock_data_dictionary();
trx_free_for_mysql(trx);
@@ -2485,9 +2589,11 @@
if ((error = create_index(trx, form, norm_name, i))) {
- trx_commit_for_mysql(trx);
+ innobase_commit_low(trx);
+
+ row_mysql_unlock_data_dictionary();
- trx_free_for_mysql(trx);
+ trx_free_for_mysql(trx);
DBUG_RETURN(error);
}
@@ -2497,17 +2603,21 @@
error = row_table_add_foreign_constraints(trx,
create_info->create_statement, norm_name);
- error = convert_error_code_to_mysql(error);
+ error = convert_error_code_to_mysql(error, NULL);
if (error) {
- trx_commit_for_mysql(trx);
+ innobase_commit_low(trx);
+
+ row_mysql_unlock_data_dictionary();
trx_free_for_mysql(trx);
DBUG_RETURN(error);
}
- trx_commit_for_mysql(trx);
+ innobase_commit_low(trx);
+
+ row_mysql_unlock_data_dictionary();
/* Flush the log to reduce probability that the .frm files and
the InnoDB data dictionary get out-of-sync if the user runs
@@ -2575,11 +2685,11 @@
srv_active_wake_master_thread();
- trx_commit_for_mysql(trx);
+ innobase_commit_low(trx);
trx_free_for_mysql(trx);
- error = convert_error_code_to_mysql(error);
+ error = convert_error_code_to_mysql(error, NULL);
DBUG_RETURN(error);
}
@@ -2640,10 +2750,10 @@
srv_active_wake_master_thread();
- trx_commit_for_mysql(trx);
+ innobase_commit_low(trx);
trx_free_for_mysql(trx);
- error = convert_error_code_to_mysql(error);
+ error = convert_error_code_to_mysql(error, NULL);
return(error);
}
@@ -2693,10 +2803,10 @@
srv_active_wake_master_thread();
- trx_commit_for_mysql(trx);
+ innobase_commit_low(trx);
trx_free_for_mysql(trx);
- error = convert_error_code_to_mysql(error);
+ error = convert_error_code_to_mysql(error, NULL);
DBUG_RETURN(error);
}
@@ -2814,7 +2924,7 @@
estimate = 2 * data_file_length / dict_index_calc_min_rec_len(index);
- DBUG_RETURN((ha_rows) estimate);
+ return((ha_rows) estimate);
}
/*************************************************************************
---------------------------------------------------------------------
Before posting, please check:
http://www.mysql.com/manual.php (the manual)
http://lists.mysql.com/ (the list archive)
To request this thread, e-mail internals-thread3925@xxxxxxxxxxxxxxx
To unsubscribe, e-mail <internals-unsubscribe@xxxxxxxxxxxxxxx>
|