mirror of
https://github.com/MariaDB/server.git
synced 2025-01-30 10:31:54 +01:00
5.6.28-76.1
This commit is contained in:
parent
1e270d504d
commit
d76eba6a6b
16 changed files with 447 additions and 119 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
|
||||
|
@ -2143,7 +2143,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(
|
||||
|
@ -2204,6 +2204,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);
|
||||
|
@ -2980,7 +2985,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(
|
||||
|
@ -3094,9 +3099,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,
|
||||
|
|
|
@ -1733,6 +1733,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)) {
|
||||
|
|
|
@ -2209,9 +2209,10 @@ Clears up tail of the LRU lists:
|
|||
* Put replaceable pages at the tail of LRU to the free list
|
||||
* 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. */
|
||||
config parameter innodb_LRU_scan_depth.
|
||||
@return number of pages flushed */
|
||||
UNIV_INTERN
|
||||
void
|
||||
ulint
|
||||
buf_flush_LRU_tail(void)
|
||||
/*====================*/
|
||||
{
|
||||
|
@ -2313,6 +2314,7 @@ buf_flush_LRU_tail(void)
|
|||
MONITOR_LRU_BATCH_PAGES,
|
||||
total_flushed);
|
||||
}
|
||||
return(total_flushed);
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
|
@ -2608,19 +2610,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;
|
||||
|
@ -2826,6 +2833,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);
|
||||
|
@ -2852,11 +2860,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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -3022,6 +3022,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.
|
||||
|
@ -6630,31 +6672,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 (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);
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
|
|
|
@ -958,10 +958,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;
|
||||
|
@ -970,6 +980,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(
|
||||
|
@ -986,7 +1004,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
|
||||
|
|
|
@ -16273,7 +16273,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 actual_priority
|
||||
|
|
|
@ -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;
|
||||
|
@ -5035,6 +5038,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.
|
||||
|
@ -5170,6 +5228,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)
|
||||
|
@ -5370,6 +5442,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);
|
||||
|
@ -5451,7 +5524,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) {
|
||||
|
@ -5586,14 +5659,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,
|
||||
/* 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++);
|
||||
}
|
||||
|
@ -5606,10 +5685,13 @@ 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);
|
||||
|
||||
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
|
||||
|
@ -5617,7 +5699,11 @@ ha_innobase::commit_inplace_alter_table(
|
|||
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
|
||||
|
@ -5639,7 +5725,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++) {
|
||||
|
|
|
@ -202,9 +202,10 @@ Clears up tail of the LRU lists:
|
|||
* Put replaceable pages at the tail of LRU to the free list
|
||||
* 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. */
|
||||
config parameter innodb_LRU_scan_depth.
|
||||
@return number of pages flushed */
|
||||
UNIV_INTERN
|
||||
void
|
||||
ulint
|
||||
buf_flush_LRU_tail(void);
|
||||
/*====================*/
|
||||
/*********************************************************************//**
|
||||
|
|
|
@ -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.
|
||||
|
@ -990,21 +1005,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));
|
||||
|
||||
/*******************************************************************//**
|
||||
|
|
|
@ -47,7 +47,7 @@ Created 1/20/1994 Heikki Tuuri
|
|||
#define INNODB_VERSION_BUGFIX MYSQL_VERSION_PATCH
|
||||
|
||||
#ifndef PERCONA_INNODB_VERSION
|
||||
#define PERCONA_INNODB_VERSION 76.0
|
||||
#define PERCONA_INNODB_VERSION 76.1
|
||||
#endif
|
||||
|
||||
/* Enable UNIV_LOG_ARCHIVE in XtraDB */
|
||||
|
|
|
@ -828,6 +828,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);
|
||||
}
|
||||
|
||||
|
|
|
@ -159,6 +159,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;
|
||||
|
@ -988,10 +991,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) {
|
||||
|
|
|
@ -1690,34 +1690,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));
|
||||
}
|
||||
|
||||
/*******************************************************************//**
|
||||
|
|
Loading…
Add table
Reference in a new issue