Commit c661970d authored by marko's avatar marko

branches/zip: Merge 1937:2015 from trunk.

parent ddcf4f8d
......@@ -581,11 +581,13 @@ next_rec:
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 */
{
......@@ -608,6 +610,7 @@ dict_load_indexes(
ibool is_sys_table;
dulint id;
mtr_t mtr;
ulint error = DB_SUCCESS;
ut_ad(mutex_own(&(dict_sys->mutex)));
......@@ -676,7 +679,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"
......@@ -684,14 +698,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)) {
fputs("InnoDB: Error: trying to load index ",
stderr);
......@@ -701,18 +711,14 @@ dict_load_indexes(
fputs("\nInnoDB: but the first index"
" is not clustered!\n", stderr);
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 */
......@@ -729,10 +735,11 @@ next_rec:
btr_pcur_move_to_next_user_rec(&pcur, &mtr);
}
func_exit:
btr_pcur_close(&pcur);
mtr_commit(&mtr);
return(TRUE);
return(error);
}
/************************************************************************
......@@ -890,11 +897,20 @@ err_exit:
mem_heap_empty(heap);
dict_load_indexes(table, heap);
err = dict_load_indexes(table, heap);
#ifndef UNIV_HOTBACKUP
err = dict_load_foreigns(table->name, TRUE);
/* 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);
......
......@@ -2384,13 +2384,18 @@ ha_innobase::open(
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);
......@@ -3544,6 +3549,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
......@@ -3596,7 +3602,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 = err;
}
}
break;
}
......@@ -3829,7 +3839,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);
}
}
......@@ -7288,8 +7298,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;
......@@ -7346,9 +7356,9 @@ 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);
fprintf(stderr, " InnoDB error (%lu): Couldn't read "
"the max AUTOINC value from the index (%s).\n",
error, index->name);
mysql_error = 1;
}
......@@ -7432,7 +7442,16 @@ 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) {
ut_print_timestamp(stderr);
sql_print_error(" InnoDB Error %lu in "
"::innobase_get_auto_increment()",
error);
}
} while (*value == 0 && error == DB_SUCCESS);
return(error);
......@@ -7465,13 +7484,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;
}
......
......@@ -69,6 +69,11 @@ Created 5/24/1996 Heikki Tuuri
#define DB_PRIMARY_KEY_IS_NULL 48 /* a column in the PRIMARY KEY
was found to be NULL */
#define DB_UNSUPPORTED 49 /* 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
......
......@@ -329,20 +329,22 @@ typedef void* os_thread_ret_t;
# define UNIV_MEM_DESC(addr, size, b) VALGRIND_CREATE_BLOCK(addr, size, b)
# define UNIV_MEM_UNDESC(b) VALGRIND_DISCARD(b)
# define UNIV_MEM_ASSERT_RW(addr, size) do { \
const void* _p = (const void*) \
const void* _p = (const void*) (ulint) \
VALGRIND_CHECK_MEM_IS_DEFINED(addr, size); \
if (UNIV_LIKELY_NULL(_p)) \
fprintf(stderr, "%p[%u] undefined at %d\n", \
(const void*) (addr), (unsigned) (size), \
((const char*) _p) - ((const char*) (addr))); \
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*) \
const void* _p = (const void*) (ulint) \
VALGRIND_CHECK_MEM_IS_ADDRESSABLE(addr, size); \
if (UNIV_LIKELY_NULL(_p)) \
fprintf(stderr, "%p[%u] unwritable at %d\n", \
(const void*) (addr), (unsigned) (size), \
((const char*) _p) - ((const char*) (addr))); \
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)
......
--innodb_locks_unsafe_for_binlog=true --innodb_lock_wait_timeout=2
set session transaction isolation level read committed;
create table t1(a int not null) engine=innodb DEFAULT CHARSET=latin1;
insert into t1 values (1),(2),(3),(4),(5),(6),(7);
set autocommit=0;
select * from t1 where a=3 lock in share mode;
a
3
set session transaction isolation level read committed;
set autocommit=0;
update t1 set a=10 where a=5;
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
commit;
update t1 set a=10 where a=5;
select * from t1 where a=2 for update;
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
select * from t1 where a=2 limit 1 for update;
a
2
update t1 set a=11 where a=6;
update t1 set a=12 where a=2;
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
update t1 set a=13 where a=1;
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
commit;
update t1 set a=14 where a=1;
commit;
select * from t1;
a
14
2
3
4
10
11
7
drop table t1;
-- source include/not_embedded.inc
-- source include/have_innodb.inc
# basic tests of semi-consistent reads
connect (a,localhost,root,,);
connect (b,localhost,root,,);
connection a;
set session transaction isolation level read committed;
create table t1(a int not null) engine=innodb DEFAULT CHARSET=latin1;
insert into t1 values (1),(2),(3),(4),(5),(6),(7);
set autocommit=0;
# this should lock the entire table
select * from t1 where a=3 lock in share mode;
connection b;
set session transaction isolation level read committed;
set autocommit=0;
-- error ER_LOCK_WAIT_TIMEOUT
update t1 set a=10 where a=5;
connection a;
commit;
connection b;
update t1 set a=10 where a=5;
connection a;
-- error ER_LOCK_WAIT_TIMEOUT
select * from t1 where a=2 for update;
# this should lock the records (1),(2)
select * from t1 where a=2 limit 1 for update;
connection b;
update t1 set a=11 where a=6;
-- error ER_LOCK_WAIT_TIMEOUT
update t1 set a=12 where a=2;
-- error ER_LOCK_WAIT_TIMEOUT
update t1 set a=13 where a=1;
connection a;
commit;
connection b;
update t1 set a=14 where a=1;
commit;
connection a;
select * from t1;
drop table t1;
connection default;
disconnect a;
disconnect b;
......@@ -4079,6 +4079,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;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment