Merge innodb-5.1-ss6765 to 5.1-bugteam.
This commit is contained in:
commit
3fcb25d806
@ -1161,3 +1161,86 @@ t1 CREATE TABLE `t1` (
|
|||||||
PRIMARY KEY (`c1`)
|
PRIMARY KEY (`c1`)
|
||||||
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1
|
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
DROP TABLE IF EXISTS t1;
|
||||||
|
Warnings:
|
||||||
|
Note 1051 Unknown table 't1'
|
||||||
|
CREATE TABLE t1 (c1 INTEGER AUTO_INCREMENT, PRIMARY KEY (c1)) ENGINE=InnoDB;
|
||||||
|
INSERT INTO t1 VALUES (-685113344), (1), (NULL), (NULL);
|
||||||
|
SELECT * FROM t1;
|
||||||
|
c1
|
||||||
|
-685113344
|
||||||
|
1
|
||||||
|
2
|
||||||
|
3
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`c1` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
PRIMARY KEY (`c1`)
|
||||||
|
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=latin1
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 (c1 INTEGER AUTO_INCREMENT, PRIMARY KEY (c1)) ENGINE=InnoDB;
|
||||||
|
INSERT INTO t1 VALUES (-685113344), (2), (NULL), (NULL);
|
||||||
|
SELECT * FROM t1;
|
||||||
|
c1
|
||||||
|
-685113344
|
||||||
|
2
|
||||||
|
3
|
||||||
|
4
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`c1` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
PRIMARY KEY (`c1`)
|
||||||
|
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=latin1
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 (c1 INTEGER AUTO_INCREMENT, PRIMARY KEY (c1)) ENGINE=InnoDB;
|
||||||
|
INSERT INTO t1 VALUES (NULL), (2), (-685113344), (NULL);
|
||||||
|
INSERT INTO t1 VALUES (4), (5), (6), (NULL);
|
||||||
|
SELECT * FROM t1;
|
||||||
|
c1
|
||||||
|
-685113344
|
||||||
|
1
|
||||||
|
2
|
||||||
|
3
|
||||||
|
4
|
||||||
|
5
|
||||||
|
6
|
||||||
|
7
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`c1` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
PRIMARY KEY (`c1`)
|
||||||
|
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=latin1
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 (c1 INTEGER AUTO_INCREMENT, PRIMARY KEY (c1)) ENGINE=InnoDB;
|
||||||
|
INSERT INTO t1 VALUES (NULL), (2), (-685113344), (5);
|
||||||
|
SELECT * FROM t1;
|
||||||
|
c1
|
||||||
|
-685113344
|
||||||
|
1
|
||||||
|
2
|
||||||
|
5
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`c1` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
PRIMARY KEY (`c1`)
|
||||||
|
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=latin1
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 (c1 INTEGER AUTO_INCREMENT, PRIMARY KEY (c1)) ENGINE=InnoDB;
|
||||||
|
INSERT INTO t1 VALUES (1), (2), (-685113344), (NULL);
|
||||||
|
SELECT * FROM t1;
|
||||||
|
c1
|
||||||
|
-685113344
|
||||||
|
1
|
||||||
|
2
|
||||||
|
3
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`c1` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
PRIMARY KEY (`c1`)
|
||||||
|
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=latin1
|
||||||
|
DROP TABLE t1;
|
||||||
|
@ -631,3 +631,34 @@ REPLACE INTO t1 VALUES (-1);
|
|||||||
SELECT * FROM t1;
|
SELECT * FROM t1;
|
||||||
SHOW CREATE TABLE t1;
|
SHOW CREATE TABLE t1;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
##
|
||||||
|
# 49497: Error 1467 (ER_AUTOINC_READ_FAILED) on inserting a negative value
|
||||||
|
#
|
||||||
|
DROP TABLE IF EXISTS t1;
|
||||||
|
CREATE TABLE t1 (c1 INTEGER AUTO_INCREMENT, PRIMARY KEY (c1)) ENGINE=InnoDB;
|
||||||
|
INSERT INTO t1 VALUES (-685113344), (1), (NULL), (NULL);
|
||||||
|
SELECT * FROM t1;
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 (c1 INTEGER AUTO_INCREMENT, PRIMARY KEY (c1)) ENGINE=InnoDB;
|
||||||
|
INSERT INTO t1 VALUES (-685113344), (2), (NULL), (NULL);
|
||||||
|
SELECT * FROM t1;
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 (c1 INTEGER AUTO_INCREMENT, PRIMARY KEY (c1)) ENGINE=InnoDB;
|
||||||
|
INSERT INTO t1 VALUES (NULL), (2), (-685113344), (NULL);
|
||||||
|
INSERT INTO t1 VALUES (4), (5), (6), (NULL);
|
||||||
|
SELECT * FROM t1;
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 (c1 INTEGER AUTO_INCREMENT, PRIMARY KEY (c1)) ENGINE=InnoDB;
|
||||||
|
INSERT INTO t1 VALUES (NULL), (2), (-685113344), (5);
|
||||||
|
SELECT * FROM t1;
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 (c1 INTEGER AUTO_INCREMENT, PRIMARY KEY (c1)) ENGINE=InnoDB;
|
||||||
|
INSERT INTO t1 VALUES (1), (2), (-685113344), (NULL);
|
||||||
|
SELECT * FROM t1;
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
@ -224,6 +224,9 @@ in the free list to the frames.
|
|||||||
/* Value in microseconds */
|
/* Value in microseconds */
|
||||||
static const int WAIT_FOR_READ = 20000;
|
static const int WAIT_FOR_READ = 20000;
|
||||||
|
|
||||||
|
/* Number of attemtps made to read in a page in the buffer pool */
|
||||||
|
static const ulint BUF_PAGE_READ_MAX_RETRIES = 100;
|
||||||
|
|
||||||
buf_pool_t* buf_pool = NULL; /* The buffer buf_pool of the database */
|
buf_pool_t* buf_pool = NULL; /* The buffer buf_pool of the database */
|
||||||
|
|
||||||
#ifdef UNIV_DEBUG
|
#ifdef UNIV_DEBUG
|
||||||
@ -1160,6 +1163,7 @@ buf_page_get_gen(
|
|||||||
ulint fix_type;
|
ulint fix_type;
|
||||||
ibool success;
|
ibool success;
|
||||||
ibool must_read;
|
ibool must_read;
|
||||||
|
ulint retries = 0;
|
||||||
|
|
||||||
ut_ad(mtr);
|
ut_ad(mtr);
|
||||||
ut_ad((rw_latch == RW_S_LATCH)
|
ut_ad((rw_latch == RW_S_LATCH)
|
||||||
@ -1200,7 +1204,29 @@ loop:
|
|||||||
return(NULL);
|
return(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
buf_read_page(space, offset);
|
if (buf_read_page(space, offset)) {
|
||||||
|
retries = 0;
|
||||||
|
} else if (retries < BUF_PAGE_READ_MAX_RETRIES) {
|
||||||
|
++retries;
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "InnoDB: Error: Unable"
|
||||||
|
" to read tablespace %lu page no"
|
||||||
|
" %lu into the buffer pool after"
|
||||||
|
" %lu attempts\n"
|
||||||
|
"InnoDB: The most probable cause"
|
||||||
|
" of this error may be that the"
|
||||||
|
" table has been corrupted.\n"
|
||||||
|
"InnoDB: You can try to fix this"
|
||||||
|
" problem by using"
|
||||||
|
" innodb_force_recovery.\n"
|
||||||
|
"InnoDB: Please see reference manual"
|
||||||
|
" for more details.\n"
|
||||||
|
"InnoDB: Aborting...\n",
|
||||||
|
space, offset,
|
||||||
|
BUF_PAGE_READ_MAX_RETRIES);
|
||||||
|
|
||||||
|
ut_error;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef UNIV_DEBUG
|
#ifdef UNIV_DEBUG
|
||||||
buf_dbg_counter++;
|
buf_dbg_counter++;
|
||||||
|
@ -299,30 +299,27 @@ buffer buf_pool if it is not already there. Sets the io_fix flag and sets
|
|||||||
an exclusive lock on the buffer frame. The flag is cleared and the x-lock
|
an exclusive lock on the buffer frame. The flag is cleared and the x-lock
|
||||||
released by the i/o-handler thread. Does a random read-ahead if it seems
|
released by the i/o-handler thread. Does a random read-ahead if it seems
|
||||||
sensible. */
|
sensible. */
|
||||||
|
ibool
|
||||||
ulint
|
|
||||||
buf_read_page(
|
buf_read_page(
|
||||||
/*==========*/
|
/*==========*/
|
||||||
/* out: number of page read requests issued: this can
|
/* out: TRUE if success, FALSE otherwise */
|
||||||
be > 1 if read-ahead occurred */
|
|
||||||
ulint space, /* in: space id */
|
ulint space, /* in: space id */
|
||||||
ulint offset) /* in: page number */
|
ulint offset) /* in: page number */
|
||||||
{
|
{
|
||||||
ib_longlong tablespace_version;
|
ib_longlong tablespace_version;
|
||||||
ulint count;
|
ulint count;
|
||||||
ulint count2;
|
|
||||||
ulint err;
|
ulint err;
|
||||||
|
|
||||||
tablespace_version = fil_space_get_version(space);
|
tablespace_version = fil_space_get_version(space);
|
||||||
|
|
||||||
count = buf_read_ahead_random(space, offset);
|
buf_read_ahead_random(space, offset);
|
||||||
|
|
||||||
/* We do the i/o in the synchronous aio mode to save thread
|
/* We do the i/o in the synchronous aio mode to save thread
|
||||||
switches: hence TRUE */
|
switches: hence TRUE */
|
||||||
|
|
||||||
count2 = buf_read_page_low(&err, TRUE, BUF_READ_ANY_PAGE, space,
|
count = buf_read_page_low(&err, TRUE, BUF_READ_ANY_PAGE, space,
|
||||||
tablespace_version, offset);
|
tablespace_version, offset);
|
||||||
srv_buf_pool_reads+= count2;
|
srv_buf_pool_reads+= count;
|
||||||
if (err == DB_TABLESPACE_DELETED) {
|
if (err == DB_TABLESPACE_DELETED) {
|
||||||
ut_print_timestamp(stderr);
|
ut_print_timestamp(stderr);
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
@ -336,7 +333,7 @@ buf_read_page(
|
|||||||
/* Flush pages from the end of the LRU list if necessary */
|
/* Flush pages from the end of the LRU list if necessary */
|
||||||
buf_flush_free_margin();
|
buf_flush_free_margin();
|
||||||
|
|
||||||
return(count + count2);
|
return(count > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
|
@ -2652,9 +2652,9 @@ ha_innobase::innobase_initialize_autoinc()
|
|||||||
auto_inc = innobase_get_int_col_max_value(field);
|
auto_inc = innobase_get_int_col_max_value(field);
|
||||||
} else {
|
} else {
|
||||||
/* We have no idea what's been passed in to us as the
|
/* We have no idea what's been passed in to us as the
|
||||||
autoinc column. We set it to the MAX_INT of our table
|
autoinc column. We set it to the 0, effectively disabling
|
||||||
autoinc type. */
|
updates to the table. */
|
||||||
auto_inc = 0xFFFFFFFFFFFFFFFFULL;
|
auto_inc = 0;
|
||||||
|
|
||||||
ut_print_timestamp(stderr);
|
ut_print_timestamp(stderr);
|
||||||
fprintf(stderr, " InnoDB: Unable to determine the AUTOINC "
|
fprintf(stderr, " InnoDB: Unable to determine the AUTOINC "
|
||||||
@ -2663,7 +2663,7 @@ ha_innobase::innobase_initialize_autoinc()
|
|||||||
|
|
||||||
if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE) {
|
if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE) {
|
||||||
/* If the recovery level is set so high that writes
|
/* If the recovery level is set so high that writes
|
||||||
are disabled we force the AUTOINC counter to the MAX
|
are disabled we force the AUTOINC counter to 0
|
||||||
value effectively disabling writes to the table.
|
value effectively disabling writes to the table.
|
||||||
Secondly, we avoid reading the table in case the read
|
Secondly, we avoid reading the table in case the read
|
||||||
results in failure due to a corrupted table/index.
|
results in failure due to a corrupted table/index.
|
||||||
@ -2672,7 +2672,10 @@ ha_innobase::innobase_initialize_autoinc()
|
|||||||
tables can be dumped with minimal hassle. If an error
|
tables can be dumped with minimal hassle. If an error
|
||||||
were returned in this case, the first attempt to read
|
were returned in this case, the first attempt to read
|
||||||
the table would fail and subsequent SELECTs would succeed. */
|
the table would fail and subsequent SELECTs would succeed. */
|
||||||
|
auto_inc = 0;
|
||||||
} else if (field == NULL) {
|
} else if (field == NULL) {
|
||||||
|
/* This is a far more serious error, best to avoid
|
||||||
|
opening the table and return failure. */
|
||||||
my_error(ER_AUTOINC_READ_FAILED, MYF(0));
|
my_error(ER_AUTOINC_READ_FAILED, MYF(0));
|
||||||
} else {
|
} else {
|
||||||
dict_index_t* index;
|
dict_index_t* index;
|
||||||
@ -2701,7 +2704,7 @@ ha_innobase::innobase_initialize_autoinc()
|
|||||||
"InnoDB: Unable to find the AUTOINC column "
|
"InnoDB: Unable to find the AUTOINC column "
|
||||||
"%s in the InnoDB table %s.\n"
|
"%s in the InnoDB table %s.\n"
|
||||||
"InnoDB: We set the next AUTOINC column "
|
"InnoDB: We set the next AUTOINC column "
|
||||||
"value to the maximum possible value,\n"
|
"value to 0,\n"
|
||||||
"InnoDB: in effect disabling the AUTOINC "
|
"InnoDB: in effect disabling the AUTOINC "
|
||||||
"next value generation.\n"
|
"next value generation.\n"
|
||||||
"InnoDB: You can either set the next "
|
"InnoDB: You can either set the next "
|
||||||
@ -2710,7 +2713,13 @@ ha_innobase::innobase_initialize_autoinc()
|
|||||||
"recreating the table.\n",
|
"recreating the table.\n",
|
||||||
col_name, index->table->name);
|
col_name, index->table->name);
|
||||||
|
|
||||||
my_error(ER_AUTOINC_READ_FAILED, MYF(0));
|
/* This will disable the AUTOINC generation. */
|
||||||
|
auto_inc = 0;
|
||||||
|
|
||||||
|
/* We want the open to succeed, so that the user can
|
||||||
|
take corrective action. ie. reads should succeed but
|
||||||
|
updates should fail. */
|
||||||
|
err = DB_SUCCESS;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* row_search_max_autoinc() should only return
|
/* row_search_max_autoinc() should only return
|
||||||
@ -3968,11 +3977,17 @@ no_commit:
|
|||||||
prebuilt->autoinc_error = DB_SUCCESS;
|
prebuilt->autoinc_error = DB_SUCCESS;
|
||||||
|
|
||||||
if ((error = update_auto_increment())) {
|
if ((error = update_auto_increment())) {
|
||||||
|
|
||||||
/* We don't want to mask autoinc overflow errors. */
|
/* We don't want to mask autoinc overflow errors. */
|
||||||
if (prebuilt->autoinc_error != DB_SUCCESS) {
|
|
||||||
error = (int) prebuilt->autoinc_error;
|
|
||||||
|
|
||||||
|
/* Handle the case where the AUTOINC sub-system
|
||||||
|
failed during initialization. */
|
||||||
|
if (prebuilt->autoinc_error == DB_UNSUPPORTED) {
|
||||||
|
error_result = ER_AUTOINC_READ_FAILED;
|
||||||
|
/* Set the error message to report too. */
|
||||||
|
my_error(ER_AUTOINC_READ_FAILED, MYF(0));
|
||||||
|
goto func_exit;
|
||||||
|
} else if (prebuilt->autoinc_error != DB_SUCCESS) {
|
||||||
|
error = (int) prebuilt->autoinc_error;
|
||||||
goto report_error;
|
goto report_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -7883,7 +7898,10 @@ ha_innobase::innobase_get_autoinc(
|
|||||||
*value = dict_table_autoinc_read(prebuilt->table);
|
*value = dict_table_autoinc_read(prebuilt->table);
|
||||||
|
|
||||||
/* It should have been initialized during open. */
|
/* It should have been initialized during open. */
|
||||||
ut_a(*value != 0);
|
if (*value == 0) {
|
||||||
|
prebuilt->autoinc_error = DB_UNSUPPORTED;
|
||||||
|
dict_table_autoinc_unlock(prebuilt->table);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return(ulong(prebuilt->autoinc_error));
|
return(ulong(prebuilt->autoinc_error));
|
||||||
@ -7963,6 +7981,11 @@ ha_innobase::get_auto_increment(
|
|||||||
invoking this method. So we are not sure if it's guaranteed to
|
invoking this method. So we are not sure if it's guaranteed to
|
||||||
be 0 or not. */
|
be 0 or not. */
|
||||||
|
|
||||||
|
/* We need the upper limit of the col type to check for
|
||||||
|
whether we update the table autoinc counter or not. */
|
||||||
|
ulonglong col_max_value = innobase_get_int_col_max_value(
|
||||||
|
table->next_number_field);
|
||||||
|
|
||||||
/* Called for the first time ? */
|
/* Called for the first time ? */
|
||||||
if (trx->n_autoinc_rows == 0) {
|
if (trx->n_autoinc_rows == 0) {
|
||||||
|
|
||||||
@ -7979,6 +8002,11 @@ ha_innobase::get_auto_increment(
|
|||||||
/* Not in the middle of a mult-row INSERT. */
|
/* Not in the middle of a mult-row INSERT. */
|
||||||
} else if (prebuilt->autoinc_last_value == 0) {
|
} else if (prebuilt->autoinc_last_value == 0) {
|
||||||
set_if_bigger(*first_value, autoinc);
|
set_if_bigger(*first_value, autoinc);
|
||||||
|
/* Check for -ve values. */
|
||||||
|
} else if (*first_value > col_max_value && trx->n_autoinc_rows > 0) {
|
||||||
|
/* Set to next logical value. */
|
||||||
|
ut_a(autoinc > trx->n_autoinc_rows);
|
||||||
|
*first_value = (autoinc - trx->n_autoinc_rows) - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
*nb_reserved_values = trx->n_autoinc_rows;
|
*nb_reserved_values = trx->n_autoinc_rows;
|
||||||
@ -7989,12 +8017,6 @@ ha_innobase::get_auto_increment(
|
|||||||
ulonglong need;
|
ulonglong need;
|
||||||
ulonglong current;
|
ulonglong current;
|
||||||
ulonglong next_value;
|
ulonglong next_value;
|
||||||
ulonglong col_max_value;
|
|
||||||
|
|
||||||
/* We need the upper limit of the col type to check for
|
|
||||||
whether we update the table autoinc counter or not. */
|
|
||||||
col_max_value = innobase_get_int_col_max_value(
|
|
||||||
table->next_number_field);
|
|
||||||
|
|
||||||
current = *first_value > col_max_value ? autoinc : *first_value;
|
current = *first_value > col_max_value ? autoinc : *first_value;
|
||||||
need = *nb_reserved_values * increment;
|
need = *nb_reserved_values * increment;
|
||||||
|
@ -18,12 +18,10 @@ buffer buf_pool if it is not already there. Sets the io_fix flag and sets
|
|||||||
an exclusive lock on the buffer frame. The flag is cleared and the x-lock
|
an exclusive lock on the buffer frame. The flag is cleared and the x-lock
|
||||||
released by the i/o-handler thread. Does a random read-ahead if it seems
|
released by the i/o-handler thread. Does a random read-ahead if it seems
|
||||||
sensible. */
|
sensible. */
|
||||||
|
ibool
|
||||||
ulint
|
|
||||||
buf_read_page(
|
buf_read_page(
|
||||||
/*==========*/
|
/*==========*/
|
||||||
/* out: number of page read requests issued: this can
|
/* out: TRUE if success, FALSE otherwise */
|
||||||
be > 1 if read-ahead occurred */
|
|
||||||
ulint space, /* in: space id */
|
ulint space, /* in: space id */
|
||||||
ulint offset);/* in: page number */
|
ulint offset);/* in: page number */
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
|
@ -306,6 +306,7 @@ FILE* lock_latest_err_file;
|
|||||||
/* Flags for recursive deadlock search */
|
/* Flags for recursive deadlock search */
|
||||||
#define LOCK_VICTIM_IS_START 1
|
#define LOCK_VICTIM_IS_START 1
|
||||||
#define LOCK_VICTIM_IS_OTHER 2
|
#define LOCK_VICTIM_IS_OTHER 2
|
||||||
|
#define LOCK_EXCEED_MAX_DEPTH 3
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
Checks if a lock request results in a deadlock. */
|
Checks if a lock request results in a deadlock. */
|
||||||
@ -332,16 +333,18 @@ lock_deadlock_recursive(
|
|||||||
was found and we chose some other trx as a
|
was found and we chose some other trx as a
|
||||||
victim: we must do the search again in this
|
victim: we must do the search again in this
|
||||||
last case because there may be another
|
last case because there may be another
|
||||||
deadlock! */
|
deadlock!
|
||||||
|
LOCK_EXCEED_MAX_DEPTH if the lock search
|
||||||
|
exceeds max steps and/or max depth. */
|
||||||
trx_t* start, /* in: recursion starting point */
|
trx_t* start, /* in: recursion starting point */
|
||||||
trx_t* trx, /* in: a transaction waiting for a lock */
|
trx_t* trx, /* in: a transaction waiting for a lock */
|
||||||
lock_t* wait_lock, /* in: the lock trx is waiting to be granted */
|
lock_t* wait_lock, /* in: the lock trx is waiting to be granted */
|
||||||
ulint* cost, /* in/out: number of calculation steps thus
|
ulint* cost, /* in/out: number of calculation steps thus
|
||||||
far: if this exceeds LOCK_MAX_N_STEPS_...
|
far: if this exceeds LOCK_MAX_N_STEPS_...
|
||||||
we return LOCK_VICTIM_IS_START */
|
we return LOCK_EXCEED_MAX_DEPTH */
|
||||||
ulint depth); /* in: recursion depth: if this exceeds
|
ulint depth); /* in: recursion depth: if this exceeds
|
||||||
LOCK_MAX_DEPTH_IN_DEADLOCK_CHECK, we
|
LOCK_MAX_DEPTH_IN_DEADLOCK_CHECK, we
|
||||||
return LOCK_VICTIM_IS_START */
|
return LOCK_EXCEED_MAX_DEPTH */
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
Gets the nth bit of a record lock. */
|
Gets the nth bit of a record lock. */
|
||||||
@ -3084,8 +3087,6 @@ lock_deadlock_occurs(
|
|||||||
lock_t* lock, /* in: lock the transaction is requesting */
|
lock_t* lock, /* in: lock the transaction is requesting */
|
||||||
trx_t* trx) /* in: transaction */
|
trx_t* trx) /* in: transaction */
|
||||||
{
|
{
|
||||||
dict_table_t* table;
|
|
||||||
dict_index_t* index;
|
|
||||||
trx_t* mark_trx;
|
trx_t* mark_trx;
|
||||||
ulint ret;
|
ulint ret;
|
||||||
ulint cost = 0;
|
ulint cost = 0;
|
||||||
@ -3107,31 +3108,50 @@ retry:
|
|||||||
|
|
||||||
ret = lock_deadlock_recursive(trx, trx, lock, &cost, 0);
|
ret = lock_deadlock_recursive(trx, trx, lock, &cost, 0);
|
||||||
|
|
||||||
if (ret == LOCK_VICTIM_IS_OTHER) {
|
switch (ret) {
|
||||||
|
case LOCK_VICTIM_IS_OTHER:
|
||||||
/* We chose some other trx as a victim: retry if there still
|
/* We chose some other trx as a victim: retry if there still
|
||||||
is a deadlock */
|
is a deadlock */
|
||||||
|
|
||||||
goto retry;
|
goto retry;
|
||||||
}
|
|
||||||
|
|
||||||
if (ret == LOCK_VICTIM_IS_START) {
|
case LOCK_EXCEED_MAX_DEPTH:
|
||||||
if (lock_get_type(lock) & LOCK_TABLE) {
|
/* If the lock search exceeds the max step
|
||||||
table = lock->un_member.tab_lock.table;
|
or the max depth, the current trx will be
|
||||||
index = NULL;
|
the victim. Print its information. */
|
||||||
} else {
|
rewind(lock_latest_err_file);
|
||||||
index = lock->index;
|
ut_print_timestamp(lock_latest_err_file);
|
||||||
table = index->table;
|
|
||||||
}
|
|
||||||
|
|
||||||
lock_deadlock_found = TRUE;
|
fputs("TOO DEEP OR LONG SEARCH IN THE LOCK TABLE"
|
||||||
|
" WAITS-FOR GRAPH, WE WILL ROLL BACK"
|
||||||
fputs("*** WE ROLL BACK TRANSACTION (2)\n",
|
" FOLLOWING TRANSACTION \n",
|
||||||
lock_latest_err_file);
|
lock_latest_err_file);
|
||||||
|
|
||||||
return(TRUE);
|
fputs("\n*** TRANSACTION:\n", lock_latest_err_file);
|
||||||
|
trx_print(lock_latest_err_file, trx, 3000);
|
||||||
|
|
||||||
|
fputs("*** WAITING FOR THIS LOCK TO BE GRANTED:\n",
|
||||||
|
lock_latest_err_file);
|
||||||
|
|
||||||
|
if (lock_get_type(lock) == LOCK_REC) {
|
||||||
|
lock_rec_print(lock_latest_err_file, lock);
|
||||||
|
} else {
|
||||||
|
lock_table_print(lock_latest_err_file, lock);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LOCK_VICTIM_IS_START:
|
||||||
|
fputs("*** WE ROLL BACK TRANSACTION (2)\n",
|
||||||
|
lock_latest_err_file);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
/* No deadlock detected*/
|
||||||
|
return(FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
return(FALSE);
|
lock_deadlock_found = TRUE;
|
||||||
|
|
||||||
|
return(TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
@ -3147,16 +3167,18 @@ lock_deadlock_recursive(
|
|||||||
was found and we chose some other trx as a
|
was found and we chose some other trx as a
|
||||||
victim: we must do the search again in this
|
victim: we must do the search again in this
|
||||||
last case because there may be another
|
last case because there may be another
|
||||||
deadlock! */
|
deadlock!
|
||||||
|
LOCK_EXCEED_MAX_DEPTH if the lock search
|
||||||
|
exceeds max steps and/or max depth. */
|
||||||
trx_t* start, /* in: recursion starting point */
|
trx_t* start, /* in: recursion starting point */
|
||||||
trx_t* trx, /* in: a transaction waiting for a lock */
|
trx_t* trx, /* in: a transaction waiting for a lock */
|
||||||
lock_t* wait_lock, /* in: the lock trx is waiting to be granted */
|
lock_t* wait_lock, /* in: the lock trx is waiting to be granted */
|
||||||
ulint* cost, /* in/out: number of calculation steps thus
|
ulint* cost, /* in/out: number of calculation steps thus
|
||||||
far: if this exceeds LOCK_MAX_N_STEPS_...
|
far: if this exceeds LOCK_MAX_N_STEPS_...
|
||||||
we return LOCK_VICTIM_IS_START */
|
we return LOCK_EXCEED_MAX_DEPTH */
|
||||||
ulint depth) /* in: recursion depth: if this exceeds
|
ulint depth) /* in: recursion depth: if this exceeds
|
||||||
LOCK_MAX_DEPTH_IN_DEADLOCK_CHECK, we
|
LOCK_MAX_DEPTH_IN_DEADLOCK_CHECK, we
|
||||||
return LOCK_VICTIM_IS_START */
|
return LOCK_EXCEED_MAX_DEPTH */
|
||||||
{
|
{
|
||||||
lock_t* lock;
|
lock_t* lock;
|
||||||
ulint bit_no = ULINT_UNDEFINED;
|
ulint bit_no = ULINT_UNDEFINED;
|
||||||
@ -3215,7 +3237,7 @@ lock_deadlock_recursive(
|
|||||||
|
|
||||||
lock_trx = lock->trx;
|
lock_trx = lock->trx;
|
||||||
|
|
||||||
if (lock_trx == start || too_far) {
|
if (lock_trx == start) {
|
||||||
|
|
||||||
/* We came back to the recursion starting
|
/* We came back to the recursion starting
|
||||||
point: a deadlock detected; or we have
|
point: a deadlock detected; or we have
|
||||||
@ -3262,19 +3284,10 @@ lock_deadlock_recursive(
|
|||||||
}
|
}
|
||||||
#ifdef UNIV_DEBUG
|
#ifdef UNIV_DEBUG
|
||||||
if (lock_print_waits) {
|
if (lock_print_waits) {
|
||||||
fputs("Deadlock detected"
|
fputs("Deadlock detected\n",
|
||||||
" or too long search\n",
|
|
||||||
stderr);
|
stderr);
|
||||||
}
|
}
|
||||||
#endif /* UNIV_DEBUG */
|
#endif /* UNIV_DEBUG */
|
||||||
if (too_far) {
|
|
||||||
|
|
||||||
fputs("TOO DEEP OR LONG SEARCH"
|
|
||||||
" IN THE LOCK TABLE"
|
|
||||||
" WAITS-FOR GRAPH\n", ef);
|
|
||||||
|
|
||||||
return(LOCK_VICTIM_IS_START);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (trx_weight_cmp(wait_lock->trx,
|
if (trx_weight_cmp(wait_lock->trx,
|
||||||
start) >= 0) {
|
start) >= 0) {
|
||||||
@ -3310,6 +3323,21 @@ lock_deadlock_recursive(
|
|||||||
return(LOCK_VICTIM_IS_OTHER);
|
return(LOCK_VICTIM_IS_OTHER);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (too_far) {
|
||||||
|
|
||||||
|
#ifdef UNIV_DEBUG
|
||||||
|
if (lock_print_waits) {
|
||||||
|
fputs("Deadlock search exceeds"
|
||||||
|
" max steps or depth.\n",
|
||||||
|
stderr);
|
||||||
|
}
|
||||||
|
#endif /* UNIV_DEBUG */
|
||||||
|
/* The information about transaction/lock
|
||||||
|
to be rolled back is available in the top
|
||||||
|
level. Do not print anything here. */
|
||||||
|
return(LOCK_EXCEED_MAX_DEPTH);
|
||||||
|
}
|
||||||
|
|
||||||
if (lock_trx->que_state == TRX_QUE_LOCK_WAIT) {
|
if (lock_trx->que_state == TRX_QUE_LOCK_WAIT) {
|
||||||
|
|
||||||
/* Another trx ahead has requested lock in an
|
/* Another trx ahead has requested lock in an
|
||||||
|
@ -759,7 +759,15 @@ next_file:
|
|||||||
#ifdef HAVE_READDIR_R
|
#ifdef HAVE_READDIR_R
|
||||||
ret = readdir_r(dir, (struct dirent*)dirent_buf, &ent);
|
ret = readdir_r(dir, (struct dirent*)dirent_buf, &ent);
|
||||||
|
|
||||||
if (ret != 0) {
|
if (ret != 0
|
||||||
|
#ifdef UNIV_AIX
|
||||||
|
/* On AIX, only if we got non-NULL 'ent' (result) value and
|
||||||
|
a non-zero 'ret' (return) value, it indicates a failed
|
||||||
|
readdir_r() call. An NULL 'ent' with an non-zero 'ret'
|
||||||
|
would indicate the "end of the directory" is reached. */
|
||||||
|
&& ent != NULL
|
||||||
|
#endif
|
||||||
|
) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"InnoDB: cannot read directory %s, error %lu\n",
|
"InnoDB: cannot read directory %s, error %lu\n",
|
||||||
dirname, (ulong)ret);
|
dirname, (ulong)ret);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user