mirror of
https://github.com/MariaDB/server.git
synced 2026-05-15 19:37:16 +02:00
5.6.28
This commit is contained in:
parent
86ff4da14d
commit
e9eaaa4b4a
11 changed files with 388 additions and 83 deletions
|
|
@ -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
|
||||
|
|
@ -2101,7 +2101,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(
|
||||
|
|
@ -2162,6 +2162,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);
|
||||
|
|
@ -2938,7 +2943,7 @@ function must always succeed, we cannot reverse it: therefore enough
|
|||
free disk space (2 pages) 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_page_split_and_insert(
|
||||
|
|
@ -3052,9 +3057,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,
|
||||
|
|
|
|||
|
|
@ -1604,6 +1604,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)) {
|
||||
|
|
|
|||
|
|
@ -1590,10 +1590,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)));
|
||||
|
||||
|
|
@ -1631,8 +1634,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);
|
||||
|
|
@ -1651,7 +1652,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)) {
|
||||
|
|
@ -1663,8 +1664,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"
|
||||
|
|
@ -1678,34 +1677,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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2990,6 +2990,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.
|
||||
|
|
@ -6520,29 +6562,108 @@ 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 (new_space_id != TRX_SYS_SPACE) {
|
||||
fil_op_write_log(MLOG_FILE_RENAME, new_space_id,
|
||||
0, 0, new_name, old_name, mtr);
|
||||
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_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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -952,10 +952,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;
|
||||
|
|
@ -964,6 +974,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(
|
||||
|
|
@ -980,7 +998,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
|
||||
|
|
|
|||
|
|
@ -156,10 +156,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;
|
||||
|
|
@ -5026,6 +5029,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.
|
||||
|
|
@ -5161,6 +5219,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)
|
||||
|
|
@ -5361,6 +5433,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);
|
||||
|
|
@ -5442,7 +5515,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) {
|
||||
|
|
@ -5577,14 +5650,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++);
|
||||
}
|
||||
|
|
@ -5597,18 +5676,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
|
||||
|
|
@ -5630,7 +5716,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++) {
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||
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
|
||||
|
|
@ -490,6 +490,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.
|
||||
|
|
@ -986,21 +1001,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));
|
||||
|
||||
/*******************************************************************//**
|
||||
|
|
|
|||
|
|
@ -827,6 +827,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"
|
||||
|
|
|
|||
|
|
@ -2068,8 +2068,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
|
||||
|
|
|
|||
|
|
@ -1454,6 +1454,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);
|
||||
|
|
@ -1489,6 +1490,8 @@ row_log_table_apply_insert_low(
|
|||
}
|
||||
|
||||
do {
|
||||
n_index++;
|
||||
|
||||
if (!(index = dict_table_get_next_index(index))) {
|
||||
break;
|
||||
}
|
||||
|
|
@ -1501,6 +1504,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);
|
||||
|
|
@ -1808,6 +1817,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));
|
||||
|
|
@ -2083,6 +2093,8 @@ func_exit_committed:
|
|||
break;
|
||||
}
|
||||
|
||||
n_index++;
|
||||
|
||||
if (index->type & DICT_FTS) {
|
||||
continue;
|
||||
}
|
||||
|
|
@ -2126,6 +2138,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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -147,6 +147,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;
|
||||
|
|
@ -958,10 +961,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) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue