summaryrefslogtreecommitdiff
path: root/storage
diff options
context:
space:
mode:
Diffstat (limited to 'storage')
-rw-r--r--storage/innobase/buf/buf0lru.c2
-rw-r--r--storage/innobase/dict/dict0dict.c4
-rw-r--r--storage/innobase/dict/dict0load.c80
-rw-r--r--storage/innobase/handler/ha_innodb.cc125
-rw-r--r--storage/innobase/handler/ha_innodb.h14
-rw-r--r--storage/innobase/ibuf/ibuf0ibuf.c4
-rw-r--r--storage/innobase/include/db0err.h6
-rw-r--r--storage/innobase/include/ha_prototypes.h16
-rw-r--r--storage/innobase/include/mach0data.h11
-rw-r--r--storage/innobase/include/mach0data.ic37
-rw-r--r--storage/innobase/include/mem0dbg.h16
-rw-r--r--storage/innobase/include/mem0mem.ic16
-rw-r--r--storage/innobase/include/rem0rec.ic1
-rw-r--r--storage/innobase/include/row0mysql.h13
-rw-r--r--storage/innobase/include/sync0rw.h2
-rw-r--r--storage/innobase/include/univ.i28
-rw-r--r--storage/innobase/include/ut0ut.h18
-rw-r--r--storage/innobase/mem/mem0dbg.c40
-rw-r--r--storage/innobase/mem/mem0mem.c6
-rw-r--r--storage/innobase/row/row0mysql.c82
-rw-r--r--storage/innobase/row/row0sel.c76
-rw-r--r--storage/innobase/sync/sync0rw.c6
-rw-r--r--storage/innobase/sync/sync0sync.c2
-rw-r--r--storage/innobase/ut/ut0ut.c71
24 files changed, 445 insertions, 231 deletions
diff --git a/storage/innobase/buf/buf0lru.c b/storage/innobase/buf/buf0lru.c
index 7b49a7641af..f3913ed49b7 100644
--- a/storage/innobase/buf/buf0lru.c
+++ b/storage/innobase/buf/buf0lru.c
@@ -881,7 +881,7 @@ buf_LRU_block_free_non_file_page(
UT_LIST_ADD_FIRST(free, buf_pool->free, block);
block->in_free_list = TRUE;
- UNIV_MEM_FREE(block->frame, UNIV_PAGE_SIZE);
+ UNIV_MEM_ASSERT_AND_FREE(block->frame, UNIV_PAGE_SIZE);
if (srv_use_awe && block->frame) {
/* Add to the list of mapped pages */
diff --git a/storage/innobase/dict/dict0dict.c b/storage/innobase/dict/dict0dict.c
index 595dfb06ee5..368ff3c2bc2 100644
--- a/storage/innobase/dict/dict0dict.c
+++ b/storage/innobase/dict/dict0dict.c
@@ -441,6 +441,8 @@ dict_table_autoinc_initialize(
dict_table_t* table, /* in: table */
ib_longlong value) /* in: next value to assign to a row */
{
+ ut_ad(mutex_own(&table->autoinc_mutex));
+
table->autoinc_inited = TRUE;
table->autoinc = value;
}
@@ -457,6 +459,8 @@ dict_table_autoinc_read(
{
ib_longlong value;
+ ut_ad(mutex_own(&table->autoinc_mutex));
+
if (!table->autoinc_inited) {
value = 0;
diff --git a/storage/innobase/dict/dict0load.c b/storage/innobase/dict/dict0load.c
index 1ff1fd54cec..f594e64f517 100644
--- a/storage/innobase/dict/dict0load.c
+++ b/storage/innobase/dict/dict0load.c
@@ -551,11 +551,13 @@ dict_load_fields(
Loads definitions for table indexes. Adds them to the data dictionary
cache. */
static
-ibool
+ulint
dict_load_indexes(
/*==============*/
- /* out: TRUE if ok, FALSE if corruption
- of dictionary table */
+ /* out: DB_SUCCESS if ok, DB_CORRUPTION
+ if corruption of dictionary table or
+ DB_UNSUPPORTED if table has unknown index
+ type */
dict_table_t* table, /* in: table */
mem_heap_t* heap) /* in: memory heap for temporary storage */
{
@@ -578,6 +580,7 @@ dict_load_indexes(
ibool is_sys_table;
dulint id;
mtr_t mtr;
+ ulint error = DB_SUCCESS;
ut_ad(mutex_own(&(dict_sys->mutex)));
@@ -624,10 +627,8 @@ dict_load_indexes(
dict_load_report_deleted_index(table->name,
ULINT_UNDEFINED);
- btr_pcur_close(&pcur);
- mtr_commit(&mtr);
-
- return(FALSE);
+ error = DB_CORRUPTION;
+ goto func_exit;
}
field = rec_get_nth_field_old(rec, 1, &len);
@@ -653,7 +654,18 @@ dict_load_indexes(
field = rec_get_nth_field_old(rec, 8, &len);
page_no = mach_read_from_4(field);
- if (page_no == FIL_NULL) {
+ /* We check for unsupported types first, so that the
+ subsequent checks are relevant for the supported types. */
+ if (type & ~(DICT_CLUSTERED | DICT_UNIQUE)) {
+
+ fprintf(stderr,
+ "InnoDB: Error: unknown type %lu"
+ " of index %s of table %s\n",
+ (ulong) type, name_buf, table->name);
+
+ error = DB_UNSUPPORTED;
+ goto func_exit;
+ } else if (page_no == FIL_NULL) {
fprintf(stderr,
"InnoDB: Error: trying to load index %s"
@@ -661,14 +673,10 @@ dict_load_indexes(
"InnoDB: but the index tree has been freed!\n",
name_buf, table->name);
- btr_pcur_close(&pcur);
- mtr_commit(&mtr);
-
- return(FALSE);
- }
-
- if ((type & DICT_CLUSTERED) == 0
- && NULL == dict_table_get_first_index(table)) {
+ error = DB_CORRUPTION;
+ goto func_exit;
+ } else if ((type & DICT_CLUSTERED) == 0
+ && NULL == dict_table_get_first_index(table)) {
fprintf(stderr,
"InnoDB: Error: trying to load index %s"
@@ -677,18 +685,14 @@ dict_load_indexes(
" is not clustered!\n",
name_buf, table->name);
- btr_pcur_close(&pcur);
- mtr_commit(&mtr);
-
- return(FALSE);
- }
-
- if (is_sys_table
- && ((type & DICT_CLUSTERED)
- || ((table == dict_sys->sys_tables)
- && (name_len == (sizeof "ID_IND") - 1)
- && (0 == ut_memcmp(name_buf, "ID_IND",
- name_len))))) {
+ error = DB_CORRUPTION;
+ goto func_exit;
+ } else if (is_sys_table
+ && ((type & DICT_CLUSTERED)
+ || ((table == dict_sys->sys_tables)
+ && (name_len == (sizeof "ID_IND") - 1)
+ && (0 == ut_memcmp(name_buf,
+ "ID_IND", name_len))))) {
/* The index was created in memory already at booting
of the database server */
@@ -704,10 +708,11 @@ dict_load_indexes(
btr_pcur_move_to_next_user_rec(&pcur, &mtr);
}
+func_exit:
btr_pcur_close(&pcur);
mtr_commit(&mtr);
- return(TRUE);
+ return(error);
}
/************************************************************************
@@ -857,11 +862,20 @@ err_exit:
mem_heap_empty(heap);
- dict_load_indexes(table, heap);
-
- err = dict_load_foreigns(table->name, TRUE);
+ err = dict_load_indexes(table, heap);
+
+ /* If the force recovery flag is set, we open the table irrespective
+ of the error condition, since the user may want to dump data from the
+ clustered index. However we load the foreign key information only if
+ all indexes were loaded. */
+ if (err != DB_SUCCESS && !srv_force_recovery) {
+ dict_mem_table_free(table);
+ table = NULL;
+ } else if (err == DB_SUCCESS) {
+ err = dict_load_foreigns(table->name, TRUE);
+ }
#if 0
- if (err != DB_SUCCESS) {
+ if (err != DB_SUCCESS && table != NULL) {
mutex_enter(&dict_foreign_err_mutex);
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index 783553f5d87..f075fe6c3b4 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -129,6 +129,7 @@ static my_bool innobase_locks_unsafe_for_binlog = FALSE;
static my_bool innobase_rollback_on_timeout = FALSE;
static my_bool innobase_create_status_file = FALSE;
static my_bool innobase_stats_on_metadata = TRUE;
+static my_bool innobase_use_adaptive_hash_indexes = TRUE;
static char* internal_innobase_data_file_path = NULL;
@@ -1143,7 +1144,6 @@ innobase_query_caching_of_table_permitted(
}
if (trx->has_search_latch) {
- ut_print_timestamp(stderr);
sql_print_error("The calling thread is holding the adaptive "
"search, latch though calling "
"innobase_query_caching_of_table_permitted.");
@@ -1246,8 +1246,7 @@ innobase_invalidate_query_cache(
}
/*********************************************************************
-Display an SQL identifier.
-This definition must match the one in innobase/ut/ut0ut.c! */
+Display an SQL identifier. */
extern "C"
void
innobase_print_identifier(
@@ -1635,6 +1634,9 @@ innobase_init(
srv_stats_on_metadata = (ibool) innobase_stats_on_metadata;
+ srv_use_adaptive_hash_indexes =
+ (ibool) innobase_use_adaptive_hash_indexes;
+
srv_print_verbose_log = mysqld_embedded ? 0 : 1;
/* Store the default charset-collation number of this MySQL
@@ -2319,14 +2321,18 @@ ha_innobase::open(
ib_table = dict_table_get(norm_name, TRUE);
if (NULL == ib_table) {
- ut_print_timestamp(stderr);
- sql_print_error("Cannot find table %s from the internal data "
- "dictionary\nof InnoDB though the .frm file "
- "for the table exists. Maybe you\nhave "
- "deleted and recreated InnoDB data files but "
- "have forgotten\nto delete the corresponding "
- ".frm files of InnoDB tables, or you\n"
- "have moved .frm files to another database?\n"
+ sql_print_error("Cannot find or open table %s from\n"
+ "the internal data dictionary of InnoDB "
+ "though the .frm file for the\n"
+ "table exists. Maybe you have deleted and "
+ "recreated InnoDB data\n"
+ "files but have forgotten to delete the "
+ "corresponding .frm files\n"
+ "of InnoDB tables, or you have moved .frm "
+ "files to another database?\n"
+ "or, the table contains indexes that this "
+ "version of the engine\n"
+ "doesn't support.\n"
"See http://dev.mysql.com/doc/refman/5.1/en/innodb-troubleshooting.html\n"
"how you can resolve the problem.\n",
norm_name);
@@ -2338,7 +2344,6 @@ ha_innobase::open(
}
if (ib_table->ibd_file_missing && !thd_tablespace_op(thd)) {
- ut_print_timestamp(stderr);
sql_print_error("MySQL is trying to open a table handle but "
"the .ibd file for\ntable %s does not exist.\n"
"Have you deleted the .ibd file from the "
@@ -3412,7 +3417,7 @@ no_commit:
/*
ut_print_timestamp(stderr);
fprintf(stderr,
- " InnoDB error: ALTER TABLE is holding lock"
+ " InnoDB: ALTER TABLE is holding lock"
" on %lu tables!\n",
prebuilt->trx->mysql_n_tables_locked);
*/
@@ -3476,6 +3481,7 @@ no_commit:
/* Handle duplicate key errors */
if (auto_inc_used) {
+ ulint err;
ulonglong auto_inc;
/* Note the number of rows processed for this statement, used
@@ -3529,7 +3535,11 @@ set_max_autoinc:
ut_a(prebuilt->table->autoinc_increment > 0);
auto_inc += prebuilt->table->autoinc_increment;
- innobase_set_max_autoinc(auto_inc);
+ err = innobase_set_max_autoinc(auto_inc);
+
+ if (err != DB_SUCCESS) {
+ error = (int) err;
+ }
}
break;
}
@@ -3765,7 +3775,7 @@ ha_innobase::update_row(
if (auto_inc != 0) {
auto_inc += prebuilt->table->autoinc_increment;
- innobase_set_max_autoinc(auto_inc);
+ error = innobase_set_max_autoinc(auto_inc);
}
}
@@ -5710,7 +5720,6 @@ ha_innobase::info(
for (i = 0; i < table->s->keys; i++) {
if (index == NULL) {
- ut_print_timestamp(stderr);
sql_print_error("Table %s contains fewer "
"indexes inside InnoDB than "
"are defined in the MySQL "
@@ -5726,7 +5735,6 @@ ha_innobase::info(
for (j = 0; j < table->key_info[i].key_parts; j++) {
if (j + 1 > index->n_uniq) {
- ut_print_timestamp(stderr);
sql_print_error(
"Index %s of %s has %lu columns unique inside InnoDB, but MySQL is asking "
"statistics for %lu columns. Have you mixed up .frm files from different "
@@ -5791,7 +5799,6 @@ ha_innobase::info(
ret = innobase_read_and_init_auto_inc(&auto_inc);
if (ret != 0) {
- ut_print_timestamp(stderr);
sql_print_error("Cannot get table %s auto-inc"
"counter value in ::info\n",
ib_table->name);
@@ -6304,6 +6311,9 @@ ha_innobase::start_stmt(
innobase_release_stat_resources(trx);
+ /* Reset the AUTOINC statement level counter for multi-row INSERTs. */
+ trx->n_autoinc_rows = 0;
+
prebuilt->sql_stat_start = TRUE;
prebuilt->hint_need_to_fetch_extra_cols = 0;
reset_template(prebuilt);
@@ -6446,9 +6456,6 @@ ha_innobase::external_lock(
innobase_register_stmt(ht, thd);
}
- trx->n_mysql_tables_in_use++;
- prebuilt->mysql_has_locked = TRUE;
-
if (trx->isolation_level == TRX_ISO_SERIALIZABLE
&& prebuilt->select_lock_type == LOCK_NONE
&& thd_test_options(thd,
@@ -6497,6 +6504,9 @@ ha_innobase::external_lock(
trx->mysql_n_tables_locked++;
}
+ trx->n_mysql_tables_in_use++;
+ prebuilt->mysql_has_locked = TRUE;
+
DBUG_RETURN(0);
}
@@ -6562,14 +6572,17 @@ ha_innobase::transactional_table_lock(
if (prebuilt->table->ibd_file_missing && !thd_tablespace_op(thd)) {
ut_print_timestamp(stderr);
- fprintf(stderr, " InnoDB error:\n"
-"MySQL is trying to use a table handle but the .ibd file for\n"
-"table %s does not exist.\n"
-"Have you deleted the .ibd file from the database directory under\n"
-"the MySQL datadir?"
-"See http://dev.mysql.com/doc/refman/5.1/en/innodb-troubleshooting.html\n"
-"how you can resolve the problem.\n",
- prebuilt->table->name);
+ fprintf(stderr,
+ " InnoDB: MySQL is trying to use a table handle"
+ " but the .ibd file for\n"
+ "InnoDB: table %s does not exist.\n"
+ "InnoDB: Have you deleted the .ibd file"
+ " from the database directory under\n"
+ "InnoDB: the MySQL datadir?"
+ "InnoDB: See"
+ " http://dev.mysql.com/doc/refman/5.1/en/innodb-troubleshooting.html\n"
+ "InnoDB: how you can resolve the problem.\n",
+ prebuilt->table->name);
DBUG_RETURN(HA_ERR_CRASHED);
}
@@ -7120,8 +7133,8 @@ the value of the auto-inc counter. */
int
ha_innobase::innobase_read_and_init_auto_inc(
/*=========================================*/
- /* out: 0 or error code:
- deadlock or lock wait timeout */
+ /* out: 0 or generic MySQL
+ error code */
longlong* value) /* out: the autoinc value */
{
longlong auto_inc;
@@ -7178,9 +7191,10 @@ ha_innobase::innobase_read_and_init_auto_inc(
++auto_inc;
dict_table_autoinc_initialize(innodb_table, auto_inc);
} else {
- fprintf(stderr, " InnoDB error: Couldn't read the "
- "max AUTOINC value from index (%s).\n",
- index->name);
+ ut_print_timestamp(stderr);
+ fprintf(stderr, " InnoDB: Error: (%lu) Couldn't read "
+ "the max AUTOINC value from the index (%s).\n",
+ error, index->name);
mysql_error = 1;
}
@@ -7217,6 +7231,11 @@ ha_innobase::innobase_get_auto_increment(
{
ulong error;
+ *value = 0;
+
+ /* Note: If the table is not initialized when we attempt the
+ read below. We initialize the table's auto-inc counter and
+ always do a reread of the AUTOINC value. */
do {
error = innobase_autoinc_lock();
@@ -7256,7 +7275,15 @@ ha_innobase::innobase_get_auto_increment(
} else {
*value = (ulonglong) autoinc;
}
+ /* A deadlock error during normal processing is OK
+ and can be ignored. */
+ } else if (error != DB_DEADLOCK) {
+
+ sql_print_error("InnoDB: Error: %lu in "
+ "::innobase_get_auto_increment()",
+ error);
}
+
} while (*value == 0 && error == DB_SUCCESS);
return(error);
@@ -7272,7 +7299,7 @@ we have a table-level lock). offset, increment, nb_desired_values are ignored.
void
ha_innobase::get_auto_increment(
-/*=================================*/
+/*============================*/
ulonglong offset, /* in: */
ulonglong increment, /* in: table autoinc increment */
ulonglong nb_desired_values, /* in: number of values reqd */
@@ -7289,13 +7316,6 @@ ha_innobase::get_auto_increment(
error = innobase_get_auto_increment(&autoinc);
if (error != DB_SUCCESS) {
- /* This should never happen in the code > ver 5.0.6,
- since we call this function only after the counter
- has been initialized. */
-
- ut_print_timestamp(stderr);
- sql_print_error("Error %lu in ::get_auto_increment()", error);
-
*first_value = (~(ulonglong) 0);
return;
}
@@ -7310,6 +7330,11 @@ ha_innobase::get_auto_increment(
trx = prebuilt->trx;
+ /* Note: We can't rely on *first_value since some MySQL engines,
+ in particular the partition engine, don't initialize it to 0 when
+ invoking this method. So we are not sure if it's guaranteed to
+ be 0 or not. */
+
/* Called for the first time ? */
if (trx->n_autoinc_rows == 0) {
@@ -7318,16 +7343,16 @@ ha_innobase::get_auto_increment(
/* It's possible for nb_desired_values to be 0:
e.g., INSERT INTO T1(C) SELECT C FROM T2; */
if (nb_desired_values == 0) {
-
+
trx->n_autoinc_rows = 1;
}
-
+
set_if_bigger(*first_value, autoinc);
/* Not in the middle of a mult-row INSERT. */
} else if (prebuilt->last_value == 0) {
set_if_bigger(*first_value, autoinc);
}
-
+
*nb_reserved_values = trx->n_autoinc_rows;
/* With old style AUTOINC locking we only update the table's
@@ -7359,7 +7384,9 @@ ha_innobase::get_auto_increment(
/* See comment in handler.h */
int
-ha_innobase::reset_auto_increment(ulonglong value)
+ha_innobase::reset_auto_increment(
+/*==============================*/
+ ulonglong value) /* in: new value for table autoinc */
{
DBUG_ENTER("ha_innobase::reset_auto_increment");
@@ -7923,6 +7950,11 @@ static MYSQL_SYSVAR_BOOL(stats_on_metadata, innobase_stats_on_metadata,
"Enable statistics gathering for metadata commands such as SHOW TABLE STATUS (on by default)",
NULL, NULL, TRUE);
+static MYSQL_SYSVAR_BOOL(use_adaptive_hash_indexes, innobase_use_adaptive_hash_indexes,
+ PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_READONLY,
+ "Enable the InnoDB adaptive hash indexes (enabled by default)",
+ NULL, NULL, TRUE);
+
static MYSQL_SYSVAR_LONG(additional_mem_pool_size, innobase_additional_mem_pool_size,
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
"Size of a memory pool InnoDB uses to store data dictionary information and other internal data structures.",
@@ -8051,6 +8083,7 @@ static struct st_mysql_sys_var* innobase_system_variables[]= {
MYSQL_SYSVAR(open_files),
MYSQL_SYSVAR(rollback_on_timeout),
MYSQL_SYSVAR(stats_on_metadata),
+ MYSQL_SYSVAR(use_adaptive_hash_indexes),
MYSQL_SYSVAR(status_file),
MYSQL_SYSVAR(support_xa),
MYSQL_SYSVAR(sync_spin_loops),
diff --git a/storage/innobase/handler/ha_innodb.h b/storage/innobase/handler/ha_innodb.h
index fe5ebd57990..773884b6584 100644
--- a/storage/innobase/handler/ha_innodb.h
+++ b/storage/innobase/handler/ha_innodb.h
@@ -250,17 +250,3 @@ int thd_binlog_format(const MYSQL_THD thd);
*/
void thd_mark_transaction_to_rollback(MYSQL_THD thd, bool all);
}
-
-/*
- don't delete it - it may be re-enabled later
- as an optimization for the most common case InnoDB+binlog
-*/
-#if 0
-int innobase_report_binlog_offset_and_commit(
- THD* thd,
- void* trx_handle,
- char* log_file_name,
- my_off_t end_offset);
-int innobase_commit_complete(void* trx_handle);
-void innobase_store_binlog_offset_and_flush_log(char *binlog_name,longlong offset);
-#endif
diff --git a/storage/innobase/ibuf/ibuf0ibuf.c b/storage/innobase/ibuf/ibuf0ibuf.c
index 44972356304..126fd9fdd33 100644
--- a/storage/innobase/ibuf/ibuf0ibuf.c
+++ b/storage/innobase/ibuf/ibuf0ibuf.c
@@ -2900,7 +2900,7 @@ dump:
ut_print_timestamp(stderr);
fprintf(stderr,
- "InnoDB: Error: Insert buffer insert"
+ " InnoDB: Error: Insert buffer insert"
" fails; page free %lu,"
" dtuple size %lu\n",
(ulong) page_get_max_insert_size(
@@ -2925,7 +2925,7 @@ dump:
buf_frame_get_page_no(page),
IBUF_BITMAP_FREE, mtr);
- fprintf(stderr, "Bitmap bits %lu\n",
+ fprintf(stderr, "InnoDB: Bitmap bits %lu\n",
(ulong) old_bits);
fputs("InnoDB: Submit a detailed bug report"
diff --git a/storage/innobase/include/db0err.h b/storage/innobase/include/db0err.h
index 0aa1b87e470..ed7ce151718 100644
--- a/storage/innobase/include/db0err.h
+++ b/storage/innobase/include/db0err.h
@@ -61,12 +61,14 @@ Created 5/24/1996 Heikki Tuuri
activated by the operation would
lead to a duplicate key in some
table */
-
#define DB_TOO_MANY_CONCURRENT_TRXS 47 /* when InnoDB runs out of the
preconfigured undo slots, this can
only happen when there are too many
concurrent transactions */
-
+#define DB_UNSUPPORTED 48 /* when InnoDB sees any artefact or
+ a feature that it can't recoginize or
+ work with e.g., FT indexes created by
+ a later version of the engine. */
/* The following are partial failure codes */
#define DB_FAIL 1000
#define DB_OVERFLOW 1001
diff --git a/storage/innobase/include/ha_prototypes.h b/storage/innobase/include/ha_prototypes.h
index 7fb50988941..ef0722321af 100644
--- a/storage/innobase/include/ha_prototypes.h
+++ b/storage/innobase/include/ha_prototypes.h
@@ -1,6 +1,8 @@
#ifndef HA_INNODB_PROTOTYPES_H
#define HA_INNODB_PROTOTYPES_H
+#ifndef UNIV_HOTBACKUP
+
#include "univ.i" /* ulint, uint */
#include "m_ctype.h" /* CHARSET_INFO */
@@ -22,6 +24,19 @@ innobase_convert_string(
CHARSET_INFO* from_cs,
uint* errors);
+/*********************************************************************
+Display an SQL identifier. */
+
+void
+innobase_print_identifier(
+/*======================*/
+ FILE* f, /* in: output stream */
+ trx_t* trx, /* in: transaction */
+ ibool table_id,/* in: TRUE=print a table name,
+ FALSE=print other identifier */
+ const char* name, /* in: name to print */
+ ulint namelen);/* in: length of name */
+
/**********************************************************************
Returns true if the thread is the replication thread on the slave
server. Used in srv_conc_enter_innodb() to determine if the thread
@@ -49,3 +64,4 @@ thd_has_edited_nontrans_tables(
void* thd); /* in: thread handle (THD*) */
#endif
+#endif
diff --git a/storage/innobase/include/mach0data.h b/storage/innobase/include/mach0data.h
index 8377114a723..37d862cc678 100644
--- a/storage/innobase/include/mach0data.h
+++ b/storage/innobase/include/mach0data.h
@@ -327,6 +327,17 @@ mach_write_to_2_little_endian(
byte* dest, /* in: where to write */
ulint n); /* in: unsigned long int to write */
+/*************************************************************
+Convert integral type from storage byte order (big endian) to
+host byte order. */
+UNIV_INLINE
+void
+mach_read_int_type(
+/*===============*/
+ byte* dest, /* out: where to write */
+ const byte* src, /* in: where to read from */
+ ulint len, /* in: length of src */
+ ibool unsigned_type); /* in: signed or unsigned flag */
#ifndef UNIV_NONINL
#include "mach0data.ic"
#endif
diff --git a/storage/innobase/include/mach0data.ic b/storage/innobase/include/mach0data.ic
index 03ece7529a8..64fb87f56ed 100644
--- a/storage/innobase/include/mach0data.ic
+++ b/storage/innobase/include/mach0data.ic
@@ -7,6 +7,8 @@ to the machine format.
Created 11/28/1995 Heikki Tuuri
***********************************************************************/
+#include "ut0mem.h"
+
/***********************************************************
The following function is used to store data in one byte. */
UNIV_INLINE
@@ -689,3 +691,38 @@ mach_write_to_2_little_endian(
*dest = (byte)(n & 0xFFUL);
}
+
+/*************************************************************
+Convert integral type from storage byte order (big endian) to
+host byte order. */
+UNIV_INLINE
+void
+mach_read_int_type(
+/*===============*/
+ byte* dest, /* out: where to write */
+ const byte* src, /* in: where to read from */
+ ulint len, /* in: length of src */
+ ibool unsigned_type) /* in: signed or unsigned flag */
+{
+#ifdef WORDS_BIGENDIAN
+ memcpy(dest, src, len);
+
+ if (!unsigned_type) {
+ dest[0] ^= 128;
+ }
+#else
+ byte* ptr;
+
+ /* Convert integer data from Innobase to a little-endian format,
+ sign bit restored to normal. */
+
+ for (ptr = dest + len; ptr != dest; ++src) {
+ --ptr;
+ *ptr = *src;
+ }
+
+ if (!unsigned_type) {
+ dest[len - 1] ^= 128;
+ }
+#endif
+}
diff --git a/storage/innobase/include/mem0dbg.h b/storage/innobase/include/mem0dbg.h
index 36cd7a89565..2393e4edb54 100644
--- a/storage/innobase/include/mem0dbg.h
+++ b/storage/innobase/include/mem0dbg.h
@@ -60,6 +60,14 @@ mem_heap_validate_or_print(
ulint* n_blocks); /* out: number of blocks in the heap,
if a NULL pointer is passed as this
argument, it is ignored */
+/******************************************************************
+Validates the contents of a memory heap. */
+
+ibool
+mem_heap_validate(
+/*==============*/
+ /* out: TRUE if ok */
+ mem_heap_t* heap); /* in: memory heap */
#endif /* UNIV_MEM_DEBUG || UNIV_DEBUG */
#ifdef UNIV_DEBUG
/******************************************************************
@@ -71,14 +79,6 @@ mem_heap_check(
/* out: TRUE if ok */
mem_heap_t* heap); /* in: memory heap */
#endif /* UNIV_DEBUG */
-/******************************************************************
-Validates the contents of a memory heap. */
-
-ibool
-mem_heap_validate(
-/*==============*/
- /* out: TRUE if ok */
- mem_heap_t* heap); /* in: memory heap */
#ifdef UNIV_MEM_DEBUG
/*********************************************************************
TRUE if no memory is currently allocated. */
diff --git a/storage/innobase/include/mem0mem.ic b/storage/innobase/include/mem0mem.ic
index adae9ad8a33..6227a27f277 100644
--- a/storage/innobase/include/mem0mem.ic
+++ b/storage/innobase/include/mem0mem.ic
@@ -271,19 +271,16 @@ mem_heap_free_heap_top(
ut_ad(mem_block_get_start(block) <= mem_block_get_free(block));
/* In the debug version erase block from top up */
- {
- ulint len = (byte*)block + block->len - old_top;
- mem_erase_buf(old_top, len);
- UNIV_MEM_FREE(old_top, len);
- }
+ mem_erase_buf(old_top, (byte*)block + block->len - old_top);
/* Update allocated memory count */
mutex_enter(&mem_hash_mutex);
mem_current_allocated_memory -= (total_size - size);
mutex_exit(&mem_hash_mutex);
#else /* UNIV_MEM_DEBUG */
- UNIV_MEM_FREE(old_top, (byte*)block + block->len - old_top);
+ UNIV_MEM_ASSERT_W(old_top, (byte*)block + block->len - old_top);
#endif /* UNIV_MEM_DEBUG */
+ UNIV_MEM_ALLOC(old_top, (byte*)block + block->len - old_top);
/* If free == start, we may free the block if it is not the first
one */
@@ -363,6 +360,7 @@ mem_heap_free_top(
/* Subtract the free field of block */
mem_block_set_free(block, mem_block_get_free(block)
- MEM_SPACE_NEEDED(n));
+ UNIV_MEM_ASSERT_W((byte*) block + mem_block_get_free(block), n);
#ifdef UNIV_MEM_DEBUG
ut_ad(mem_block_get_start(block) <= mem_block_get_free(block));
@@ -378,7 +376,11 @@ mem_heap_free_top(
== mem_block_get_start(block))) {
mem_heap_block_free(heap, block);
} else {
- UNIV_MEM_FREE((byte*) block + mem_block_get_free(block), n);
+ /* Avoid a bogus UNIV_MEM_ASSERT_W() warning in a
+ subsequent invocation of mem_heap_free_top().
+ Originally, this was UNIV_MEM_FREE(), to catch writes
+ to freed memory. */
+ UNIV_MEM_ALLOC((byte*) block + mem_block_get_free(block), n);
}
}
diff --git a/storage/innobase/include/rem0rec.ic b/storage/innobase/include/rem0rec.ic
index 95aa65fabba..5a4a0a0b5df 100644
--- a/storage/innobase/include/rem0rec.ic
+++ b/storage/innobase/include/rem0rec.ic
@@ -801,6 +801,7 @@ rec_offs_set_n_alloc(
{
ut_ad(offsets);
ut_ad(n_alloc > 0);
+ UNIV_MEM_ASSERT_AND_ALLOC(offsets, n_alloc * sizeof *offsets);
offsets[0] = n_alloc;
}
diff --git a/storage/innobase/include/row0mysql.h b/storage/innobase/include/row0mysql.h
index aabb7f5f047..fd7ec8918ee 100644
--- a/storage/innobase/include/row0mysql.h
+++ b/storage/innobase/include/row0mysql.h
@@ -319,9 +319,11 @@ 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
-printing of monitor output by the master thread. */
+Drops a table for MySQL. If the name of the table ends in
+one of "innodb_monitor", "innodb_lock_monitor", "innodb_tablespace_monitor",
+"innodb_table_monitor", then this will also start the printing of monitor
+output by the master thread. If the table name ends in "innodb_mem_validate",
+InnoDB will try to invoke mem_validate(). */
int
row_create_table_for_mysql(
@@ -399,8 +401,9 @@ row_truncate_table_for_mysql(
dict_table_t* table, /* in: table handle */
trx_t* trx); /* in: transaction handle */
/*************************************************************************
-Drops a table for MySQL. If the name of the dropped table ends to
-characters INNODB_MONITOR, then this also stops printing of monitor
+Drops a table for MySQL. If the name of the dropped table ends in
+one of "innodb_monitor", "innodb_lock_monitor", "innodb_tablespace_monitor",
+"innodb_table_monitor", then this will also stop the printing of monitor
output by the master thread. */
int
diff --git a/storage/innobase/include/sync0rw.h b/storage/innobase/include/sync0rw.h
index abf04253141..7d2f63803d0 100644
--- a/storage/innobase/include/sync0rw.h
+++ b/storage/innobase/include/sync0rw.h
@@ -101,6 +101,7 @@ void
rw_lock_free(
/*=========*/
rw_lock_t* lock); /* in: rw-lock */
+#ifdef UNIV_DEBUG
/**********************************************************************
Checks that the rw-lock has been initialized and that there are no
simultaneous shared and exclusive locks. */
@@ -109,6 +110,7 @@ ibool
rw_lock_validate(
/*=============*/
rw_lock_t* lock);
+#endif /* UNIV_DEBUG */
/******************************************************************
NOTE! The following macros should be used in rw s-locking, not the
corresponding function. */
diff --git a/storage/innobase/include/univ.i b/storage/innobase/include/univ.i
index ba8e6e56219..8163ae16e4e 100644
--- a/storage/innobase/include/univ.i
+++ b/storage/innobase/include/univ.i
@@ -308,11 +308,39 @@ typedef void* os_thread_ret_t;
# define UNIV_MEM_INVALID(addr, size) VALGRIND_MAKE_MEM_UNDEFINED(addr, size)
# define UNIV_MEM_FREE(addr, size) VALGRIND_MAKE_MEM_NOACCESS(addr, size)
# define UNIV_MEM_ALLOC(addr, size) VALGRIND_MAKE_MEM_UNDEFINED(addr, size)
+# define UNIV_MEM_ASSERT_RW(addr, size) do { \
+ const void* _p = (const void*) (ulint) \
+ VALGRIND_CHECK_MEM_IS_DEFINED(addr, size); \
+ if (UNIV_LIKELY_NULL(_p)) \
+ fprintf(stderr, "%s:%d: %p[%u] undefined at %ld\n", \
+ __FILE__, __LINE__, \
+ (const void*) (addr), (unsigned) (size), (long) \
+ (((const char*) _p) - ((const char*) (addr)))); \
+ } while (0)
+# define UNIV_MEM_ASSERT_W(addr, size) do { \
+ const void* _p = (const void*) (ulint) \
+ VALGRIND_CHECK_MEM_IS_ADDRESSABLE(addr, size); \
+ if (UNIV_LIKELY_NULL(_p)) \
+ fprintf(stderr, "%s:%d: %p[%u] unwritable at %ld\n", \
+ __FILE__, __LINE__, \
+ (const void*) (addr), (unsigned) (size), (long) \
+ (((const char*) _p) - ((const char*) (addr)))); \
+ } while (0)
#else
# define UNIV_MEM_VALID(addr, size) do {} while(0)
# define UNIV_MEM_INVALID(addr, size) do {} while(0)
# define UNIV_MEM_FREE(addr, size) do {} while(0)
# define UNIV_MEM_ALLOC(addr, size) do {} while(0)
+# define UNIV_MEM_ASSERT_RW(addr, size) do {} while(0)
+# define UNIV_MEM_ASSERT_W(addr, size) do {} while(0)
#endif
+#define UNIV_MEM_ASSERT_AND_FREE(addr, size) do { \
+ UNIV_MEM_ASSERT_W(addr, size); \
+ UNIV_MEM_FREE(addr, size); \
+} while (0)
+#define UNIV_MEM_ASSERT_AND_ALLOC(addr, size) do { \
+ UNIV_MEM_ASSERT_W(addr, size); \
+ UNIV_MEM_ALLOC(addr, size); \
+} while (0)
#endif
diff --git a/storage/innobase/include/ut0ut.h b/storage/innobase/include/ut0ut.h
index 825c10d5f11..a60ce73c35a 100644
--- a/storage/innobase/include/ut0ut.h
+++ b/storage/innobase/include/ut0ut.h
@@ -263,6 +263,24 @@ ut_copy_file(
FILE* dest, /* in: output file */
FILE* src); /* in: input file to be appended to output */
+/**************************************************************************
+snprintf(). */
+
+#ifdef __WIN__
+int
+ut_snprintf(
+ /* out: number of characters that would
+ have been printed if the size were
+ unlimited, not including the terminating
+ '\0'. */
+ char* str, /* out: string */
+ size_t size, /* in: str size */
+ const char* fmt, /* in: format */
+ ...); /* in: format values */
+#else
+#define ut_snprintf snprintf
+#endif /* __WIN__ */
+
#ifndef UNIV_NONINL
#include "ut0ut.ic"
#endif
diff --git a/storage/innobase/mem/mem0dbg.c b/storage/innobase/mem/mem0dbg.c
index eb77dd01f6d..72452907c3f 100644
--- a/storage/innobase/mem/mem0dbg.c
+++ b/storage/innobase/mem/mem0dbg.c
@@ -223,6 +223,8 @@ mem_init_buf(
{
byte* ptr;
+ UNIV_MEM_ASSERT_W(buf, n);
+
for (ptr = buf; ptr < buf + n; ptr++) {
if (ut_rnd_gen_ibool()) {
@@ -231,6 +233,8 @@ mem_init_buf(
*ptr = 0xBE;
}
}
+
+ UNIV_MEM_INVALID(buf, n);
}
/*******************************************************************
@@ -245,6 +249,8 @@ mem_erase_buf(
{
byte* ptr;
+ UNIV_MEM_ASSERT_W(buf, n);
+
for (ptr = buf; ptr < buf + n; ptr++) {
if (ut_rnd_gen_ibool()) {
*ptr = 0xDE;
@@ -252,6 +258,8 @@ mem_erase_buf(
*ptr = 0xAD;
}
}
+
+ UNIV_MEM_FREE(buf, n);
}
/*******************************************************************
@@ -546,9 +554,7 @@ completed:
}
*error = FALSE;
}
-#endif /* UNIV_MEM_DEBUG || UNIV_DEBUG */
-#ifdef UNIV_DEBUG
/******************************************************************
Prints the contents of a memory heap. */
static
@@ -575,20 +581,6 @@ mem_heap_print(
}
/******************************************************************
-Checks that an object is a memory heap (or a block of it). */
-
-ibool
-mem_heap_check(
-/*===========*/
- /* out: TRUE if ok */
- mem_heap_t* heap) /* in: memory heap */
-{
- ut_a(heap->magic_n == MEM_BLOCK_MAGIC_N);
-
- return(TRUE);
-}
-
-/******************************************************************
Validates the contents of a memory heap. */
ibool
@@ -614,6 +606,22 @@ mem_heap_validate(
return(TRUE);
}
+#endif /* UNIV_MEM_DEBUG || UNIV_DEBUG */
+
+#ifdef UNIV_DEBUG
+/******************************************************************
+Checks that an object is a memory heap (or a block of it). */
+
+ibool
+mem_heap_check(
+/*===========*/
+ /* out: TRUE if ok */
+ mem_heap_t* heap) /* in: memory heap */
+{
+ ut_a(heap->magic_n == MEM_BLOCK_MAGIC_N);
+
+ return(TRUE);
+}
#endif /* UNIV_DEBUG */
#ifdef UNIV_MEM_DEBUG
diff --git a/storage/innobase/mem/mem0mem.c b/storage/innobase/mem/mem0mem.c
index d89a3a55d88..f4fd178a39c 100644
--- a/storage/innobase/mem/mem0mem.c
+++ b/storage/innobase/mem/mem0mem.c
@@ -512,9 +512,9 @@ mem_heap_block_free(
of hex 0xDE and 0xAD. */
mem_erase_buf((byte*)block, len);
-
-#endif
- UNIV_MEM_FREE(block, len);
+#else /* UNIV_MEM_DEBUG */
+ UNIV_MEM_ASSERT_AND_FREE(block, len);
+#endif /* UNIV_MEM_DEBUG */
if (init_block) {
/* Do not have to free: do nothing */
diff --git a/storage/innobase/row/row0mysql.c b/storage/innobase/row/row0mysql.c
index b8d201e3da2..b3cf20b78b8 100644
--- a/storage/innobase/row/row0mysql.c
+++ b/storage/innobase/row/row0mysql.c
@@ -1728,10 +1728,11 @@ row_mysql_unlock_data_dictionary(
}
/*************************************************************************
-Does a table creation operation for MySQL. If the name of the table
-to be created is equal with one of the predefined magic table names,
-then this also starts printing the corresponding monitor output by
-the master thread. */
+Drops a table for MySQL. If the name of the table ends in
+one of "innodb_monitor", "innodb_lock_monitor", "innodb_tablespace_monitor",
+"innodb_table_monitor", then this will also start the printing of monitor
+output by the master thread. If the table name ends in "innodb_mem_validate",
+InnoDB will try to invoke mem_validate(). */
int
row_create_table_for_mysql(
@@ -1756,13 +1757,11 @@ row_create_table_for_mysql(
ut_ad(trx->dict_operation_lock_mode == RW_X_LATCH);
if (srv_created_new_raw) {
- fputs("InnoDB: A new raw disk partition was initialized or\n"
- "InnoDB: innodb_force_recovery is on: we do not allow\n"
- "InnoDB: database modifications by the user. Shut down\n"
- "InnoDB: mysqld and edit my.cnf so that newraw"
- " is replaced\n"
- "InnoDB: with raw, and innodb_force_... is removed.\n",
- stderr);
+ fputs("InnoDB: A new raw disk partition was initialized:\n"
+ "InnoDB: we do not allow database modifications"
+ " by the user.\n"
+ "InnoDB: Shut down mysqld and edit my.cnf so that newraw"
+ " is replaced with raw.\n", stderr);
dict_mem_table_free(table);
trx_commit_for_mysql(trx);
@@ -2703,13 +2702,11 @@ row_truncate_table_for_mysql(
ut_ad(table);
if (srv_created_new_raw) {
- fputs("InnoDB: A new raw disk partition was initialized or\n"
- "InnoDB: innodb_force_recovery is on: we do not allow\n"
- "InnoDB: database modifications by the user. Shut down\n"
- "InnoDB: mysqld and edit my.cnf so that newraw"
- " is replaced\n"
- "InnoDB: with raw, and innodb_force_... is removed.\n",
- stderr);
+ fputs("InnoDB: A new raw disk partition was initialized:\n"
+ "InnoDB: we do not allow database modifications"
+ " by the user.\n"
+ "InnoDB: Shut down mysqld and edit my.cnf so that newraw"
+ " is replaced with raw.\n", stderr);
return(DB_ERROR);
}
@@ -2898,7 +2895,9 @@ next_rec:
/* MySQL calls ha_innobase::reset_auto_increment() which does
the same thing. */
+ dict_table_autoinc_lock(table);
dict_table_autoinc_initialize(table, 0);
+ dict_table_autoinc_unlock(table);
dict_update_statistics(table);
trx_commit_for_mysql(trx);
@@ -2916,9 +2915,10 @@ funct_exit:
#endif /* !UNIV_HOTBACKUP */
/*************************************************************************
-Drops a table for MySQL. If the name of the table to be dropped is equal
-with one of the predefined magic table names, then this also stops printing
-the corresponding monitor output by the master thread. */
+Drops a table for MySQL. If the name of the dropped table ends in
+one of "innodb_monitor", "innodb_lock_monitor", "innodb_tablespace_monitor",
+"innodb_table_monitor", then this will also stop the printing of monitor
+output by the master thread. */
int
row_drop_table_for_mysql(
@@ -2934,21 +2934,17 @@ row_drop_table_for_mysql(
ulint err;
const char* table_name;
ulint namelen;
- char* dir_path_of_temp_table = NULL;
- ibool success;
ibool locked_dictionary = FALSE;
pars_info_t* info = NULL;
ut_a(name != NULL);
if (srv_created_new_raw) {
- fputs("InnoDB: A new raw disk partition was initialized or\n"
- "InnoDB: innodb_force_recovery is on: we do not allow\n"
- "InnoDB: database modifications by the user. Shut down\n"
- "InnoDB: mysqld and edit my.cnf so that newraw"
- " is replaced\n"
- "InnoDB: with raw, and innodb_force_... is removed.\n",
- stderr);
+ fputs("InnoDB: A new raw disk partition was initialized:\n"
+ "InnoDB: we do not allow database modifications"
+ " by the user.\n"
+ "InnoDB: Shut down mysqld and edit my.cnf so that newraw"
+ " is replaced with raw.\n", stderr);
return(DB_ERROR);
}
@@ -3232,14 +3228,20 @@ check_next_foreign:
} else {
ibool is_path;
const char* name_or_path;
+ mem_heap_t* heap;
+ heap = mem_heap_create(200);
+
+ /* Clone the name, in case it has been allocated
+ from table->heap, which will be freed by
+ dict_table_remove_from_cache(table) below. */
+ name = mem_heap_strdup(heap, name);
space_id = table->space;
if (table->dir_path_of_temp_table != NULL) {
- dir_path_of_temp_table = mem_strdup(
- table->dir_path_of_temp_table);
is_path = TRUE;
- name_or_path = dir_path_of_temp_table;
+ name_or_path = mem_heap_strdup(
+ heap, table->dir_path_of_temp_table);
} else {
is_path = FALSE;
name_or_path = name;
@@ -3272,13 +3274,7 @@ check_next_foreign:
"InnoDB: of table ");
ut_print_name(stderr, trx, TRUE, name);
fprintf(stderr, ".\n");
-
- goto funct_exit;
- }
-
- success = fil_delete_tablespace(space_id);
-
- if (!success) {
+ } else if (!fil_delete_tablespace(space_id)) {
fprintf(stderr,
"InnoDB: We removed now the InnoDB"
" internal data dictionary entry\n"
@@ -3296,6 +3292,8 @@ check_next_foreign:
err = DB_ERROR;
}
}
+
+ mem_heap_free(heap);
}
funct_exit:
@@ -3305,10 +3303,6 @@ funct_exit:
row_mysql_unlock_data_dictionary(trx);
}
- if (dir_path_of_temp_table) {
- mem_free(dir_path_of_temp_table);
- }
-
trx->op_info = "";
#ifndef UNIV_HOTBACKUP
diff --git a/storage/innobase/row/row0sel.c b/storage/innobase/row/row0sel.c
index fdf6aa46351..29bded114e0 100644
--- a/storage/innobase/row/row0sel.c
+++ b/storage/innobase/row/row0sel.c
@@ -531,12 +531,13 @@ row_sel_build_prev_vers(
/*====================*/
/* out: DB_SUCCESS or error code */
read_view_t* read_view, /* in: read view */
- plan_t* plan, /* in: plan node for table */
+ dict_index_t* index, /* in: plan node for table */
rec_t* rec, /* in: record in a clustered index */
ulint** offsets, /* in/out: offsets returned by
rec_get_offsets(rec, plan->index) */
mem_heap_t** offset_heap, /* in/out: memory heap from which
the offsets are allocated */
+ mem_heap_t** old_vers_heap, /* out: old version heap to use */
rec_t** old_vers, /* out: old version, or NULL if the
record does not exist in the view:
i.e., it was freshly inserted
@@ -545,15 +546,15 @@ row_sel_build_prev_vers(
{
ulint err;
- if (plan->old_vers_heap) {
- mem_heap_empty(plan->old_vers_heap);
+ if (*old_vers_heap) {
+ mem_heap_empty(*old_vers_heap);
} else {
- plan->old_vers_heap = mem_heap_create(512);
+ *old_vers_heap = mem_heap_create(512);
}
err = row_vers_build_for_consistent_read(
- rec, mtr, plan->index, offsets, read_view, offset_heap,
- plan->old_vers_heap, old_vers);
+ rec, mtr, index, offsets, read_view, offset_heap,
+ *old_vers_heap, old_vers);
return(err);
}
@@ -765,9 +766,11 @@ row_sel_get_clust_rec(
if (!lock_clust_rec_cons_read_sees(clust_rec, index, offsets,
node->read_view)) {
- err = row_sel_build_prev_vers(node->read_view, plan,
- clust_rec, &offsets,
- &heap, &old_vers, mtr);
+ err = row_sel_build_prev_vers(
+ node->read_view, index, clust_rec,
+ &offsets, &heap, &plan->old_vers_heap,
+ &old_vers, mtr);
+
if (err != DB_SUCCESS) {
goto err_exit;
@@ -1490,10 +1493,11 @@ skip_lock:
if (!lock_clust_rec_cons_read_sees(rec, index, offsets,
node->read_view)) {
- err = row_sel_build_prev_vers(node->read_view,
- plan, rec,
- &offsets, &heap,
- &old_vers, &mtr);
+ err = row_sel_build_prev_vers(
+ node->read_view, index, rec,
+ &offsets, &heap, &plan->old_vers_heap,
+ &old_vers, &mtr);
+
if (err != DB_SUCCESS) {
goto lock_wait_or_error;
@@ -3999,6 +4003,7 @@ no_gap_lock:
mutex_enter(&kernel_mutex);
if (trx->was_chosen_as_deadlock_victim) {
mutex_exit(&kernel_mutex);
+ err = DB_DEADLOCK;
goto lock_wait_or_error;
}
@@ -4521,7 +4526,8 @@ row_search_check_if_query_cache_permitted(
}
/***********************************************************************
-Read the AUTOINC column from the current row. */
+Read the AUTOINC column from the current row. If the value is less than
+0 and the type is not unsigned then we reset the value to 0. */
static
ib_longlong
row_search_autoinc_read_column(
@@ -4536,6 +4542,7 @@ row_search_autoinc_read_column(
const byte* data;
ib_longlong value;
mem_heap_t* heap = NULL;
+ /* Our requirement is that dest should be word aligned. */
byte dest[sizeof(value)];
ulint offsets_[REC_OFFS_NORMAL_SIZE];
ulint* offsets = offsets_;
@@ -4554,26 +4561,43 @@ row_search_autoinc_read_column(
ut_a(len != UNIV_SQL_NULL);
ut_a(len <= sizeof value);
- /* Copy integer data and restore sign bit */
- if (unsigned_type || (data[0] & 128))
- memset(dest, 0x00, sizeof(dest));
- else
- memset(dest, 0xff, sizeof(dest));
+ mach_read_int_type(dest, data, len, unsigned_type);
+
+ /* The assumption here is that the AUTOINC value can't be negative
+ and that dest is word aligned. */
+ switch (len) {
+ case 8:
+ value = *(ib_longlong*) dest;
+ break;
+
+ case 4:
+ value = *(ib_uint32_t*) dest;
+ break;
- memcpy(dest + (sizeof(value) - len), data, len);
+ case 3:
+ value = *(ib_uint32_t*) dest;
+ value &= 0xFFFFFF;
+ break;
- if (!unsigned_type)
- dest[sizeof(value) - len] ^= 128;
+ case 2:
+ value = *(uint16 *) dest;
+ break;
- /* The assumption here is that the AUTOINC value can't be negative.*/
- value = (((ib_longlong) mach_read_from_4(dest)) << 32) |
- ((ib_longlong) mach_read_from_4(dest + 4));
+ case 1:
+ value = *dest;
+ break;
+
+ default:
+ ut_error;
+ }
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
- ut_a(value >= 0);
+ if (!unsigned_type && value < 0) {
+ value = 0;
+ }
return(value);
}
diff --git a/storage/innobase/sync/sync0rw.c b/storage/innobase/sync/sync0rw.c
index 4db780c8b3f..8dbc69816e9 100644
--- a/storage/innobase/sync/sync0rw.c
+++ b/storage/innobase/sync/sync0rw.c
@@ -174,9 +174,7 @@ rw_lock_free(
/*=========*/
rw_lock_t* lock) /* in: rw-lock */
{
-#ifdef UNIV_DEBUG
- ut_a(rw_lock_validate(lock));
-#endif /* UNIV_DEBUG */
+ ut_ad(rw_lock_validate(lock));
ut_a(rw_lock_get_writer(lock) == RW_LOCK_NOT_LOCKED);
ut_a(rw_lock_get_waiters(lock) == 0);
ut_a(rw_lock_get_reader_count(lock) == 0);
@@ -199,6 +197,7 @@ rw_lock_free(
mutex_exit(&rw_lock_list_mutex);
}
+#ifdef UNIV_DEBUG
/**********************************************************************
Checks that the rw-lock has been initialized and that there are no
simultaneous shared and exclusive locks. */
@@ -226,6 +225,7 @@ rw_lock_validate(
return(TRUE);
}
+#endif /* UNIV_DEBUG */
/**********************************************************************
Lock an rw-lock in shared mode for the current thread. If the rw-lock is
diff --git a/storage/innobase/sync/sync0sync.c b/storage/innobase/sync/sync0sync.c
index bf3f4d1ff20..39872f72204 100644
--- a/storage/innobase/sync/sync0sync.c
+++ b/storage/innobase/sync/sync0sync.c
@@ -830,7 +830,7 @@ sync_thread_levels_g(
mutex = slot->latch;
fprintf(stderr,
- "InnoDB error: sync levels should be"
+ "InnoDB: sync levels should be"
" > %lu but a level is %lu\n",
(ulong) limit, (ulong) slot->level);
diff --git a/storage/innobase/ut/ut0ut.c b/storage/innobase/ut/ut0ut.c
index 389063ad821..1ca278cd633 100644
--- a/storage/innobase/ut/ut0ut.c
+++ b/storage/innobase/ut/ut0ut.c
@@ -18,6 +18,7 @@ Created 5/11/1994 Heikki Tuuri
#include "ut0sort.h"
#include "trx0trx.h"
+#include "ha_prototypes.h"
ibool ut_always_false = FALSE;
@@ -70,22 +71,6 @@ ut_gettimeofday(
#define ut_gettimeofday gettimeofday
#endif
-#ifndef UNIV_HOTBACKUP
-/*********************************************************************
-Display an SQL identifier.
-This definition must match the one in sql/ha_innodb.cc! */
-extern
-void
-innobase_print_identifier(
-/*======================*/
- FILE* f, /* in: output stream */
- trx_t* trx, /* in: transaction */
- ibool table_id,/* in: TRUE=print a table name,
- FALSE=print other identifier */
- const char* name, /* in: name to print */
- ulint namelen);/* in: length of name */
-#endif /* !UNIV_HOTBACKUP */
-
/************************************************************
Gets the high 32 bits in a ulint. That is makes a shift >> 32,
but since there seem to be compiler bugs in both gcc and Visual C++,
@@ -360,6 +345,8 @@ ut_print_buf(
const byte* data;
ulint i;
+ UNIV_MEM_ASSERT_RW(buf, len);
+
fprintf(file, " len %lu; hex ", len);
for (data = (const byte*)buf, i = 0; i < len; i++) {
@@ -474,17 +461,20 @@ ut_print_namel(
#ifdef UNIV_HOTBACKUP
fwrite(name, 1, namelen, f);
#else
- char* slash = memchr(name, '/', namelen);
+ if (table_id) {
+ char* slash = memchr(name, '/', namelen);
+ if (!slash) {
- if (UNIV_LIKELY_NULL(slash)) {
- /* Print the database name and table name separately. */
- ut_ad(table_id);
+ goto no_db_name;
+ }
+ /* Print the database name and table name separately. */
innobase_print_identifier(f, trx, TRUE, name, slash - name);
putc('.', f);
innobase_print_identifier(f, trx, TRUE, slash + 1,
namelen - (slash - name) - 1);
} else {
+no_db_name:
innobase_print_identifier(f, trx, table_id, name, namelen);
}
#endif
@@ -515,3 +505,44 @@ ut_copy_file(
}
} while (len > 0);
}
+
+/**************************************************************************
+snprintf(). */
+
+#ifdef __WIN__
+#include <stdarg.h>
+int
+ut_snprintf(
+ /* out: number of characters that would
+ have been printed if the size were
+ unlimited, not including the terminating
+ '\0'. */
+ char* str, /* out: string */
+ size_t size, /* in: str size */
+ const char* fmt, /* in: format */
+ ...) /* in: format values */
+{
+ int res;
+ va_list ap1;
+ va_list ap2;
+
+ va_start(ap1, fmt);
+ va_start(ap2, fmt);
+
+ res = _vscprintf(fmt, ap1);
+ ut_a(res != -1);
+
+ if (size > 0) {
+ _vsnprintf(str, size, fmt, ap2);
+
+ if ((size_t) res >= size) {
+ str[size - 1] = '\0';
+ }
+ }
+
+ va_end(ap1);
+ va_end(ap2);
+
+ return(res);
+}
+#endif /* __WIN__ */