Skip to content

Commit

Permalink
5.6.28
Browse files Browse the repository at this point in the history
  • Loading branch information
vuvova committed Dec 13, 2015
1 parent 86ff4da commit e9eaaa4
Show file tree
Hide file tree
Showing 11 changed files with 388 additions and 83 deletions.
20 changes: 17 additions & 3 deletions storage/innobase/btr/btr0btr.cc
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -3052,9 +3057,18 @@ btr_page_split_and_insert(
}
}

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,
Expand Down
4 changes: 4 additions & 0 deletions storage/innobase/btr/btr0cur.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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)) {
Expand Down
42 changes: 25 additions & 17 deletions storage/innobase/dict/dict0dict.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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)));

Expand Down Expand Up @@ -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);
Expand All @@ -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)) {
Expand All @@ -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"
Expand All @@ -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);
}

Expand Down
159 changes: 140 additions & 19 deletions storage/innobase/fil/fil0fil.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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 (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);
}
26 changes: 22 additions & 4 deletions storage/innobase/fsp/fsp0fsp.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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(
Expand All @@ -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
Expand Down
Loading

0 comments on commit e9eaaa4

Please sign in to comment.