Commit c72506c0 authored by Vasil Dimov's avatar Vasil Dimov

Merge mysql-5.5-innodb -> mysql-5.5

parents c83ed6be 262668e3
...@@ -659,7 +659,7 @@ dict_create_index_tree_step( ...@@ -659,7 +659,7 @@ dict_create_index_tree_step(
/* printf("Created a new index tree in space %lu root page %lu\n", /* printf("Created a new index tree in space %lu root page %lu\n",
index->space, index->page_no); */ index->space, index->page_no); */
page_rec_write_index_page_no(btr_pcur_get_rec(&pcur), page_rec_write_field(btr_pcur_get_rec(&pcur),
DICT_SYS_INDEXES_PAGE_NO_FIELD, DICT_SYS_INDEXES_PAGE_NO_FIELD,
node->page_no, &mtr); node->page_no, &mtr);
btr_pcur_close(&pcur); btr_pcur_close(&pcur);
...@@ -731,8 +731,7 @@ dict_drop_index_tree( ...@@ -731,8 +731,7 @@ dict_drop_index_tree(
root_page_no); */ root_page_no); */
btr_free_root(space, zip_size, root_page_no, mtr); btr_free_root(space, zip_size, root_page_no, mtr);
page_rec_write_index_page_no(rec, page_rec_write_field(rec, DICT_SYS_INDEXES_PAGE_NO_FIELD,
DICT_SYS_INDEXES_PAGE_NO_FIELD,
FIL_NULL, mtr); FIL_NULL, mtr);
} }
...@@ -836,7 +835,7 @@ dict_truncate_index_tree( ...@@ -836,7 +835,7 @@ dict_truncate_index_tree(
in SYS_INDEXES, so that the database will not get into an in SYS_INDEXES, so that the database will not get into an
inconsistent state in case it crashes between the mtr_commit() inconsistent state in case it crashes between the mtr_commit()
below and the following mtr_commit() call. */ below and the following mtr_commit() call. */
page_rec_write_index_page_no(rec, DICT_SYS_INDEXES_PAGE_NO_FIELD, page_rec_write_field(rec, DICT_SYS_INDEXES_PAGE_NO_FIELD,
FIL_NULL, mtr); FIL_NULL, mtr);
/* We will need to commit the mini-transaction in order to avoid /* We will need to commit the mini-transaction in order to avoid
......
...@@ -429,7 +429,7 @@ dict_process_sys_fields_rec( ...@@ -429,7 +429,7 @@ dict_process_sys_fields_rec(
mach_write_to_8(last_index_id, last_id); mach_write_to_8(last_index_id, last_id);
err_msg = dict_load_field_low(buf, NULL, sys_field, 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); *index_id = mach_read_from_8(buf);
...@@ -994,6 +994,9 @@ dict_load_columns( ...@@ -994,6 +994,9 @@ dict_load_columns(
/** Error message for a delete-marked record in dict_load_field_low() */ /** 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_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 Loads an index field definition from a SYS_FIELDS record to
dict_index_t. dict_index_t.
...@@ -1015,7 +1018,12 @@ dict_load_field_low( ...@@ -1015,7 +1018,12 @@ dict_load_field_low(
byte* last_index_id, /*!< in: last index id */ byte* last_index_id, /*!< in: last index id */
mem_heap_t* heap, /*!< in/out: memory heap mem_heap_t* heap, /*!< in/out: memory heap
for temporary storage */ 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; const byte* field;
ulint len; ulint len;
...@@ -1095,6 +1103,19 @@ dict_load_field_low( ...@@ -1095,6 +1103,19 @@ dict_load_field_low(
goto 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) { if (index) {
dict_mem_index_add_field( dict_mem_index_add_field(
index, mem_heap_strdupl(heap, (const char*) field, len), index, mem_heap_strdupl(heap, (const char*) field, len),
...@@ -1155,13 +1176,15 @@ dict_load_fields( ...@@ -1155,13 +1176,15 @@ dict_load_fields(
BTR_SEARCH_LEAF, &pcur, &mtr); BTR_SEARCH_LEAF, &pcur, &mtr);
for (i = 0; i < index->n_fields; i++) { 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); rec = btr_pcur_get_rec(&pcur);
ut_a(btr_pcur_is_on_user_rec(&pcur)); ut_a(btr_pcur_is_on_user_rec(&pcur));
err_msg = dict_load_field_low(buf, index, NULL, NULL, NULL, 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) { if (err_msg == dict_load_field_del) {
/* There could be delete marked records in /* There could be delete marked records in
...@@ -1170,7 +1193,24 @@ dict_load_fields( ...@@ -1170,7 +1193,24 @@ dict_load_fields(
goto next_rec; goto next_rec;
} else if (err_msg) { } else if (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); fprintf(stderr, "InnoDB: %s\n", err_msg);
}
error = DB_CORRUPTION; error = DB_CORRUPTION;
goto func_exit; goto func_exit;
} }
...@@ -1446,7 +1486,26 @@ dict_load_indexes( ...@@ -1446,7 +1486,26 @@ dict_load_indexes(
of the database server */ of the database server */
dict_mem_index_free(index); dict_mem_index_free(index);
} else { } 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, error = dict_index_add_to_cache(table, index,
index->page, FALSE); index->page, FALSE);
/* The data dictionary tables should never contain /* The data dictionary tables should never contain
...@@ -1771,10 +1830,19 @@ dict_load_table( ...@@ -1771,10 +1830,19 @@ dict_load_table(
} else { } else {
table->fk_max_recusive_level = 0; table->fk_max_recusive_level = 0;
} }
} else if (!srv_force_recovery) { } 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); dict_table_remove_from_cache(table);
table = NULL; table = NULL;
} }
}
#if 0 #if 0
if (err != DB_SUCCESS && table != NULL) { if (err != DB_SUCCESS && table != NULL) {
......
...@@ -856,7 +856,8 @@ fil_node_close_file( ...@@ -856,7 +856,8 @@ fil_node_close_file(
ut_a(node->open); ut_a(node->open);
ut_a(node->n_pending == 0); ut_a(node->n_pending == 0);
ut_a(node->n_pending_flushes == 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); ret = os_file_close(node->handle);
ut_a(ret); ut_a(ret);
......
...@@ -155,7 +155,12 @@ dict_load_field_low( ...@@ -155,7 +155,12 @@ dict_load_field_low(
byte* last_index_id, /*!< in: last index id */ byte* last_index_id, /*!< in: last index id */
mem_heap_t* heap, /*!< in/out: memory heap mem_heap_t* heap, /*!< in/out: memory heap
for temporary storage */ 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 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 the cluster definition if the table is a member in a cluster. Also loads
......
...@@ -619,17 +619,16 @@ page_rec_find_owner_rec( ...@@ -619,17 +619,16 @@ page_rec_find_owner_rec(
/*====================*/ /*====================*/
rec_t* rec); /*!< in: the physical record */ rec_t* rec); /*!< in: the physical record */
/***********************************************************************//** /***********************************************************************//**
This is a low-level operation which is used in a database index creation Write a 32-bit field in a data dictionary record. */
to update the page number of a created B-tree to a data dictionary UNIV_INLINE
record. */
UNIV_INTERN
void void
page_rec_write_index_page_no( page_rec_write_field(
/*=========================*/ /*=================*/
rec_t* rec, /*!< in: record to update */ rec_t* rec, /*!< in/out: record to update */
ulint i, /*!< in: index of the field to update */ ulint i, /*!< in: index of the field to update */
ulint page_no,/*!< in: value to write */ 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 Returns the maximum combined size of records which can be inserted on top
of record heap. of record heap.
......
...@@ -959,6 +959,27 @@ page_get_free_space_of_empty( ...@@ -959,6 +959,27 @@ page_get_free_space_of_empty(
- 2 * PAGE_DIR_SLOT_SIZE)); - 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 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 / takes its size plus the fraction of the dir cell size /
......
...@@ -4051,16 +4051,23 @@ os_aio_func( ...@@ -4051,16 +4051,23 @@ os_aio_func(
Windows async i/o, Windows does not allow us to use Windows async i/o, Windows does not allow us to use
ordinary synchronous os_file_read etc. on the same file, ordinary synchronous os_file_read etc. on the same file,
therefore we have built a special mechanism for synchronous 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) { if (type == OS_FILE_READ) {
return(os_file_read(file, buf, offset, return(os_file_read_func(file, buf, offset,
offset_high, n)); offset_high, n));
} }
ut_a(type == OS_FILE_WRITE); 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: try_again:
......
...@@ -1253,28 +1253,6 @@ page_move_rec_list_start( ...@@ -1253,28 +1253,6 @@ page_move_rec_list_start(
return(TRUE); 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 */ #endif /* !UNIV_HOTBACKUP */
/**************************************************************//** /**************************************************************//**
......
...@@ -2941,7 +2941,7 @@ row_truncate_table_for_mysql( ...@@ -2941,7 +2941,7 @@ row_truncate_table_for_mysql(
rec = btr_pcur_get_rec(&pcur); rec = btr_pcur_get_rec(&pcur);
if (root_page_no != FIL_NULL) { if (root_page_no != FIL_NULL) {
page_rec_write_index_page_no( page_rec_write_field(
rec, DICT_SYS_INDEXES_PAGE_NO_FIELD, rec, DICT_SYS_INDEXES_PAGE_NO_FIELD,
root_page_no, &mtr); root_page_no, &mtr);
/* We will need to commit and restart the /* We will need to commit and restart the
......
...@@ -1985,8 +1985,6 @@ trx_undo_free_prepared( ...@@ -1985,8 +1985,6 @@ trx_undo_free_prepared(
/*===================*/ /*===================*/
trx_t* trx) /*!< in/out: PREPARED transaction */ trx_t* trx) /*!< in/out: PREPARED transaction */
{ {
mutex_enter(&trx->rseg->mutex);
ut_ad(srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS); ut_ad(srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS);
if (trx->update_undo) { if (trx->update_undo) {
...@@ -2001,6 +1999,5 @@ trx_undo_free_prepared( ...@@ -2001,6 +1999,5 @@ trx_undo_free_prepared(
trx->insert_undo); trx->insert_undo);
trx_undo_mem_free(trx->insert_undo); trx_undo_mem_free(trx->insert_undo);
} }
mutex_exit(&trx->rseg->mutex);
} }
#endif /* !UNIV_HOTBACKUP */ #endif /* !UNIV_HOTBACKUP */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment