diff options
author | Vasil Dimov <vasil.dimov@oracle.com> | 2011-05-22 23:12:46 +0300 |
---|---|---|
committer | Vasil Dimov <vasil.dimov@oracle.com> | 2011-05-22 23:12:46 +0300 |
commit | bf5c6fd8ccdaccb6b9144abd654d6bba92ed06e7 (patch) | |
tree | 129def16cacbd5044a2d9318e038266b3cf58597 /storage/innobase | |
parent | b8c48b4dfc8b1a2f8077b8257ac144102809198a (diff) | |
parent | 30835b55d58c5a2c04085d315bf6f2f1d81ffc30 (diff) | |
download | mariadb-git-bf5c6fd8ccdaccb6b9144abd654d6bba92ed06e7.tar.gz |
Merge mysql-5.5-innodb -> mysql-5.5
Diffstat (limited to 'storage/innobase')
-rw-r--r-- | storage/innobase/dict/dict0crea.c | 15 | ||||
-rw-r--r-- | storage/innobase/dict/dict0load.c | 86 | ||||
-rw-r--r-- | storage/innobase/fil/fil0fil.c | 3 | ||||
-rw-r--r-- | storage/innobase/include/dict0load.h | 7 | ||||
-rw-r--r-- | storage/innobase/include/page0page.h | 15 | ||||
-rw-r--r-- | storage/innobase/include/page0page.ic | 21 | ||||
-rw-r--r-- | storage/innobase/os/os0file.c | 13 | ||||
-rw-r--r-- | storage/innobase/page/page0page.c | 22 | ||||
-rw-r--r-- | storage/innobase/row/row0mysql.c | 2 | ||||
-rw-r--r-- | storage/innobase/trx/trx0undo.c | 3 |
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 */ |