summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergei Golubchik <serg@mariadb.org>2015-06-16 10:57:05 +0200
committerSergei Golubchik <serg@mariadb.org>2015-06-16 10:57:05 +0200
commit139ba26dbacc37858d7746b8ef53a7330f9a8fcc (patch)
tree0bf94269a09817dea143e6125928e7385c4a2ac2
parent085297a1214814cd7eacbab2afb24c7a08bfc40e (diff)
downloadmariadb-git-139ba26dbacc37858d7746b8ef53a7330f9a8fcc.tar.gz
5.6.25
-rw-r--r--storage/innobase/api/api0api.cc15
-rw-r--r--storage/innobase/buf/buf0buf.cc277
-rw-r--r--storage/innobase/buf/buf0checksum.cc11
-rw-r--r--storage/innobase/handler/ha_innodb.cc37
-rw-r--r--storage/innobase/include/api0api.h10
-rw-r--r--storage/innobase/include/os0file.h8
-rw-r--r--storage/innobase/include/page0page.h16
-rw-r--r--storage/innobase/os/os0file.cc11
-rw-r--r--storage/innobase/page/page0page.cc44
-rw-r--r--storage/innobase/page/page0zip.cc97
-rw-r--r--storage/innobase/row/row0mysql.cc95
-rw-r--r--storage/innobase/srv/srv0start.cc34
-rw-r--r--storage/innobase/sync/sync0arr.cc8
-rw-r--r--storage/innobase/trx/trx0sys.cc4
-rw-r--r--storage/innobase/trx/trx0trx.cc5
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<ib_trx_t>(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_t>(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<ib_uint32_t>(mach_read_from_4(
static_cast<const unsigned char*>(data) + FIL_PAGE_SPACE_OR_CHKSUM));
+ ulint page_no = mach_read_from_4(static_cast<const unsigned char*> (data) + FIL_PAGE_OFFSET);
+ ulint space_id = mach_read_from_4(static_cast<const unsigned char*>
+ (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_t>(srv_checksum_algorithm);
+
+ if (curr_algo == SRV_CHECKSUM_ALGORITHM_NONE) {
+ return(TRUE);
+ }
+
calc = static_cast<ib_uint32_t>(page_zip_calc_checksum(
- data, size, static_cast<srv_checksum_algorithm_t>(
- 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<ib_uint32_t>(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<ib_uint32_t>(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<ib_uint32_t>(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<ib_uint32_t>(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);