From 139ba26dbacc37858d7746b8ef53a7330f9a8fcc Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 16 Jun 2015 10:57:05 +0200 Subject: 5.6.25 --- storage/innobase/api/api0api.cc | 15 ++ storage/innobase/buf/buf0buf.cc | 277 ++++++++++++++++++++-------------- storage/innobase/buf/buf0checksum.cc | 11 +- storage/innobase/handler/ha_innodb.cc | 37 +++-- storage/innobase/include/api0api.h | 10 +- storage/innobase/include/os0file.h | 8 +- storage/innobase/include/page0page.h | 16 +- storage/innobase/os/os0file.cc | 11 +- storage/innobase/page/page0page.cc | 44 +++++- storage/innobase/page/page0zip.cc | 97 ++++++++++-- storage/innobase/row/row0mysql.cc | 95 ++++-------- storage/innobase/srv/srv0start.cc | 34 ++++- storage/innobase/sync/sync0arr.cc | 8 +- storage/innobase/trx/trx0sys.cc | 4 - storage/innobase/trx/trx0trx.cc | 5 +- 15 files changed, 436 insertions(+), 236 deletions(-) diff --git a/storage/innobase/api/api0api.cc b/storage/innobase/api/api0api.cc index d5dd9ca0081..ad8a29d7439 100644 --- a/storage/innobase/api/api0api.cc +++ b/storage/innobase/api/api0api.cc @@ -595,6 +595,21 @@ ib_trx_begin( return(static_cast(trx)); } + +/*****************************************************************//** +Check if transaction is read_only +@return transaction read_only status */ +UNIV_INTERN +ib_u32_t +ib_trx_read_only( +/*=============*/ + ib_trx_t ib_trx) /*!< in: trx handle */ +{ + trx_t* trx = (trx_t*) ib_trx; + + return(trx->read_only); +} + /*****************************************************************//** Get the transaction's state. @return transaction state */ diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc index a676d70a992..311e3326f2b 100644 --- a/storage/innobase/buf/buf0buf.cc +++ b/storage/innobase/buf/buf0buf.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1995, 2014, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1995, 2015, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2008, Google Inc. Portions of this file contain modifications contributed and copyrighted by @@ -486,6 +486,79 @@ buf_page_is_zeroes( return(true); } +/** Checks if the page is in crc32 checksum format. +@param[in] read_buf database page +@param[in] checksum_field1 new checksum field +@param[in] checksum_field2 old checksum field +@return true if the page is in crc32 checksum format */ +UNIV_INLINE +bool +buf_page_is_checksum_valid_crc32( + const byte* read_buf, + ulint checksum_field1, + ulint checksum_field2) +{ + ib_uint32_t crc32 = buf_calc_page_crc32(read_buf); + + return(checksum_field1 == crc32 && checksum_field2 == crc32); +} + +/** Checks if the page is in innodb checksum format. +@param[in] read_buf database page +@param[in] checksum_field1 new checksum field +@param[in] checksum_field2 old checksum field +@return true if the page is in innodb checksum format */ +UNIV_INLINE +bool +buf_page_is_checksum_valid_innodb( + const byte* read_buf, + ulint checksum_field1, + ulint checksum_field2) +{ + /* There are 2 valid formulas for + checksum_field2 (old checksum field) which algo=innodb could have + written to the page: + + 1. Very old versions of InnoDB only stored 8 byte lsn to the + start and the end of the page. + + 2. Newer InnoDB versions store the old formula checksum + (buf_calc_page_old_checksum()). */ + + if (checksum_field2 != mach_read_from_4(read_buf + FIL_PAGE_LSN) + && checksum_field2 != buf_calc_page_old_checksum(read_buf)) { + return(false); + } + + /* old field is fine, check the new field */ + + /* InnoDB versions < 4.0.14 and < 4.1.1 stored the space id + (always equal to 0), to FIL_PAGE_SPACE_OR_CHKSUM */ + + if (checksum_field1 != 0 + && checksum_field1 != buf_calc_page_new_checksum(read_buf)) { + return(false); + } + + return(true); +} + +/** Checks if the page is in none checksum format. +@param[in] read_buf database page +@param[in] checksum_field1 new checksum field +@param[in] checksum_field2 old checksum field +@return true if the page is in none checksum format */ +UNIV_INLINE +bool +buf_page_is_checksum_valid_none( + const byte* read_buf, + ulint checksum_field1, + ulint checksum_field2) +{ + return(checksum_field1 == checksum_field2 + && checksum_field1 == BUF_NO_CHECKSUM_MAGIC); +} + /********************************************************************//** Checks if a page is corrupt. @return TRUE if corrupted */ @@ -501,8 +574,6 @@ buf_page_is_corrupted( { ulint checksum_field1; ulint checksum_field2; - ibool crc32_inited = FALSE; - ib_uint32_t crc32 = ULINT32_UNDEFINED; if (!zip_size && memcmp(read_buf + FIL_PAGE_LSN + 4, @@ -582,148 +653,121 @@ buf_page_is_corrupted( return(FALSE); } - switch ((srv_checksum_algorithm_t) srv_checksum_algorithm) { - case SRV_CHECKSUM_ALGORITHM_STRICT_CRC32: - - crc32 = buf_calc_page_crc32(read_buf); - - return(checksum_field1 != crc32 || checksum_field2 != crc32); - - case SRV_CHECKSUM_ALGORITHM_STRICT_INNODB: - - return(checksum_field1 - != buf_calc_page_new_checksum(read_buf) - || checksum_field2 - != buf_calc_page_old_checksum(read_buf)); - - case SRV_CHECKSUM_ALGORITHM_STRICT_NONE: + DBUG_EXECUTE_IF("buf_page_is_corrupt_failure", return(TRUE); ); - return(checksum_field1 != BUF_NO_CHECKSUM_MAGIC - || checksum_field2 != BUF_NO_CHECKSUM_MAGIC); + ulint page_no = mach_read_from_4(read_buf + FIL_PAGE_OFFSET); + ulint space_id = mach_read_from_4(read_buf + FIL_PAGE_SPACE_ID); + const srv_checksum_algorithm_t curr_algo = + static_cast(srv_checksum_algorithm); + switch (curr_algo) { case SRV_CHECKSUM_ALGORITHM_CRC32: - case SRV_CHECKSUM_ALGORITHM_INNODB: - /* There are 3 valid formulas for - checksum_field2 (old checksum field): - - 1. Very old versions of InnoDB only stored 8 byte lsn to the - start and the end of the page. - - 2. InnoDB versions before MySQL 5.6.3 store the old formula - checksum (buf_calc_page_old_checksum()). - - 3. InnoDB versions 5.6.3 and newer with - innodb_checksum_algorithm=strict_crc32|crc32 store CRC32. */ - - /* since innodb_checksum_algorithm is not strict_* allow - any of the algos to match for the old field */ - - if (checksum_field2 - != mach_read_from_4(read_buf + FIL_PAGE_LSN) - && checksum_field2 != BUF_NO_CHECKSUM_MAGIC) { - - /* The checksum does not match any of the - fast to check. First check the selected algorithm - for writing checksums because we assume that the - chance of it matching is higher. */ - - if (srv_checksum_algorithm - == SRV_CHECKSUM_ALGORITHM_CRC32) { - - crc32 = buf_calc_page_crc32(read_buf); - crc32_inited = TRUE; - - if (checksum_field2 != crc32 - && checksum_field2 - != buf_calc_page_old_checksum(read_buf)) { + case SRV_CHECKSUM_ALGORITHM_STRICT_CRC32: - return(TRUE); - } - } else { - ut_ad(srv_checksum_algorithm - == SRV_CHECKSUM_ALGORITHM_INNODB); + if (buf_page_is_checksum_valid_crc32(read_buf, + checksum_field1, checksum_field2)) { + return(FALSE); + } - if (checksum_field2 - != buf_calc_page_old_checksum(read_buf)) { + if (buf_page_is_checksum_valid_none(read_buf, + checksum_field1, checksum_field2)) { + if (curr_algo + == SRV_CHECKSUM_ALGORITHM_STRICT_CRC32) { + page_warn_strict_checksum( + curr_algo, + SRV_CHECKSUM_ALGORITHM_NONE, + space_id, page_no); + } - crc32 = buf_calc_page_crc32(read_buf); - crc32_inited = TRUE; + return(FALSE); + } - if (checksum_field2 != crc32) { - return(TRUE); - } - } + if (buf_page_is_checksum_valid_innodb(read_buf, + checksum_field1, checksum_field2)) { + if (curr_algo + == SRV_CHECKSUM_ALGORITHM_STRICT_CRC32) { + page_warn_strict_checksum( + curr_algo, + SRV_CHECKSUM_ALGORITHM_INNODB, + space_id, page_no); } - } - /* old field is fine, check the new field */ + return(FALSE); + } - /* InnoDB versions < 4.0.14 and < 4.1.1 stored the space id - (always equal to 0), to FIL_PAGE_SPACE_OR_CHKSUM */ + return(TRUE); - if (checksum_field1 != 0 - && checksum_field1 != BUF_NO_CHECKSUM_MAGIC) { + case SRV_CHECKSUM_ALGORITHM_INNODB: + case SRV_CHECKSUM_ALGORITHM_STRICT_INNODB: - /* The checksum does not match any of the - fast to check. First check the selected algorithm - for writing checksums because we assume that the - chance of it matching is higher. */ + if (buf_page_is_checksum_valid_innodb(read_buf, + checksum_field1, checksum_field2)) { + return(FALSE); + } - if (srv_checksum_algorithm - == SRV_CHECKSUM_ALGORITHM_CRC32) { + if (buf_page_is_checksum_valid_none(read_buf, + checksum_field1, checksum_field2)) { + if (curr_algo + == SRV_CHECKSUM_ALGORITHM_STRICT_INNODB) { + page_warn_strict_checksum( + curr_algo, + SRV_CHECKSUM_ALGORITHM_NONE, + space_id, page_no); + } - if (!crc32_inited) { - crc32 = buf_calc_page_crc32(read_buf); - crc32_inited = TRUE; - } + return(FALSE); + } - if (checksum_field1 != crc32 - && checksum_field1 - != buf_calc_page_new_checksum(read_buf)) { + if (buf_page_is_checksum_valid_crc32(read_buf, + checksum_field1, checksum_field2)) { + if (curr_algo + == SRV_CHECKSUM_ALGORITHM_STRICT_INNODB) { + page_warn_strict_checksum( + curr_algo, + SRV_CHECKSUM_ALGORITHM_CRC32, + space_id, page_no); + } - return(TRUE); - } - } else { - ut_ad(srv_checksum_algorithm - == SRV_CHECKSUM_ALGORITHM_INNODB); + return(FALSE); + } - if (checksum_field1 - != buf_calc_page_new_checksum(read_buf)) { + return(TRUE); - if (!crc32_inited) { - crc32 = buf_calc_page_crc32( - read_buf); - crc32_inited = TRUE; - } + case SRV_CHECKSUM_ALGORITHM_STRICT_NONE: - if (checksum_field1 != crc32) { - return(TRUE); - } - } - } + if (buf_page_is_checksum_valid_none(read_buf, + checksum_field1, checksum_field2)) { + return(FALSE); } - /* If CRC32 is stored in at least one of the fields, then the - other field must also be CRC32 */ - if (crc32_inited - && ((checksum_field1 == crc32 - && checksum_field2 != crc32) - || (checksum_field1 != crc32 - && checksum_field2 == crc32))) { + if (buf_page_is_checksum_valid_crc32(read_buf, + checksum_field1, checksum_field2)) { + page_warn_strict_checksum( + curr_algo, + SRV_CHECKSUM_ALGORITHM_CRC32, + space_id, page_no); + return(FALSE); + } - return(TRUE); + if (buf_page_is_checksum_valid_innodb(read_buf, + checksum_field1, checksum_field2)) { + page_warn_strict_checksum( + curr_algo, + SRV_CHECKSUM_ALGORITHM_INNODB, + space_id, page_no); + return(FALSE); } - break; + return(TRUE); + case SRV_CHECKSUM_ALGORITHM_NONE: /* should have returned FALSE earlier */ - ut_error; + break; /* no default so the compiler will emit a warning if new enum is added and not handled here */ } - DBUG_EXECUTE_IF("buf_page_is_corrupt_failure", return(TRUE); ); - + ut_error; return(FALSE); } @@ -1673,6 +1717,9 @@ page_found: goto page_found; } + /* The maximum number of purge threads should never exceed + BUF_POOL_WATCH_SIZE. So there is no way for purge thread + instance to hold a watch when setting another watch. */ for (i = 0; i < BUF_POOL_WATCH_SIZE; i++) { bpage = &buf_pool->watch[i]; diff --git a/storage/innobase/buf/buf0checksum.cc b/storage/innobase/buf/buf0checksum.cc index ec79bbe6be9..5289cd8cef2 100644 --- a/storage/innobase/buf/buf0checksum.cc +++ b/storage/innobase/buf/buf0checksum.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1995, 2011, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1995, 2015, 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 @@ -138,14 +138,17 @@ buf_checksum_algorithm_name( { switch (algo) { case SRV_CHECKSUM_ALGORITHM_CRC32: - case SRV_CHECKSUM_ALGORITHM_STRICT_CRC32: return("crc32"); + case SRV_CHECKSUM_ALGORITHM_STRICT_CRC32: + return("strict_crc32"); case SRV_CHECKSUM_ALGORITHM_INNODB: - case SRV_CHECKSUM_ALGORITHM_STRICT_INNODB: return("innodb"); + case SRV_CHECKSUM_ALGORITHM_STRICT_INNODB: + return("strict_innodb"); case SRV_CHECKSUM_ALGORITHM_NONE: - case SRV_CHECKSUM_ALGORITHM_STRICT_NONE: return("none"); + case SRV_CHECKSUM_ALGORITHM_STRICT_NONE: + return("strict_none"); } ut_error; diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 691d4373054..ed9317f5a5d 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -482,7 +482,8 @@ ib_cb_t innodb_api_cb[] = { (ib_cb_t) ib_get_idx_field_name, (ib_cb_t) ib_trx_get_start_time, (ib_cb_t) ib_cfg_bk_commit_interval, - (ib_cb_t) ib_cursor_stmt_begin + (ib_cb_t) ib_cursor_stmt_begin, + (ib_cb_t) ib_trx_read_only }; /*************************************************************//** @@ -10509,6 +10510,13 @@ ha_innobase::estimate_rows_upper_bound() prebuilt->trx->op_info = ""; + /* Set num_rows less than MERGEBUFF to simulate the case where we do + not have enough space to merge the externally sorted file blocks. */ + DBUG_EXECUTE_IF("set_num_rows_lt_MERGEBUFF", + estimate = 2; + DBUG_SET("-d,set_num_rows_lt_MERGEBUFF"); + ); + DBUG_RETURN((ha_rows) estimate); } @@ -10779,7 +10787,6 @@ ha_innobase::info_low( dict_table_t* ib_table; ha_rows rec_per_key; ib_uint64_t n_rows; - char path[FN_REFLEN]; os_file_stat_t stat_info; DBUG_ENTER("info"); @@ -10837,17 +10844,6 @@ ha_innobase::info_low( "returning various info to MySQL"; } - my_snprintf(path, sizeof(path), "%s/%s%s", - mysql_data_home, ib_table->name, reg_ext); - - unpack_filename(path,path); - - /* Note that we do not know the access time of the table, - nor the CHECK TABLE time, nor the UPDATE or INSERT time. */ - - if (os_file_get_status(path, &stat_info, false) == DB_SUCCESS) { - stats.create_time = (ulong) stat_info.ctime; - } } if (flag & HA_STATUS_VARIABLE) { @@ -10982,6 +10978,7 @@ ha_innobase::info_low( if (flag & HA_STATUS_CONST) { ulong i; + char path[FN_REFLEN]; /* Verify the number of index in InnoDB and MySQL matches up. If prebuilt->clust_index_was_generated holds, InnoDB defines GEN_CLUST_INDEX internally */ @@ -11105,6 +11102,20 @@ ha_innobase::info_low( if (!(flag & HA_STATUS_NO_LOCK)) { dict_table_stats_unlock(ib_table, RW_S_LATCH); } + + my_snprintf(path, sizeof(path), "%s/%s%s", + mysql_data_home, + table->s->normalized_path.str, + reg_ext); + + unpack_filename(path,path); + + /* Note that we do not know the access time of the table, + nor the CHECK TABLE time, nor the UPDATE or INSERT time. */ + + if (os_file_get_status(path, &stat_info, false) == DB_SUCCESS) { + stats.create_time = (ulong) stat_info.ctime; + } } if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE) { diff --git a/storage/innobase/include/api0api.h b/storage/innobase/include/api0api.h index d77d691becc..e4c9c941de5 100644 --- a/storage/innobase/include/api0api.h +++ b/storage/innobase/include/api0api.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2011, 2013, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2011, 2015, 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 @@ -494,6 +494,14 @@ ib_trx_state( /*=========*/ ib_trx_t ib_trx); /*!< in: trx handle */ + +/*****************************************************************//** +Check if the transaction is read_only */ +ib_u32_t +ib_trx_read_only( +/*=============*/ + ib_trx_t ib_trx); /*!< in: trx handle */ + /*****************************************************************//** Release the resources of the transaction. If the transaction was selected as a victim by InnoDB and rolled back then use this function diff --git a/storage/innobase/include/os0file.h b/storage/innobase/include/os0file.h index ad9b6a9ac10..246a4f277e2 100644 --- a/storage/innobase/include/os0file.h +++ b/storage/innobase/include/os0file.h @@ -1,6 +1,6 @@ /*********************************************************************** -Copyright (c) 1995, 2014, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1995, 2015, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2009, Percona Inc. Portions of this file contain modifications contributed and copyrighted @@ -383,10 +383,10 @@ to original un-instrumented file I/O APIs */ enum os_file_type_t { OS_FILE_TYPE_UNKNOWN = 0, - OS_FILE_TYPE_FILE, /* regular file */ + OS_FILE_TYPE_FILE, /* regular file + (or a character/block device) */ OS_FILE_TYPE_DIR, /* directory */ - OS_FILE_TYPE_LINK, /* symbolic link */ - OS_FILE_TYPE_BLOCK /* block device */ + OS_FILE_TYPE_LINK /* symbolic link */ }; /* Maximum path string length in bytes when referring to tables with in the diff --git a/storage/innobase/include/page0page.h b/storage/innobase/include/page0page.h index b572f7abb49..0bd0a009cae 100644 --- a/storage/innobase/include/page0page.h +++ b/storage/innobase/include/page0page.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1994, 2013, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1994, 2015, 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 @@ -1110,6 +1110,20 @@ page_find_rec_with_heap_no( const rec_t* page_find_rec_max_not_deleted( const page_t* page); + +/** Issue a warning when the checksum that is stored in the page is valid, +but different than the global setting innodb_checksum_algorithm. +@param[in] current_algo current checksum algorithm +@param[in] page_checksum page valid checksum +@param[in] space_id tablespace id +@param[in] page_no page number */ +void +page_warn_strict_checksum( + srv_checksum_algorithm_t curr_algo, + srv_checksum_algorithm_t page_checksum, + ulint space_id, + ulint page_no); + #ifdef UNIV_MATERIALIZE #undef UNIV_INLINE #define UNIV_INLINE UNIV_INLINE_ORIGINAL diff --git a/storage/innobase/os/os0file.cc b/storage/innobase/os/os0file.cc index fb7e8ca1eb7..8c8b033a39a 100644 --- a/storage/innobase/os/os0file.cc +++ b/storage/innobase/os/os0file.cc @@ -1,6 +1,6 @@ /*********************************************************************** -Copyright (c) 1995, 2014, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1995, 2015, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2009, Percona Inc. Portions of this file contain modifications contributed and copyrighted @@ -3187,8 +3187,9 @@ os_file_get_status( stat_info->type = OS_FILE_TYPE_LINK; break; case S_IFBLK: - stat_info->type = OS_FILE_TYPE_BLOCK; - break; + /* Handle block device as regular file. */ + case S_IFCHR: + /* Handle character device as regular file. */ case S_IFREG: stat_info->type = OS_FILE_TYPE_FILE; break; @@ -3197,8 +3198,8 @@ os_file_get_status( } - if (check_rw_perm && (stat_info->type == OS_FILE_TYPE_FILE - || stat_info->type == OS_FILE_TYPE_BLOCK)) { + if (check_rw_perm && stat_info->type == OS_FILE_TYPE_FILE) { + int fh; int access; diff --git a/storage/innobase/page/page0page.cc b/storage/innobase/page/page0page.cc index bd5fb36af8f..cb2381df48c 100644 --- a/storage/innobase/page/page0page.cc +++ b/storage/innobase/page/page0page.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1994, 2013, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1994, 2015, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2012, Facebook Inc. This program is free software; you can redistribute it and/or modify it under @@ -2811,3 +2811,45 @@ page_find_rec_max_not_deleted( } return(prev_rec); } + +/** Issue a warning when the checksum that is stored in the page is valid, +but different than the global setting innodb_checksum_algorithm. +@param[in] current_algo current checksum algorithm +@param[in] page_checksum page valid checksum +@param[in] space_id tablespace id +@param[in] page_no page number */ +void +page_warn_strict_checksum( + srv_checksum_algorithm_t curr_algo, + srv_checksum_algorithm_t page_checksum, + ulint space_id, + ulint page_no) +{ + srv_checksum_algorithm_t curr_algo_nonstrict; + switch (curr_algo) { + case SRV_CHECKSUM_ALGORITHM_STRICT_CRC32: + curr_algo_nonstrict = SRV_CHECKSUM_ALGORITHM_CRC32; + break; + case SRV_CHECKSUM_ALGORITHM_STRICT_INNODB: + curr_algo_nonstrict = SRV_CHECKSUM_ALGORITHM_INNODB; + break; + case SRV_CHECKSUM_ALGORITHM_STRICT_NONE: + curr_algo_nonstrict = SRV_CHECKSUM_ALGORITHM_NONE; + break; + default: + ut_error; + } + + ib_logf(IB_LOG_LEVEL_WARN, + "innodb_checksum_algorithm is set to \"%s\"" + " but the page [page id: space=" ULINTPF "," + " page number=" ULINTPF "] contains a valid checksum \"%s\"." + " Accepting the page as valid. Change innodb_checksum_algorithm" + " to \"%s\" to silently accept such pages or rewrite all pages" + " so that they contain \"%s\" checksum.", + buf_checksum_algorithm_name(curr_algo), + space_id, page_no, + buf_checksum_algorithm_name(page_checksum), + buf_checksum_algorithm_name(curr_algo_nonstrict), + buf_checksum_algorithm_name(curr_algo_nonstrict)); +} diff --git a/storage/innobase/page/page0zip.cc b/storage/innobase/page/page0zip.cc index dd1dc763b90..e5176148edd 100644 --- a/storage/innobase/page/page0zip.cc +++ b/storage/innobase/page/page0zip.cc @@ -4889,6 +4889,10 @@ page_zip_verify_checksum( stored = static_cast(mach_read_from_4( static_cast(data) + FIL_PAGE_SPACE_OR_CHKSUM)); + ulint page_no = mach_read_from_4(static_cast (data) + FIL_PAGE_OFFSET); + ulint space_id = mach_read_from_4(static_cast + (data) + FIL_PAGE_SPACE_ID); + #if FIL_PAGE_LSN % 8 #error "FIL_PAGE_LSN must be 64 bit aligned" #endif @@ -4909,40 +4913,113 @@ page_zip_verify_checksum( return(TRUE); } + const srv_checksum_algorithm_t curr_algo = + static_cast(srv_checksum_algorithm); + + if (curr_algo == SRV_CHECKSUM_ALGORITHM_NONE) { + return(TRUE); + } + calc = static_cast(page_zip_calc_checksum( - data, size, static_cast( - srv_checksum_algorithm))); + data, size, curr_algo)); if (stored == calc) { return(TRUE); } - switch ((srv_checksum_algorithm_t) srv_checksum_algorithm) { + switch (curr_algo) { case SRV_CHECKSUM_ALGORITHM_STRICT_CRC32: - case SRV_CHECKSUM_ALGORITHM_STRICT_INNODB: - case SRV_CHECKSUM_ALGORITHM_STRICT_NONE: - return(stored == calc); case SRV_CHECKSUM_ALGORITHM_CRC32: + if (stored == BUF_NO_CHECKSUM_MAGIC) { + if (curr_algo + == SRV_CHECKSUM_ALGORITHM_STRICT_CRC32) { + page_warn_strict_checksum( + curr_algo, + SRV_CHECKSUM_ALGORITHM_NONE, + space_id, page_no); + } + return(TRUE); } - crc32 = calc; + innodb = static_cast(page_zip_calc_checksum( data, size, SRV_CHECKSUM_ALGORITHM_INNODB)); + + if (stored == innodb) { + if (curr_algo + == SRV_CHECKSUM_ALGORITHM_STRICT_CRC32) { + page_warn_strict_checksum( + curr_algo, + SRV_CHECKSUM_ALGORITHM_INNODB, + space_id, page_no); + } + + return(TRUE); + } + break; + case SRV_CHECKSUM_ALGORITHM_STRICT_INNODB: case SRV_CHECKSUM_ALGORITHM_INNODB: + if (stored == BUF_NO_CHECKSUM_MAGIC) { + if (curr_algo + == SRV_CHECKSUM_ALGORITHM_STRICT_INNODB) { + page_warn_strict_checksum( + curr_algo, + SRV_CHECKSUM_ALGORITHM_NONE, + space_id, page_no); + } + + return(TRUE); + } + + crc32 = static_cast(page_zip_calc_checksum( + data, size, SRV_CHECKSUM_ALGORITHM_CRC32)); + + if (stored == crc32) { + if (curr_algo + == SRV_CHECKSUM_ALGORITHM_STRICT_INNODB) { + page_warn_strict_checksum( + curr_algo, + SRV_CHECKSUM_ALGORITHM_CRC32, + space_id, page_no); + } + return(TRUE); } + + break; + case SRV_CHECKSUM_ALGORITHM_STRICT_NONE: + crc32 = static_cast(page_zip_calc_checksum( data, size, SRV_CHECKSUM_ALGORITHM_CRC32)); - innodb = calc; + + if (stored == crc32) { + page_warn_strict_checksum( + curr_algo, SRV_CHECKSUM_ALGORITHM_CRC32, + space_id, page_no); + + return(TRUE); + } + + innodb = static_cast(page_zip_calc_checksum( + data, size, SRV_CHECKSUM_ALGORITHM_INNODB)); + + if (stored == innodb) { + page_warn_strict_checksum( + curr_algo, + SRV_CHECKSUM_ALGORITHM_INNODB, + space_id, page_no); + return(TRUE); + } + break; case SRV_CHECKSUM_ALGORITHM_NONE: - return(TRUE); + ut_error; /* no default so the compiler will emit a warning if new enum is added and not handled here */ } - return(stored == crc32 || stored == innodb); + return(FALSE); } diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc index c53fa530b42..3140e18a0b1 100644 --- a/storage/innobase/row/row0mysql.cc +++ b/storage/innobase/row/row0mysql.cc @@ -1322,18 +1322,14 @@ row_insert_for_mysql( mem_analyze_corruption(prebuilt); ut_error; - } else if (srv_created_new_raw || srv_force_recovery) { - fputs("InnoDB: A new raw disk partition was initialized or\n" - "InnoDB: innodb_force_recovery is on: we do not allow\n" + } else if (srv_force_recovery) { + fputs("InnoDB: innodb_force_recovery is on: we do not allow\n" "InnoDB: database modifications by the user. Shut down\n" "InnoDB: mysqld and edit my.cnf so that" - " newraw is replaced\n" - "InnoDB: with raw, and innodb_force_... is removed.\n", + "InnoDB: innodb_force_... is removed.\n", stderr); - if(srv_force_recovery) { - return(DB_READ_ONLY); - } - return(DB_ERROR); + + return(DB_READ_ONLY); } trx->op_info = "inserting"; @@ -1715,18 +1711,14 @@ row_update_for_mysql( ut_error; } - if (UNIV_UNLIKELY(srv_created_new_raw || srv_force_recovery)) { - fputs("InnoDB: A new raw disk partition was initialized or\n" - "InnoDB: innodb_force_recovery is on: we do not allow\n" + if (UNIV_UNLIKELY(srv_force_recovery)) { + fputs("InnoDB: innodb_force_recovery is on: we do not allow\n" "InnoDB: database modifications by the user. Shut down\n" - "InnoDB: mysqld and edit my.cnf so that newraw" - " is replaced\n" - "InnoDB: with raw, and innodb_force_... is removed.\n", + "InnoDB: mysqld and edit my.cnf so that" + "InnoDB: innodb_force_... is removed.\n", stderr); - if(srv_force_recovery) { - return(DB_READ_ONLY); - } - return(DB_ERROR); + + return(DB_READ_ONLY); } DEBUG_SYNC_C("innodb_row_update_for_mysql_begin"); @@ -2204,22 +2196,6 @@ row_create_table_for_mysql( goto err_exit; ); - if (srv_created_new_raw) { - fputs("InnoDB: A new raw disk partition was initialized:\n" - "InnoDB: we do not allow database modifications" - " by the user.\n" - "InnoDB: Shut down mysqld and edit my.cnf so that newraw" - " is replaced with raw.\n", stderr); -err_exit: - dict_mem_table_free(table); - - if (commit) { - trx_commit_for_mysql(trx); - } - - return(DB_ERROR); - } - trx->op_info = "creating table"; if (row_mysql_is_system_table(table->name)) { @@ -2230,7 +2206,19 @@ err_exit: "InnoDB: MySQL system tables must be" " of the MyISAM type!\n", table->name); - goto err_exit; + +#ifndef DBUG_OFF +err_exit: +#endif /* !DBUG_OFF */ + dict_mem_table_free(table); + + if (commit) { + trx_commit_for_mysql(trx); + } + + trx->op_info = ""; + + return(DB_ERROR); } trx_start_if_not_started_xa(trx); @@ -3280,16 +3268,6 @@ row_truncate_table_for_mysql( ut_ad(table); - if (srv_created_new_raw) { - fputs("InnoDB: A new raw disk partition was initialized:\n" - "InnoDB: we do not allow database modifications" - " by the user.\n" - "InnoDB: Shut down mysqld and edit my.cnf so that newraw" - " is replaced with raw.\n", stderr); - - return(DB_ERROR); - } - if (dict_table_is_discarded(table)) { return(DB_TABLESPACE_DELETED); } else if (table->ibd_file_missing) { @@ -3769,16 +3747,6 @@ row_drop_table_for_mysql( ut_a(name != NULL); - if (srv_created_new_raw) { - fputs("InnoDB: A new raw disk partition was initialized:\n" - "InnoDB: we do not allow database modifications" - " by the user.\n" - "InnoDB: Shut down mysqld and edit my.cnf so that newraw" - " is replaced with raw.\n", stderr); - - DBUG_RETURN(DB_ERROR); - } - /* The table name is prefixed with the database name and a '/'. Certain table names starting with 'innodb_' have their special meaning regardless of the database name. Thus, we need to @@ -4791,19 +4759,16 @@ row_rename_table_for_mysql( ut_a(new_name != NULL); ut_ad(trx->state == TRX_STATE_ACTIVE); - if (srv_created_new_raw || srv_force_recovery) { - fputs("InnoDB: A new raw disk partition was initialized or\n" - "InnoDB: innodb_force_recovery is on: we do not allow\n" + if (srv_force_recovery) { + fputs("InnoDB: innodb_force_recovery is on: we do not allow\n" "InnoDB: database modifications by the user. Shut down\n" - "InnoDB: mysqld and edit my.cnf so that newraw" - " is replaced\n" - "InnoDB: with raw, and innodb_force_... is removed.\n", + "InnoDB: mysqld and edit my.cnf so that" + "InnoDB: innodb_force_... is removed.\n", stderr); - if(srv_force_recovery) { - err = DB_READ_ONLY; - } + err = DB_READ_ONLY; goto funct_exit; + } else if (row_mysql_is_system_table(new_name)) { fprintf(stderr, diff --git a/storage/innobase/srv/srv0start.cc b/storage/innobase/srv/srv0start.cc index fde0d1552be..d888d13d863 100644 --- a/storage/innobase/srv/srv0start.cc +++ b/storage/innobase/srv/srv0start.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved. +Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved. Copyright (c) 2008, Google Inc. Copyright (c) 2009, Percona Inc. @@ -222,8 +222,8 @@ srv_file_check_mode( /* Note: stat.rw_perm is only valid of files */ - if (stat.type == OS_FILE_TYPE_FILE - || stat.type == OS_FILE_TYPE_BLOCK) { + if (stat.type == OS_FILE_TYPE_FILE) { + if (!stat.rw_perm) { ib_logf(IB_LOG_LEVEL_ERROR, @@ -420,14 +420,18 @@ srv_parse_data_file_paths_and_sizes( && *(str + 1) == 'e' && *(str + 2) == 'w') { str += 3; - (srv_data_file_is_raw_partition)[i] = SRV_NEW_RAW; + /* Initialize new raw device only during bootstrap */ + (srv_data_file_is_raw_partition)[i] = + opt_bootstrap ? SRV_NEW_RAW : SRV_OLD_RAW; } if (*str == 'r' && *(str + 1) == 'a' && *(str + 2) == 'w') { str += 3; + /* Initialize new raw device only during bootstrap */ if ((srv_data_file_is_raw_partition)[i] == 0) { - (srv_data_file_is_raw_partition)[i] = SRV_OLD_RAW; + (srv_data_file_is_raw_partition)[i] = + opt_bootstrap ? SRV_NEW_RAW : SRV_OLD_RAW; } } @@ -880,6 +884,24 @@ open_or_create_data_files( return(DB_ERROR); } + + const char* check_msg; + check_msg = fil_read_first_page( + files[i], FALSE, &flags, &space, +#ifdef UNIV_LOG_ARCHIVE + min_arch_log_no, max_arch_log_no, +#endif /* UNIV_LOG_ARCHIVE */ + min_flushed_lsn, max_flushed_lsn); + + /* If first page is valid, don't overwrite DB. + It prevents overwriting DB when mysql_install_db + starts mysqld multiple times during bootstrap. */ + if (check_msg == NULL) { + + srv_created_new_raw = FALSE; + ret = FALSE; + } + } else if (srv_data_file_is_raw_partition[i] == SRV_OLD_RAW) { srv_start_raw_disk_in_use = TRUE; @@ -3025,9 +3047,9 @@ innobase_shutdown_for_mysql(void) ibuf_close(); log_shutdown(); - lock_sys_close(); trx_sys_file_format_close(); trx_sys_close(); + lock_sys_close(); /* We don't create these mutexes in RO mode because we don't create the temp files that the cover. */ diff --git a/storage/innobase/sync/sync0arr.cc b/storage/innobase/sync/sync0arr.cc index d56d328d8c3..4feea36a253 100644 --- a/storage/innobase/sync/sync0arr.cc +++ b/storage/innobase/sync/sync0arr.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1995, 2013, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1995, 2015, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2008, Google Inc. Portions of this file contain modifications contributed and copyrighted by @@ -1036,8 +1036,8 @@ sync_array_print_info_low( ulint count = 0; fprintf(file, - "OS WAIT ARRAY INFO: reservation count %ld\n", - (long) arr->res_count); + "OS WAIT ARRAY INFO: reservation count " ULINTPF "\n", + arr->res_count); for (i = 0; count < arr->n_reserved; ++i) { sync_cell_t* cell; @@ -1132,7 +1132,7 @@ sync_array_print( } fprintf(file, - "OS WAIT ARRAY INFO: signal count %ld\n", (long) sg_count); + "OS WAIT ARRAY INFO: signal count " ULINTPF "\n", sg_count); } diff --git a/storage/innobase/trx/trx0sys.cc b/storage/innobase/trx/trx0sys.cc index 52830a77b12..5eb3cef46c1 100644 --- a/storage/innobase/trx/trx0sys.cc +++ b/storage/innobase/trx/trx0sys.cc @@ -1187,8 +1187,6 @@ trx_sys_close(void) /* Free the double write data structures. */ buf_dblwr_free(); - mutex_enter(&trx_sys->mutex); - ut_a(UT_LIST_GET_LEN(trx_sys->ro_trx_list) == 0); /* Only prepared transactions may be left in the system. Free them. */ @@ -1228,8 +1226,6 @@ trx_sys_close(void) ut_a(UT_LIST_GET_LEN(trx_sys->rw_trx_list) == 0); ut_a(UT_LIST_GET_LEN(trx_sys->mysql_trx_list) == 0); - mutex_exit(&trx_sys->mutex); - mutex_free(&trx_sys->mutex); mem_free(trx_sys); diff --git a/storage/innobase/trx/trx0trx.cc b/storage/innobase/trx/trx0trx.cc index c2d5c1f7c7f..937a64a0e46 100644 --- a/storage/innobase/trx/trx0trx.cc +++ b/storage/innobase/trx/trx0trx.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2014, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1996, 2015, 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 @@ -303,11 +303,10 @@ trx_free_prepared( /*==============*/ trx_t* trx) /*!< in, own: trx object */ { - ut_ad(mutex_own(&trx_sys->mutex)); - ut_a(trx_state_eq(trx, TRX_STATE_PREPARED)); ut_a(trx->magic_n == TRX_MAGIC_N); + lock_trx_release_locks(trx); trx_undo_free_prepared(trx); assert_trx_in_rw_list(trx); -- cgit v1.2.1