summaryrefslogtreecommitdiff
path: root/storage/xtradb/row
diff options
context:
space:
mode:
Diffstat (limited to 'storage/xtradb/row')
-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
4 files changed, 162 insertions, 78 deletions
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);