summaryrefslogtreecommitdiff
path: root/storage/xtradb
diff options
context:
space:
mode:
Diffstat (limited to 'storage/xtradb')
-rw-r--r--storage/xtradb/btr/btr0btr.cc20
-rw-r--r--storage/xtradb/btr/btr0cur.cc4
-rw-r--r--storage/xtradb/buf/buf0flu.cc22
-rw-r--r--storage/xtradb/dict/dict0dict.cc42
-rw-r--r--storage/xtradb/fil/fil0fil.cc159
-rw-r--r--storage/xtradb/fsp/fsp0fsp.cc26
-rw-r--r--storage/xtradb/handler/ha_innodb.cc83
-rw-r--r--storage/xtradb/handler/handler0alter.cc192
-rw-r--r--storage/xtradb/include/buf0flu.h2
-rw-r--r--storage/xtradb/include/fil0fil.h43
-rw-r--r--storage/xtradb/include/ha_prototypes.h14
-rw-r--r--storage/xtradb/include/row0merge.h5
-rw-r--r--storage/xtradb/include/srv0mon.h5
-rw-r--r--storage/xtradb/include/srv0srv.h12
-rw-r--r--storage/xtradb/include/univ.i4
-rw-r--r--storage/xtradb/log/log0recv.cc4
-rw-r--r--storage/xtradb/row/row0import.cc16
-rw-r--r--storage/xtradb/row/row0log.cc17
-rw-r--r--storage/xtradb/row/row0merge.cc157
-rw-r--r--storage/xtradb/row/row0mysql.cc50
-rw-r--r--storage/xtradb/srv/srv0mon.cc35
-rw-r--r--storage/xtradb/srv/srv0srv.cc6
-rw-r--r--storage/xtradb/srv/srv0start.cc15
-rw-r--r--storage/xtradb/sync/sync0sync.cc61
24 files changed, 712 insertions, 282 deletions
diff --git a/storage/xtradb/btr/btr0btr.cc b/storage/xtradb/btr/btr0btr.cc
index 067cd4e5e1c..caa35d31109 100644
--- a/storage/xtradb/btr/btr0btr.cc
+++ b/storage/xtradb/btr/btr0btr.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.
Copyright (c) 2014, 2015, MariaDB Corporation
@@ -2285,7 +2285,7 @@ the tuple. It is assumed that mtr contains an x-latch on the tree.
NOTE that the operation of this function must always succeed,
we cannot reverse it: therefore enough free disk space must be
guaranteed to be available before this function is called.
-@return inserted record */
+@return inserted record or NULL if run out of space */
UNIV_INTERN
rec_t*
btr_root_raise_and_insert(
@@ -2346,6 +2346,11 @@ btr_root_raise_and_insert(
level = btr_page_get_level(root, mtr);
new_block = btr_page_alloc(index, 0, FSP_NO_DIR, level, mtr, mtr);
+
+ if (new_block == NULL && os_has_said_disk_full) {
+ return(NULL);
+ }
+
new_page = buf_block_get_frame(new_block);
new_page_zip = buf_block_get_page_zip(new_block);
ut_a(!new_page_zip == !root_page_zip);
@@ -3130,7 +3135,7 @@ this function is called.
NOTE: jonaso added support for calling function with tuple == NULL
which cause it to only split a page.
-@return inserted record */
+@return inserted record or NULL if run out of space */
UNIV_INTERN
rec_t*
btr_page_split_and_insert(
@@ -3244,9 +3249,18 @@ func_start:
}
}
+ DBUG_EXECUTE_IF("disk_is_full",
+ os_has_said_disk_full = true;
+ return(NULL););
+
/* 2. Allocate a new page to the index */
new_block = btr_page_alloc(cursor->index, hint_page_no, direction,
btr_page_get_level(page, mtr), mtr, mtr);
+
+ if (new_block == NULL && os_has_said_disk_full) {
+ return(NULL);
+ }
+
new_page = buf_block_get_frame(new_block);
new_page_zip = buf_block_get_page_zip(new_block);
btr_page_create(new_block, new_page_zip, cursor->index,
diff --git a/storage/xtradb/btr/btr0cur.cc b/storage/xtradb/btr/btr0cur.cc
index c949bcae476..5bb94dfce2a 100644
--- a/storage/xtradb/btr/btr0cur.cc
+++ b/storage/xtradb/btr/btr0cur.cc
@@ -1785,6 +1785,10 @@ btr_cur_pessimistic_insert(
flags, cursor, offsets, heap, entry, n_ext, mtr);
}
+ if (*rec == NULL && os_has_said_disk_full) {
+ return(DB_OUT_OF_FILE_SPACE);
+ }
+
ut_ad(page_rec_get_next(btr_cur_get_rec(cursor)) == *rec);
if (!(flags & BTR_NO_LOCKING_FLAG)) {
diff --git a/storage/xtradb/buf/buf0flu.cc b/storage/xtradb/buf/buf0flu.cc
index 037d94dd514..5d64b75784a 100644
--- a/storage/xtradb/buf/buf0flu.cc
+++ b/storage/xtradb/buf/buf0flu.cc
@@ -2251,7 +2251,7 @@ Clears up tail of the LRU lists:
* Flush dirty pages at the tail of LRU to the disk
The depth to which we scan each buffer pool is controlled by dynamic
config parameter innodb_LRU_scan_depth.
-@return total pages flushed */
+@return number of pages flushed */
UNIV_INTERN
ulint
buf_flush_LRU_tail(void)
@@ -2671,19 +2671,24 @@ static
void
page_cleaner_adapt_lru_sleep_time(
/*==============================*/
- ulint* lru_sleep_time) /*!< in/out: desired page cleaner thread sleep
+ ulint* lru_sleep_time, /*!< in/out: desired page cleaner thread sleep
time for LRU flushes */
+ ulint lru_n_flushed) /*!< in: number of flushed in previous batch */
+
{
ulint free_len = buf_get_total_free_list_length();
ulint max_free_len = srv_LRU_scan_depth * srv_buf_pool_instances;
- if (free_len < max_free_len / 100) {
+ if (free_len < max_free_len / 100 && lru_n_flushed) {
- /* Free lists filled less than 1%, no sleep */
+ /* Free lists filled less than 1%
+ and iteration was able to flush, no sleep */
*lru_sleep_time = 0;
- } else if (free_len > max_free_len / 5) {
+ } else if (free_len > max_free_len / 5
+ || (free_len < max_free_len / 100 && lru_n_flushed == 0)) {
- /* Free lists filled more than 20%, sleep a bit more */
+ /* Free lists filled more than 20%
+ or no pages flushed in previous batch, sleep a bit more */
*lru_sleep_time += 50;
if (*lru_sleep_time > srv_cleaner_max_lru_time)
*lru_sleep_time = srv_cleaner_max_lru_time;
@@ -2885,6 +2890,7 @@ DECLARE_THREAD(buf_flush_lru_manager_thread)(
{
ulint next_loop_time = ut_time_ms() + 1000;
ulint lru_sleep_time = srv_cleaner_max_lru_time;
+ ulint lru_n_flushed = 1;
#ifdef UNIV_PFS_THREAD
pfs_register_thread(buf_lru_manager_thread_key);
@@ -2911,11 +2917,11 @@ DECLARE_THREAD(buf_flush_lru_manager_thread)(
page_cleaner_sleep_if_needed(next_loop_time);
- page_cleaner_adapt_lru_sleep_time(&lru_sleep_time);
+ page_cleaner_adapt_lru_sleep_time(&lru_sleep_time, lru_n_flushed);
next_loop_time = ut_time_ms() + lru_sleep_time;
- buf_flush_LRU_tail();
+ lru_n_flushed = buf_flush_LRU_tail();
}
buf_lru_manager_is_active = false;
diff --git a/storage/xtradb/dict/dict0dict.cc b/storage/xtradb/dict/dict0dict.cc
index f6621473077..206038d36c9 100644
--- a/storage/xtradb/dict/dict0dict.cc
+++ b/storage/xtradb/dict/dict0dict.cc
@@ -1659,10 +1659,13 @@ dict_table_rename_in_cache(
to preserve the original table name
in constraints which reference it */
{
+ dberr_t err;
dict_foreign_t* foreign;
dict_index_t* index;
ulint fold;
char old_name[MAX_FULL_NAME_LEN + 1];
+ os_file_type_t ftype;
+ ibool exists;
ut_ad(mutex_own(&(dict_sys->mutex)));
@@ -1700,8 +1703,6 @@ dict_table_rename_in_cache(
.ibd file and rebuild the .isl file if needed. */
if (dict_table_is_discarded(table)) {
- os_file_type_t type;
- ibool exists;
char* filepath;
ut_ad(table->space != TRX_SYS_SPACE);
@@ -1720,7 +1721,7 @@ dict_table_rename_in_cache(
fil_delete_tablespace(table->space, BUF_REMOVE_ALL_NO_WRITE);
/* Delete any temp file hanging around. */
- if (os_file_status(filepath, &exists, &type)
+ if (os_file_status(filepath, &exists, &ftype)
&& exists
&& !os_file_delete_if_exists(innodb_file_temp_key,
filepath)) {
@@ -1732,8 +1733,6 @@ dict_table_rename_in_cache(
mem_free(filepath);
} else if (table->space != TRX_SYS_SPACE) {
- char* new_path = NULL;
-
if (DICT_TF2_FLAG_IS_SET(table, DICT_TF2_TEMPORARY)) {
ut_print_timestamp(stderr);
fputs(" InnoDB: Error: trying to rename a"
@@ -1747,34 +1746,43 @@ dict_table_rename_in_cache(
}
return(DB_ERROR);
+ }
- } else if (DICT_TF_HAS_DATA_DIR(table->flags)) {
- char* old_path;
-
- old_path = fil_space_get_first_path(table->space);
+ char* new_path = NULL;
+ char* old_path = fil_space_get_first_path(table->space);
+ if (DICT_TF_HAS_DATA_DIR(table->flags)) {
new_path = os_file_make_new_pathname(
old_path, new_name);
- mem_free(old_path);
-
- dberr_t err = fil_create_link_file(
- new_name, new_path);
-
+ err = fil_create_link_file(new_name, new_path);
if (err != DB_SUCCESS) {
mem_free(new_path);
+ mem_free(old_path);
return(DB_TABLESPACE_EXISTS);
}
+ } else {
+ new_path = fil_make_ibd_name(new_name, false);
+ }
+
+ /* New filepath must not exist. */
+ err = fil_rename_tablespace_check(
+ table->space, old_path, new_path, false);
+ if (err != DB_SUCCESS) {
+ mem_free(old_path);
+ mem_free(new_path);
+ return(err);
}
ibool success = fil_rename_tablespace(
old_name, table->space, new_name, new_path);
+ mem_free(old_path);
+ mem_free(new_path);
+
/* If the tablespace is remote, a new .isl file was created
If success, delete the old one. If not, delete the new one. */
- if (new_path) {
-
- mem_free(new_path);
+ if (DICT_TF_HAS_DATA_DIR(table->flags)) {
fil_delete_link_file(success ? old_name : new_name);
}
diff --git a/storage/xtradb/fil/fil0fil.cc b/storage/xtradb/fil/fil0fil.cc
index 65827717230..5f0c52b5cc8 100644
--- a/storage/xtradb/fil/fil0fil.cc
+++ b/storage/xtradb/fil/fil0fil.cc
@@ -2994,6 +2994,48 @@ fil_make_isl_name(
return(filename);
}
+/** Test if a tablespace file can be renamed to a new filepath by checking
+if that the old filepath exists and the new filepath does not exist.
+@param[in] space_id tablespace id
+@param[in] old_path old filepath
+@param[in] new_path new filepath
+@param[in] is_discarded whether the tablespace is discarded
+@return innodb error code */
+dberr_t
+fil_rename_tablespace_check(
+ ulint space_id,
+ const char* old_path,
+ const char* new_path,
+ bool is_discarded)
+{
+ ulint exists = false;
+ os_file_type_t ftype;
+
+ if (!is_discarded
+ && os_file_status(old_path, &exists, &ftype)
+ && !exists) {
+ ib_logf(IB_LOG_LEVEL_ERROR,
+ "Cannot rename '%s' to '%s' for space ID %lu"
+ " because the source file does not exist.",
+ old_path, new_path, space_id);
+
+ return(DB_TABLESPACE_NOT_FOUND);
+ }
+
+ exists = false;
+ if (!os_file_status(new_path, &exists, &ftype) || exists) {
+ ib_logf(IB_LOG_LEVEL_ERROR,
+ "Cannot rename '%s' to '%s' for space ID %lu"
+ " because the target file exists."
+ " Remove the target file and try again.",
+ old_path, new_path, space_id);
+
+ return(DB_TABLESPACE_EXISTS);
+ }
+
+ return(DB_SUCCESS);
+}
+
/*******************************************************************//**
Renames a single-table tablespace. The tablespace must be cached in the
tablespace memory cache.
@@ -6918,31 +6960,110 @@ fil_get_space_names(
return(err);
}
-/****************************************************************//**
-Generate redo logs for swapping two .ibd files */
+/** Generate redo log for swapping two .ibd files
+@param[in] old_table old table
+@param[in] new_table new table
+@param[in] tmp_name temporary table name
+@param[in,out] mtr mini-transaction
+@return innodb error code */
UNIV_INTERN
-void
+dberr_t
fil_mtr_rename_log(
-/*===============*/
- ulint old_space_id, /*!< in: tablespace id of the old
- table. */
- const char* old_name, /*!< in: old table name */
- ulint new_space_id, /*!< in: tablespace id of the new
- table */
- const char* new_name, /*!< in: new table name */
- const char* tmp_name, /*!< in: temp table name used while
- swapping */
- mtr_t* mtr) /*!< in/out: mini-transaction */
+ const dict_table_t* old_table,
+ const dict_table_t* new_table,
+ const char* tmp_name,
+ mtr_t* mtr)
{
- if (old_space_id != TRX_SYS_SPACE) {
- fil_op_write_log(MLOG_FILE_RENAME, old_space_id,
- 0, 0, old_name, tmp_name, mtr);
+ dberr_t err = DB_SUCCESS;
+ char* old_path;
+
+ /* If neither table is file-per-table,
+ there will be no renaming of files. */
+ if (old_table->space == TRX_SYS_SPACE
+ && new_table->space == TRX_SYS_SPACE) {
+ return(DB_SUCCESS);
+ }
+
+ if (DICT_TF_HAS_DATA_DIR(old_table->flags)) {
+ old_path = os_file_make_remote_pathname(
+ old_table->data_dir_path, old_table->name, "ibd");
+ } else {
+ old_path = fil_make_ibd_name(old_table->name, false);
+ }
+ if (old_path == NULL) {
+ return(DB_OUT_OF_MEMORY);
+ }
+
+ if (old_table->space != TRX_SYS_SPACE) {
+ char* tmp_path;
+
+ if (DICT_TF_HAS_DATA_DIR(old_table->flags)) {
+ tmp_path = os_file_make_remote_pathname(
+ old_table->data_dir_path, tmp_name, "ibd");
+ }
+ else {
+ tmp_path = fil_make_ibd_name(tmp_name, false);
+ }
+
+ if (tmp_path == NULL) {
+ mem_free(old_path);
+ return(DB_OUT_OF_MEMORY);
+ }
+
+ /* Temp filepath must not exist. */
+ err = fil_rename_tablespace_check(
+ old_table->space, old_path, tmp_path,
+ dict_table_is_discarded(old_table));
+ mem_free(tmp_path);
+ if (err != DB_SUCCESS) {
+ mem_free(old_path);
+ return(err);
+ }
+
+ fil_op_write_log(MLOG_FILE_RENAME, old_table->space,
+ 0, 0, old_table->name, tmp_name, mtr);
}
- if (new_space_id != TRX_SYS_SPACE) {
- fil_op_write_log(MLOG_FILE_RENAME, new_space_id,
- 0, 0, new_name, old_name, mtr);
+ if (new_table->space != TRX_SYS_SPACE) {
+
+ /* Destination filepath must not exist unless this ALTER
+ TABLE starts and ends with a file_per-table tablespace. */
+ if (old_table->space == TRX_SYS_SPACE) {
+ char* new_path = NULL;
+
+ if (DICT_TF_HAS_DATA_DIR(new_table->flags)) {
+ new_path = os_file_make_remote_pathname(
+ new_table->data_dir_path,
+ new_table->name, "ibd");
+ }
+ else {
+ new_path = fil_make_ibd_name(
+ new_table->name, false);
+ }
+
+ if (new_path == NULL) {
+ mem_free(old_path);
+ return(DB_OUT_OF_MEMORY);
+ }
+
+ err = fil_rename_tablespace_check(
+ new_table->space, new_path, old_path,
+ dict_table_is_discarded(new_table));
+ mem_free(new_path);
+ if (err != DB_SUCCESS) {
+ mem_free(old_path);
+ return(err);
+ }
+ }
+
+ fil_op_write_log(MLOG_FILE_RENAME, new_table->space,
+ 0, 0, new_table->name, old_table->name, mtr);
+
}
+
+ mem_free(old_path);
+
+ return(err);
}
/*************************************************************************
diff --git a/storage/xtradb/fsp/fsp0fsp.cc b/storage/xtradb/fsp/fsp0fsp.cc
index 9af25b53a90..790232edb66 100644
--- a/storage/xtradb/fsp/fsp0fsp.cc
+++ b/storage/xtradb/fsp/fsp0fsp.cc
@@ -961,10 +961,20 @@ fsp_try_extend_data_file(
}
} else {
/* We extend single-table tablespaces first one extent
- at a time, but for bigger tablespaces more. It is not
- enough to extend always by one extent, because some
- extents are frag page extents. */
+ at a time, but 4 at a time for bigger tablespaces. It is
+ not enough to extend always by one extent, because we need
+ to add at least one extent to FSP_FREE.
+ A single extent descriptor page will track many extents.
+ And the extent that uses its extent descriptor page is
+ put onto the FSP_FREE_FRAG list. Extents that do not
+ use their extent descriptor page are added to FSP_FREE.
+ The physical page size is used to determine how many
+ extents are tracked on one extent descriptor page. */
ulint extent_size; /*!< one megabyte, in pages */
+ ulint threshold; /*!< The size of the tablespace
+ (in number of pages) where we
+ start allocating more than one
+ extent at a time. */
if (!zip_size) {
extent_size = FSP_EXTENT_SIZE;
@@ -973,6 +983,14 @@ fsp_try_extend_data_file(
* UNIV_PAGE_SIZE / zip_size;
}
+ /* Threshold is set at 32mb except when the page
+ size is small enough that it must be done sooner.
+ For page size less than 4k, we may reach the
+ extent contains extent descriptor page before
+ 32 mb. */
+ threshold = ut_min((32 * extent_size),
+ (zip_size ? zip_size : UNIV_PAGE_SIZE));
+
if (size < extent_size) {
/* Let us first extend the file to extent_size */
success = fsp_try_extend_data_file_with_pages(
@@ -989,7 +1007,7 @@ fsp_try_extend_data_file(
size = extent_size;
}
- if (size < 32 * extent_size) {
+ if (size < threshold) {
size_increase = extent_size;
} else {
/* Below in fsp_fill_free_list() we assume
diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc
index 2f989a47d86..89d31619ae2 100644
--- a/storage/xtradb/handler/ha_innodb.cc
+++ b/storage/xtradb/handler/ha_innodb.cc
@@ -5,7 +5,7 @@ Copyright (c) 2013, 2015, MariaDB Corporation.
Copyright (c) 2008, 2009 Google Inc.
Copyright (c) 2009, Percona Inc.
Copyright (c) 2012, Facebook Inc.
-Copyright (c) 2013, 2015, MariaDB Corporation.
+Copyright (c) 2013, 2014 SkySQL Ab. All Rights Reserved.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -944,12 +944,6 @@ static SHOW_VAR innodb_status_variables[]= {
(char*) &export_vars.innodb_os_log_pending_writes, SHOW_LONG},
{"os_log_written",
(char*) &export_vars.innodb_os_log_written, SHOW_LONGLONG},
- {"os_merge_buffers_written",
- (char*) &export_vars.innodb_merge_buffers_written, SHOW_LONGLONG},
- {"os_merge_buffers_read",
- (char*) &export_vars.innodb_merge_buffers_read, SHOW_LONGLONG},
- {"os_merge_buffers_merged",
- (char*) &export_vars.innodb_merge_buffers_merged, SHOW_LONGLONG},
{"page_size",
(char*) &export_vars.innodb_page_size, SHOW_LONG},
{"pages_created",
@@ -1490,7 +1484,6 @@ Normalizes a table name string. A normalized name consists of the
database name catenated to '/' and table name. An example:
test/mytable. On Windows normalization puts both the database name and the
table name always to lower case if "set_lower_case" is set to TRUE. */
-static
void
normalize_table_name_low(
/*=====================*/
@@ -5386,7 +5379,6 @@ Normalizes a table name string. A normalized name consists of the
database name catenated to '/' and table name. Example: test/mytable.
On Windows normalization puts both the database name and the
table name always to lower case if "set_lower_case" is set to TRUE. */
-static
void
normalize_table_name_low(
/*=====================*/
@@ -8323,7 +8315,13 @@ ha_innobase::write_row(
ha_statistic_increment(&SSV::ha_write_count);
- if (UNIV_UNLIKELY(share->ib_table->is_corrupt)) {
+ if (share->ib_table != prebuilt->table) {
+ fprintf(stderr,
+ "InnoDB: Warning: share->ib_table %p prebuilt->table %p table %s is_corrupt %d.",
+ share->ib_table, prebuilt->table, prebuilt->table->name, prebuilt->table->is_corrupt);
+ }
+
+ if (UNIV_UNLIKELY(share->ib_table && share->ib_table->is_corrupt)) {
DBUG_RETURN(HA_ERR_CRASHED);
}
@@ -8670,7 +8668,13 @@ wsrep_error:
func_exit:
innobase_active_small();
- if (UNIV_UNLIKELY(share->ib_table->is_corrupt)) {
+ if (share->ib_table != prebuilt->table) {
+ fprintf(stderr,
+ "InnoDB: Warning: share->ib_table %p prebuilt->table %p table %s is_corrupt %d.",
+ share->ib_table, prebuilt->table, prebuilt->table->name, prebuilt->table->is_corrupt);
+ }
+
+ if (UNIV_UNLIKELY(share->ib_table && share->ib_table->is_corrupt)) {
DBUG_RETURN(HA_ERR_CRASHED);
}
@@ -9084,7 +9088,13 @@ ha_innobase::update_row(
ha_statistic_increment(&SSV::ha_update_count);
- if (UNIV_UNLIKELY(share->ib_table->is_corrupt)) {
+ if (share->ib_table != prebuilt->table) {
+ fprintf(stderr,
+ "InnoDB: Warning: share->ib_table %p prebuilt->table %p table %s is_corrupt %d.",
+ share->ib_table, prebuilt->table, prebuilt->table->name, prebuilt->table->is_corrupt);
+ }
+
+ if (UNIV_UNLIKELY(share->ib_table && share->ib_table->is_corrupt)) {
DBUG_RETURN(HA_ERR_CRASHED);
}
@@ -9199,7 +9209,13 @@ func_exit:
wsrep_error:
#endif /* WITH_WSREP */
- if (UNIV_UNLIKELY(share->ib_table->is_corrupt)) {
+ if (share->ib_table != prebuilt->table) {
+ fprintf(stderr,
+ "InnoDB: Warning: share->ib_table %p prebuilt->table %p table %s is_corrupt %d.",
+ share->ib_table, prebuilt->table, prebuilt->table->name, prebuilt->table->is_corrupt);
+ }
+
+ if (UNIV_UNLIKELY(share->ib_table && share->ib_table->is_corrupt)) {
DBUG_RETURN(HA_ERR_CRASHED);
}
@@ -12721,7 +12737,13 @@ ha_innobase::truncate()
update_thd(ha_thd());
- if (UNIV_UNLIKELY(share->ib_table->is_corrupt)) {
+ if (share->ib_table != prebuilt->table) {
+ fprintf(stderr,
+ "InnoDB: Warning: share->ib_table %p prebuilt->table %p table %s is_corrupt %d.",
+ share->ib_table, prebuilt->table, prebuilt->table->name, prebuilt->table->is_corrupt);
+ }
+
+ if (UNIV_UNLIKELY(share->ib_table && share->ib_table->is_corrupt)) {
DBUG_RETURN(HA_ERR_CRASHED);
}
@@ -12736,7 +12758,13 @@ ha_innobase::truncate()
err = row_truncate_table_for_mysql(prebuilt->table, prebuilt->trx);
- if (UNIV_UNLIKELY(share->ib_table->is_corrupt)) {
+ if (share->ib_table != prebuilt->table) {
+ fprintf(stderr,
+ "InnoDB: Warning: share->ib_table %p prebuilt->table %p table %s is_corrupt %d.",
+ share->ib_table, prebuilt->table, prebuilt->table->name, prebuilt->table->is_corrupt);
+ }
+
+ if (UNIV_UNLIKELY(share->ib_table && share->ib_table->is_corrupt)) {
DBUG_RETURN(HA_ERR_CRASHED);
}
@@ -14126,7 +14154,13 @@ ha_innobase::analyze(
{
int ret;
- if (UNIV_UNLIKELY(share->ib_table->is_corrupt)) {
+ if (share->ib_table != prebuilt->table) {
+ fprintf(stderr,
+ "InnoDB: Warning: share->ib_table %p prebuilt->table %p table %s is_corrupt %d.",
+ share->ib_table, prebuilt->table, prebuilt->table->name, prebuilt->table->is_corrupt);
+ }
+
+ if (UNIV_UNLIKELY(share->ib_table && share->ib_table->is_corrupt)) {
return(HA_ADMIN_CORRUPT);
}
@@ -14136,7 +14170,13 @@ ha_innobase::analyze(
HA_STATUS_TIME | HA_STATUS_CONST | HA_STATUS_VARIABLE,
true /* this is ANALYZE */);
- if (UNIV_UNLIKELY(share->ib_table->is_corrupt)) {
+ if (share->ib_table != prebuilt->table) {
+ fprintf(stderr,
+ "InnoDB: Warning: share->ib_table %p prebuilt->table %p table %s is_corrupt %d.",
+ share->ib_table, prebuilt->table, prebuilt->table->name, prebuilt->table->is_corrupt);
+ }
+
+ if (UNIV_UNLIKELY(share->ib_table && share->ib_table->is_corrupt)) {
return(HA_ADMIN_CORRUPT);
}
@@ -15345,7 +15385,13 @@ ha_innobase::transactional_table_lock(
update_thd(thd);
- if (UNIV_UNLIKELY(share->ib_table->is_corrupt)) {
+ if (share->ib_table != prebuilt->table) {
+ fprintf(stderr,
+ "InnoDB: Warning: share->ib_table %p prebuilt->table %p table %s is_corrupt %d.",
+ share->ib_table, prebuilt->table, prebuilt->table->name, prebuilt->table->is_corrupt);
+ }
+
+ if (UNIV_UNLIKELY(share->ib_table && share->ib_table->is_corrupt)) {
DBUG_RETURN(HA_ERR_CRASHED);
}
@@ -18445,7 +18491,6 @@ innodb_sched_priority_purge_update(
return;
}
- ut_ad(purge_sys->state == PURGE_STATE_RUN);
for (ulint i = 0; i < srv_n_purge_threads; i++) {
ulint nice = os_thread_get_priority(srv_purge_tids[i]);
ulint actual_priority
diff --git a/storage/xtradb/handler/handler0alter.cc b/storage/xtradb/handler/handler0alter.cc
index 076c4b6c3b6..ea02463010c 100644
--- a/storage/xtradb/handler/handler0alter.cc
+++ b/storage/xtradb/handler/handler0alter.cc
@@ -167,10 +167,13 @@ my_error_innodb(
/* TODO: report the row, as we do for DB_DUPLICATE_KEY */
my_error(ER_INVALID_USE_OF_NULL, MYF(0));
break;
+ case DB_TABLESPACE_EXISTS:
+ my_error(ER_TABLESPACE_EXISTS, MYF(0), table);
+ break;
+
#ifdef UNIV_DEBUG
case DB_SUCCESS:
case DB_DUPLICATE_KEY:
- case DB_TABLESPACE_EXISTS:
case DB_ONLINE_LOG_TOO_BIG:
/* These codes should not be passed here. */
ut_error;
@@ -202,12 +205,14 @@ innobase_fulltext_exist(
/*******************************************************************//**
Determine if ALTER TABLE needs to rebuild the table.
@param ha_alter_info the DDL operation
+@param altered_table MySQL original table
@return whether it is necessary to rebuild the table */
static __attribute__((nonnull, warn_unused_result))
bool
innobase_need_rebuild(
/*==================*/
- const Alter_inplace_info* ha_alter_info)
+ const Alter_inplace_info* ha_alter_info,
+ const TABLE* altered_table)
{
if (ha_alter_info->handler_flags
== Alter_inplace_info::CHANGE_CREATE_OPTION
@@ -219,6 +224,34 @@ innobase_need_rebuild(
return(false);
}
+ /* If alter table changes column name and adds a new
+ index, we need to check is this new index created
+ to new column name. This is because column name
+ changes are done normally after creating indexes. */
+ if ((ha_alter_info->handler_flags
+ & Alter_inplace_info::ALTER_COLUMN_NAME) &&
+ ((ha_alter_info->handler_flags
+ & Alter_inplace_info::ADD_INDEX) ||
+ (ha_alter_info->handler_flags
+ & Alter_inplace_info::ADD_FOREIGN_KEY))) {
+ for (ulint i = 0; i < ha_alter_info->key_count; i++) {
+ const KEY* key = &ha_alter_info->key_info_buffer[
+ ha_alter_info->index_add_buffer[i]];
+
+ for (ulint j = 0; j < key->user_defined_key_parts; j++) {
+ const KEY_PART_INFO* key_part = &(key->key_part[j]);
+ const Field* field = altered_table->field[key_part->fieldnr];
+
+ /* Field used on added index is renamed on
+ this same alter table. We need table
+ rebuild. */
+ if (field->flags & FIELD_IS_RENAMED) {
+ return (true);
+ }
+ }
+ }
+ }
+
return(!!(ha_alter_info->handler_flags & INNOBASE_ALTER_REBUILD));
}
@@ -557,7 +590,7 @@ ha_innobase::check_if_supported_inplace_alter(
operation is possible. */
} else if (((ha_alter_info->handler_flags
& Alter_inplace_info::ADD_PK_INDEX)
- || innobase_need_rebuild(ha_alter_info))
+ || innobase_need_rebuild(ha_alter_info, table))
&& (innobase_fulltext_exist(altered_table))) {
/* Refuse to rebuild the table online, if
fulltext indexes are to survive the rebuild. */
@@ -1558,7 +1591,8 @@ innobase_create_index_def(
index_def_t* index, /*!< out: index definition */
mem_heap_t* heap, /*!< in: heap where memory
is allocated */
- const Field** fields) /*!z in: MySQL table fields */
+ const Field** fields) /*!< in: MySQL table fields
+ */
{
const KEY* key = &keys[key_number];
ulint i;
@@ -1854,9 +1888,11 @@ innobase_create_key_defs(
bool& add_fts_doc_id,
/*!< in: whether we need to add new DOC ID
column for FTS index */
- bool& add_fts_doc_idx)
+ bool& add_fts_doc_idx,
/*!< in: whether we need to add new DOC ID
index for FTS index */
+ const TABLE* table)
+ /*!< in: MySQL table that is being altered */
{
index_def_t* indexdef;
index_def_t* indexdefs;
@@ -1906,7 +1942,8 @@ innobase_create_key_defs(
}
const bool rebuild = new_primary || add_fts_doc_id
- || innobase_need_rebuild(ha_alter_info);
+ || innobase_need_rebuild(ha_alter_info, table);
+
/* Reserve one more space if new_primary is true, and we might
need to add the FTS_DOC_ID_INDEX */
indexdef = indexdefs = static_cast<index_def_t*>(
@@ -2744,7 +2781,8 @@ prepare_inplace_alter_table_dict(
ctx->heap, ha_alter_info, altered_table, ctx->num_to_add_index,
num_fts_index,
row_table_got_default_clust_index(ctx->new_table),
- fts_doc_id_col, add_fts_doc_id, add_fts_doc_id_idx);
+ fts_doc_id_col, add_fts_doc_id, add_fts_doc_id_idx,
+ old_table);
new_clustered = DICT_CLUSTERED & index_defs[0].ind_type;
@@ -2757,7 +2795,7 @@ prepare_inplace_alter_table_dict(
/* This is not an online operation (LOCK=NONE). */
} else if (ctx->add_autoinc == ULINT_UNDEFINED
&& num_fts_index == 0
- && (!innobase_need_rebuild(ha_alter_info)
+ && (!innobase_need_rebuild(ha_alter_info, old_table)
|| !innobase_fulltext_exist(altered_table))) {
/* InnoDB can perform an online operation (LOCK=NONE). */
} else {
@@ -2774,7 +2812,7 @@ prepare_inplace_alter_table_dict(
is just copied from old table and stored in indexdefs[0] */
DBUG_ASSERT(!add_fts_doc_id || new_clustered);
DBUG_ASSERT(!!new_clustered ==
- (innobase_need_rebuild(ha_alter_info)
+ (innobase_need_rebuild(ha_alter_info, old_table)
|| add_fts_doc_id));
/* Allocate memory for dictionary index definitions */
@@ -3034,7 +3072,7 @@ prepare_inplace_alter_table_dict(
add_cols, ctx->heap);
ctx->add_cols = add_cols;
} else {
- DBUG_ASSERT(!innobase_need_rebuild(ha_alter_info));
+ DBUG_ASSERT(!innobase_need_rebuild(ha_alter_info, old_table));
if (!ctx->new_table->fts
&& innobase_fulltext_exist(altered_table)) {
@@ -3055,7 +3093,7 @@ prepare_inplace_alter_table_dict(
ctx->add_index[a] = row_merge_create_index(
ctx->trx, ctx->new_table,
- &index_defs[a]);
+ &index_defs[a], ctx->col_names);
add_key_nums[a] = index_defs[a].key_number;
@@ -3925,7 +3963,7 @@ err_exit:
if (!(ha_alter_info->handler_flags & INNOBASE_ALTER_DATA)
|| (ha_alter_info->handler_flags
== Alter_inplace_info::CHANGE_CREATE_OPTION
- && !innobase_need_rebuild(ha_alter_info))) {
+ && !innobase_need_rebuild(ha_alter_info, table))) {
if (heap) {
ha_alter_info->handler_ctx
@@ -4099,7 +4137,7 @@ ok_exit:
if (ha_alter_info->handler_flags
== Alter_inplace_info::CHANGE_CREATE_OPTION
- && !innobase_need_rebuild(ha_alter_info)) {
+ && !innobase_need_rebuild(ha_alter_info, table)) {
goto ok_exit;
}
@@ -4811,9 +4849,11 @@ commit_get_autoinc(
Field* autoinc_field =
old_table->found_next_number_field;
+ KEY* autoinc_key =
+ old_table->key_info + old_table->s->next_number_index;
- dict_index_t* index = dict_table_get_index_on_first_col(
- ctx->old_table, autoinc_field->field_index);
+ dict_index_t* index = dict_table_get_index_on_name(
+ ctx->old_table, autoinc_key->name);
max_autoinc = ha_alter_info->create_info->auto_increment_value;
@@ -5221,6 +5261,61 @@ commit_cache_rebuild(
DBUG_VOID_RETURN;
}
+/** Store the column number of the columns in a list belonging
+to indexes which are not being dropped.
+@param[in] ctx In-place ALTER TABLE context
+@param[out] drop_col_list list which will be set, containing columns
+ which is part of index being dropped */
+static
+void
+get_col_list_to_be_dropped(
+ ha_innobase_inplace_ctx* ctx,
+ std::set<ulint>& drop_col_list)
+{
+ for (ulint index_count = 0; index_count < ctx->num_to_drop_index;
+ index_count++) {
+ dict_index_t* index = ctx->drop_index[index_count];
+
+ for (ulint col = 0; col < index->n_user_defined_cols; col++) {
+ ulint col_no = dict_index_get_nth_col_no(index, col);
+ drop_col_list.insert(col_no);
+ }
+ }
+}
+
+/** For each column, which is part of an index which is not going to be
+dropped, it checks if the column number of the column is same as col_no
+argument passed.
+@param[in] table table object
+@param[in] col_no column number of the column which is to be checked
+@retval true column exists
+@retval false column does not exist. */
+static
+bool
+check_col_exists_in_indexes(
+ const dict_table_t* table,
+ ulint col_no)
+{
+ for (dict_index_t* index = dict_table_get_first_index(table); index;
+ index = dict_table_get_next_index(index)) {
+
+ if (index->to_be_dropped) {
+ continue;
+ }
+
+ for (ulint col = 0; col < index->n_user_defined_cols; col++) {
+
+ ulint index_col_no = dict_index_get_nth_col_no(
+ index, col);
+ if (col_no == index_col_no) {
+ return(true);
+ }
+ }
+ }
+
+ return(false);
+}
+
/** Commit the changes made during prepare_inplace_alter_table()
and inplace_alter_table() inside the data dictionary tables,
when not rebuilding the table.
@@ -5356,6 +5451,20 @@ commit_cache_norebuild(
DBUG_ASSERT(!ctx->need_rebuild());
+ std::set<ulint> drop_list;
+ std::set<ulint>::const_iterator col_it;
+
+ /* Check if the column, part of an index to be dropped is part of any
+ other index which is not being dropped. If it so, then set the ord_part
+ of the column to 0. */
+ get_col_list_to_be_dropped(ctx, drop_list);
+
+ for(col_it = drop_list.begin(); col_it != drop_list.end(); ++col_it) {
+ if (!check_col_exists_in_indexes(ctx->new_table, *col_it)) {
+ ctx->new_table->cols[*col_it].ord_part = 0;
+ }
+ }
+
for (ulint i = 0; i < ctx->num_to_add_index; i++) {
dict_index_t* index = ctx->add_index[i];
DBUG_ASSERT(dict_index_get_online_status(index)
@@ -5556,6 +5665,7 @@ ha_innobase::commit_inplace_alter_table(
Alter_inplace_info* ha_alter_info,
bool commit)
{
+ dberr_t error;
ha_innobase_inplace_ctx* ctx0
= static_cast<ha_innobase_inplace_ctx*>
(ha_alter_info->handler_ctx);
@@ -5637,7 +5747,7 @@ ha_innobase::commit_inplace_alter_table(
transactions collected during crash recovery could be
holding InnoDB locks only, not MySQL locks. */
- dberr_t error = row_merge_lock_table(
+ error = row_merge_lock_table(
prebuilt->trx, ctx->old_table, LOCK_X);
if (error != DB_SUCCESS) {
@@ -5772,14 +5882,20 @@ ha_innobase::commit_inplace_alter_table(
= static_cast<ha_innobase_inplace_ctx*>(*pctx);
DBUG_ASSERT(ctx->need_rebuild());
- /* Generate the redo log for the file
- operations that will be performed in
- commit_cache_rebuild(). */
- fil_mtr_rename_log(ctx->old_table->space,
- ctx->old_table->name,
- ctx->new_table->space,
- ctx->new_table->name,
- ctx->tmp_name, &mtr);
+ /* Check for any possible problems for any
+ file operations that will be performed in
+ commit_cache_rebuild(), and if none, generate
+ the redo log for these operations. */
+ error = fil_mtr_rename_log(ctx->old_table,
+ ctx->new_table,
+ ctx->tmp_name, &mtr);
+ if (error != DB_SUCCESS) {
+ /* Out of memory or a problem will occur
+ when renaming files. */
+ fail = true;
+ my_error_innodb(error, ctx->old_table->name,
+ ctx->old_table->flags);
+ }
DBUG_INJECT_CRASH("ib_commit_inplace_crash",
crash_inject_count++);
}
@@ -5792,18 +5908,25 @@ ha_innobase::commit_inplace_alter_table(
DBUG_EXECUTE_IF("innodb_alter_commit_crash_before_commit",
log_buffer_flush_to_disk();
DBUG_SUICIDE(););
- ut_ad(trx_state_eq(trx, TRX_STATE_ACTIVE));
ut_ad(!trx->fts_trx);
- ut_ad(trx->insert_undo || trx->update_undo);
- /* The following call commits the
- mini-transaction, making the data dictionary
- transaction committed at mtr.end_lsn. The
- transaction becomes 'durable' by the time when
- log_buffer_flush_to_disk() returns. In the
- logical sense the commit in the file-based
- data structures happens here. */
- trx_commit_low(trx, &mtr);
+ if (fail) {
+ mtr_set_log_mode(&mtr, MTR_LOG_NO_REDO);
+ mtr_commit(&mtr);
+ trx_rollback_for_mysql(trx);
+ } else {
+ /* The following call commits the
+ mini-transaction, making the data dictionary
+ transaction committed at mtr.end_lsn. The
+ transaction becomes 'durable' by the time when
+ log_buffer_flush_to_disk() returns. In the
+ logical sense the commit in the file-based
+ data structures happens here. */
+ ut_ad(trx_state_eq(trx, TRX_STATE_ACTIVE));
+ ut_ad(trx->insert_undo || trx->update_undo);
+
+ trx_commit_low(trx, &mtr);
+ }
/* If server crashes here, the dictionary in
InnoDB and MySQL will differ. The .ibd files
@@ -5825,7 +5948,6 @@ ha_innobase::commit_inplace_alter_table(
update the in-memory structures, close some handles, release
temporary files, and (unless we rolled back) update persistent
statistics. */
- dberr_t error = DB_SUCCESS;
for (inplace_alter_handler_ctx** pctx = ctx_array;
*pctx; pctx++) {
diff --git a/storage/xtradb/include/buf0flu.h b/storage/xtradb/include/buf0flu.h
index c51010e33bc..87ce7d88bdf 100644
--- a/storage/xtradb/include/buf0flu.h
+++ b/storage/xtradb/include/buf0flu.h
@@ -211,7 +211,7 @@ Clears up tail of the LRU lists:
* Flush dirty pages at the tail of LRU to the disk
The depth to which we scan each buffer pool is controlled by dynamic
config parameter innodb_LRU_scan_depth.
-@return total pages flushed */
+@return number of pages flushed */
UNIV_INTERN
ulint
buf_flush_LRU_tail(void);
diff --git a/storage/xtradb/include/fil0fil.h b/storage/xtradb/include/fil0fil.h
index 2a3995519a7..973882a50b4 100644
--- a/storage/xtradb/include/fil0fil.h
+++ b/storage/xtradb/include/fil0fil.h
@@ -1,7 +1,7 @@
/*****************************************************************************
-Copyright (c) 1995, 2014, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2013, 2015, MariaDB Corporation.
+Copyright (c) 1995, 2015, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2013, 2016, MariaDB Corporation.
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
@@ -699,6 +699,21 @@ fil_discard_tablespace(
ulint id) /*!< in: space id */
__attribute__((warn_unused_result));
#endif /* !UNIV_HOTBACKUP */
+
+/** Test if a tablespace file can be renamed to a new filepath by checking
+if that the old filepath exists and the new filepath does not exist.
+@param[in] space_id tablespace id
+@param[in] old_path old filepath
+@param[in] new_path new filepath
+@param[in] is_discarded whether the tablespace is discarded
+@return innodb error code */
+dberr_t
+fil_rename_tablespace_check(
+ ulint space_id,
+ const char* old_path,
+ const char* new_path,
+ bool is_discarded);
+
/*******************************************************************//**
Renames a single-table tablespace. The tablespace must be cached in the
tablespace memory cache.
@@ -1223,21 +1238,19 @@ fil_get_space_names(
/*!< in/out: Vector for collecting the names. */
__attribute__((warn_unused_result));
-/****************************************************************//**
-Generate redo logs for swapping two .ibd files */
+/** Generate redo log for swapping two .ibd files
+@param[in] old_table old table
+@param[in] new_table new table
+@param[in] tmp_name temporary table name
+@param[in,out] mtr mini-transaction
+@return innodb error code */
UNIV_INTERN
-void
+dberr_t
fil_mtr_rename_log(
-/*===============*/
- ulint old_space_id, /*!< in: tablespace id of the old
- table. */
- const char* old_name, /*!< in: old table name */
- ulint new_space_id, /*!< in: tablespace id of the new
- table */
- const char* new_name, /*!< in: new table name */
- const char* tmp_name, /*!< in: temp table name used while
- swapping */
- mtr_t* mtr) /*!< in/out: mini-transaction */
+ const dict_table_t* old_table,
+ const dict_table_t* new_table,
+ const char* tmp_name,
+ mtr_t* mtr)
__attribute__((nonnull));
/*******************************************************************//**
diff --git a/storage/xtradb/include/ha_prototypes.h b/storage/xtradb/include/ha_prototypes.h
index 9ec6a7ff4b4..a9c003d5bb1 100644
--- a/storage/xtradb/include/ha_prototypes.h
+++ b/storage/xtradb/include/ha_prototypes.h
@@ -655,4 +655,18 @@ ib_push_warning(
ulint error, /*!< in: error code to push as warning */
const char *format,/*!< in: warning message */
...);
+
+/*****************************************************************//**
+Normalizes a table name string. A normalized name consists of the
+database name catenated to '/' and table name. An example:
+test/mytable. On Windows normalization puts both the database name and the
+table name always to lower case if "set_lower_case" is set to TRUE. */
+void
+normalize_table_name_low(
+/*=====================*/
+ char* norm_name, /*!< out: normalized name as a
+ null-terminated string */
+ const char* name, /*!< in: table name string */
+ ibool set_lower_case); /*!< in: TRUE if we want to set
+ name to lower case */
#endif /* HA_INNODB_PROTOTYPES_H */
diff --git a/storage/xtradb/include/row0merge.h b/storage/xtradb/include/row0merge.h
index 196543f25e1..3e3459b8703 100644
--- a/storage/xtradb/include/row0merge.h
+++ b/storage/xtradb/include/row0merge.h
@@ -268,8 +268,11 @@ row_merge_create_index(
/*===================*/
trx_t* trx, /*!< in/out: trx (sets error_state) */
dict_table_t* table, /*!< in: the index is on this table */
- const index_def_t* index_def);
+ const index_def_t* index_def,
/*!< in: the index definition */
+ const char** col_names);
+ /*! in: column names if columns are
+ renamed or NULL */
/*********************************************************************//**
Check if a transaction can use an index.
@return TRUE if index can be used by the transaction else FALSE */
diff --git a/storage/xtradb/include/srv0mon.h b/storage/xtradb/include/srv0mon.h
index 658cd94d1ec..33ae7749ca5 100644
--- a/storage/xtradb/include/srv0mon.h
+++ b/storage/xtradb/include/srv0mon.h
@@ -2,7 +2,7 @@
Copyright (c) 2010, 2013, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc.
-Copyright (c) 2013, 2015, MariaDB Corporation.
+Copyright (c) 2013, 2016, MariaDB Corporation.
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
@@ -263,9 +263,6 @@ enum monitor_id_t {
MONITOR_OVLD_OS_LOG_FSYNC,
MONITOR_OVLD_OS_LOG_PENDING_FSYNC,
MONITOR_OVLD_OS_LOG_PENDING_WRITES,
- MONITOR_MERGE_BLOCKS_WRITTEN,
- MONITOR_MERGE_BLOCKS_READ,
- MONITOR_MERGE_BLOCKS_MERGED,
/* Transaction related counters */
MONITOR_MODULE_TRX,
diff --git a/storage/xtradb/include/srv0srv.h b/storage/xtradb/include/srv0srv.h
index 9a3bf4e74ae..a2d300957ba 100644
--- a/storage/xtradb/include/srv0srv.h
+++ b/storage/xtradb/include/srv0srv.h
@@ -3,7 +3,7 @@
Copyright (c) 1995, 2015, Oracle and/or its affiliates.
Copyright (c) 2008, 2009, Google Inc.
Copyright (c) 2009, Percona Inc.
-Copyright (c) 2013, 2015, MariaDB Corporation.
+Copyright (c) 2013, 2014, SkySQL Ab. All Rights Reserved.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -186,13 +186,6 @@ struct srv_stats_t {
/** Number of lock waits that have been up to max time (i.e.) lock
wait timeout */
ulint_ctr_1_t n_lock_max_wait_time;
-
- /** Number of merge buffers written */
- ulint_ctr_64_t merge_buffers_written;
- /** Number of merge buffers read */
- ulint_ctr_64_t merge_buffers_read;
- /** Number of merge buffers merged */
- ulint_ctr_64_t merge_buffers_merged;
};
extern const char* srv_main_thread_op_info;
@@ -1214,9 +1207,6 @@ struct export_var_t{
ulint innodb_purge_view_trx_id_age; /*!< rw_max_trx_id
- purged view's min trx_id */
#endif /* UNIV_DEBUG */
- ib_int64_t innodb_merge_buffers_written;
- ib_int64_t innodb_merge_buffers_read;
- ib_int64_t innodb_merge_buffers_merged;
ib_int64_t innodb_page_compression_saved;/*!< Number of bytes saved
by page compression */
diff --git a/storage/xtradb/include/univ.i b/storage/xtradb/include/univ.i
index dabaee4110c..f4a0da12476 100644
--- a/storage/xtradb/include/univ.i
+++ b/storage/xtradb/include/univ.i
@@ -45,10 +45,10 @@ Created 1/20/1994 Heikki Tuuri
#define INNODB_VERSION_MAJOR 5
#define INNODB_VERSION_MINOR 6
-#define INNODB_VERSION_BUGFIX 26
+#define INNODB_VERSION_BUGFIX 28
#ifndef PERCONA_INNODB_VERSION
-#define PERCONA_INNODB_VERSION 76.0
+#define PERCONA_INNODB_VERSION 76.1
#endif
/* Enable UNIV_LOG_ARCHIVE in XtraDB */
diff --git a/storage/xtradb/log/log0recv.cc b/storage/xtradb/log/log0recv.cc
index b0e69107723..c9bf5cf3f9e 100644
--- a/storage/xtradb/log/log0recv.cc
+++ b/storage/xtradb/log/log0recv.cc
@@ -849,6 +849,10 @@ not_consistent:
fprintf(stderr,
"InnoDB: No valid checkpoint found.\n"
+ "InnoDB: If you are attempting downgrade"
+ " from MySQL 5.7.9 or later,\n"
+ "InnoDB: please refer to " REFMAN
+ "upgrading-downgrading.html\n"
"InnoDB: If this error appears when you are"
" creating an InnoDB database,\n"
"InnoDB: the problem may be that during"
diff --git a/storage/xtradb/row/row0import.cc b/storage/xtradb/row/row0import.cc
index ac6380e5a27..893ffcab3da 100644
--- a/storage/xtradb/row/row0import.cc
+++ b/storage/xtradb/row/row0import.cc
@@ -2070,8 +2070,20 @@ PageConverter::validate(
return(IMPORT_PAGE_STATUS_CORRUPTED);
} else if (offset > 0 && page_get_page_no(page) == 0) {
- const byte* b = page;
- const byte* e = b + m_page_size;
+ ulint checksum;
+
+ checksum = mach_read_from_4(page + FIL_PAGE_SPACE_OR_CHKSUM);
+ if (checksum != 0) {
+ /* Checksum check passed in buf_page_is_corrupted(). */
+ ib_logf(IB_LOG_LEVEL_WARN,
+ "%s: Page %lu checksum %lu should be zero.",
+ m_filepath, (ulong) (offset / m_page_size),
+ checksum);
+ }
+
+ const byte* b = page + FIL_PAGE_OFFSET;
+ const byte* e = page + m_page_size
+ - FIL_PAGE_END_LSN_OLD_CHKSUM;
/* If the page number is zero and offset > 0 then
the entire page MUST consist of zeroes. If not then
diff --git a/storage/xtradb/row/row0log.cc b/storage/xtradb/row/row0log.cc
index 7014b8b99d2..b0c6f881f81 100644
--- a/storage/xtradb/row/row0log.cc
+++ b/storage/xtradb/row/row0log.cc
@@ -1462,6 +1462,7 @@ row_log_table_apply_insert_low(
dtuple_t* entry;
const row_log_t*log = dup->index->online_log;
dict_index_t* index = dict_table_get_first_index(log->table);
+ ulint n_index = 0;
ut_ad(dtuple_validate(row));
ut_ad(trx_id);
@@ -1497,6 +1498,8 @@ row_log_table_apply_insert_low(
}
do {
+ n_index++;
+
if (!(index = dict_table_get_next_index(index))) {
break;
}
@@ -1509,6 +1512,12 @@ row_log_table_apply_insert_low(
error = row_ins_sec_index_entry_low(
flags, BTR_MODIFY_TREE,
index, offsets_heap, heap, entry, trx_id, thr);
+
+ /* Report correct index name for duplicate key error. */
+ if (error == DB_DUPLICATE_KEY) {
+ thr_get_trx(thr)->error_key_num = n_index;
+ }
+
} while (error == DB_SUCCESS);
return(error);
@@ -1816,6 +1825,7 @@ row_log_table_apply_update(
mtr_t mtr;
btr_pcur_t pcur;
dberr_t error;
+ ulint n_index = 0;
ut_ad(dtuple_get_n_fields_cmp(old_pk)
== dict_index_get_n_unique(index));
@@ -2091,6 +2101,8 @@ func_exit_committed:
break;
}
+ n_index++;
+
if (index->type & DICT_FTS) {
continue;
}
@@ -2134,6 +2146,11 @@ func_exit_committed:
BTR_MODIFY_TREE, index, offsets_heap, heap,
entry, trx_id, thr);
+ /* Report correct index name for duplicate key error. */
+ if (error == DB_DUPLICATE_KEY) {
+ thr_get_trx(thr)->error_key_num = n_index;
+ }
+
mtr_start(&mtr);
}
diff --git a/storage/xtradb/row/row0merge.cc b/storage/xtradb/row/row0merge.cc
index ad3e7619c8a..8d7fcd7388c 100644
--- a/storage/xtradb/row/row0merge.cc
+++ b/storage/xtradb/row/row0merge.cc
@@ -1,7 +1,6 @@
/*****************************************************************************
Copyright (c) 2005, 2015, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2014, 2015, MariaDB Corporation.
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
@@ -971,7 +970,6 @@ row_merge_read(
success = os_file_read_no_error_handling(OS_FILE_FROM_FD(fd), buf,
ofs, srv_sort_buf_size);
- srv_stats.merge_buffers_read.inc();
/* For encrypted tables, decrypt data after reading and copy data */
if (crypt_data && crypt_buf) {
@@ -1027,7 +1025,6 @@ row_merge_write(
}
ret = os_file_write("(merge)", OS_FILE_FROM_FD(fd), out_buf, ofs, buf_len);
- srv_stats.merge_buffers_written.inc();
#ifdef UNIV_DEBUG
if (row_merge_print_block_write) {
@@ -1916,7 +1913,7 @@ write_buffers:
/* We have enough data tuples to form a block.
Sort them and write to disk. */
- if (UNIV_LIKELY(buf->n_tuples)) {
+ if (buf->n_tuples) {
if (dict_index_is_unique(buf->index)) {
row_merge_dup_t dup = {
buf->index, table, col_map, 0};
@@ -1957,17 +1954,13 @@ write_buffers:
dict_index_get_lock(buf->index));
}
- /* Do not write empty buffers to temporary file */
- if (buf->n_tuples) {
-
- row_merge_buf_write(buf, file, block);
+ row_merge_buf_write(buf, file, block);
- if (!row_merge_write(file->fd, file->offset++, block,
- crypt_data, crypt_block, new_table->space)) {
- err = DB_TEMP_FILE_WRITE_FAILURE;
- trx->error_key_num = i;
- break;
- }
+ if (!row_merge_write(file->fd, file->offset++, block,
+ crypt_data, crypt_block, new_table->space)) {
+ err = DB_TEMP_FILE_WRITE_FAILURE;
+ trx->error_key_num = i;
+ break;
}
UNIV_MEM_INVALID(&block[0], srv_sort_buf_size);
@@ -2284,8 +2277,6 @@ done1:
b2, of->fd, &of->offset,
crypt_data, crypt_block ? &crypt_block[2 * srv_sort_buf_size] : NULL, space);
- srv_stats.merge_buffers_merged.inc();
-
return(b2 ? DB_SUCCESS : DB_CORRUPTION);
}
@@ -3746,8 +3737,11 @@ row_merge_create_index(
/*===================*/
trx_t* trx, /*!< in/out: trx (sets error_state) */
dict_table_t* table, /*!< in: the index is on this table */
- const index_def_t* index_def)
+ const index_def_t* index_def,
/*!< in: the index definition */
+ const char** col_names)
+ /*! in: column names if columns are
+ renamed or NULL */
{
dict_index_t* index;
dberr_t err;
@@ -3767,9 +3761,24 @@ row_merge_create_index(
for (i = 0; i < n_fields; i++) {
index_field_t* ifield = &index_def->fields[i];
- const char * col_name = ifield->col_name ?
- dict_table_get_col_name_for_mysql(table, ifield->col_name) :
- dict_table_get_col_name(table, ifield->col_no);
+ const char * col_name;
+
+ /*
+ Alter table renaming a column and then adding a index
+ to this new name e.g ALTER TABLE t
+ CHANGE COLUMN b c INT NOT NULL, ADD UNIQUE INDEX (c);
+ requires additional check as column names are not yet
+ changed when new index definitions are created. Table's
+ new column names are on a array of column name pointers
+ if any of the column names are changed. */
+
+ if (col_names && col_names[i]) {
+ col_name = col_names[i];
+ } else {
+ col_name = ifield->col_name ?
+ dict_table_get_col_name_for_mysql(table, ifield->col_name) :
+ dict_table_get_col_name(table, ifield->col_no);
+ }
dict_mem_index_add_field(
index,
@@ -4110,71 +4119,67 @@ wait_again:
#ifdef FTS_INTERNAL_DIAG_PRINT
DEBUG_FTS_SORT_PRINT("FTS_SORT: Complete Insert\n");
#endif
- } else {
- /* Sorting and inserting is required only if
- there really is records */
- if (UNIV_LIKELY(merge_files[i].n_rec)) {
- char buf[3 * NAME_LEN];
- char *bufend;
- row_merge_dup_t dup = {
- sort_idx, table, col_map, 0};
+ } else if (UNIV_LIKELY(merge_files[i].n_rec)) {
+ char buf[3 * NAME_LEN];
+ char *bufend;
+ row_merge_dup_t dup = {
+ sort_idx, table, col_map, 0};
- pct_cost = (COST_BUILD_INDEX_STATIC +
- (total_dynamic_cost * merge_files[i].offset /
- total_index_blocks)) /
- (total_static_cost + total_dynamic_cost)
- * PCT_COST_MERGESORT_INDEX * 100;
+ pct_cost = (COST_BUILD_INDEX_STATIC +
+ (total_dynamic_cost * merge_files[i].offset /
+ total_index_blocks)) /
+ (total_static_cost + total_dynamic_cost)
+ * PCT_COST_MERGESORT_INDEX * 100;
+
+ bufend = innobase_convert_name(buf, sizeof buf,
+ indexes[i]->name, strlen(indexes[i]->name),
+ trx ? trx->mysql_thd : NULL,
+ FALSE);
- bufend = innobase_convert_name(buf, sizeof buf,
- indexes[i]->name, strlen(indexes[i]->name),
- trx ? trx->mysql_thd : NULL,
- FALSE);
+ buf[bufend - buf]='\0';
- buf[bufend - buf]='\0';
+ sql_print_information("InnoDB: Online DDL : Start merge-sorting"
+ " index %s (%lu / %lu), estimated cost : %2.4f",
+ buf, (i+1), n_indexes, pct_cost);
- sql_print_information("InnoDB: Online DDL : Start merge-sorting"
- " index %s (%lu / %lu), estimated cost : %2.4f",
- buf, (i+1), n_indexes, pct_cost);
+ error = row_merge_sort(
+ trx, &dup, &merge_files[i],
+ block, &tmpfd, true,
+ pct_progress, pct_cost,
+ crypt_data, crypt_block, new_table->space);
- error = row_merge_sort(
- trx, &dup, &merge_files[i],
- block, &tmpfd, true,
- pct_progress, pct_cost,
- crypt_data, crypt_block, new_table->space);
+ pct_progress += pct_cost;
+
+ sql_print_information("InnoDB: Online DDL : End of "
+ " merge-sorting index %s (%lu / %lu)",
+ buf, (i+1), n_indexes);
+
+ DBUG_EXECUTE_IF(
+ "ib_merge_wait_after_sort",
+ os_thread_sleep(20000000);); /* 20 sec */
+ if (error == DB_SUCCESS) {
+ pct_cost = (COST_BUILD_INDEX_STATIC +
+ (total_dynamic_cost * merge_files[i].offset /
+ total_index_blocks)) /
+ (total_static_cost + total_dynamic_cost) *
+ PCT_COST_INSERT_INDEX * 100;
+
+ sql_print_information("InnoDB: Online DDL : Start "
+ "building index %s (%lu / %lu), estimated "
+ "cost : %2.4f", buf, (i+1),
+ n_indexes, pct_cost);
+
+ error = row_merge_insert_index_tuples(
+ trx->id, sort_idx, old_table,
+ merge_files[i].fd, block,
+ merge_files[i].n_rec, pct_progress, pct_cost,
+ crypt_data, crypt_block, new_table->space);
pct_progress += pct_cost;
- sql_print_information("InnoDB: Online DDL : End of "
- " merge-sorting index %s (%lu / %lu)",
+ sql_print_information("InnoDB: Online DDL : "
+ "End of building index %s (%lu / %lu)",
buf, (i+1), n_indexes);
-
- DBUG_EXECUTE_IF(
- "ib_merge_wait_after_sort",
- os_thread_sleep(20000000);); /* 20 sec */
-
- if (error == DB_SUCCESS) {
- pct_cost = (COST_BUILD_INDEX_STATIC +
- (total_dynamic_cost * merge_files[i].offset /
- total_index_blocks)) /
- (total_static_cost + total_dynamic_cost) *
- PCT_COST_INSERT_INDEX * 100;
-
- sql_print_information("InnoDB: Online DDL : Start "
- "building index %s (%lu / %lu), estimated "
- "cost : %2.4f", buf, (i+1),
- n_indexes, pct_cost);
-
- error = row_merge_insert_index_tuples(
- trx->id, sort_idx, old_table,
- merge_files[i].fd, block,
- merge_files[i].n_rec, pct_progress, pct_cost,
- crypt_data, crypt_block, new_table->space);
- pct_progress += pct_cost;
-
- sql_print_information("InnoDB: Online DDL : "
- "End of building index %s (%lu / %lu)",
- buf, (i+1), n_indexes);
- }
}
}
diff --git a/storage/xtradb/row/row0mysql.cc b/storage/xtradb/row/row0mysql.cc
index 55e685ac19c..9427b20daf9 100644
--- a/storage/xtradb/row/row0mysql.cc
+++ b/storage/xtradb/row/row0mysql.cc
@@ -4894,6 +4894,7 @@ row_rename_table_for_mysql(
pars_info_t* info = NULL;
int retry;
bool aux_fts_rename = false;
+ char* is_part = NULL;
ut_a(old_name != NULL);
ut_a(new_name != NULL);
@@ -4931,6 +4932,55 @@ row_rename_table_for_mysql(
table = dict_table_open_on_name(old_name, dict_locked, FALSE,
DICT_ERR_IGNORE_NONE);
+ /* We look for pattern #P# to see if the table is partitioned
+ MySQL table. */
+#ifdef __WIN__
+ is_part = strstr((char *)old_name, (char *)"#p#");
+#else
+ is_part = strstr((char *)old_name, (char *)"#P#");
+#endif /* __WIN__ */
+
+ /* 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
+ for sub-partition names as well. InnoDB always
+ normalises file names to lower case on Windows, this
+ can potentially cause problems when copying/moving
+ tables between platforms.
+
+ 1) If boot against an installation from Windows
+ platform, then its partition table name could
+ be all be in lower case in system tables. So we
+ will need to check lower case name when load table.
+
+ 2) If we boot an installation from other case
+ sensitive platform in Windows, we might need to
+ check the existence of table name without lowering
+ case them in the system table. */
+ if (!table &&
+ is_part &&
+ innobase_get_lower_case_table_names() == 1) {
+ char par_case_name[MAX_FULL_NAME_LEN + 1];
+#ifndef __WIN__
+ /* Check for the table using lower
+ case name, including the partition
+ separator "P" */
+ memcpy(par_case_name, old_name,
+ strlen(old_name));
+ par_case_name[strlen(old_name)] = 0;
+ innobase_casedn_str(par_case_name);
+#else
+ /* On Windows platfrom, check
+ whether there exists table name in
+ system table whose name is
+ not being normalized to lower case */
+ normalize_table_name_low(
+ par_case_name, old_name, FALSE);
+#endif
+ table = dict_table_open_on_name(par_case_name, dict_locked, FALSE,
+ DICT_ERR_IGNORE_NONE);
+ }
+
if (!table) {
err = DB_TABLE_NOT_FOUND;
ut_print_timestamp(stderr);
diff --git a/storage/xtradb/srv/srv0mon.cc b/storage/xtradb/srv/srv0mon.cc
index 597e7cadc6a..e72868c6450 100644
--- a/storage/xtradb/srv/srv0mon.cc
+++ b/storage/xtradb/srv/srv0mon.cc
@@ -2,7 +2,7 @@
Copyright (c) 2010, 2014, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc.
-Copyright (c) 2013, 2015, MariaDB Corporation.
+Copyright (c) 2013, 2016, MariaDB Corporation.
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
@@ -715,24 +715,6 @@ static monitor_info_t innodb_counter_info[] =
MONITOR_EXISTING | MONITOR_DEFAULT_ON),
MONITOR_DEFAULT_START, MONITOR_OVLD_OS_LOG_PENDING_WRITES},
- {"os_merge_blocks_written", "os",
- "Number of merge blocks written (innodb_os_merge_blocks_written)",
- static_cast<monitor_type_t>(
- MONITOR_EXISTING | MONITOR_DEFAULT_ON),
- MONITOR_DEFAULT_START, MONITOR_MERGE_BLOCKS_WRITTEN},
-
- {"os_merge_blocks_read", "os",
- "Number of merge blocks read (innodb_os_merge_blocks_read)",
- static_cast<monitor_type_t>(
- MONITOR_EXISTING | MONITOR_DEFAULT_ON),
- MONITOR_DEFAULT_START, MONITOR_MERGE_BLOCKS_READ},
-
- {"os_merge_blocks_merged", "os",
- "Number of merge blocks merged (innodb_os_merge_blocks_merged)",
- static_cast<monitor_type_t>(
- MONITOR_EXISTING | MONITOR_DEFAULT_ON),
- MONITOR_DEFAULT_START, MONITOR_MERGE_BLOCKS_MERGED},
-
/* ========== Counters for Transaction Module ========== */
{"module_trx", "transaction", "Transaction Manager",
MONITOR_MODULE,
@@ -1790,21 +1772,6 @@ srv_mon_process_existing_counter(
update_min = TRUE;
break;
- /* innodb_os_merge_blocks_written */
- case MONITOR_MERGE_BLOCKS_WRITTEN:
- value = srv_stats.merge_buffers_written;
- break;
-
- /* innodb_os_merge_blocks_read */
- case MONITOR_MERGE_BLOCKS_READ:
- value = srv_stats.merge_buffers_read;
- break;
-
- /* innodb_os_merge_blocks_merged */
- case MONITOR_MERGE_BLOCKS_MERGED:
- value = srv_stats.merge_buffers_merged;
- break;
-
/* innodb_log_waits */
case MONITOR_OVLD_LOG_WAITS:
value = srv_stats.log_waits;
diff --git a/storage/xtradb/srv/srv0srv.cc b/storage/xtradb/srv/srv0srv.cc
index 2164451225b..794b119a090 100644
--- a/storage/xtradb/srv/srv0srv.cc
+++ b/storage/xtradb/srv/srv0srv.cc
@@ -3,7 +3,7 @@
Copyright (c) 1995, 2015, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, 2009 Google Inc.
Copyright (c) 2009, Percona Inc.
-Copyright (c) 2013, 2015, MariaDB Corporation.
+Copyright (c) 2013, 2014, SkySQL Ab. All Rights Reserved.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -2034,10 +2034,6 @@ srv_export_innodb_status(void)
}
#endif /* UNIV_DEBUG */
- export_vars.innodb_merge_buffers_written = srv_stats.merge_buffers_written;
- export_vars.innodb_merge_buffers_read = srv_stats.merge_buffers_read;
- export_vars.innodb_merge_buffers_merged = srv_stats.merge_buffers_merged;
-
export_vars.innodb_sec_rec_cluster_reads =
srv_stats.n_sec_rec_cluster_reads;
export_vars.innodb_sec_rec_cluster_reads_avoided =
diff --git a/storage/xtradb/srv/srv0start.cc b/storage/xtradb/srv/srv0start.cc
index e0f9bde63fa..17f9e53e76f 100644
--- a/storage/xtradb/srv/srv0start.cc
+++ b/storage/xtradb/srv/srv0start.cc
@@ -188,6 +188,9 @@ static const ulint SRV_UNDO_TABLESPACE_SIZE_IN_PAGES =
#define SRV_N_PENDING_IOS_PER_THREAD OS_AIO_N_PENDING_IOS_PER_THREAD
#define SRV_MAX_N_PENDING_SYNC_IOS 100
+/** The round off to MB is similar as done in srv_parse_megabytes() */
+#define CALC_NUMBER_OF_PAGES(size) ((size) / (1024 * 1024)) * \
+ ((1024 * 1024) / (UNIV_PAGE_SIZE))
#ifdef UNIV_PFS_THREAD
/* Keys to register InnoDB threads with performance schema */
UNIV_INTERN mysql_pfs_key_t io_handler_thread_key;
@@ -1020,10 +1023,16 @@ open_or_create_data_files(
size_check:
size = os_file_get_size(files[i]);
ut_a(size != (os_offset_t) -1);
- /* Round size downward to megabytes */
- rounded_size_pages = (ulint)
- (size >> UNIV_PAGE_SIZE_SHIFT);
+ /* Under some error conditions like disk full
+ narios or file size reaching filesystem
+ limit the data file could contain an incomplete
+ extent at the end. When we extend a data file
+ and if some failure happens, then also the data
+ file could contain an incomplete extent. So we
+ need to round the size downward to a megabyte.*/
+
+ rounded_size_pages = (ulint) CALC_NUMBER_OF_PAGES(size);
if (i == srv_n_data_files - 1
&& srv_auto_extend_last_data_file) {
diff --git a/storage/xtradb/sync/sync0sync.cc b/storage/xtradb/sync/sync0sync.cc
index 3facb99ac0a..702dd240f16 100644
--- a/storage/xtradb/sync/sync0sync.cc
+++ b/storage/xtradb/sync/sync0sync.cc
@@ -1657,34 +1657,49 @@ sync_print_wait_info(
/*=================*/
FILE* file) /*!< in: file where to print */
{
+ // Sum counter values once
+ ib_int64_t mutex_spin_wait_count_val
+ = static_cast<ib_int64_t>(mutex_spin_wait_count);
+ ib_int64_t mutex_spin_round_count_val
+ = static_cast<ib_int64_t>(mutex_spin_round_count);
+ ib_int64_t mutex_os_wait_count_val
+ = static_cast<ib_int64_t>(mutex_os_wait_count);
+ ib_int64_t rw_s_spin_wait_count_val
+ = static_cast<ib_int64_t>(rw_lock_stats.rw_s_spin_wait_count);
+ ib_int64_t rw_s_spin_round_count_val
+ = static_cast<ib_int64_t>(rw_lock_stats.rw_s_spin_round_count);
+ ib_int64_t rw_s_os_wait_count_val
+ = static_cast<ib_int64_t>(rw_lock_stats.rw_s_os_wait_count);
+ ib_int64_t rw_x_spin_wait_count_val
+ = static_cast<ib_int64_t>(rw_lock_stats.rw_x_spin_wait_count);
+ ib_int64_t rw_x_spin_round_count_val
+ = static_cast<ib_int64_t>(rw_lock_stats.rw_x_spin_round_count);
+ ib_int64_t rw_x_os_wait_count_val
+ = static_cast<ib_int64_t>(rw_lock_stats.rw_x_os_wait_count);
+
fprintf(file,
- "Mutex spin waits " UINT64PF ", rounds " UINT64PF ", "
- "OS waits " UINT64PF "\n"
- "RW-shared spins " UINT64PF ", rounds " UINT64PF ", "
- "OS waits " UINT64PF "\n"
- "RW-excl spins " UINT64PF ", rounds " UINT64PF ", "
- "OS waits " UINT64PF "\n",
- (ib_uint64_t) mutex_spin_wait_count,
- (ib_uint64_t) mutex_spin_round_count,
- (ib_uint64_t) mutex_os_wait_count,
- (ib_uint64_t) rw_lock_stats.rw_s_spin_wait_count,
- (ib_uint64_t) rw_lock_stats.rw_s_spin_round_count,
- (ib_uint64_t) rw_lock_stats.rw_s_os_wait_count,
- (ib_uint64_t) rw_lock_stats.rw_x_spin_wait_count,
- (ib_uint64_t) rw_lock_stats.rw_x_spin_round_count,
- (ib_uint64_t) rw_lock_stats.rw_x_os_wait_count);
+ "Mutex spin waits " INT64PF ", rounds " INT64PF ", "
+ "OS waits " INT64PF "\n"
+ "RW-shared spins " INT64PF ", rounds " INT64PF ", "
+ "OS waits " INT64PF "\n"
+ "RW-excl spins " INT64PF ", rounds " INT64PF ", "
+ "OS waits " INT64PF "\n",
+ mutex_spin_wait_count_val, mutex_spin_round_count_val,
+ mutex_os_wait_count_val,
+ rw_s_spin_wait_count_val, rw_s_spin_round_count_val,
+ rw_s_os_wait_count_val,
+ rw_x_spin_wait_count_val, rw_x_spin_round_count_val,
+ rw_x_os_wait_count_val);
fprintf(file,
"Spin rounds per wait: %.2f mutex, %.2f RW-shared, "
"%.2f RW-excl\n",
- (double) mutex_spin_round_count /
- (mutex_spin_wait_count ? mutex_spin_wait_count : 1),
- (double) rw_lock_stats.rw_s_spin_round_count /
- (rw_lock_stats.rw_s_spin_wait_count
- ? rw_lock_stats.rw_s_spin_wait_count : 1),
- (double) rw_lock_stats.rw_x_spin_round_count /
- (rw_lock_stats.rw_x_spin_wait_count
- ? rw_lock_stats.rw_x_spin_wait_count : 1));
+ (double) mutex_spin_round_count_val /
+ (mutex_spin_wait_count_val ? mutex_spin_wait_count_val : 1LL),
+ (double) rw_s_spin_round_count_val /
+ (rw_s_spin_wait_count_val ? rw_s_spin_wait_count_val : 1LL),
+ (double) rw_x_spin_round_count_val /
+ (rw_x_spin_wait_count_val ? rw_x_spin_wait_count_val : 1LL));
}
/*******************************************************************//**