summaryrefslogtreecommitdiff
path: root/storage
diff options
context:
space:
mode:
authorGeorgi Kodinov <Georgi.Kodinov@Oracle.com>2011-06-06 16:53:46 +0300
committerGeorgi Kodinov <Georgi.Kodinov@Oracle.com>2011-06-06 16:53:46 +0300
commit1dcd90b80b105422052a130937131f149d61e583 (patch)
tree6f31262b2aae660a5536bb962c312d14b320ed47 /storage
parentdd7e8529e0901d8ac69fef7cb0ad7c003d20a7ed (diff)
parentb502a64bba3143a77632042f02876086ab7dff7b (diff)
downloadmariadb-git-1dcd90b80b105422052a130937131f149d61e583.tar.gz
merge of mysql-5.1->mysql-5.1-security
Diffstat (limited to 'storage')
-rw-r--r--storage/archive/azio.c9
-rw-r--r--storage/archive/ha_archive.cc3
-rw-r--r--storage/innobase/dict/dict0load.c64
-rw-r--r--storage/innobase/handler/ha_innodb.cc12
-rw-r--r--storage/innodb_plugin/dict/dict0load.c63
-rw-r--r--storage/innodb_plugin/handler/ha_innodb.cc12
-rw-r--r--storage/innodb_plugin/include/univ.i2
7 files changed, 147 insertions, 18 deletions
diff --git a/storage/archive/azio.c b/storage/archive/azio.c
index c1dd6e6f38c..aaf8233a30c 100644
--- a/storage/archive/azio.c
+++ b/storage/archive/azio.c
@@ -114,6 +114,15 @@ int az_open (azio_stream *s, const char *path, int Flags, File fd)
errno = 0;
s->file = fd < 0 ? my_open(path, Flags, MYF(0)) : fd;
+ DBUG_EXECUTE_IF("simulate_archive_open_failure",
+ {
+ if (s->file >= 0)
+ {
+ my_close(s->file, MYF(0));
+ s->file= -1;
+ my_errno= EMFILE;
+ }
+ });
if (s->file < 0 )
{
diff --git a/storage/archive/ha_archive.cc b/storage/archive/ha_archive.cc
index e5c483daac5..4da98507dcf 100644
--- a/storage/archive/ha_archive.cc
+++ b/storage/archive/ha_archive.cc
@@ -1586,11 +1586,12 @@ int ha_archive::check(THD* thd, HA_CHECK_OPT* check_opt)
azflush(&(share->archive_write), Z_SYNC_FLUSH);
pthread_mutex_unlock(&share->mutex);
+ if (init_archive_reader())
+ DBUG_RETURN(HA_ADMIN_CORRUPT);
/*
Now we will rewind the archive file so that we are positioned at the
start of the file.
*/
- init_archive_reader();
read_data_header(&archive);
while (!(rc= get_row(&archive, table->record[0])))
count--;
diff --git a/storage/innobase/dict/dict0load.c b/storage/innobase/dict/dict0load.c
index c505bfbd6c4..7e820cfb08d 100644
--- a/storage/innobase/dict/dict0load.c
+++ b/storage/innobase/dict/dict0load.c
@@ -454,9 +454,11 @@ dict_load_report_deleted_index(
/************************************************************************
Loads definitions for index fields. */
static
-void
+ulint
dict_load_fields(
/*=============*/
+ /* out: DB_SUCCESS if ok, DB_CORRUPTION
+ if failed */
dict_table_t* table, /* in: table */
dict_index_t* index, /* in: index whose fields to load */
mem_heap_t* heap) /* in: memory heap for temporary storage */
@@ -474,6 +476,7 @@ dict_load_fields(
byte* buf;
ulint i;
mtr_t mtr;
+ ulint error = DB_SUCCESS;
ut_ad(mutex_own(&(dict_sys->mutex)));
@@ -535,6 +538,26 @@ dict_load_fields(
field = rec_get_nth_field_old(rec, 4, &len);
+ if (prefix_len >= DICT_MAX_INDEX_COL_LEN) {
+ fprintf(stderr, "InnoDB: Error: load index"
+ " '%s' failed.\n"
+ "InnoDB: index field '%s' has a prefix"
+ " length of %lu bytes,\n"
+ "InnoDB: which exceeds the"
+ " maximum limit of %lu bytes.\n"
+ "InnoDB: Please use server that"
+ " supports long index prefix\n"
+ "InnoDB: or turn on"
+ " innodb_force_recovery to load"
+ " the table\n",
+ index->name, mem_heap_strdupl(
+ heap, (char*) field, len),
+ (ulong) prefix_len,
+ (ulong) (DICT_MAX_INDEX_COL_LEN - 1));
+ error = DB_CORRUPTION;
+ goto func_exit;
+ }
+
dict_mem_index_add_field(index,
mem_heap_strdupl(heap,
(char*) field, len),
@@ -543,8 +566,10 @@ dict_load_fields(
btr_pcur_move_to_next_user_rec(&pcur, &mtr);
}
+func_exit:
btr_pcur_close(&pcur);
mtr_commit(&mtr);
+ return(error);
}
/************************************************************************
@@ -701,10 +726,28 @@ dict_load_indexes(
space, type, n_fields);
index->id = id;
- dict_load_fields(table, index, heap);
+ error = dict_load_fields(table, index, heap);
+
+ if (error != DB_SUCCESS) {
+ fprintf(stderr, "InnoDB: Error: load index '%s'"
+ " for table '%s' failed\n",
+ index->name, table->name);
+
+ /* If the force recovery flag is set, and
+ if the failed index is not the primary index, we
+ will continue and open other indexes */
+ if (srv_force_recovery
+ && !(index->type & DICT_CLUSTERED)) {
+ error = DB_SUCCESS;
+ goto next_rec;
+ } else {
+ goto func_exit;
+ }
+ }
+
dict_index_add_to_cache(table, index, page_no);
}
-
+next_rec:
btr_pcur_move_to_next_user_rec(&pcur, &mtr);
}
@@ -881,9 +924,18 @@ err_exit:
} else {
table->fk_max_recusive_level = 0;
}
- } else if (!srv_force_recovery) {
- dict_table_remove_from_cache(table);
- table = NULL;
+ } else {
+ dict_index_t* index;
+
+ /* Make sure that at least the clustered index was loaded.
+ Otherwise refuse to load the table */
+ index = dict_table_get_first_index(table);
+
+ if (!srv_force_recovery || !index
+ || !(index->type & DICT_CLUSTERED)) {
+ dict_table_remove_from_cache(table);
+ table = NULL;
+ }
}
#if 0
if (err != DB_SUCCESS && table != NULL) {
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index 2afacf6d2a8..dfe13ccbbfe 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -7325,10 +7325,18 @@ ha_innobase::external_lock(
reset_template(prebuilt);
- if (lock_type == F_WRLCK) {
+ if (lock_type == F_WRLCK
+ || (table->s->tmp_table
+ && thd_sql_command(thd) == SQLCOM_LOCK_TABLES)) {
/* If this is a SELECT, then it is in UPDATE TABLE ...
- or SELECT ... FOR UPDATE */
+ or SELECT ... FOR UPDATE
+
+ For temporary tables which are locked for READ by LOCK TABLES
+ updates are still allowed by SQL-layer. In order to accomodate
+ for such a situation we always request X-lock for such table
+ at LOCK TABLES time.
+ */
prebuilt->select_lock_type = LOCK_X;
prebuilt->stored_select_lock_type = LOCK_X;
}
diff --git a/storage/innodb_plugin/dict/dict0load.c b/storage/innodb_plugin/dict/dict0load.c
index c3825902536..7a0b6edcb08 100644
--- a/storage/innodb_plugin/dict/dict0load.c
+++ b/storage/innodb_plugin/dict/dict0load.c
@@ -553,9 +553,10 @@ dict_load_columns(
}
/********************************************************************//**
-Loads definitions for index fields. */
+Loads definitions for index fields.
+@return DB_SUCCESS if ok, DB_CORRUPTION if failed */
static
-void
+ulint
dict_load_fields(
/*=============*/
dict_index_t* index, /*!< in: index whose fields to load */
@@ -574,6 +575,7 @@ dict_load_fields(
byte* buf;
ulint i;
mtr_t mtr;
+ ulint error = DB_SUCCESS;
ut_ad(mutex_own(&(dict_sys->mutex)));
@@ -640,6 +642,26 @@ dict_load_fields(
field = rec_get_nth_field_old(rec, 4, &len);
+ if (prefix_len >= DICT_MAX_INDEX_COL_LEN) {
+ fprintf(stderr, "InnoDB: Error: load index"
+ " '%s' failed.\n"
+ "InnoDB: index field '%s' has a prefix"
+ " length of %lu bytes,\n"
+ "InnoDB: which exceeds the"
+ " maximum limit of %lu bytes.\n"
+ "InnoDB: Please use server that"
+ " supports long index prefix\n"
+ "InnoDB: or turn on"
+ " innodb_force_recovery to load"
+ " the table\n",
+ index->name, mem_heap_strdupl(
+ heap, (char*) field, len),
+ (ulong) prefix_len,
+ (ulong) (DICT_MAX_INDEX_COL_LEN - 1));
+ error = DB_CORRUPTION;
+ goto func_exit;
+ }
+
dict_mem_index_add_field(index,
mem_heap_strdupl(heap,
(char*) field, len),
@@ -649,8 +671,10 @@ next_rec:
btr_pcur_move_to_next_user_rec(&pcur, &mtr);
}
+func_exit:
btr_pcur_close(&pcur);
mtr_commit(&mtr);
+ return(error);
}
/********************************************************************//**
@@ -801,7 +825,25 @@ dict_load_indexes(
space, type, n_fields);
index->id = id;
- dict_load_fields(index, heap);
+ error = dict_load_fields(index, heap);
+
+ if (error != DB_SUCCESS) {
+ fprintf(stderr, "InnoDB: Error: load index '%s'"
+ " for table '%s' failed\n",
+ index->name, table->name);
+
+ /* If the force recovery flag is set, and
+ if the failed index is not the primary index, we
+ will continue and open other indexes */
+ if (srv_force_recovery
+ && !(index->type & DICT_CLUSTERED)) {
+ error = DB_SUCCESS;
+ goto next_rec;
+ } else {
+ goto func_exit;
+ }
+ }
+
error = dict_index_add_to_cache(table, index, page_no,
FALSE);
/* The data dictionary tables should never contain
@@ -1027,9 +1069,18 @@ err_exit:
} else {
table->fk_max_recusive_level = 0;
}
- } else if (!srv_force_recovery) {
- dict_table_remove_from_cache(table);
- table = NULL;
+ } else {
+ dict_index_t* index;
+
+ /* Make sure that at least the clustered index was loaded.
+ Otherwise refuse to load the table */
+ index = dict_table_get_first_index(table);
+
+ if (!srv_force_recovery || !index
+ || !(index->type & DICT_CLUSTERED)) {
+ dict_table_remove_from_cache(table);
+ table = NULL;
+ }
}
#if 0
if (err != DB_SUCCESS && table != NULL) {
diff --git a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/handler/ha_innodb.cc
index 2b0dbf82b34..a9c9f379528 100644
--- a/storage/innodb_plugin/handler/ha_innodb.cc
+++ b/storage/innodb_plugin/handler/ha_innodb.cc
@@ -8642,10 +8642,18 @@ ha_innobase::external_lock(
reset_template(prebuilt);
- if (lock_type == F_WRLCK) {
+ if (lock_type == F_WRLCK
+ || (table->s->tmp_table
+ && thd_sql_command(thd) == SQLCOM_LOCK_TABLES)) {
/* If this is a SELECT, then it is in UPDATE TABLE ...
- or SELECT ... FOR UPDATE */
+ or SELECT ... FOR UPDATE
+
+ For temporary tables which are locked for READ by LOCK TABLES
+ updates are still allowed by SQL-layer. In order to accomodate
+ for such a situation we always request X-lock for such table
+ at LOCK TABLES time.
+ */
prebuilt->select_lock_type = LOCK_X;
prebuilt->stored_select_lock_type = LOCK_X;
}
diff --git a/storage/innodb_plugin/include/univ.i b/storage/innodb_plugin/include/univ.i
index dc75879dbad..6ac227a59a6 100644
--- a/storage/innodb_plugin/include/univ.i
+++ b/storage/innodb_plugin/include/univ.i
@@ -46,7 +46,7 @@ Created 1/20/1994 Heikki Tuuri
#define INNODB_VERSION_MAJOR 1
#define INNODB_VERSION_MINOR 0
-#define INNODB_VERSION_BUGFIX 16
+#define INNODB_VERSION_BUGFIX 17
/* The following is the InnoDB version as shown in
SELECT plugin_version FROM information_schema.plugins;