diff options
Diffstat (limited to 'storage/innobase')
25 files changed, 510 insertions, 174 deletions
diff --git a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c index 31be914afa0..5a8ddacac1a 100644 --- a/storage/innobase/buf/buf0buf.c +++ b/storage/innobase/buf/buf0buf.c @@ -520,6 +520,8 @@ UNIV_INTERN ibool buf_page_is_corrupted( /*==================*/ + ibool check_lsn, /*!< in: TRUE if we need to check + and complain about the LSN */ const byte* read_buf, /*!< in: a database page */ ulint zip_size) /*!< in: size of compressed page; 0 for uncompressed pages */ @@ -539,7 +541,7 @@ buf_page_is_corrupted( } #ifndef UNIV_HOTBACKUP - if (recv_lsn_checks_on) { + if (check_lsn && recv_lsn_checks_on) { ib_uint64_t current_lsn; if (log_peek_lsn(¤t_lsn) @@ -1834,7 +1836,7 @@ lookup: buf_read_page(space, zip_size, offset); #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG - ut_a(++buf_dbg_counter % 37 || buf_validate()); + ut_a(++buf_dbg_counter % 5771 || buf_validate()); #endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */ } @@ -2347,7 +2349,7 @@ loop2: } #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG - ut_a(++buf_dbg_counter % 37 || buf_validate()); + ut_a(++buf_dbg_counter % 5771 || buf_validate()); #endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */ goto loop; } @@ -3432,7 +3434,7 @@ buf_page_create( memset(frame + FIL_PAGE_FILE_FLUSH_LSN, 0, 8); #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG - ut_a(++buf_dbg_counter % 357 || buf_validate()); + ut_a(++buf_dbg_counter % 5771 || buf_validate()); #endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */ #ifdef UNIV_IBUF_COUNT_DEBUG ut_a(ibuf_count_get(buf_block_get_space(block), @@ -3575,7 +3577,7 @@ buf_page_io_complete( /* From version 3.23.38 up we store the page checksum to the 4 first bytes of the page end lsn field */ - if (buf_page_is_corrupted(frame, + if (buf_page_is_corrupted(TRUE, frame, buf_page_get_zip_size(bpage))) { corrupt: fprintf(stderr, diff --git a/storage/innobase/dict/dict0crea.c b/storage/innobase/dict/dict0crea.c index cb3dbcbe4ac..bd4e449d11b 100644 --- a/storage/innobase/dict/dict0crea.c +++ b/storage/innobase/dict/dict0crea.c @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2011, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1996, 2013, Oracle and/or its affiliates. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -44,6 +44,21 @@ Created 1/8/1996 Heikki Tuuri #include "ut0vec.h" #include "ha_prototypes.h" +/************************************************************************* +Checks if a table name contains the string TEMP_TABLE_PATH_PREFIX which +denotes temporary tables in MySQL. */ +static +ibool +row_is_mysql_tmp_table_name( +/*========================*/ + /* out: TRUE if temporary table */ + const char* name) /* in: table name in the form + 'database/tablename' */ +{ + return(strstr(name, TEMP_TABLE_PATH_PREFIX) != NULL); +} + + /*****************************************************************//** Based on a table object, this function builds the entry to be inserted in the SYS_TABLES system table. @@ -1424,26 +1439,46 @@ dict_create_add_foreign_to_dictionary( { ulint error; ulint i; - - pars_info_t* info = pars_info_create(); + pars_info_t* info; if (foreign->id == NULL) { - char* stripped_name; /* Generate a new constraint id */ ulint namelen = strlen(table->name); char* id = mem_heap_alloc(foreign->heap, namelen + 20); - /* no overflow if number < 1e13 */ - sprintf(id, "%s_ibfk_%lu", table->name, (ulong) (*id_nr)++); - foreign->id = id; - stripped_name = strchr(foreign->id, '/') + 1; - if (innobase_check_identifier_length(stripped_name)) { - fprintf(stderr, "InnoDB: Generated foreign key " - "name (%s) is too long\n", foreign->id); - return(DB_IDENTIFIER_TOO_LONG); + if (row_is_mysql_tmp_table_name(table->name)) { + sprintf(id, "%s_ibfk_%lu", table->name, + (ulong) (*id_nr)++); + } else { + char table_name[MAX_TABLE_NAME_LEN + 20] = ""; + uint errors = 0; + + strncpy(table_name, table->name, + MAX_TABLE_NAME_LEN + 20); + + innobase_convert_to_system_charset( + strchr(table_name, '/') + 1, + strchr(table->name, '/') + 1, + MAX_TABLE_NAME_LEN, &errors); + + if (errors) { + strncpy(table_name, table->name, + MAX_TABLE_NAME_LEN + 20); + } + + sprintf(id, "%s_ibfk_%lu", table_name, + (ulong) (*id_nr)++); + + if (innobase_check_identifier_length( + strchr(id,'/') + 1)) { + return(DB_IDENTIFIER_TOO_LONG); + } } + foreign->id = id; } + info = pars_info_create(); + pars_info_add_str_literal(info, "id", foreign->id); pars_info_add_str_literal(info, "for_name", table->name); diff --git a/storage/innobase/dict/dict0dict.c b/storage/innobase/dict/dict0dict.c index a887ff0b1ca..aec2264ad1c 100644 --- a/storage/innobase/dict/dict0dict.c +++ b/storage/innobase/dict/dict0dict.c @@ -770,8 +770,10 @@ dict_table_get( /* If table->ibd_file_missing == TRUE, this will print an error message and return without doing anything. */ - dict_update_statistics(table, TRUE /* only update stats - if they have not been initialized */); + dict_update_statistics( + table, + TRUE, /* only update stats if not initialized */ + FALSE /* update even if not changed too much */); } return(table); @@ -1114,22 +1116,78 @@ dict_table_rename_in_cache( dict_mem_foreign_table_name_lookup_set(foreign, FALSE); } if (strchr(foreign->id, '/')) { + /* This is a >= 4.0.18 format id */ + ulint db_len; char* old_id; + char old_name_cs_filename[MAX_TABLE_NAME_LEN+20]; + uint errors = 0; + + /* All table names are internally stored in charset + my_charset_filename (except the temp tables and the + partition identifier suffix in partition tables). The + foreign key constraint names are internally stored + in UTF-8 charset. The variable fkid here is used + to store foreign key constraint name in charset + my_charset_filename for comparison further below. */ + char fkid[MAX_TABLE_NAME_LEN+20]; + ibool on_tmp = FALSE; + + /* The old table name in my_charset_filename is stored + in old_name_cs_filename */ + + strncpy(old_name_cs_filename, old_name, + MAX_TABLE_NAME_LEN); + if (strstr(old_name, TEMP_TABLE_PATH_PREFIX) == NULL) { + + innobase_convert_to_system_charset( + strchr(old_name_cs_filename, '/') + 1, + strchr(old_name, '/') + 1, + MAX_TABLE_NAME_LEN, &errors); + + if (errors) { + /* There has been an error to convert + old table into UTF-8. This probably + means that the old table name is + actually in UTF-8. */ + innobase_convert_to_filename_charset( + strchr(old_name_cs_filename, + '/') + 1, + strchr(old_name, '/') + 1, + MAX_TABLE_NAME_LEN); + } else { + /* Old name already in + my_charset_filename */ + strncpy(old_name_cs_filename, old_name, + MAX_TABLE_NAME_LEN); + } + } - /* This is a >= 4.0.18 format id */ + strncpy(fkid, foreign->id, MAX_TABLE_NAME_LEN); + + if (strstr(fkid, TEMP_TABLE_PATH_PREFIX) == NULL) { + innobase_convert_to_filename_charset( + strchr(fkid, '/') + 1, + strchr(foreign->id, '/') + 1, + MAX_TABLE_NAME_LEN+20); + } else { + on_tmp = TRUE; + } old_id = mem_strdup(foreign->id); - if (ut_strlen(foreign->id) > ut_strlen(old_name) + if (ut_strlen(fkid) > ut_strlen(old_name_cs_filename) + ((sizeof dict_ibfk) - 1) - && !memcmp(foreign->id, old_name, - ut_strlen(old_name)) - && !memcmp(foreign->id + ut_strlen(old_name), + && !memcmp(fkid, old_name_cs_filename, + ut_strlen(old_name_cs_filename)) + && !memcmp(fkid + ut_strlen(old_name_cs_filename), dict_ibfk, (sizeof dict_ibfk) - 1)) { /* This is a generated >= 4.0.18 format id */ + char table_name[MAX_TABLE_NAME_LEN] = ""; + uint errors = 0; + if (strlen(table->name) > strlen(old_name)) { foreign->id = mem_heap_alloc( foreign->heap, @@ -1137,11 +1195,36 @@ dict_table_rename_in_cache( + strlen(old_id) + 1); } + /* Convert the table name to UTF-8 */ + strncpy(table_name, table->name, + MAX_TABLE_NAME_LEN); + innobase_convert_to_system_charset( + strchr(table_name, '/') + 1, + strchr(table->name, '/') + 1, + MAX_TABLE_NAME_LEN, &errors); + + if (errors) { + /* Table name could not be converted + from charset my_charset_filename to + UTF-8. This means that the table name + is already in UTF-8 (#mysql#50). */ + strncpy(table_name, table->name, + MAX_TABLE_NAME_LEN); + } + /* Replace the prefix 'databasename/tablename' with the new names */ - strcpy(foreign->id, table->name); - strcat(foreign->id, - old_id + ut_strlen(old_name)); + strcpy(foreign->id, table_name); + if (on_tmp) { + strcat(foreign->id, + old_id + ut_strlen(old_name)); + } else { + sprintf(strchr(foreign->id, '/') + 1, + "%s%s", + strchr(table_name, '/') +1, + strstr(old_id, "_ibfk_") ); + } + } else { /* This is a >= 4.0.18 format id where the user gave the id name */ @@ -4340,10 +4423,14 @@ void dict_update_statistics( /*===================*/ dict_table_t* table, /*!< in/out: table */ - ibool only_calc_if_missing_stats)/*!< in: only + ibool only_calc_if_missing_stats,/*!< in: only update/recalc the stats if they have not been initialized yet, otherwise do nothing */ + ibool only_calc_if_changed_too_much)/*!< in: only + update/recalc the stats if the table + has been changed too much since the + last stats update/recalc */ { dict_index_t* index; ulint sum_of_index_sizes = 0; @@ -4373,7 +4460,10 @@ dict_update_statistics( dict_table_stats_lock(table, RW_X_LATCH); - if (only_calc_if_missing_stats && table->stat_initialized) { + if ((only_calc_if_missing_stats && table->stat_initialized) + || (only_calc_if_changed_too_much + && !DICT_TABLE_CHANGED_TOO_MUCH(table))) { + dict_table_stats_unlock(table, RW_X_LATCH); return; } @@ -4532,7 +4622,10 @@ dict_table_print_low( ut_ad(mutex_own(&(dict_sys->mutex))); - dict_update_statistics(table, FALSE /* update even if initialized */); + dict_update_statistics( + table, + FALSE, /* update even if initialized */ + FALSE /* update even if not changed too much */); dict_table_stats_lock(table, RW_S_LATCH); @@ -4679,7 +4772,6 @@ dict_print_info_on_foreign_key_in_create_format( dict_foreign_t* foreign, /*!< in: foreign key constraint */ ibool add_newline) /*!< in: whether to add a newline */ { - char constraint_name[MAX_TABLE_NAME_LEN]; const char* stripped_id; ulint i; @@ -4701,9 +4793,7 @@ dict_print_info_on_foreign_key_in_create_format( } fputs(" CONSTRAINT ", file); - innobase_convert_from_id(&my_charset_filename, constraint_name, - stripped_id, MAX_TABLE_NAME_LEN); - ut_print_name(file, trx, FALSE, constraint_name); + ut_print_name(file, trx, FALSE, stripped_id); fputs(" FOREIGN KEY (", file); for (i = 0;;) { diff --git a/storage/innobase/dict/dict0load.c b/storage/innobase/dict/dict0load.c index 208d013e82d..f6e7a417f88 100644 --- a/storage/innobase/dict/dict0load.c +++ b/storage/innobase/dict/dict0load.c @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2010, Innobase Oy. All Rights Reserved. +Copyright (c) 1996, 2013, Innobase Oy. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -352,8 +352,10 @@ dict_process_sys_tables_rec( /* Update statistics if DICT_TABLE_UPDATE_STATS is set */ - dict_update_statistics(*table, FALSE /* update even if - initialized */); + dict_update_statistics( + *table, + FALSE, /* update even if initialized */ + FALSE /* update even if not changed too much */); } return(NULL); diff --git a/storage/innobase/fil/fil0fil.c b/storage/innobase/fil/fil0fil.c index c3a206fb009..3e10d45b3a4 100644 --- a/storage/innobase/fil/fil0fil.c +++ b/storage/innobase/fil/fil0fil.c @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1995, 2010, Innobase Oy. All Rights Reserved. +Copyright (c) 1995, 2013, Oracle and/or its affiliates. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -1860,10 +1860,62 @@ fil_write_flushed_lsn_to_data_files( } /*******************************************************************//** +Checks the consistency of the first data page of a data file +at database startup. +@retval NULL on success, or if innodb_force_recovery is set +@return pointer to an error message string */ +static __attribute__((warn_unused_result)) +const char* +fil_check_first_page( +/*=================*/ + const page_t* page, /*!< in: data page */ + ibool first_page) /*!< in: TRUE if this is the + first page of the tablespace */ +{ + ulint space_id; + ulint flags; + + if (srv_force_recovery >= SRV_FORCE_IGNORE_CORRUPT) { + return(NULL); + } + + space_id = mach_read_from_4(FSP_HEADER_OFFSET + FSP_SPACE_ID + page); + flags = mach_read_from_4(FSP_HEADER_OFFSET + FSP_SPACE_FLAGS + page); + + if (first_page && !space_id && !flags) { + ulint nonzero_bytes = UNIV_PAGE_SIZE; + const byte* b = page; + + while (!*b && --nonzero_bytes) { + b++; + } + + if (!nonzero_bytes) { + return("space header page consists of zero bytes"); + } + } + + if (buf_page_is_corrupted( + FALSE, page, dict_table_flags_to_zip_size(flags))) { + return("checksum mismatch"); + } + + if (!first_page + || (page_get_space_id(page) == space_id + && page_get_page_no(page) == 0)) { + return(NULL); + } + + return("inconsistent data in space header"); +} + +/*******************************************************************//** Reads the flushed lsn, arch no, and tablespace flag fields from a data -file at database startup. */ +file at database startup. +@retval NULL on success, or if innodb_force_recovery is set +@return pointer to an error message string */ UNIV_INTERN -void +const char* fil_read_first_page( /*================*/ os_file_t data_file, /*!< in: open data file */ @@ -1885,6 +1937,7 @@ fil_read_first_page( byte* buf; page_t* page; ib_uint64_t flushed_lsn; + const char* check_msg; buf = ut_malloc(2 * UNIV_PAGE_SIZE); /* Align the memory for a possible read from a raw device */ @@ -1892,13 +1945,18 @@ fil_read_first_page( os_file_read(data_file, page, 0, 0, UNIV_PAGE_SIZE); - *flags = mach_read_from_4(page + - FSP_HEADER_OFFSET + FSP_SPACE_FLAGS); + *flags = mach_read_from_4(FSP_HEADER_OFFSET + FSP_SPACE_FLAGS + page); flushed_lsn = mach_read_from_8(page + FIL_PAGE_FILE_FLUSH_LSN); + check_msg = fil_check_first_page(page, !one_read_already); + ut_free(buf); + if (check_msg) { + return(check_msg); + } + if (!one_read_already) { *min_flushed_lsn = flushed_lsn; *max_flushed_lsn = flushed_lsn; @@ -1906,7 +1964,7 @@ fil_read_first_page( *min_arch_log_no = arch_log_no; *max_arch_log_no = arch_log_no; #endif /* UNIV_LOG_ARCHIVE */ - return; + return(NULL); } if (*min_flushed_lsn > flushed_lsn) { @@ -1923,6 +1981,8 @@ fil_read_first_page( *max_arch_log_no = arch_log_no; } #endif /* UNIV_LOG_ARCHIVE */ + + return(NULL); } /*================ SINGLE-TABLE TABLESPACES ==========================*/ @@ -3151,6 +3211,7 @@ fil_open_single_table_tablespace( os_file_t file; char* filepath; ibool success; + const char* check_msg; byte* buf2; byte* page; ulint space_id; @@ -3211,6 +3272,8 @@ fil_open_single_table_tablespace( success = os_file_read(file, page, 0, 0, UNIV_PAGE_SIZE); + check_msg = fil_check_first_page(page, TRUE); + /* We have to read the tablespace id and flags from the file. */ space_id = fsp_header_get_space_id(page); @@ -3218,8 +3281,20 @@ fil_open_single_table_tablespace( ut_free(buf2); - if (UNIV_UNLIKELY(space_id != id - || space_flags != (flags & ~(~0 << DICT_TF_BITS)))) { + if (check_msg) { + ut_print_timestamp(stderr); + fprintf(stderr, " InnoDB: Error: %s in file ", check_msg); + ut_print_filename(stderr, filepath); + fprintf(stderr, " (tablespace id=%lu, flags=%lu)\n" + "InnoDB: Please refer to " REFMAN + "innodb-troubleshooting-datadict.html\n", + (ulong) id, (ulong) flags); + success = FALSE; + goto func_exit; + } + + if (space_id != id + || space_flags != (flags & ~(~0 << DICT_TF_BITS))) { ut_print_timestamp(stderr); fputs(" InnoDB: Error: tablespace id and flags in file ", @@ -3447,10 +3522,21 @@ fil_load_single_table_tablespace( page = ut_align(buf2, UNIV_PAGE_SIZE); if (size >= FIL_IBD_FILE_INITIAL_SIZE * UNIV_PAGE_SIZE) { + const char* check_msg; + success = os_file_read(file, page, 0, 0, UNIV_PAGE_SIZE); /* We have to read the tablespace id from the file */ + check_msg = fil_check_first_page(page, TRUE); + + if (check_msg) { + fprintf(stderr, + "InnoDB: Error: %s in file %s", + check_msg, filepath); + goto func_exit; + } + space_id = fsp_header_get_space_id(page); flags = fsp_header_get_flags(page); } else { diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 0bedbcca73c..3545d5b53bb 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -1162,33 +1162,27 @@ innobase_convert_from_table_id( /********************************************************************** Check if the length of the identifier exceeds the maximum allowed. -The input to this function is an identifier in charset my_charset_filename. return true when length of identifier is too long. */ -extern "C" UNIV_INTERN +extern "C" my_bool innobase_check_identifier_length( /*=============================*/ - const char* id) /* in: identifier to check. it must belong - to charset my_charset_filename */ + const char* id) /* in: FK identifier to check excluding the + database portion. */ { - char tmp[MAX_TABLE_NAME_LEN + 10]; - uint errors; - uint len; int well_formed_error = 0; - CHARSET_INFO* cs1 = &my_charset_filename; - CHARSET_INFO* cs2 = thd_charset(current_thd); + CHARSET_INFO *cs = system_charset_info; + DBUG_ENTER("innobase_check_identifier_length"); - len = strconvert(cs1, id, cs2, tmp, MAX_TABLE_NAME_LEN + 10, &errors); + uint res = cs->cset->well_formed_len(cs, id, id + strlen(id), + NAME_CHAR_LEN, + &well_formed_error); - uint res = cs2->cset->well_formed_len(cs2, tmp, tmp + len, - NAME_CHAR_LEN, - &well_formed_error); - - if (well_formed_error || res != len) { - my_error(ER_TOO_LONG_IDENT, MYF(0), tmp); - return(true); + if (well_formed_error || res == NAME_CHAR_LEN) { + my_error(ER_TOO_LONG_IDENT, MYF(0), id); + DBUG_RETURN(true); } - return(false); + DBUG_RETURN(false); } /******************************************************************//** @@ -3916,7 +3910,6 @@ ha_innobase::open( dict_table_t* ib_table; char norm_name[1000]; THD* thd; - ulint retries = 0; char* is_part = NULL; ibool par_case_name_set = FALSE; char par_case_name[MAX_FULL_NAME_LEN + 1]; @@ -3949,22 +3942,18 @@ ha_innobase::open( upd_buf_size = 0; /* We look for pattern #P# to see if the table is partitioned - MySQL table. The retry logic for partitioned tables is a - workaround for http://bugs.mysql.com/bug.php?id=33349. Look - at support issue https://support.mysql.com/view.php?id=21080 - for more details. */ + MySQL table. */ #ifdef __WIN__ is_part = strstr(norm_name, "#p#"); #else is_part = strstr(norm_name, "#P#"); #endif /* __WIN__ */ -retry: /* Get pointer to a table object in InnoDB dictionary cache */ ib_table = dict_table_get(norm_name, TRUE); if (NULL == ib_table) { - if (is_part && retries < 10) { + if (is_part) { /* MySQL partition engine hard codes the file name separator as "#P#". The text case is fixed even if lower_case_table_names is set to 1 or 2. This is true @@ -4007,11 +3996,7 @@ retry: ib_table = dict_table_get( par_case_name, FALSE); } - if (!ib_table) { - ++retries; - os_thread_sleep(100000); - goto retry; - } else { + if (ib_table) { #ifndef __WIN__ sql_print_warning("Partition table %s opened " "after converting to lower " @@ -4037,9 +4022,8 @@ retry: } if (is_part) { - sql_print_error("Failed to open table %s after " - "%lu attempts.\n", norm_name, - retries); + sql_print_error("Failed to open table %s.\n", + norm_name); } sql_print_error("Cannot find or open table %s from\n" @@ -8227,9 +8211,10 @@ ha_innobase::info_low( prebuilt->trx->op_info = "updating table statistics"; - dict_update_statistics(ib_table, - FALSE /* update even if stats - are initialized */); + dict_update_statistics( + ib_table, + FALSE, /* update even if initialized */ + FALSE /* update even if not changed too much */); prebuilt->trx->op_info = "returning various info to MySQL"; } @@ -12123,3 +12108,55 @@ test_innobase_convert_name() } #endif /* UNIV_COMPILE_TEST_FUNCS */ + +/********************************************************************** +Converts an identifier from my_charset_filename to UTF-8 charset. */ +extern "C" +uint +innobase_convert_to_filename_charset( +/*=================================*/ + char* to, /* out: converted identifier */ + const char* from, /* in: identifier to convert */ + ulint len) /* in: length of 'to', in bytes */ +{ + uint errors; + uint rlen; + CHARSET_INFO* cs_to = &my_charset_filename; + CHARSET_INFO* cs_from = system_charset_info; + + rlen = strconvert(cs_from, from, cs_to, to, len, &errors); + + if (errors) { + fprintf(stderr, "InnoDB: There was a problem in converting" + "'%s' in charset %s to charset %s", from, cs_from->name, + cs_to->name); + } + + return(rlen); +} + +/********************************************************************** +Converts an identifier from my_charset_filename to UTF-8 charset. */ +extern "C" +uint +innobase_convert_to_system_charset( +/*===============================*/ + char* to, /* out: converted identifier */ + const char* from, /* in: identifier to convert */ + ulint len, /* in: length of 'to', in bytes */ + uint* errors) /* out: error return */ +{ + uint rlen; + CHARSET_INFO* cs1 = &my_charset_filename; + CHARSET_INFO* cs2 = system_charset_info; + + rlen = strconvert(cs1, from, cs2, to, len, errors); + + if (*errors) { + fprintf(stderr, "InnoDB: There was a problem in converting" + "'%s' in charset %s to charset %s", from, cs1->name, + cs2->name); + } + + return(rlen); +} diff --git a/storage/innobase/ibuf/ibuf0ibuf.c b/storage/innobase/ibuf/ibuf0ibuf.c index 11505121fa2..46a8d5b744c 100644 --- a/storage/innobase/ibuf/ibuf0ibuf.c +++ b/storage/innobase/ibuf/ibuf0ibuf.c @@ -4271,7 +4271,7 @@ Deletes from ibuf the record on which pcur is positioned. If we have to resort to a pessimistic delete, this function commits mtr and closes the cursor. @return TRUE if mtr was committed and pcur closed in this operation */ -static +static __attribute__((warn_unused_result)) ibool ibuf_delete_rec( /*============*/ @@ -4577,6 +4577,12 @@ ibuf_merge_or_delete_for_page( loop: ibuf_mtr_start(&mtr); + /* Position pcur in the insert buffer at the first entry for this + index page */ + btr_pcur_open_on_user_rec( + ibuf->index, search_tuple, PAGE_CUR_GE, BTR_MODIFY_LEAF, + &pcur, &mtr); + if (block) { ibool success; @@ -4595,12 +4601,6 @@ loop: buf_block_dbg_add_level(block, SYNC_IBUF_TREE_NODE); } - /* Position pcur in the insert buffer at the first entry for this - index page */ - btr_pcur_open_on_user_rec( - ibuf->index, search_tuple, PAGE_CUR_GE, BTR_MODIFY_LEAF, - &pcur, &mtr); - if (!btr_pcur_is_on_user_rec(&pcur)) { ut_ad(btr_pcur_is_after_last_in_tree(&pcur, &mtr)); @@ -4743,6 +4743,7 @@ loop: /* Deletion was pessimistic and mtr was committed: we start from the beginning again */ + ut_ad(mtr.state == MTR_COMMITTED); goto loop; } else if (btr_pcur_is_after_last_on_page(&pcur)) { ibuf_mtr_commit(&mtr); @@ -4873,6 +4874,7 @@ loop: /* Deletion was pessimistic and mtr was committed: we start from the beginning again */ + ut_ad(mtr.state == MTR_COMMITTED); goto loop; } diff --git a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h index b7f6eae3f09..562f2f0887c 100644 --- a/storage/innobase/include/buf0buf.h +++ b/storage/innobase/include/buf0buf.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1995, 2012, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1995, 2013, Oracle and/or its affiliates. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -663,9 +663,12 @@ UNIV_INTERN ibool buf_page_is_corrupted( /*==================*/ + ibool check_lsn, /*!< in: TRUE if we need to check + and complain about the LSN */ const byte* read_buf, /*!< in: a database page */ - ulint zip_size); /*!< in: size of compressed page; + ulint zip_size) /*!< in: size of compressed page; 0 for uncompressed pages */ + __attribute__((warn_unused_result)); #ifndef UNIV_HOTBACKUP /**********************************************************************//** Gets the space id, page offset, and byte offset within page of a diff --git a/storage/innobase/include/dict0dict.h b/storage/innobase/include/dict0dict.h index 54af14313c4..7b55a59ea19 100644 --- a/storage/innobase/include/dict0dict.h +++ b/storage/innobase/include/dict0dict.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2012, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1996, 2013, Oracle and/or its affiliates. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -1124,6 +1124,18 @@ ulint dict_index_calc_min_rec_len( /*========================*/ const dict_index_t* index); /*!< in: index */ + +/** Calculate new statistics if 1 / 16 of table has been modified +since the last time a statistics batch was run. +We calculate statistics at most every 16th round, since we may have +a counter table which is very small and updated very often. +@param t table +@return true if the table has changed too much and stats need to be +recalculated +*/ +#define DICT_TABLE_CHANGED_TOO_MUCH(t) \ + ((ib_int64_t) (t)->stat_modified_counter > 16 + (t)->stat_n_rows / 16) + /*********************************************************************//** Calculates new estimates for table and index statistics. The statistics are used in query optimization. */ @@ -1132,10 +1144,14 @@ void dict_update_statistics( /*===================*/ dict_table_t* table, /*!< in/out: table */ - ibool only_calc_if_missing_stats);/*!< in: only + ibool only_calc_if_missing_stats,/*!< in: only update/recalc the stats if they have not been initialized yet, otherwise do nothing */ + ibool only_calc_if_changed_too_much);/*!< in: only + update/recalc the stats if the table + has been changed too much since the + last stats update/recalc */ /********************************************************************//** Reserves the dictionary system mutex for MySQL. */ UNIV_INTERN diff --git a/storage/innobase/include/dict0mem.h b/storage/innobase/include/dict0mem.h index 980417715b3..0ee5721d34b 100644 --- a/storage/innobase/include/dict0mem.h +++ b/storage/innobase/include/dict0mem.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2012, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1996, 2013, Oracle and/or its affiliates. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -127,7 +127,7 @@ This could result in rescursive calls and out of stack error eventually. DICT_FK_MAX_RECURSIVE_LOAD defines the maximum number of recursive loads, when exceeded, the child table will not be loaded. It will be loaded when the foreign constraint check needs to be run. */ -#define DICT_FK_MAX_RECURSIVE_LOAD 255 +#define DICT_FK_MAX_RECURSIVE_LOAD 20 /** Similarly, when tables are chained together with foreign key constraints with on cascading delete/update clause, delete from parent table could @@ -607,7 +607,13 @@ struct dict_table_struct{ /*!< flag: TRUE if the maximum length of a single row exceeds BIG_ROW_SIZE; initialized in dict_table_add_to_cache() */ - /** Statistics for query optimization */ + /** Statistics for query optimization. + The following stat_* members are usually + protected by dict_table_stats_lock(). In + some exceptional cases (performance critical + code paths) we access or modify stat_n_rows + and stat_modified_counter without any + protection. */ /* @{ */ unsigned stat_initialized:1; /*!< TRUE if statistics have been calculated the first time diff --git a/storage/innobase/include/dict0types.h b/storage/innobase/include/dict0types.h index f0a05a38070..8e3a04f7956 100644 --- a/storage/innobase/include/dict0types.h +++ b/storage/innobase/include/dict0types.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2009, Innobase Oy. All Rights Reserved. +Copyright (c) 1996, 2013, Oracle and/or its affiliates. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -58,4 +58,7 @@ enum dict_err_ignore { typedef enum dict_err_ignore dict_err_ignore_t; +#define TEMP_TABLE_PREFIX "#sql" +#define TEMP_TABLE_PATH_PREFIX "/" TEMP_TABLE_PREFIX + #endif diff --git a/storage/innobase/include/fil0fil.h b/storage/innobase/include/fil0fil.h index a804c261447..dd188e4dad1 100644 --- a/storage/innobase/include/fil0fil.h +++ b/storage/innobase/include/fil0fil.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1995, 2010, Innobase Oy. All Rights Reserved. +Copyright (c) 1995, 2013, Oracle and/or its affiliates. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -326,10 +326,12 @@ fil_write_flushed_lsn_to_data_files( ulint arch_log_no); /*!< in: latest archived log file number */ /*******************************************************************//** -Reads the flushed lsn and arch no fields from a data file at database -startup. */ +Reads the flushed lsn, arch no, and tablespace flag fields from a data +file at database startup. +@retval NULL on success, or if innodb_force_recovery is set +@return pointer to an error message string */ UNIV_INTERN -void +const char* fil_read_first_page( /*================*/ os_file_t data_file, /*!< in: open data file */ @@ -345,8 +347,9 @@ fil_read_first_page( #endif /* UNIV_LOG_ARCHIVE */ ib_uint64_t* min_flushed_lsn, /*!< out: min of flushed lsn values in data files */ - ib_uint64_t* max_flushed_lsn); /*!< out: max of flushed + ib_uint64_t* max_flushed_lsn) /*!< out: max of flushed lsn values in data files */ + __attribute__((warn_unused_result)); /*******************************************************************//** Increments the count of pending operation, if space is not being deleted. @return TRUE if being deleted, and operation should be skipped */ diff --git a/storage/innobase/include/ha_prototypes.h b/storage/innobase/include/ha_prototypes.h index ae0188fdaa1..dc730f9b6b3 100644 --- a/storage/innobase/include/ha_prototypes.h +++ b/storage/innobase/include/ha_prototypes.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2006, 2010, Innobase Oy. All Rights Reserved. +Copyright (c) 2000, 2013, Oracle and/or its affiliates. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -307,4 +307,24 @@ innobase_check_identifier_length( const char* id); /* in: identifier to check. it must belong to charset my_charset_filename */ +/********************************************************************** +Converts an identifier from my_charset_filename to UTF-8 charset. */ +uint +innobase_convert_to_system_charset( +/*===============================*/ + char* to, /* out: converted identifier */ + const char* from, /* in: identifier to convert */ + ulint len, /* in: length of 'to', in bytes */ + uint* errors); /* out: error return */ + +/********************************************************************** +Converts an identifier from my_charset_filename to UTF-8 charset. */ +uint +innobase_convert_to_filename_charset( +/*=================================*/ + char* to, /* out: converted identifier */ + const char* from, /* in: identifier to convert */ + ulint len); /* in: length of 'to', in bytes */ + + #endif diff --git a/storage/innobase/include/os0file.h b/storage/innobase/include/os0file.h index 8ef0906ff5f..9d1b3f18f8a 100644 --- a/storage/innobase/include/os0file.h +++ b/storage/innobase/include/os0file.h @@ -21,7 +21,7 @@ Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., -59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA ***********************************************************************/ diff --git a/storage/innobase/include/page0zip.ic b/storage/innobase/include/page0zip.ic index b5480604bdf..9e9dda90936 100644 --- a/storage/innobase/include/page0zip.ic +++ b/storage/innobase/include/page0zip.ic @@ -229,9 +229,7 @@ ibool page_zip_get_trailer_len( /*=====================*/ const page_zip_des_t* page_zip,/*!< in: compressed page */ - ibool is_clust,/*!< in: TRUE if clustered index */ - ulint* entry_size)/*!< out: size of the uncompressed - portion of a user record */ + ibool is_clust)/*!< in: TRUE if clustered index */ { ulint uncompressed_size; @@ -250,10 +248,6 @@ page_zip_get_trailer_len( ut_ad(!page_zip->n_blobs); } - if (entry_size) { - *entry_size = uncompressed_size; - } - return((page_dir_get_n_heap(page_zip->data) - 2) * uncompressed_size + page_zip->n_blobs * BTR_EXTERN_FIELD_REF_SIZE); @@ -270,11 +264,9 @@ page_zip_max_ins_size( const page_zip_des_t* page_zip,/*!< in: compressed page */ ibool is_clust)/*!< in: TRUE if clustered index */ { - ulint uncompressed_size; ulint trailer_len; - trailer_len = page_zip_get_trailer_len(page_zip, is_clust, - &uncompressed_size); + trailer_len = page_zip_get_trailer_len(page_zip, is_clust); /* When a record is created, a pointer may be added to the dense directory. @@ -283,7 +275,7 @@ page_zip_max_ins_size( Also the BLOB pointers will be allocated from there, but we may as well count them in the length of the record. */ - trailer_len += uncompressed_size; + trailer_len += PAGE_ZIP_DIR_SLOT_SIZE; return((lint) page_zip_get_size(page_zip) - trailer_len - page_zip->m_end @@ -303,13 +295,11 @@ page_zip_available( ulint create) /*!< in: nonzero=add the record to the heap */ { - ulint uncompressed_size; ulint trailer_len; ut_ad(length > REC_N_NEW_EXTRA_BYTES); - trailer_len = page_zip_get_trailer_len(page_zip, is_clust, - &uncompressed_size); + trailer_len = page_zip_get_trailer_len(page_zip, is_clust); /* Subtract the fixed extra bytes and add the maximum space needed for identifying the record (encoded heap_no). */ @@ -323,7 +313,7 @@ page_zip_available( Also the BLOB pointers will be allocated from there, but we may as well count them in the length of the record. */ - trailer_len += uncompressed_size; + trailer_len += PAGE_ZIP_DIR_SLOT_SIZE; } return(UNIV_LIKELY(length diff --git a/storage/innobase/lock/lock0lock.c b/storage/innobase/lock/lock0lock.c index a5ce43496af..cd9db2a02b1 100644 --- a/storage/innobase/lock/lock0lock.c +++ b/storage/innobase/lock/lock0lock.c @@ -4980,6 +4980,7 @@ lock_rec_validate_page( { const lock_t* lock; const rec_t* rec; + dict_index_t* index; ulint nth_lock = 0; ulint nth_bit = 0; ulint i; @@ -5029,6 +5030,7 @@ loop: if (i == 1 || lock_rec_get_nth_bit(lock, i)) { + index = lock->index; rec = page_find_rec_with_heap_no(block->frame, i); ut_a(rec); offsets = rec_get_offsets(rec, lock->index, offsets, @@ -5045,7 +5047,7 @@ loop: check WILL break the latching order and may cause a deadlock of threads. */ - lock_rec_queue_validate(block, rec, lock->index, + lock_rec_queue_validate(block, rec, index, offsets); lock_mutex_enter_kernel(); diff --git a/storage/innobase/log/log0recv.c b/storage/innobase/log/log0recv.c index c4ad94a4906..814736d9b14 100644 --- a/storage/innobase/log/log0recv.c +++ b/storage/innobase/log/log0recv.c @@ -1648,19 +1648,6 @@ recv_recover_page_func( } #endif /* UNIV_ZIP_DEBUG */ - mutex_enter(&(recv_sys->mutex)); - - if (recv_max_page_lsn < page_lsn) { - recv_max_page_lsn = page_lsn; - } - - recv_addr->state = RECV_PROCESSED; - - ut_a(recv_sys->n_addrs); - recv_sys->n_addrs--; - - mutex_exit(&(recv_sys->mutex)); - #ifndef UNIV_HOTBACKUP if (modification_to_page) { ut_a(block); @@ -1677,6 +1664,20 @@ recv_recover_page_func( mtr.modifications = FALSE; mtr_commit(&mtr); + + mutex_enter(&(recv_sys->mutex)); + + if (recv_max_page_lsn < page_lsn) { + recv_max_page_lsn = page_lsn; + } + + recv_addr->state = RECV_PROCESSED; + + ut_a(recv_sys->n_addrs); + recv_sys->n_addrs--; + + mutex_exit(&(recv_sys->mutex)); + } #ifndef UNIV_HOTBACKUP diff --git a/storage/innobase/mem/mem0mem.c b/storage/innobase/mem/mem0mem.c index 7727760f1cd..797de06c896 100644 --- a/storage/innobase/mem/mem0mem.c +++ b/storage/innobase/mem/mem0mem.c @@ -353,7 +353,13 @@ mem_heap_create_block( block = (mem_block_t*) buf_block->frame; } - ut_ad(block); + if(!block) { + ut_print_timestamp(stderr); + fprintf(stderr, + " InnoDB: Unable to allocate memory of size %lu.\n", + len); + ut_error; + } block->buf_block = buf_block; block->free_block = NULL; #else /* !UNIV_HOTBACKUP */ diff --git a/storage/innobase/os/os0file.c b/storage/innobase/os/os0file.c index 0d036f6f032..8fc22fbd119 100644 --- a/storage/innobase/os/os0file.c +++ b/storage/innobase/os/os0file.c @@ -21,7 +21,7 @@ Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., -59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA ***********************************************************************/ diff --git a/storage/innobase/page/page0zip.c b/storage/innobase/page/page0zip.c index f9338da079e..a4a357ae44a 100644 --- a/storage/innobase/page/page0zip.c +++ b/storage/innobase/page/page0zip.c @@ -2271,13 +2271,12 @@ zlib_done: if (UNIV_UNLIKELY (page_zip_get_trailer_len(page_zip, - dict_index_is_clust(index), NULL) + dict_index_is_clust(index)) + page_zip->m_end >= page_zip_get_size(page_zip))) { page_zip_fail(("page_zip_decompress_node_ptrs:" " %lu + %lu >= %lu, %lu\n", (ulong) page_zip_get_trailer_len( - page_zip, dict_index_is_clust(index), - NULL), + page_zip, dict_index_is_clust(index)), (ulong) page_zip->m_end, (ulong) page_zip_get_size(page_zip), (ulong) dict_index_is_clust(index))); @@ -2428,12 +2427,12 @@ zlib_done: page_zip->m_nonempty = mod_log_ptr != d_stream->next_in; } - if (UNIV_UNLIKELY(page_zip_get_trailer_len(page_zip, FALSE, NULL) + if (UNIV_UNLIKELY(page_zip_get_trailer_len(page_zip, FALSE) + page_zip->m_end >= page_zip_get_size(page_zip))) { page_zip_fail(("page_zip_decompress_sec: %lu + %lu >= %lu\n", (ulong) page_zip_get_trailer_len( - page_zip, FALSE, NULL), + page_zip, FALSE), (ulong) page_zip->m_end, (ulong) page_zip_get_size(page_zip))); return(FALSE); @@ -2759,12 +2758,12 @@ zlib_done: page_zip->m_nonempty = mod_log_ptr != d_stream->next_in; } - if (UNIV_UNLIKELY(page_zip_get_trailer_len(page_zip, TRUE, NULL) + if (UNIV_UNLIKELY(page_zip_get_trailer_len(page_zip, TRUE) + page_zip->m_end >= page_zip_get_size(page_zip))) { page_zip_fail(("page_zip_decompress_clust: %lu + %lu >= %lu\n", (ulong) page_zip_get_trailer_len( - page_zip, TRUE, NULL), + page_zip, TRUE), (ulong) page_zip->m_end, (ulong) page_zip_get_size(page_zip))); return(FALSE); @@ -4639,8 +4638,7 @@ page_zip_copy_recs( memcpy(page_zip, src_zip, sizeof *page_zip); page_zip->data = data; } - ut_ad(page_zip_get_trailer_len(page_zip, - dict_index_is_clust(index), NULL) + ut_ad(page_zip_get_trailer_len(page_zip, dict_index_is_clust(index)) + page_zip->m_end < page_zip_get_size(page_zip)); if (!page_is_leaf(src) diff --git a/storage/innobase/row/row0ins.c b/storage/innobase/row/row0ins.c index 21afa9eff0d..8312ef38311 100644 --- a/storage/innobase/row/row0ins.c +++ b/storage/innobase/row/row0ins.c @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2012, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1996, 2013, Oracle and/or its affiliates. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -1698,6 +1698,7 @@ row_ins_scan_sec_index_for_duplicate( do { const rec_t* rec = btr_pcur_get_rec(&pcur); const buf_block_t* block = btr_pcur_get_block(&pcur); + ulint lock_type; if (page_rec_is_infimum(rec)) { @@ -1707,6 +1708,16 @@ row_ins_scan_sec_index_for_duplicate( offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &heap); + /* If the transaction isolation level is no stronger than + READ COMMITTED, then avoid gap locks. */ + if (!page_rec_is_supremum(rec) + && thr_get_trx(thr)->isolation_level + <= TRX_ISO_READ_COMMITTED) { + lock_type = LOCK_REC_NOT_GAP; + } else { + lock_type = LOCK_ORDINARY; + } + if (allow_duplicates) { /* If the SQL-query will update or replace @@ -1715,13 +1726,11 @@ row_ins_scan_sec_index_for_duplicate( INSERT ON DUPLICATE KEY UPDATE). */ err = row_ins_set_exclusive_rec_lock( - LOCK_ORDINARY, block, - rec, index, offsets, thr); + lock_type, block, rec, index, offsets, thr); } else { err = row_ins_set_shared_rec_lock( - LOCK_ORDINARY, block, - rec, index, offsets, thr); + lock_type, block, rec, index, offsets, thr); } switch (err) { diff --git a/storage/innobase/row/row0mysql.c b/storage/innobase/row/row0mysql.c index 77fa6518b35..ff8f79f4f3f 100644 --- a/storage/innobase/row/row0mysql.c +++ b/storage/innobase/row/row0mysql.c @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2000, 2012, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2000, 2013, Oracle and/or its affiliates. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -53,7 +53,7 @@ Created 9/17/2000 Heikki Tuuri #include "ibuf0ibuf.h" #include "m_string.h" #include "my_sys.h" - +#include "ha_prototypes.h" /** Provide optional 4.x backwards compatibility for 5.0 and above */ UNIV_INTERN ibool row_rollback_on_timeout = FALSE; @@ -962,17 +962,12 @@ row_update_statistics_if_needed( table->stat_modified_counter = counter + 1; - /* Calculate new statistics if 1 / 16 of table has been modified - since the last time a statistics batch was run, or if - stat_modified_counter > 2 000 000 000 (to avoid wrap-around). - We calculate statistics at most every 16th round, since we may have - a counter table which is very small and updated very often. */ - - if (counter > 2000000000 - || ((ib_int64_t)counter > 16 + table->stat_n_rows / 16)) { + if (DICT_TABLE_CHANGED_TOO_MUCH(table)) { - dict_update_statistics(table, FALSE /* update even if stats - are initialized */); + dict_update_statistics( + table, + FALSE, /* update even if stats are initialized */ + TRUE /* only update if stats changed too much */); } } @@ -3050,8 +3045,10 @@ next_rec: dict_table_autoinc_lock(table); dict_table_autoinc_initialize(table, 1); dict_table_autoinc_unlock(table); - dict_update_statistics(table, FALSE /* update even if stats are - initialized */); + dict_update_statistics( + table, + FALSE, /* update even if stats are initialized */ + FALSE /* update even if not changed too much */); trx_commit_for_mysql(trx); @@ -3959,12 +3956,29 @@ row_rename_table_for_mysql( goto end; } else if (!new_is_tmp) { /* Rename all constraints. */ + char new_table_name[MAX_TABLE_NAME_LEN] = ""; + uint errors = 0; info = pars_info_create(); pars_info_add_str_literal(info, "new_table_name", new_name); pars_info_add_str_literal(info, "old_table_name", old_name); + strncpy(new_table_name, new_name, MAX_TABLE_NAME_LEN); + innobase_convert_to_system_charset( + strchr(new_table_name, '/') + 1, + strchr(new_name, '/') +1, + MAX_TABLE_NAME_LEN, &errors); + + if (errors) { + /* Table name could not be converted from charset + my_charset_filename to UTF-8. This means that the + table name is already in UTF-8 (#mysql#50). */ + strncpy(new_table_name, new_name, MAX_TABLE_NAME_LEN); + } + + pars_info_add_str_literal(info, "new_table_utf8", new_table_name); + err = que_eval_sql( info, "PROCEDURE RENAME_CONSTRAINT_IDS () IS\n" @@ -3976,6 +3990,7 @@ row_rename_table_for_mysql( "old_t_name_len INT;\n" "new_db_name_len INT;\n" "id_len INT;\n" + "offset INT;\n" "found INT;\n" "BEGIN\n" "found := 1;\n" @@ -3984,8 +3999,6 @@ row_rename_table_for_mysql( "new_db_name := SUBSTR(:new_table_name, 0,\n" " new_db_name_len);\n" "old_t_name_len := LENGTH(:old_table_name);\n" - "gen_constr_prefix := CONCAT(:old_table_name,\n" - " '_ibfk_');\n" "WHILE found = 1 LOOP\n" " SELECT ID INTO foreign_id\n" " FROM SYS_FOREIGN\n" @@ -4002,12 +4015,13 @@ row_rename_table_for_mysql( " id_len := LENGTH(foreign_id);\n" " IF (INSTR(foreign_id, '/') > 0) THEN\n" " IF (INSTR(foreign_id,\n" - " gen_constr_prefix) > 0)\n" + " '_ibfk_') > 0)\n" " THEN\n" + " offset := INSTR(foreign_id, '_ibfk_') - 1;\n" " new_foreign_id :=\n" - " CONCAT(:new_table_name,\n" - " SUBSTR(foreign_id, old_t_name_len,\n" - " id_len - old_t_name_len));\n" + " CONCAT(:new_table_utf8,\n" + " SUBSTR(foreign_id, offset,\n" + " id_len - offset));\n" " ELSE\n" " new_foreign_id :=\n" " CONCAT(new_db_name,\n" diff --git a/storage/innobase/srv/srv0srv.c b/storage/innobase/srv/srv0srv.c index 86caf9d4243..849e97b31f7 100644 --- a/storage/innobase/srv/srv0srv.c +++ b/storage/innobase/srv/srv0srv.c @@ -1719,7 +1719,8 @@ srv_suspend_mysql_thread( finish_time = (ib_int64_t) sec * 1000000 + ms; } - diff_time = (ulint) (finish_time - start_time); + diff_time = (finish_time > start_time) ? + (ulint) (finish_time - start_time) : 0; srv_n_lock_wait_current_count--; srv_n_lock_wait_time = srv_n_lock_wait_time + diff_time; diff --git a/storage/innobase/srv/srv0start.c b/storage/innobase/srv/srv0start.c index 86669a50895..d3d2e956e22 100644 --- a/storage/innobase/srv/srv0start.c +++ b/storage/innobase/srv/srv0start.c @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2010, Innobase Oy. All Rights Reserved. +Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. Copyright (c) 2008, Google Inc. Copyright (c) 2009, Percona Inc. @@ -818,6 +818,7 @@ open_or_create_data_files( } if (ret == FALSE) { + const char* check_msg; /* We open the data file */ if (one_created) { @@ -915,13 +916,20 @@ open_or_create_data_files( return(DB_ERROR); } skip_size_check: - fil_read_first_page( + check_msg = fil_read_first_page( files[i], one_opened, &flags, #ifdef UNIV_LOG_ARCHIVE min_arch_log_no, max_arch_log_no, #endif /* UNIV_LOG_ARCHIVE */ min_flushed_lsn, max_flushed_lsn); + if (check_msg) { + fprintf(stderr, + "InnoDB: Error: %s in data file %s\n", + check_msg, name); + return(DB_ERROR); + } + if (!one_opened && UNIV_PAGE_SIZE != fsp_flags_get_page_size(flags)) { diff --git a/storage/innobase/trx/trx0sys.c b/storage/innobase/trx/trx0sys.c index bc51dc43032..256e22d1b50 100644 --- a/storage/innobase/trx/trx0sys.c +++ b/storage/innobase/trx/trx0sys.c @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2012, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1996, 2013, Oracle and/or its affiliates. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -564,7 +564,8 @@ trx_sys_doublewrite_init_or_restore_pages( /* Check if the page is corrupt */ if (UNIV_UNLIKELY - (buf_page_is_corrupted(read_buf, zip_size))) { + (buf_page_is_corrupted( + TRUE, read_buf, zip_size))) { fprintf(stderr, "InnoDB: Warning: database page" @@ -575,7 +576,8 @@ trx_sys_doublewrite_init_or_restore_pages( " the doublewrite buffer.\n", (ulong) space_id, (ulong) page_no); - if (buf_page_is_corrupted(page, zip_size)) { + if (buf_page_is_corrupted( + TRUE, page, zip_size)) { fprintf(stderr, "InnoDB: Dump of the page:\n"); buf_page_print( |