mirror of
https://github.com/MariaDB/server.git
synced 2025-01-20 05:52:27 +01:00
Applying InnoDB snapshot
Detailed revision comments: r6425 | marko | 2010-01-12 13:47:11 +0200 (Tue, 12 Jan 2010) | 45 lines branches/zip: Merge revisions 6350:6424 from branches/5.1: ------------------------------------------------------------------------ r6421 | jyang | 2010-01-12 07:59:16 +0200 (Tue, 12 Jan 2010) | 8 lines Changed paths: M /branches/5.1/row/row0mysql.c branches/5.1: Fix bug #49238: Creating/Dropping a temporary table while at 1023 transactions will cause assert. Handle possible DB_TOO_MANY_CONCURRENT_TRXS when deleting metadata in row_drop_table_for_mysql(). rb://220, approved by Marko ------------------------------------------------------------------------ r6422 | marko | 2010-01-12 11:34:27 +0200 (Tue, 12 Jan 2010) | 3 lines Changed paths: M /branches/5.1/handler/ha_innodb.cc M /branches/5.1/handler/ha_innodb.h branches/5.1: Non-functional change: Make innobase_get_int_col_max_value() a static function. It does not access any fields of class ha_innobase. ------------------------------------------------------------------------ r6424 | marko | 2010-01-12 12:22:19 +0200 (Tue, 12 Jan 2010) | 16 lines Changed paths: M /branches/5.1/handler/ha_innodb.cc M /branches/5.1/handler/ha_innodb.h branches/5.1: In innobase_initialize_autoinc(), do not attempt to read the maximum auto-increment value from the table if innodb_force_recovery is set to at least 4, so that writes are disabled. (Bug #46193) innobase_get_int_col_max_value(): Move the function definition before ha_innobase::innobase_initialize_autoinc(), because that function now calls this function. ha_innobase::innobase_initialize_autoinc(): Change the return type to void. Do not attempt to read the maximum auto-increment value from the table if innodb_force_recovery is set to at least 4. Issue ER_AUTOINC_READ_FAILED to the client when the auto-increment value cannot be read. rb://144 by Sunny, revised by Marko ------------------------------------------------------------------------
This commit is contained in:
parent
ba5d13fdfd
commit
68afad078a
4 changed files with 171 additions and 118 deletions
|
@ -1,6 +1,19 @@
|
|||
2010-01-12 The InnoDB Team
|
||||
|
||||
* handler/ha_innodb.cc, handler/ha_innodb.h:
|
||||
Fix Bug #46193 crash when accessing tables after enabling
|
||||
innodb_force_recovery option
|
||||
|
||||
2010-01-12 The InnoDB Team
|
||||
|
||||
* row/row0mysql.c:
|
||||
Fix Bug#49238 Creating/Dropping a temporary table while at 1023
|
||||
transactions will cause assert.
|
||||
|
||||
2009-12-02 The InnoDB Team
|
||||
|
||||
* srv/srv0start.c: Display the zlib version number at startup.
|
||||
* srv/srv0start.c:
|
||||
Display the zlib version number at startup.
|
||||
InnoDB compressed tables use zlib, and the implementation depends
|
||||
on the zlib function compressBound(), whose definition was slightly
|
||||
changed in zlib version 1.2.3.1 in 2006. MySQL bundles zlib 1.2.3
|
||||
|
|
|
@ -3006,59 +3006,150 @@ normalize_table_name(
|
|||
}
|
||||
|
||||
/********************************************************************//**
|
||||
Get the upper limit of the MySQL integral and floating-point type.
|
||||
@return maximum allowed value for the field */
|
||||
static
|
||||
ulonglong
|
||||
innobase_get_int_col_max_value(
|
||||
/*===========================*/
|
||||
const Field* field) /*!< in: MySQL field */
|
||||
{
|
||||
ulonglong max_value = 0;
|
||||
|
||||
switch(field->key_type()) {
|
||||
/* TINY */
|
||||
case HA_KEYTYPE_BINARY:
|
||||
max_value = 0xFFULL;
|
||||
break;
|
||||
case HA_KEYTYPE_INT8:
|
||||
max_value = 0x7FULL;
|
||||
break;
|
||||
/* SHORT */
|
||||
case HA_KEYTYPE_USHORT_INT:
|
||||
max_value = 0xFFFFULL;
|
||||
break;
|
||||
case HA_KEYTYPE_SHORT_INT:
|
||||
max_value = 0x7FFFULL;
|
||||
break;
|
||||
/* MEDIUM */
|
||||
case HA_KEYTYPE_UINT24:
|
||||
max_value = 0xFFFFFFULL;
|
||||
break;
|
||||
case HA_KEYTYPE_INT24:
|
||||
max_value = 0x7FFFFFULL;
|
||||
break;
|
||||
/* LONG */
|
||||
case HA_KEYTYPE_ULONG_INT:
|
||||
max_value = 0xFFFFFFFFULL;
|
||||
break;
|
||||
case HA_KEYTYPE_LONG_INT:
|
||||
max_value = 0x7FFFFFFFULL;
|
||||
break;
|
||||
/* BIG */
|
||||
case HA_KEYTYPE_ULONGLONG:
|
||||
max_value = 0xFFFFFFFFFFFFFFFFULL;
|
||||
break;
|
||||
case HA_KEYTYPE_LONGLONG:
|
||||
max_value = 0x7FFFFFFFFFFFFFFFULL;
|
||||
break;
|
||||
case HA_KEYTYPE_FLOAT:
|
||||
/* We use the maximum as per IEEE754-2008 standard, 2^24 */
|
||||
max_value = 0x1000000ULL;
|
||||
break;
|
||||
case HA_KEYTYPE_DOUBLE:
|
||||
/* We use the maximum as per IEEE754-2008 standard, 2^53 */
|
||||
max_value = 0x20000000000000ULL;
|
||||
break;
|
||||
default:
|
||||
ut_error;
|
||||
}
|
||||
|
||||
return(max_value);
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
Set the autoinc column max value. This should only be called once from
|
||||
ha_innobase::open(). Therefore there's no need for a covering lock.
|
||||
@return DB_SUCCESS or error code */
|
||||
ha_innobase::open(). Therefore there's no need for a covering lock. */
|
||||
UNIV_INTERN
|
||||
ulint
|
||||
void
|
||||
ha_innobase::innobase_initialize_autoinc()
|
||||
/*======================================*/
|
||||
{
|
||||
dict_index_t* index;
|
||||
ulonglong auto_inc;
|
||||
const char* col_name;
|
||||
ulint error;
|
||||
|
||||
col_name = table->found_next_number_field->field_name;
|
||||
index = innobase_get_index(table->s->next_number_index);
|
||||
|
||||
/* Execute SELECT MAX(col_name) FROM TABLE; */
|
||||
error = row_search_max_autoinc(index, col_name, &auto_inc);
|
||||
|
||||
switch (error) {
|
||||
case DB_SUCCESS:
|
||||
|
||||
/* At the this stage we don't know the increment
|
||||
or the offset, so use default inrement of 1. */
|
||||
++auto_inc;
|
||||
break;
|
||||
|
||||
case DB_RECORD_NOT_FOUND:
|
||||
ut_print_timestamp(stderr);
|
||||
fprintf(stderr, " InnoDB: MySQL and InnoDB data "
|
||||
"dictionaries are out of sync.\n"
|
||||
"InnoDB: Unable to find the AUTOINC column %s in the "
|
||||
"InnoDB table %s.\n"
|
||||
"InnoDB: We set the next AUTOINC column value to the "
|
||||
"maximum possible value,\n"
|
||||
"InnoDB: in effect disabling the AUTOINC next value "
|
||||
"generation.\n"
|
||||
"InnoDB: You can either set the next AUTOINC value "
|
||||
"explicitly using ALTER TABLE\n"
|
||||
"InnoDB: or fix the data dictionary by recreating "
|
||||
"the table.\n",
|
||||
col_name, index->table->name);
|
||||
const Field* field = table->found_next_number_field;
|
||||
|
||||
if (field != NULL) {
|
||||
auto_inc = innobase_get_int_col_max_value(field);
|
||||
} else {
|
||||
/* 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 type. */
|
||||
auto_inc = 0xFFFFFFFFFFFFFFFFULL;
|
||||
break;
|
||||
|
||||
default:
|
||||
return(error);
|
||||
ut_print_timestamp(stderr);
|
||||
fprintf(stderr, " InnoDB: Unable to determine the AUTOINC "
|
||||
"column name\n");
|
||||
}
|
||||
|
||||
if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE) {
|
||||
/* If the recovery level is set so high that writes
|
||||
are disabled we force the AUTOINC counter to the MAX
|
||||
value effectively disabling writes to the table.
|
||||
Secondly, we avoid reading the table in case the read
|
||||
results in failure due to a corrupted table/index.
|
||||
|
||||
We will not return an error to the client, so that the
|
||||
tables can be dumped with minimal hassle. If an error
|
||||
were returned in this case, the first attempt to read
|
||||
the table would fail and subsequent SELECTs would succeed. */
|
||||
} else if (field == NULL) {
|
||||
my_error(ER_AUTOINC_READ_FAILED, MYF(0));
|
||||
} else {
|
||||
dict_index_t* index;
|
||||
const char* col_name;
|
||||
ulonglong read_auto_inc;
|
||||
ulint err;
|
||||
|
||||
update_thd(ha_thd());
|
||||
col_name = field->field_name;
|
||||
index = innobase_get_index(table->s->next_number_index);
|
||||
|
||||
/* Execute SELECT MAX(col_name) FROM TABLE; */
|
||||
err = row_search_max_autoinc(index, col_name, &read_auto_inc);
|
||||
|
||||
switch (err) {
|
||||
case DB_SUCCESS:
|
||||
/* At the this stage we do not know the increment
|
||||
or the offset, so use a default increment of 1. */
|
||||
auto_inc = read_auto_inc + 1;
|
||||
break;
|
||||
|
||||
case DB_RECORD_NOT_FOUND:
|
||||
ut_print_timestamp(stderr);
|
||||
fprintf(stderr, " InnoDB: MySQL and InnoDB data "
|
||||
"dictionaries are out of sync.\n"
|
||||
"InnoDB: Unable to find the AUTOINC column "
|
||||
"%s in the InnoDB table %s.\n"
|
||||
"InnoDB: We set the next AUTOINC column "
|
||||
"value to the maximum possible value,\n"
|
||||
"InnoDB: in effect disabling the AUTOINC "
|
||||
"next value generation.\n"
|
||||
"InnoDB: You can either set the next "
|
||||
"AUTOINC value explicitly using ALTER TABLE\n"
|
||||
"InnoDB: or fix the data dictionary by "
|
||||
"recreating the table.\n",
|
||||
col_name, index->table->name);
|
||||
|
||||
my_error(ER_AUTOINC_READ_FAILED, MYF(0));
|
||||
break;
|
||||
default:
|
||||
/* row_search_max_autoinc() should only return
|
||||
one of DB_SUCCESS or DB_RECORD_NOT_FOUND. */
|
||||
ut_error;
|
||||
}
|
||||
}
|
||||
|
||||
dict_table_autoinc_initialize(prebuilt->table, auto_inc);
|
||||
|
||||
return(DB_SUCCESS);
|
||||
}
|
||||
|
||||
/*****************************************************************//**
|
||||
|
@ -3265,8 +3356,6 @@ retry:
|
|||
|
||||
/* Only if the table has an AUTOINC column. */
|
||||
if (prebuilt->table != NULL && table->found_next_number_field != NULL) {
|
||||
ulint error;
|
||||
|
||||
dict_table_autoinc_lock(prebuilt->table);
|
||||
|
||||
/* Since a table can already be "open" in InnoDB's internal
|
||||
|
@ -3275,8 +3364,7 @@ retry:
|
|||
autoinc value from a previous MySQL open. */
|
||||
if (dict_table_autoinc_read(prebuilt->table) == 0) {
|
||||
|
||||
error = innobase_initialize_autoinc();
|
||||
ut_a(error == DB_SUCCESS);
|
||||
innobase_initialize_autoinc();
|
||||
}
|
||||
|
||||
dict_table_autoinc_unlock(prebuilt->table);
|
||||
|
@ -4092,67 +4180,6 @@ skip_field:
|
|||
}
|
||||
}
|
||||
|
||||
/********************************************************************//**
|
||||
Get the upper limit of the MySQL integral and floating-point type. */
|
||||
UNIV_INTERN
|
||||
ulonglong
|
||||
ha_innobase::innobase_get_int_col_max_value(
|
||||
/*========================================*/
|
||||
const Field* field)
|
||||
{
|
||||
ulonglong max_value = 0;
|
||||
|
||||
switch(field->key_type()) {
|
||||
/* TINY */
|
||||
case HA_KEYTYPE_BINARY:
|
||||
max_value = 0xFFULL;
|
||||
break;
|
||||
case HA_KEYTYPE_INT8:
|
||||
max_value = 0x7FULL;
|
||||
break;
|
||||
/* SHORT */
|
||||
case HA_KEYTYPE_USHORT_INT:
|
||||
max_value = 0xFFFFULL;
|
||||
break;
|
||||
case HA_KEYTYPE_SHORT_INT:
|
||||
max_value = 0x7FFFULL;
|
||||
break;
|
||||
/* MEDIUM */
|
||||
case HA_KEYTYPE_UINT24:
|
||||
max_value = 0xFFFFFFULL;
|
||||
break;
|
||||
case HA_KEYTYPE_INT24:
|
||||
max_value = 0x7FFFFFULL;
|
||||
break;
|
||||
/* LONG */
|
||||
case HA_KEYTYPE_ULONG_INT:
|
||||
max_value = 0xFFFFFFFFULL;
|
||||
break;
|
||||
case HA_KEYTYPE_LONG_INT:
|
||||
max_value = 0x7FFFFFFFULL;
|
||||
break;
|
||||
/* BIG */
|
||||
case HA_KEYTYPE_ULONGLONG:
|
||||
max_value = 0xFFFFFFFFFFFFFFFFULL;
|
||||
break;
|
||||
case HA_KEYTYPE_LONGLONG:
|
||||
max_value = 0x7FFFFFFFFFFFFFFFULL;
|
||||
break;
|
||||
case HA_KEYTYPE_FLOAT:
|
||||
/* We use the maximum as per IEEE754-2008 standard, 2^24 */
|
||||
max_value = 0x1000000ULL;
|
||||
break;
|
||||
case HA_KEYTYPE_DOUBLE:
|
||||
/* We use the maximum as per IEEE754-2008 standard, 2^53 */
|
||||
max_value = 0x20000000000000ULL;
|
||||
break;
|
||||
default:
|
||||
ut_error;
|
||||
}
|
||||
|
||||
return(max_value);
|
||||
}
|
||||
|
||||
/********************************************************************//**
|
||||
This special handling is really to overcome the limitations of MySQL's
|
||||
binlogging. We need to eliminate the non-determinism that will arise in
|
||||
|
|
|
@ -91,9 +91,8 @@ class ha_innobase: public handler
|
|||
ulint innobase_reset_autoinc(ulonglong auto_inc);
|
||||
ulint innobase_get_autoinc(ulonglong* value);
|
||||
ulint innobase_update_autoinc(ulonglong auto_inc);
|
||||
ulint innobase_initialize_autoinc();
|
||||
void innobase_initialize_autoinc();
|
||||
dict_index_t* innobase_get_index(uint keynr);
|
||||
ulonglong innobase_get_int_col_max_value(const Field* field);
|
||||
|
||||
/* Init values for the class: */
|
||||
public:
|
||||
|
|
|
@ -3255,19 +3255,13 @@ check_next_foreign:
|
|||
"END;\n"
|
||||
, FALSE, trx);
|
||||
|
||||
if (err != DB_SUCCESS) {
|
||||
ut_a(err == DB_OUT_OF_FILE_SPACE);
|
||||
|
||||
err = DB_MUST_GET_MORE_FILE_SPACE;
|
||||
|
||||
row_mysql_handle_errors(&err, trx, NULL, NULL);
|
||||
|
||||
ut_error;
|
||||
} else {
|
||||
switch (err) {
|
||||
ibool is_temp;
|
||||
const char* name_or_path;
|
||||
mem_heap_t* heap;
|
||||
|
||||
case DB_SUCCESS:
|
||||
|
||||
heap = mem_heap_create(200);
|
||||
|
||||
/* Clone the name, in case it has been allocated
|
||||
|
@ -3333,7 +3327,27 @@ check_next_foreign:
|
|||
}
|
||||
|
||||
mem_heap_free(heap);
|
||||
break;
|
||||
|
||||
case DB_TOO_MANY_CONCURRENT_TRXS:
|
||||
/* Cannot even find a free slot for the
|
||||
the undo log. We can directly exit here
|
||||
and return the DB_TOO_MANY_CONCURRENT_TRXS
|
||||
error. */
|
||||
break;
|
||||
|
||||
case DB_OUT_OF_FILE_SPACE:
|
||||
err = DB_MUST_GET_MORE_FILE_SPACE;
|
||||
|
||||
row_mysql_handle_errors(&err, trx, NULL, NULL);
|
||||
|
||||
/* Fall through to raise error */
|
||||
|
||||
default:
|
||||
/* No other possible error returns */
|
||||
ut_error;
|
||||
}
|
||||
|
||||
funct_exit:
|
||||
|
||||
if (locked_dictionary) {
|
||||
|
|
Loading…
Reference in a new issue