summaryrefslogtreecommitdiff
path: root/storage/innobase
diff options
context:
space:
mode:
authorVasil Dimov <vasil.dimov@oracle.com>2011-05-22 23:12:46 +0300
committerVasil Dimov <vasil.dimov@oracle.com>2011-05-22 23:12:46 +0300
commitbf5c6fd8ccdaccb6b9144abd654d6bba92ed06e7 (patch)
tree129def16cacbd5044a2d9318e038266b3cf58597 /storage/innobase
parentb8c48b4dfc8b1a2f8077b8257ac144102809198a (diff)
parent30835b55d58c5a2c04085d315bf6f2f1d81ffc30 (diff)
downloadmariadb-git-bf5c6fd8ccdaccb6b9144abd654d6bba92ed06e7.tar.gz
Merge mysql-5.5-innodb -> mysql-5.5
Diffstat (limited to 'storage/innobase')
-rw-r--r--storage/innobase/dict/dict0crea.c15
-rw-r--r--storage/innobase/dict/dict0load.c86
-rw-r--r--storage/innobase/fil/fil0fil.c3
-rw-r--r--storage/innobase/include/dict0load.h7
-rw-r--r--storage/innobase/include/page0page.h15
-rw-r--r--storage/innobase/include/page0page.ic21
-rw-r--r--storage/innobase/os/os0file.c13
-rw-r--r--storage/innobase/page/page0page.c22
-rw-r--r--storage/innobase/row/row0mysql.c2
-rw-r--r--storage/innobase/trx/trx0undo.c3
10 files changed, 131 insertions, 56 deletions
diff --git a/storage/innobase/dict/dict0crea.c b/storage/innobase/dict/dict0crea.c
index d0344e72703..9a528d679a7 100644
--- a/storage/innobase/dict/dict0crea.c
+++ b/storage/innobase/dict/dict0crea.c
@@ -659,9 +659,9 @@ dict_create_index_tree_step(
/* printf("Created a new index tree in space %lu root page %lu\n",
index->space, index->page_no); */
- page_rec_write_index_page_no(btr_pcur_get_rec(&pcur),
- DICT_SYS_INDEXES_PAGE_NO_FIELD,
- node->page_no, &mtr);
+ page_rec_write_field(btr_pcur_get_rec(&pcur),
+ DICT_SYS_INDEXES_PAGE_NO_FIELD,
+ node->page_no, &mtr);
btr_pcur_close(&pcur);
mtr_commit(&mtr);
@@ -731,9 +731,8 @@ dict_drop_index_tree(
root_page_no); */
btr_free_root(space, zip_size, root_page_no, mtr);
- page_rec_write_index_page_no(rec,
- DICT_SYS_INDEXES_PAGE_NO_FIELD,
- FIL_NULL, mtr);
+ page_rec_write_field(rec, DICT_SYS_INDEXES_PAGE_NO_FIELD,
+ FIL_NULL, mtr);
}
/*******************************************************************//**
@@ -836,8 +835,8 @@ create:
in SYS_INDEXES, so that the database will not get into an
inconsistent state in case it crashes between the mtr_commit()
below and the following mtr_commit() call. */
- page_rec_write_index_page_no(rec, DICT_SYS_INDEXES_PAGE_NO_FIELD,
- FIL_NULL, mtr);
+ page_rec_write_field(rec, DICT_SYS_INDEXES_PAGE_NO_FIELD,
+ FIL_NULL, mtr);
/* We will need to commit the mini-transaction in order to avoid
deadlocks in the btr_create() call, because otherwise we would
diff --git a/storage/innobase/dict/dict0load.c b/storage/innobase/dict/dict0load.c
index aad3145f7a4..7d531c26157 100644
--- a/storage/innobase/dict/dict0load.c
+++ b/storage/innobase/dict/dict0load.c
@@ -429,7 +429,7 @@ dict_process_sys_fields_rec(
mach_write_to_8(last_index_id, last_id);
err_msg = dict_load_field_low(buf, NULL, sys_field,
- pos, last_index_id, heap, rec);
+ pos, last_index_id, heap, rec, NULL, 0);
*index_id = mach_read_from_8(buf);
@@ -994,6 +994,9 @@ dict_load_columns(
/** Error message for a delete-marked record in dict_load_field_low() */
static const char* dict_load_field_del = "delete-marked record in SYS_FIELDS";
+static const char* dict_load_field_too_big = "column prefix exceeds maximum"
+ " limit";
+
/********************************************************************//**
Loads an index field definition from a SYS_FIELDS record to
dict_index_t.
@@ -1015,7 +1018,12 @@ dict_load_field_low(
byte* last_index_id, /*!< in: last index id */
mem_heap_t* heap, /*!< in/out: memory heap
for temporary storage */
- const rec_t* rec) /*!< in: SYS_FIELDS record */
+ const rec_t* rec, /*!< in: SYS_FIELDS record */
+ char* addition_err_str,/*!< out: additional error message
+ that requires information to be
+ filled, or NULL */
+ ulint err_str_len) /*!< in: length of addition_err_str
+ in bytes */
{
const byte* field;
ulint len;
@@ -1095,6 +1103,19 @@ err_len:
goto err_len;
}
+ if (prefix_len >= DICT_MAX_INDEX_COL_LEN) {
+ if (addition_err_str) {
+ ut_snprintf(addition_err_str, err_str_len,
+ "index field '%s' has a prefix length"
+ " of %lu bytes",
+ mem_heap_strdupl(
+ heap, (const char*) field, len),
+ (ulong) prefix_len);
+ }
+
+ return(dict_load_field_too_big);
+ }
+
if (index) {
dict_mem_index_add_field(
index, mem_heap_strdupl(heap, (const char*) field, len),
@@ -1154,14 +1175,16 @@ dict_load_fields(
btr_pcur_open_on_user_rec(sys_index, tuple, PAGE_CUR_GE,
BTR_SEARCH_LEAF, &pcur, &mtr);
for (i = 0; i < index->n_fields; i++) {
- const char* err_msg;
+ const char* err_msg;
+ char addition_err_str[1024];
rec = btr_pcur_get_rec(&pcur);
ut_a(btr_pcur_is_on_user_rec(&pcur));
err_msg = dict_load_field_low(buf, index, NULL, NULL, NULL,
- heap, rec);
+ heap, rec, addition_err_str,
+ sizeof(addition_err_str));
if (err_msg == dict_load_field_del) {
/* There could be delete marked records in
@@ -1170,7 +1193,24 @@ dict_load_fields(
goto next_rec;
} else if (err_msg) {
- fprintf(stderr, "InnoDB: %s\n", err_msg);
+ if (err_msg == dict_load_field_too_big) {
+ fprintf(stderr, "InnoDB: Error: load index"
+ " '%s' failed.\n"
+ "InnoDB: %s,\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, addition_err_str,
+ (ulong) (DICT_MAX_INDEX_COL_LEN - 1));
+
+ } else {
+ fprintf(stderr, "InnoDB: %s\n", err_msg);
+ }
+
error = DB_CORRUPTION;
goto func_exit;
}
@@ -1446,7 +1486,26 @@ corrupted:
of the database server */
dict_mem_index_free(index);
} else {
- 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
+ && !dict_index_is_clust(index)) {
+ error = DB_SUCCESS;
+ goto next_rec;
+ } else {
+ goto func_exit;
+ }
+ }
+
error = dict_index_add_to_cache(table, index,
index->page, FALSE);
/* The data dictionary tables should never contain
@@ -1771,9 +1830,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
+ || !dict_index_is_clust(index)) {
+ dict_table_remove_from_cache(table);
+ table = NULL;
+ }
}
#if 0
if (err != DB_SUCCESS && table != NULL) {
diff --git a/storage/innobase/fil/fil0fil.c b/storage/innobase/fil/fil0fil.c
index 0d9846fdbf8..196f4bd3f42 100644
--- a/storage/innobase/fil/fil0fil.c
+++ b/storage/innobase/fil/fil0fil.c
@@ -856,7 +856,8 @@ fil_node_close_file(
ut_a(node->open);
ut_a(node->n_pending == 0);
ut_a(node->n_pending_flushes == 0);
- ut_a(node->modification_counter == node->flush_counter);
+ ut_a(node->modification_counter == node->flush_counter
+ || srv_fast_shutdown == 2);
ret = os_file_close(node->handle);
ut_a(ret);
diff --git a/storage/innobase/include/dict0load.h b/storage/innobase/include/dict0load.h
index 51d07f43446..16177ade713 100644
--- a/storage/innobase/include/dict0load.h
+++ b/storage/innobase/include/dict0load.h
@@ -155,7 +155,12 @@ dict_load_field_low(
byte* last_index_id, /*!< in: last index id */
mem_heap_t* heap, /*!< in/out: memory heap
for temporary storage */
- const rec_t* rec); /*!< in: SYS_FIELDS record */
+ const rec_t* rec, /*!< in: SYS_FIELDS record */
+ char* addition_err_str,/*!< out: additional error message
+ that requires information to be
+ filled, or NULL */
+ ulint err_str_len); /*!< in: length of addition_err_str
+ in bytes */
/********************************************************************//**
Loads a table definition and also all its index definitions, and also
the cluster definition if the table is a member in a cluster. Also loads
diff --git a/storage/innobase/include/page0page.h b/storage/innobase/include/page0page.h
index 0a15dfbf2a1..fc082e9b189 100644
--- a/storage/innobase/include/page0page.h
+++ b/storage/innobase/include/page0page.h
@@ -619,17 +619,16 @@ page_rec_find_owner_rec(
/*====================*/
rec_t* rec); /*!< in: the physical record */
/***********************************************************************//**
-This is a low-level operation which is used in a database index creation
-to update the page number of a created B-tree to a data dictionary
-record. */
-UNIV_INTERN
+Write a 32-bit field in a data dictionary record. */
+UNIV_INLINE
void
-page_rec_write_index_page_no(
-/*=========================*/
- rec_t* rec, /*!< in: record to update */
+page_rec_write_field(
+/*=================*/
+ rec_t* rec, /*!< in/out: record to update */
ulint i, /*!< in: index of the field to update */
ulint page_no,/*!< in: value to write */
- mtr_t* mtr); /*!< in: mtr */
+ mtr_t* mtr) /*!< in/out: mini-transaction */
+ __attribute__((nonnull));
/************************************************************//**
Returns the maximum combined size of records which can be inserted on top
of record heap.
diff --git a/storage/innobase/include/page0page.ic b/storage/innobase/include/page0page.ic
index e9624c2360f..75e562a158d 100644
--- a/storage/innobase/include/page0page.ic
+++ b/storage/innobase/include/page0page.ic
@@ -959,6 +959,27 @@ page_get_free_space_of_empty(
- 2 * PAGE_DIR_SLOT_SIZE));
}
+/***********************************************************************//**
+Write a 32-bit field in a data dictionary record. */
+UNIV_INLINE
+void
+page_rec_write_field(
+/*=================*/
+ rec_t* rec, /*!< in/out: record to update */
+ ulint i, /*!< in: index of the field to update */
+ ulint val, /*!< in: value to write */
+ mtr_t* mtr) /*!< in/out: mini-transaction */
+{
+ byte* data;
+ ulint len;
+
+ data = rec_get_nth_field_old(rec, i, &len);
+
+ ut_ad(len == 4);
+
+ mlog_write_ulint(data, val, MLOG_4BYTES, mtr);
+}
+
/************************************************************//**
Each user record on a page, and also the deleted user records in the heap
takes its size plus the fraction of the dir cell size /
diff --git a/storage/innobase/os/os0file.c b/storage/innobase/os/os0file.c
index 50607e07076..bd48d0e4b6e 100644
--- a/storage/innobase/os/os0file.c
+++ b/storage/innobase/os/os0file.c
@@ -4051,16 +4051,23 @@ os_aio_func(
Windows async i/o, Windows does not allow us to use
ordinary synchronous os_file_read etc. on the same file,
therefore we have built a special mechanism for synchronous
- wait in the Windows case. */
+ wait in the Windows case.
+ Also note that the Performance Schema instrumentation has
+ been performed by current os_aio_func()'s wrapper function
+ pfs_os_aio_func(). So we would no longer need to call
+ Performance Schema instrumented os_file_read() and
+ os_file_write(). Instead, we should use os_file_read_func()
+ and os_file_write_func() */
if (type == OS_FILE_READ) {
- return(os_file_read(file, buf, offset,
+ return(os_file_read_func(file, buf, offset,
offset_high, n));
}
ut_a(type == OS_FILE_WRITE);
- return(os_file_write(name, file, buf, offset, offset_high, n));
+ return(os_file_write_func(name, file, buf, offset,
+ offset_high, n));
}
try_again:
diff --git a/storage/innobase/page/page0page.c b/storage/innobase/page/page0page.c
index 964d0e2abef..6064d028ae1 100644
--- a/storage/innobase/page/page0page.c
+++ b/storage/innobase/page/page0page.c
@@ -1253,28 +1253,6 @@ page_move_rec_list_start(
return(TRUE);
}
-
-/***********************************************************************//**
-This is a low-level operation which is used in a database index creation
-to update the page number of a created B-tree to a data dictionary record. */
-UNIV_INTERN
-void
-page_rec_write_index_page_no(
-/*=========================*/
- rec_t* rec, /*!< in: record to update */
- ulint i, /*!< in: index of the field to update */
- ulint page_no,/*!< in: value to write */
- mtr_t* mtr) /*!< in: mtr */
-{
- byte* data;
- ulint len;
-
- data = rec_get_nth_field_old(rec, i, &len);
-
- ut_ad(len == 4);
-
- mlog_write_ulint(data, page_no, MLOG_4BYTES, mtr);
-}
#endif /* !UNIV_HOTBACKUP */
/**************************************************************//**
diff --git a/storage/innobase/row/row0mysql.c b/storage/innobase/row/row0mysql.c
index f7e5c5fdceb..aef4595f5fe 100644
--- a/storage/innobase/row/row0mysql.c
+++ b/storage/innobase/row/row0mysql.c
@@ -2941,7 +2941,7 @@ row_truncate_table_for_mysql(
rec = btr_pcur_get_rec(&pcur);
if (root_page_no != FIL_NULL) {
- page_rec_write_index_page_no(
+ page_rec_write_field(
rec, DICT_SYS_INDEXES_PAGE_NO_FIELD,
root_page_no, &mtr);
/* We will need to commit and restart the
diff --git a/storage/innobase/trx/trx0undo.c b/storage/innobase/trx/trx0undo.c
index 070d6332a4f..4cb4b7b79c5 100644
--- a/storage/innobase/trx/trx0undo.c
+++ b/storage/innobase/trx/trx0undo.c
@@ -1985,8 +1985,6 @@ trx_undo_free_prepared(
/*===================*/
trx_t* trx) /*!< in/out: PREPARED transaction */
{
- mutex_enter(&trx->rseg->mutex);
-
ut_ad(srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS);
if (trx->update_undo) {
@@ -2001,6 +1999,5 @@ trx_undo_free_prepared(
trx->insert_undo);
trx_undo_mem_free(trx->insert_undo);
}
- mutex_exit(&trx->rseg->mutex);
}
#endif /* !UNIV_HOTBACKUP */