summaryrefslogtreecommitdiff
path: root/storage/innobase/row/row0trunc.cc
diff options
context:
space:
mode:
Diffstat (limited to 'storage/innobase/row/row0trunc.cc')
-rw-r--r--storage/innobase/row/row0trunc.cc263
1 files changed, 101 insertions, 162 deletions
diff --git a/storage/innobase/row/row0trunc.cc b/storage/innobase/row/row0trunc.cc
index fce512afa81..b3a996d990a 100644
--- a/storage/innobase/row/row0trunc.cc
+++ b/storage/innobase/row/row0trunc.cc
@@ -295,14 +295,12 @@ public:
snprintf(m_log_file_name + log_file_name_len,
log_file_name_buf_sz - log_file_name_len,
- "%s%lu_%lu_%s",
+ "%s" ULINTPF "_" IB_ID_FMT "_%s",
TruncateLogger::s_log_prefix,
- (ulong) m_table->space,
- (ulong) m_table->id,
+ m_table->space_id, m_table->id,
TruncateLogger::s_log_ext);
return(DB_SUCCESS);
-
}
/**
@@ -375,7 +373,7 @@ public:
which is currently 0. */
err = m_truncate.write(
log_buf + 4, log_buf + sz - 4,
- m_table->space, m_table->name.m_name,
+ m_table->space_id, m_table->name.m_name,
m_flags, m_table->flags, lsn);
DBUG_EXECUTE_IF("ib_err_trunc_oom_logging",
@@ -438,7 +436,7 @@ public:
- If checkpoint happens post truncate and crash happens post
this point then neither MLOG_TRUNCATE nor REDO record
from action before truncate are accessible. */
- if (!is_system_tablespace(m_table->space)) {
+ if (!is_system_tablespace(m_table->space_id)) {
mtr_t mtr;
byte* log_ptr;
@@ -446,7 +444,7 @@ public:
log_ptr = mlog_open(&mtr, 11 + 8);
log_ptr = mlog_write_initial_log_record_low(
- MLOG_TRUNCATE, m_table->space, 0,
+ MLOG_TRUNCATE, m_table->space_id, 0,
log_ptr, &mtr);
mach_write_to_8(log_ptr, lsn);
@@ -983,8 +981,7 @@ DropIndex::operator()(mtr_t* mtr, btr_pcur_t* pcur) const
}
#endif /* UNIV_DEBUG */
- DBUG_EXECUTE_IF("ib_err_trunc_drop_index",
- freed = false;);
+ DBUG_EXECUTE_IF("ib_err_trunc_drop_index", return DB_ERROR;);
if (freed) {
@@ -1001,16 +998,8 @@ DropIndex::operator()(mtr_t* mtr, btr_pcur_t* pcur) const
btr_pcur_restore_position(BTR_MODIFY_LEAF, pcur, mtr);
} else {
- /* Check if the .ibd file is missing. */
- bool found;
-
- fil_space_get_page_size(m_table->space, &found);
-
- DBUG_EXECUTE_IF("ib_err_trunc_drop_index",
- found = false;);
-
- if (!found) {
- return(DB_ERROR);
+ if (!m_table->space) {
+ return DB_ERROR;
}
}
@@ -1069,8 +1058,7 @@ CreateIndex::operator()(mtr_t* mtr, btr_pcur_t* pcur) const
}
#endif /* UNIV_DEBUG */
- DBUG_EXECUTE_IF("ib_err_trunc_create_index",
- root_page_no = FIL_NULL;);
+ DBUG_EXECUTE_IF("ib_err_trunc_create_index", return DB_ERROR;);
if (root_page_no != FIL_NULL) {
@@ -1092,13 +1080,7 @@ CreateIndex::operator()(mtr_t* mtr, btr_pcur_t* pcur) const
btr_pcur_restore_position(BTR_MODIFY_LEAF, pcur, mtr);
} else {
- bool found;
- fil_space_get_page_size(m_table->space, &found);
-
- DBUG_EXECUTE_IF("ib_err_trunc_create_index",
- found = false;);
-
- if (!found) {
+ if (!m_table->space) {
return(DB_ERROR);
}
}
@@ -1144,6 +1126,7 @@ row_truncate_rollback(
bool corrupted,
bool unlock_index)
{
+ ut_ad(!table->is_temporary());
if (unlock_index) {
dict_table_x_unlock_indexes(table);
}
@@ -1154,7 +1137,7 @@ row_truncate_rollback(
trx->error_state = DB_SUCCESS;
- if (corrupted && !dict_table_is_temporary(table)) {
+ if (corrupted) {
/* Cleanup action to ensure we don't left over stale entries
if we are marking table as corrupted. This will ensure
@@ -1190,21 +1173,6 @@ row_truncate_rollback(
trx_commit_for_mysql(trx);
}
-
- } else if (corrupted && dict_table_is_temporary(table)) {
-
- dict_table_x_lock_indexes(table);
-
- for (dict_index_t* index = UT_LIST_GET_FIRST(table->indexes);
- index != NULL;
- index = UT_LIST_GET_NEXT(indexes, index)) {
-
- dict_drop_index_tree_in_mem(index, index->page);
-
- index->page = FIL_NULL;
- }
-
- dict_table_x_unlock_indexes(table);
}
table->corrupted = corrupted;
@@ -1262,7 +1230,7 @@ row_truncate_complete(
/* This function will reset back the stop_new_ops
and is_being_truncated so that fil-ops can re-start. */
dberr_t err2 = truncate_t::truncate(
- table->space,
+ table->space_id,
table->data_dir_path,
table->name.m_name, fsp_flags, false);
@@ -1569,37 +1537,6 @@ row_truncate_update_system_tables(
}
/**
-Prepare for the truncate process. On success all of the table's indexes will
-be locked in X mode.
-@param table table to truncate
-@param flags tablespace flags
-@return error code or DB_SUCCESS */
-static MY_ATTRIBUTE((warn_unused_result))
-dberr_t
-row_truncate_prepare(dict_table_t* table, ulint* flags)
-{
- ut_ad(!dict_table_is_temporary(table));
- ut_ad(dict_table_is_file_per_table(table));
-
- *flags = fil_space_get_flags(table->space);
-
- ut_ad(!dict_table_is_temporary(table));
-
- dict_get_and_save_data_dir_path(table, true);
-
- if (*flags != ULINT_UNDEFINED) {
-
- dberr_t err = fil_prepare_for_truncate(table->space);
-
- if (err != DB_SUCCESS) {
- return(err);
- }
- }
-
- return(DB_SUCCESS);
-}
-
-/**
Do foreign key checks before starting TRUNCATE.
@param table table being truncated
@param trx transaction covering the truncate
@@ -1666,7 +1603,7 @@ row_truncate_sanity_checks(
return(DB_TABLESPACE_DELETED);
} else if (!table->is_readable()) {
- if (fil_space_get(table->space) == NULL) {
+ if (!table->space) {
return(DB_TABLESPACE_NOT_FOUND);
} else {
@@ -1691,9 +1628,9 @@ fil_reinit_space_header_for_table(
ulint size,
trx_t* trx)
{
- ulint id = table->space;
-
- ut_a(!is_system_tablespace(id));
+ fil_space_t* space = table->space;
+ ut_a(!is_system_tablespace(space->id));
+ ut_ad(space->id == table->space_id);
/* Invalidate in the buffer pool all pages belonging
to the tablespace. The buffer pool scan may take long
@@ -1710,7 +1647,7 @@ fil_reinit_space_header_for_table(
from disabling AHI during the scan */
btr_search_s_lock_all();
DEBUG_SYNC_C("buffer_pool_scan");
- buf_LRU_flush_or_remove_pages(id, NULL);
+ buf_LRU_flush_or_remove_pages(space->id, NULL);
btr_search_s_unlock_all();
row_mysql_lock_data_dictionary(trx);
@@ -1718,15 +1655,7 @@ fil_reinit_space_header_for_table(
dict_table_x_lock_indexes(table);
/* Remove all insert buffer entries for the tablespace */
- ibuf_delete_for_discarded_space(id);
-
- mutex_enter(&fil_system.mutex);
- fil_space_t* space = fil_space_get_by_id(id);
- /* TRUNCATE TABLE is protected by an exclusive table lock.
- The table cannot be dropped or the tablespace discarded
- while we are holding the transactional table lock. Thus,
- there is no need to invoke fil_space_acquire(). */
- mutex_exit(&fil_system.mutex);
+ ibuf_delete_for_discarded_space(space->id);
mtr_t mtr;
@@ -1753,10 +1682,8 @@ row_truncate_table_for_mysql(
{
bool is_file_per_table = dict_table_is_file_per_table(table);
dberr_t err;
-#ifdef UNIV_DEBUG
- ulint old_space = table->space;
-#endif /* UNIV_DEBUG */
TruncateLogger* logger = NULL;
+ ut_d(const fil_space_t* old_space = table->space);
/* Understanding the truncate flow.
@@ -1922,10 +1849,18 @@ row_truncate_table_for_mysql(
dict_table_x_lock_indexes(table);
if (!dict_table_is_temporary(table)) {
+ fsp_flags = table->space
+ ? table->space->flags
+ : ULINT_UNDEFINED;
if (is_file_per_table) {
+ ut_ad(!table->is_temporary());
+ ut_ad(dict_table_is_file_per_table(table));
- err = row_truncate_prepare(table, &fsp_flags);
+ dict_get_and_save_data_dir_path(table, true);
+ err = table->space
+ ? fil_prepare_for_truncate(table->space_id)
+ : DB_TABLESPACE_NOT_FOUND;
DBUG_EXECUTE_IF("ib_err_trunc_preparing_for_truncate",
err = DB_ERROR;);
@@ -1939,8 +1874,6 @@ row_truncate_table_for_mysql(
table, trx, fsp_flags, logger, err));
}
} else {
- fsp_flags = fil_space_get_flags(table->space);
-
DBUG_EXECUTE_IF("ib_err_trunc_preparing_for_truncate",
fsp_flags = ULINT_UNDEFINED;);
@@ -2012,28 +1945,55 @@ row_truncate_table_for_mysql(
dict_table_get_first_index(table)->remove_instant();
} else {
ut_ad(!table->is_instant());
- /* For temporary tables we don't have entries in SYSTEM TABLES*/
- ut_ad(fsp_is_system_temporary(table->space));
+ ut_ad(table->space == fil_system.temp_space);
+ bool fail = false;
for (dict_index_t* index = UT_LIST_GET_FIRST(table->indexes);
index != NULL;
index = UT_LIST_GET_NEXT(indexes, index)) {
+ if (index->page != FIL_NULL) {
+ btr_free(page_id_t(SRV_TMP_SPACE_ID,
+ index->page),
+ univ_page_size);
+ }
- err = dict_truncate_index_tree_in_mem(index);
-
- if (err != DB_SUCCESS) {
- row_truncate_rollback(
- table, trx, new_id, has_internal_doc_id,
- no_redo, true, true);
- return(row_truncate_complete(
- table, trx, fsp_flags, logger, err));
+ mtr_t mtr;
+ mtr.start();
+ mtr.set_log_mode(MTR_LOG_NO_REDO);
+ index->page = btr_create(
+ index->type, table->space, index->id, index,
+ NULL, &mtr);
+ DBUG_EXECUTE_IF("ib_err_trunc_temp_recreate_index",
+ index->page = FIL_NULL;);
+ mtr.commit();
+ if (index->page == FIL_NULL) {
+ fail = true;
+ break;
}
+ }
+ if (fail) {
+ for (dict_index_t* index = UT_LIST_GET_FIRST(
+ table->indexes);
+ index != NULL;
+ index = UT_LIST_GET_NEXT(indexes, index)) {
+ if (index->page != FIL_NULL) {
+ btr_free(page_id_t(SRV_TMP_SPACE_ID,
+ index->page),
+ univ_page_size);
+ index->page = FIL_NULL;
+ }
+ }
+ }
- DBUG_EXECUTE_IF(
- "ib_trunc_crash_during_drop_index_temp_table",
- log_buffer_flush_to_disk();
- os_thread_sleep(2000000);
- DBUG_SUICIDE(););
+ table->corrupted = fail;
+ if (fail) {
+ return row_truncate_complete(
+ table, trx, fsp_flags, logger, DB_ERROR);
}
+
+ DBUG_EXECUTE_IF(
+ "ib_trunc_crash_during_drop_index_temp_table",
+ log_buffer_flush_to_disk();
+ DBUG_SUICIDE(););
}
if (is_file_per_table && fsp_flags != ULINT_UNDEFINED) {
@@ -2169,12 +2129,11 @@ fil_recreate_table(
/* Step-1: Scan for active indexes from REDO logs and drop
all the indexes using low level function that take root_page_no
and space-id. */
- truncate.drop_indexes(TRX_SYS_SPACE);
+ truncate.drop_indexes(fil_system.sys_space);
/* Step-2: Scan for active indexes and re-create them. */
dberr_t err = truncate.create_indexes(
- name, TRX_SYS_SPACE, univ_page_size,
- fil_system.sys_space->flags, format_flags);
+ name, fil_system.sys_space, format_flags);
if (err != DB_SUCCESS) {
ib::info() << "Recovery failed for TRUNCATE TABLE '"
<< name << "' within the system tablespace";
@@ -2292,8 +2251,7 @@ fil_recreate_tablespace(
/* Step-4: Re-Create Indexes to newly re-created tablespace.
This operation will restore tablespace back to what it was
when it was created during CREATE TABLE. */
- err = truncate.create_indexes(
- name, space_id, page_size, flags, format_flags);
+ err = truncate.create_indexes(name, space, format_flags);
if (err != DB_SUCCESS) {
goto func_exit;
}
@@ -2955,8 +2913,7 @@ truncate_t::index_t::set(
/** Create an index for a table.
@param[in] table_name table name, for which to create
the index
-@param[in] space_id space id where we have to
-create the index
+@param[in] space tablespace
@param[in] page_size page size of the .ibd file
@param[in] index_type type of index to truncate
@param[in] index_id id of index to truncate
@@ -2967,15 +2924,14 @@ create index
inline ulint
truncate_t::create_index(
const char* table_name,
- ulint space_id,
- const page_size_t& page_size,
+ fil_space_t* space,
ulint index_type,
index_id_t index_id,
const btr_create_t& btr_redo_create_info,
mtr_t* mtr) const
{
ulint root_page_no = btr_create(
- index_type, space_id, page_size, index_id,
+ index_type, space, index_id,
NULL, &btr_redo_create_info, mtr);
if (root_page_no == FIL_NULL) {
@@ -2984,7 +2940,7 @@ truncate_t::create_index(
<< srv_force_recovery << ". Continuing crash recovery"
" even though we failed to create index " << index_id
<< " for compressed table '" << table_name << "' with"
- " tablespace " << space_id << " during recovery";
+ " file " << space->chain.start->name;
}
return(root_page_no);
@@ -2992,30 +2948,27 @@ truncate_t::create_index(
/** Check if index has been modified since TRUNCATE log snapshot
was recorded.
-@param space_id space_id where table/indexes resides.
-@param root_page_no root page of index that needs to be verified.
+@param[in] space tablespace
+@param[in] root_page_no index root page number
@return true if modified else false */
-
+inline
bool
truncate_t::is_index_modified_since_logged(
- ulint space_id,
- ulint root_page_no) const
+ const fil_space_t* space,
+ ulint root_page_no) const
{
- mtr_t mtr;
- bool found;
- const page_size_t& page_size = fil_space_get_page_size(space_id,
- &found);
- dberr_t err = DB_SUCCESS;
-
- ut_ad(found);
+ dberr_t err;
+ mtr_t mtr;
mtr_start(&mtr);
/* Root page could be in free state if truncate crashed after drop_index
and page was not allocated for any other object. */
buf_block_t* block= buf_page_get_gen(
- page_id_t(space_id, root_page_no), page_size, RW_X_LATCH, NULL,
+ page_id_t(space->id, root_page_no), page_size_t(space->flags),
+ RW_X_LATCH, NULL,
BUF_GET_POSSIBLY_FREED, __FILE__, __LINE__, &mtr, &err);
+ if (!block) return true;
page_t* root = buf_block_get_frame(block);
@@ -3039,31 +2992,21 @@ truncate_t::is_index_modified_since_logged(
}
/** Drop indexes for a table.
-@param space_id space_id where table/indexes resides. */
-
-void
-truncate_t::drop_indexes(
- ulint space_id) const
+@param[in,out] space tablespace */
+void truncate_t::drop_indexes(fil_space_t* space) const
{
mtr_t mtr;
- ulint root_page_no = FIL_NULL;
indexes_t::const_iterator end = m_indexes.end();
+ const page_size_t page_size(space->flags);
for (indexes_t::const_iterator it = m_indexes.begin();
it != end;
++it) {
- root_page_no = it->m_root_page_no;
-
- bool found;
- const page_size_t& page_size
- = fil_space_get_page_size(space_id, &found);
-
- ut_ad(found);
+ ulint root_page_no = it->m_root_page_no;
- if (is_index_modified_since_logged(
- space_id, root_page_no)) {
+ if (is_index_modified_since_logged(space, root_page_no)) {
/* Page has been modified since TRUNCATE log snapshot
was recorded so not safe to drop the index. */
continue;
@@ -3071,14 +3014,14 @@ truncate_t::drop_indexes(
mtr_start(&mtr);
- if (space_id != TRX_SYS_SPACE) {
+ if (space->id != TRX_SYS_SPACE) {
/* Do not log changes for single-table
tablespaces, we are in recovery mode. */
mtr_set_log_mode(&mtr, MTR_LOG_NO_REDO);
}
if (root_page_no != FIL_NULL) {
- const page_id_t root_page_id(space_id, root_page_no);
+ const page_id_t root_page_id(space->id, root_page_no);
btr_free_if_exists(
root_page_id, page_size, it->m_id, &mtr);
@@ -3094,24 +3037,20 @@ truncate_t::drop_indexes(
/** Create the indexes for a table
@param[in] table_name table name, for which to create the indexes
-@param[in] space_id space id where we have to create the indexes
-@param[in] page_size page size of the .ibd file
-@param[in] flags tablespace flags
+@param[in,out] space tablespace
@param[in] format_flags page format flags
@return DB_SUCCESS or error code. */
inline dberr_t
truncate_t::create_indexes(
const char* table_name,
- ulint space_id,
- const page_size_t& page_size,
- ulint flags,
+ fil_space_t* space,
ulint format_flags)
{
mtr_t mtr;
mtr_start(&mtr);
- if (space_id != TRX_SYS_SPACE) {
+ if (space->id != TRX_SYS_SPACE) {
/* Do not log changes for single-table tablespaces, we
are in recovery mode. */
mtr_set_log_mode(&mtr, MTR_LOG_NO_REDO);
@@ -3128,12 +3067,12 @@ truncate_t::create_indexes(
++it) {
btr_create_t btr_redo_create_info(
- FSP_FLAGS_GET_ZIP_SSIZE(flags)
+ FSP_FLAGS_GET_ZIP_SSIZE(space->flags)
? &it->m_fields[0] : NULL);
btr_redo_create_info.format_flags = format_flags;
- if (FSP_FLAGS_GET_ZIP_SSIZE(flags)) {
+ if (FSP_FLAGS_GET_ZIP_SSIZE(space->flags)) {
btr_redo_create_info.n_fields = it->m_n_fields;
/* Skip the NUL appended field */
@@ -3143,7 +3082,7 @@ truncate_t::create_indexes(
}
root_page_no = create_index(
- table_name, space_id, page_size, it->m_type, it->m_id,
+ table_name, space, it->m_type, it->m_id,
btr_redo_create_info, &mtr);
if (root_page_no == FIL_NULL) {