summaryrefslogtreecommitdiff
path: root/storage/innobase
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2018-03-27 16:31:10 +0300
committerMarko Mäkelä <marko.makela@mariadb.com>2018-03-29 22:02:05 +0300
commit4cad42392a2c498a2be92a77b21b1ec4027c9ea9 (patch)
treeb1f652d9f6488acb87d5cb206a2867f84124ee4c /storage/innobase
parentc02c329a8e9e024c1dc2399284b29a13d8d85783 (diff)
downloadmariadb-git-4cad42392a2c498a2be92a77b21b1ec4027c9ea9.tar.gz
MDEV-12266: Change dict_table_t::space to fil_space_t*
InnoDB always keeps all tablespaces in the fil_system cache. The fil_system.LRU is only for closing file handles; the fil_space_t and fil_node_t for all data files will remain in main memory. Between startup to shutdown, they can only be created and removed by DDL statements. Therefore, we can let dict_table_t::space point directly to the fil_space_t. dict_table_t::space_id: A numeric tablespace ID for the corner cases where we do not have a tablespace. The most prominent examples are ALTER TABLE...DISCARD TABLESPACE or a missing or corrupted file. There are a few functional differences; most notably: (1) DROP TABLE will delete matching .ibd and .cfg files, even if they were not attached to the data dictionary. (2) Some error messages will report file names instead of numeric IDs. There still are many functions that use numeric tablespace IDs instead of fil_space_t*, and many functions could be converted to fil_space_t member functions. Also, Tablespace and Datafile should be merged with fil_space_t and fil_node_t. page_id_t and buf_page_get_gen() could use fil_space_t& instead of a numeric ID, and after moving to a single buffer pool (MDEV-15058), buf_pool_t::page_hash could be moved to fil_space_t::page_hash. FilSpace: Remove. Only few calls to fil_space_acquire() will remain, and gradually they should be removed. mtr_t::set_named_space_id(ulint): Renamed from set_named_space(), to prevent accidental calls to this slower function. Very few callers remain. fseg_create(), fsp_reserve_free_extents(): Take fil_space_t* as a parameter instead of a space_id. fil_space_t::rename(): Wrapper for fil_rename_tablespace_check(), fil_name_write_rename(), fil_rename_tablespace(). Mariabackup passes the parameter log=false; InnoDB passes log=true. dict_mem_table_create(): Take fil_space_t* instead of space_id as parameter. dict_process_sys_tables_rec_and_mtr_commit(): Replace the parameter 'status' with 'bool cached'. dict_get_and_save_data_dir_path(): Avoid copying the fil_node_t::name. fil_ibd_open(): Return the tablespace. fil_space_t::set_imported(): Replaces fil_space_set_imported(). truncate_t: Change many member function parameters to fil_space_t*, and remove page_size parameters. row_truncate_prepare(): Merge to its only caller. row_drop_table_from_cache(): Assert that the table is persistent. dict_create_sys_indexes_tuple(): Write SYS_INDEXES.SPACE=FIL_NULL if the tablespace has been discarded. row_import_update_discarded_flag(): Remove a constant parameter.
Diffstat (limited to 'storage/innobase')
-rw-r--r--storage/innobase/btr/btr0btr.cc248
-rw-r--r--storage/innobase/btr/btr0bulk.cc42
-rw-r--r--storage/innobase/btr/btr0cur.cc93
-rw-r--r--storage/innobase/btr/btr0defragment.cc36
-rw-r--r--storage/innobase/btr/btr0scrub.cc32
-rw-r--r--storage/innobase/btr/btr0sea.cc14
-rw-r--r--storage/innobase/buf/buf0buf.cc54
-rw-r--r--storage/innobase/buf/buf0dblwr.cc10
-rw-r--r--storage/innobase/buf/buf0flu.cc14
-rw-r--r--storage/innobase/buf/buf0lru.cc2
-rw-r--r--storage/innobase/dict/dict0boot.cc33
-rw-r--r--storage/innobase/dict/dict0crea.cc157
-rw-r--r--storage/innobase/dict/dict0dict.cc74
-rw-r--r--storage/innobase/dict/dict0load.cc121
-rw-r--r--storage/innobase/dict/dict0mem.cc10
-rw-r--r--storage/innobase/dict/dict0stats.cc10
-rw-r--r--storage/innobase/fil/fil0fil.cc498
-rw-r--r--storage/innobase/fsp/fsp0fsp.cc75
-rw-r--r--storage/innobase/fsp/fsp0sysspace.cc8
-rw-r--r--storage/innobase/fts/fts0fts.cc6
-rw-r--r--storage/innobase/gis/gis0rtree.cc12
-rw-r--r--storage/innobase/gis/gis0sea.cc23
-rw-r--r--storage/innobase/handler/ha_innodb.cc105
-rw-r--r--storage/innobase/handler/handler0alter.cc23
-rw-r--r--storage/innobase/handler/i_s.cc25
-rw-r--r--storage/innobase/ibuf/ibuf0ibuf.cc67
-rw-r--r--storage/innobase/include/btr0btr.h6
-rw-r--r--storage/innobase/include/btr0bulk.h11
-rw-r--r--storage/innobase/include/btr0sea.ic6
-rw-r--r--storage/innobase/include/buf0buf.h14
-rw-r--r--storage/innobase/include/buf0flu.h8
-rw-r--r--storage/innobase/include/buf0lru.h1
-rw-r--r--storage/innobase/include/dict0crea.h16
-rw-r--r--storage/innobase/include/dict0dict.h33
-rw-r--r--storage/innobase/include/dict0dict.ic33
-rw-r--r--storage/innobase/include/dict0load.h16
-rw-r--r--storage/innobase/include/dict0mem.h40
-rw-r--r--storage/innobase/include/dict0types.h30
-rw-r--r--storage/innobase/include/fil0fil.h233
-rw-r--r--storage/innobase/include/fsp0fsp.h31
-rw-r--r--storage/innobase/include/fsp0sysspace.h8
-rw-r--r--storage/innobase/include/fsp0types.h11
-rw-r--r--storage/innobase/include/ibuf0ibuf.h13
-rw-r--r--storage/innobase/include/mtr0mtr.h14
-rw-r--r--storage/innobase/include/row0import.h24
-rw-r--r--storage/innobase/include/row0row.h2
-rw-r--r--storage/innobase/include/row0trunc.h30
-rw-r--r--storage/innobase/include/trx0rseg.h10
-rw-r--r--storage/innobase/mtr/mtr0log.cc2
-rw-r--r--storage/innobase/mtr/mtr0mtr.cc47
-rw-r--r--storage/innobase/page/page0page.cc2
-rw-r--r--storage/innobase/page/page0zip.cc2
-rw-r--r--storage/innobase/pars/pars0pars.cc2
-rw-r--r--storage/innobase/row/row0ftsort.cc8
-rw-r--r--storage/innobase/row/row0import.cc135
-rw-r--r--storage/innobase/row/row0log.cc8
-rw-r--r--storage/innobase/row/row0merge.cc39
-rw-r--r--storage/innobase/row/row0mysql.cc401
-rw-r--r--storage/innobase/row/row0quiesce.cc11
-rw-r--r--storage/innobase/row/row0sel.cc17
-rw-r--r--storage/innobase/row/row0trunc.cc263
-rw-r--r--storage/innobase/row/row0uins.cc2
-rw-r--r--storage/innobase/row/row0upd.cc20
-rw-r--r--storage/innobase/srv/srv0start.cc9
-rw-r--r--storage/innobase/trx/trx0rseg.cc13
-rw-r--r--storage/innobase/trx/trx0sys.cc4
-rw-r--r--storage/innobase/trx/trx0undo.cc23
67 files changed, 1232 insertions, 2158 deletions
diff --git a/storage/innobase/btr/btr0btr.cc b/storage/innobase/btr/btr0btr.cc
index f869afd6a68..07cec1844a6 100644
--- a/storage/innobase/btr/btr0btr.cc
+++ b/storage/innobase/btr/btr0btr.cc
@@ -223,24 +223,25 @@ btr_root_block_get(
or RW_X_LATCH */
mtr_t* mtr) /*!< in: mtr */
{
- const ulint space = dict_index_get_space(index);
- const page_id_t page_id(space, dict_index_get_page(index));
- const page_size_t page_size(dict_table_page_size(index->table));
+ if (!index->table || !index->table->space) {
+ return NULL;
+ }
- buf_block_t* block = btr_block_get(page_id, page_size, mode,
- index, mtr);
+ buf_block_t* block = btr_block_get(
+ page_id_t(index->table->space->id, index->page),
+ page_size_t(index->table->space->flags), mode,
+ index, mtr);
if (!block) {
- if (index && index->table) {
- index->table->file_unreadable = true;
-
- ib_push_warning(
- static_cast<THD*>(NULL), DB_DECRYPTION_FAILED,
- "Table %s in tablespace %lu is encrypted but encryption service or"
- " used key_id is not available. "
- " Can't continue reading table.",
- index->table->name, space);
- }
+ index->table->file_unreadable = true;
+
+ ib_push_warning(
+ static_cast<THD*>(NULL), DB_DECRYPTION_FAILED,
+ "Table %s in file %s is encrypted but encryption service or"
+ " used key_id is not available. "
+ " Can't continue reading table.",
+ index->table->name,
+ UT_LIST_GET_FIRST(index->table->space->chain)->name);
return NULL;
}
@@ -252,9 +253,9 @@ btr_root_block_get(
const page_t* root = buf_block_get_frame(block);
ut_a(btr_root_fseg_validate(FIL_PAGE_DATA + PAGE_BTR_SEG_LEAF
- + root, space));
+ + root, index->table->space->id));
ut_a(btr_root_fseg_validate(FIL_PAGE_DATA + PAGE_BTR_SEG_TOP
- + root, space));
+ + root, index->table->space->id));
}
#endif /* UNIV_BTR_DEBUG */
@@ -365,9 +366,8 @@ btr_root_adjust_on_import(
buf_block_t* block;
page_zip_des_t* page_zip;
dict_table_t* table = index->table;
- const ulint space_id = dict_index_get_space(index);
- const page_id_t page_id(space_id, dict_index_get_page(index));
- const page_size_t page_size(dict_table_page_size(table));
+ const page_id_t page_id(table->space->id, index->page);
+ const page_size_t page_size(table->space->flags);
DBUG_EXECUTE_IF("ib_import_trigger_corruption_3",
return(DB_CORRUPTION););
@@ -396,10 +396,9 @@ btr_root_adjust_on_import(
} else {
/* Check that the table flags and the tablespace
flags match. */
- ulint flags = dict_tf_to_fsp_flags(table->flags);
- ulint fsp_flags = fil_space_get_flags(table->space);
- err = flags == fsp_flags
- ? DB_SUCCESS : DB_CORRUPTION;
+ err = (dict_tf_to_fsp_flags(table->flags)
+ == table->space->flags)
+ ? DB_SUCCESS : DB_CORRUPTION;
}
} else {
err = DB_SUCCESS;
@@ -409,10 +408,10 @@ btr_root_adjust_on_import(
if (err == DB_SUCCESS
&& (!btr_root_fseg_adjust_on_import(
FIL_PAGE_DATA + PAGE_BTR_SEG_LEAF
- + page, page_zip, space_id, &mtr)
+ + page, page_zip, table->space->id, &mtr)
|| !btr_root_fseg_adjust_on_import(
FIL_PAGE_DATA + PAGE_BTR_SEG_TOP
- + page, page_zip, space_id, &mtr))) {
+ + page, page_zip, table->space->id, &mtr))) {
err = DB_CORRUPTION;
}
@@ -478,8 +477,8 @@ btr_page_alloc_for_ibuf(
ut_a(node_addr.page != FIL_NULL);
new_block = buf_page_get(
- page_id_t(dict_index_get_space(index), node_addr.page),
- dict_table_page_size(index->table),
+ page_id_t(index->table->space->id, node_addr.page),
+ page_size_t(index->table->space->flags),
RW_X_LATCH, mtr);
new_page = buf_block_get_frame(new_block);
@@ -927,13 +926,14 @@ btr_node_ptr_get_child(
mtr_t* mtr) /*!< in: mtr */
{
ut_ad(rec_offs_validate(node_ptr, index, offsets));
-
- const page_id_t page_id(
- page_get_space_id(page_align(node_ptr)),
- btr_node_ptr_get_child_page_no(node_ptr, offsets));
-
- return(btr_block_get(page_id, dict_table_page_size(index->table),
- RW_SX_LATCH, index, mtr));
+ ut_ad(index->table->space->id
+ == page_get_space_id(page_align(node_ptr)));
+
+ return btr_block_get(
+ page_id_t(index->table->space->id,
+ btr_node_ptr_get_child_page_no(node_ptr, offsets)),
+ page_size_t(index->table->space->flags),
+ RW_SX_LATCH, index, mtr);
}
/************************************************************//**
@@ -1179,8 +1179,7 @@ btr_free_root_check(
/** Create the root node for a new index tree.
@param[in] type type of the index
-@param[in] space space where created
-@param[in] page_size page size
+@param[in,out] space tablespace where created
@param[in] index_id index id
@param[in] index index, or NULL when applying TRUNCATE
log record during recovery
@@ -1191,8 +1190,7 @@ record during recovery
ulint
btr_create(
ulint type,
- ulint space,
- const page_size_t& page_size,
+ fil_space_t* space,
index_id_t index_id,
dict_index_t* index,
const btr_create_t* btr_redo_create_info,
@@ -1365,7 +1363,7 @@ btr_free_but_not_root(
leaf_loop:
mtr_start(&mtr);
mtr_set_log_mode(&mtr, log_mode);
- mtr.set_named_space(block->page.id.space());
+ mtr.set_named_space_id(block->page.id.space());
page_t* root = block->frame;
@@ -1395,7 +1393,7 @@ leaf_loop:
top_loop:
mtr_start(&mtr);
mtr_set_log_mode(&mtr, log_mode);
- mtr.set_named_space(block->page.id.space());
+ mtr.set_named_space_id(block->page.id.space());
root = block->frame;
@@ -1409,7 +1407,6 @@ top_loop:
mtr_commit(&mtr);
if (!finished) {
-
goto top_loop;
}
}
@@ -1435,7 +1432,7 @@ btr_free_if_exists(
ut_ad(page_is_root(root->frame));
btr_free_but_not_root(root, mtr->get_log_mode());
- mtr->set_named_space(page_id.space());
+ mtr->set_named_space_id(page_id.space());
btr_free_root(root, mtr);
btr_free_root_invalidate(root, mtr);
}
@@ -1474,25 +1471,19 @@ btr_read_autoinc(dict_index_t* index)
ut_ad(index->is_primary());
ut_ad(index->table->persistent_autoinc);
ut_ad(!index->table->is_temporary());
-
- if (fil_space_t* space = fil_space_acquire(index->table->space)) {
- mtr_t mtr;
- mtr.start();
- ib_uint64_t autoinc;
- if (buf_block_t* block = buf_page_get(
- page_id_t(space->id, index->page),
- page_size_t(space->flags),
- RW_S_LATCH, &mtr)) {
- autoinc = page_get_autoinc(block->frame);
- } else {
- autoinc = 0;
- }
- mtr.commit();
- fil_space_release(space);
- return(autoinc);
+ mtr_t mtr;
+ mtr.start();
+ ib_uint64_t autoinc;
+ if (buf_block_t* block = buf_page_get(
+ page_id_t(index->table->space->id, index->page),
+ page_size_t(index->table->space->flags),
+ RW_S_LATCH, &mtr)) {
+ autoinc = page_get_autoinc(block->frame);
+ } else {
+ autoinc = 0;
}
-
- return(0);
+ mtr.commit();
+ return autoinc;
}
/** Read the last used AUTO_INCREMENT value from PAGE_ROOT_AUTO_INC,
@@ -1510,42 +1501,38 @@ btr_read_autoinc_with_fallback(const dict_table_t* table, unsigned col_no)
dict_index_t* index = dict_table_get_first_index(table);
if (index == NULL) {
- } else if (fil_space_t* space = fil_space_acquire(table->space)) {
- mtr_t mtr;
- mtr.start();
- buf_block_t* block = buf_page_get(
- page_id_t(space->id, index->page),
- page_size_t(space->flags),
- RW_S_LATCH, &mtr);
-
- ib_uint64_t autoinc = block
- ? page_get_autoinc(block->frame) : 0;
- const bool retry = block && autoinc == 0
- && !page_is_empty(block->frame);
- mtr.commit();
- fil_space_release(space);
-
- if (retry) {
- /* This should be an old data file where
- PAGE_ROOT_AUTO_INC was initialized to 0.
- Fall back to reading MAX(autoinc_col).
- There should be an index on it. */
- const dict_col_t* autoinc_col
- = dict_table_get_nth_col(table, col_no);
- while (index != NULL
- && index->fields[0].col != autoinc_col) {
- index = dict_table_get_next_index(index);
- }
+ return 0;
+ }
- if (index) {
- autoinc = row_search_max_autoinc(index);
- }
+ mtr_t mtr;
+ mtr.start();
+ buf_block_t* block = buf_page_get(
+ page_id_t(index->table->space->id, index->page),
+ page_size_t(index->table->space->flags),
+ RW_S_LATCH, &mtr);
+
+ ib_uint64_t autoinc = block ? page_get_autoinc(block->frame) : 0;
+ const bool retry = block && autoinc == 0
+ && !page_is_empty(block->frame);
+ mtr.commit();
+
+ if (retry) {
+ /* This should be an old data file where
+ PAGE_ROOT_AUTO_INC was initialized to 0.
+ Fall back to reading MAX(autoinc_col).
+ There should be an index on it. */
+ const dict_col_t* autoinc_col
+ = dict_table_get_nth_col(table, col_no);
+ while (index && index->fields[0].col != autoinc_col) {
+ index = dict_table_get_next_index(index);
}
- return(autoinc);
+ if (index) {
+ autoinc = row_search_max_autoinc(index);
+ }
}
- return(0);
+ return autoinc;
}
/** Write the next available AUTO_INCREMENT value to PAGE_ROOT_AUTO_INC.
@@ -1561,18 +1548,15 @@ btr_write_autoinc(dict_index_t* index, ib_uint64_t autoinc, bool reset)
ut_ad(index->table->persistent_autoinc);
ut_ad(!index->table->is_temporary());
- if (fil_space_t* space = fil_space_acquire(index->table->space)) {
- mtr_t mtr;
- mtr.start();
- mtr.set_named_space(space);
- page_set_autoinc(buf_page_get(
- page_id_t(space->id, index->page),
- page_size_t(space->flags),
- RW_SX_LATCH, &mtr),
- index, autoinc, &mtr, reset);
- mtr.commit();
- fil_space_release(space);
- }
+ mtr_t mtr;
+ mtr.start();
+ fil_space_t* space = index->table->space;
+ mtr.set_named_space(space);
+ page_set_autoinc(buf_page_get(page_id_t(space->id, index->page),
+ page_size_t(space->flags),
+ RW_SX_LATCH, &mtr),
+ index, autoinc, &mtr, reset);
+ mtr.commit();
}
/*************************************************************//**
@@ -1998,7 +1982,7 @@ btr_root_raise_and_insert(
#endif /* UNIV_ZIP_DEBUG */
#ifdef UNIV_BTR_DEBUG
if (!dict_index_is_ibuf(index)) {
- ulint space = dict_index_get_space(index);
+ ulint space = index->table->space->id;
ut_a(btr_root_fseg_validate(FIL_PAGE_DATA + PAGE_BTR_SEG_LEAF
+ root, space));
@@ -3734,7 +3718,6 @@ btr_compress(
mtr_t* mtr) /*!< in/out: mini-transaction */
{
dict_index_t* index;
- ulint space;
ulint left_page_no;
ulint right_page_no;
buf_block_t* merge_block;
@@ -3771,9 +3754,8 @@ btr_compress(
#endif /* UNIV_DEBUG */
ut_ad(mtr_is_block_fix(mtr, block, MTR_MEMO_PAGE_X_FIX, index->table));
- space = dict_index_get_space(index);
- const page_size_t page_size(dict_table_page_size(index->table));
+ const page_size_t page_size(index->table->space->flags);
MONITOR_INC(MONITOR_INDEX_MERGE_ATTEMPTS);
@@ -3931,7 +3913,8 @@ retry:
btr_search_drop_page_hash_index(block);
/* Remove the page from the level list */
- btr_level_list_remove(space, page_size, page, index, mtr);
+ btr_level_list_remove(index->table->space->id,
+ page_size, page, index, mtr);
if (dict_index_is_spatial(index)) {
rec_t* my_rec = father_cursor.page_cur.rec;
@@ -4063,7 +4046,8 @@ retry:
#endif /* UNIV_BTR_DEBUG */
/* Remove the page from the level list */
- btr_level_list_remove(space, page_size, (page_t*)page, index, mtr);
+ btr_level_list_remove(index->table->space->id,
+ page_size, page, index, mtr);
ut_ad(btr_node_ptr_get_child_page_no(
btr_cur_get_rec(&father_cursor), offsets)
@@ -4307,7 +4291,7 @@ btr_discard_only_page_on_level(
#ifdef UNIV_BTR_DEBUG
if (!dict_index_is_ibuf(index)) {
const page_t* root = buf_block_get_frame(block);
- const ulint space = dict_index_get_space(index);
+ const ulint space = index->table->space->id;
ut_a(btr_root_fseg_validate(FIL_PAGE_DATA + PAGE_BTR_SEG_LEAF
+ root, space));
ut_a(btr_root_fseg_validate(FIL_PAGE_DATA + PAGE_BTR_SEG_TOP
@@ -4369,8 +4353,6 @@ btr_discard_page(
ut_ad(mtr_is_block_fix(mtr, block, MTR_MEMO_PAGE_X_FIX, index->table));
- const ulint space = dict_index_get_space(index);
-
MONITOR_INC(MONITOR_INDEX_DISCARD);
#ifdef UNIV_DEBUG
@@ -4386,12 +4368,12 @@ btr_discard_page(
left_page_no = btr_page_get_prev(buf_block_get_frame(block), mtr);
right_page_no = btr_page_get_next(buf_block_get_frame(block), mtr);
- const page_size_t page_size(dict_table_page_size(index->table));
+ const page_size_t page_size(index->table->space->flags);
if (left_page_no != FIL_NULL) {
merge_block = btr_block_get(
- page_id_t(space, left_page_no), page_size,
- RW_X_LATCH, index, mtr);
+ page_id_t(index->table->space->id, left_page_no),
+ page_size, RW_X_LATCH, index, mtr);
merge_page = buf_block_get_frame(merge_block);
#ifdef UNIV_BTR_DEBUG
@@ -4406,8 +4388,8 @@ btr_discard_page(
== btr_cur_get_rec(&parent_cursor)));
} else if (right_page_no != FIL_NULL) {
merge_block = btr_block_get(
- page_id_t(space, right_page_no), page_size,
- RW_X_LATCH, index, mtr);
+ page_id_t(index->table->space->id, right_page_no),
+ page_size, RW_X_LATCH, index, mtr);
merge_page = buf_block_get_frame(merge_block);
#ifdef UNIV_BTR_DEBUG
@@ -4455,7 +4437,8 @@ btr_discard_page(
}
/* Remove the page from the level list */
- btr_level_list_remove(space, page_size, page, index, mtr);
+ btr_level_list_remove(index->table->space->id, page_size,
+ page, index, mtr);
#ifdef UNIV_ZIP_DEBUG
{
@@ -4984,7 +4967,7 @@ btr_validate_level(
}
#endif
- fil_space_t* space = fil_space_get(index->table->space);
+ fil_space_t* space = index->table->space;
const page_size_t table_page_size(
dict_table_page_size(index->table));
const page_size_t space_page_size(space->flags);
@@ -5011,7 +4994,7 @@ btr_validate_level(
ret = false;
}
- ut_a(index->table->space == block->page.id.space());
+ ut_a(index->table->space->id == block->page.id.space());
ut_a(block->page.id.space() == page_get_space_id(page));
#ifdef UNIV_ZIP_DEBUG
page_zip = buf_block_get_page_zip(block);
@@ -5040,8 +5023,6 @@ btr_validate_level(
left_page_no = btr_page_get_prev(page, &mtr);
while (left_page_no != FIL_NULL) {
- page_id_t left_page_id(
- index->table->space, left_page_no);
/* To obey latch order of tree blocks,
we should release the right_block once to
obtain lock of the uncle block. */
@@ -5050,7 +5031,8 @@ btr_validate_level(
savepoint2 = mtr_set_savepoint(&mtr);
block = btr_block_get(
- left_page_id,
+ page_id_t(index->table->space->id,
+ left_page_no),
table_page_size,
RW_SX_LATCH, index, &mtr);
page = buf_block_get_frame(block);
@@ -5078,7 +5060,7 @@ loop:
ut_a(!page_zip || page_zip_validate(page_zip, page, index));
#endif /* UNIV_ZIP_DEBUG */
- ut_a(block->page.id.space() == index->table->space);
+ ut_a(block->page.id.space() == index->table->space->id);
if (fseg_page_is_free(space, block->page.id.page_no())) {
@@ -5121,7 +5103,7 @@ loop:
savepoint = mtr_set_savepoint(&mtr);
right_block = btr_block_get(
- page_id_t(index->table->space, right_page_no),
+ page_id_t(index->table->space->id, right_page_no),
table_page_size,
RW_SX_LATCH, index, &mtr);
@@ -5298,13 +5280,13 @@ loop:
&mtr, savepoint, right_block);
btr_block_get(
- page_id_t(index->table->space,
+ page_id_t(index->table->space->id,
parent_right_page_no),
table_page_size,
RW_SX_LATCH, index, &mtr);
right_block = btr_block_get(
- page_id_t(index->table->space,
+ page_id_t(index->table->space->id,
right_page_no),
table_page_size,
RW_SX_LATCH, index, &mtr);
@@ -5382,14 +5364,14 @@ node_ptr_fails:
if (parent_right_page_no != FIL_NULL) {
btr_block_get(
page_id_t(
- index->table->space,
+ index->table->space->id,
parent_right_page_no),
table_page_size,
RW_SX_LATCH, index, &mtr);
}
} else if (parent_page_no != FIL_NULL) {
btr_block_get(
- page_id_t(index->table->space,
+ page_id_t(index->table->space->id,
parent_page_no),
table_page_size,
RW_SX_LATCH, index, &mtr);
@@ -5397,7 +5379,7 @@ node_ptr_fails:
}
block = btr_block_get(
- page_id_t(index->table->space, right_page_no),
+ page_id_t(index->table->space->id, right_page_no),
table_page_size,
RW_SX_LATCH, index, &mtr);
@@ -5543,8 +5525,8 @@ btr_can_merge_with_page(
index = btr_cur_get_index(cursor);
page = btr_cur_get_page(cursor);
- const page_id_t page_id(dict_index_get_space(index), page_no);
- const page_size_t page_size(dict_table_page_size(index->table));
+ const page_id_t page_id(index->table->space->id, page_no);
+ const page_size_t page_size(index->table->space->flags);
mblock = btr_block_get(page_id, page_size, RW_X_LATCH, index, mtr);
mpage = buf_block_get_frame(mblock);
diff --git a/storage/innobase/btr/btr0bulk.cc b/storage/innobase/btr/btr0bulk.cc
index 96fec531687..87316ec7638 100644
--- a/storage/innobase/btr/btr0bulk.cc
+++ b/storage/innobase/btr/btr0bulk.cc
@@ -80,10 +80,7 @@ PageBulk::init()
new_block = btr_page_alloc(m_index, 0, FSP_UP, m_level,
&alloc_mtr, mtr);
- if (n_reserved > 0) {
- fil_space_release_free_extents(m_index->table->space,
- n_reserved);
- }
+ m_index->table->space->release_free_extents(n_reserved);
alloc_mtr.commit();
@@ -107,11 +104,10 @@ PageBulk::init()
btr_page_set_index_id(new_page, NULL, m_index->id, mtr);
} else {
- page_id_t page_id(dict_index_get_space(m_index), m_page_no);
- page_size_t page_size(dict_table_page_size(m_index->table));
-
- new_block = btr_block_get(page_id, page_size,
- RW_X_LATCH, m_index, mtr);
+ new_block = btr_block_get(
+ page_id_t(m_index->table->space->id, m_page_no),
+ page_size_t(m_index->table->space->flags),
+ RW_X_LATCH, m_index, mtr);
new_page = buf_block_get_frame(new_block);
new_page_zip = buf_block_get_page_zip(new_block);
@@ -611,12 +607,11 @@ PageBulk::latch()
__FILE__, __LINE__, m_mtr);
/* In case the block is S-latched by page_cleaner. */
if (!ret) {
- page_id_t page_id(dict_index_get_space(m_index), m_page_no);
- page_size_t page_size(dict_table_page_size(m_index->table));
-
- m_block = buf_page_get_gen(page_id, page_size, RW_X_LATCH,
- m_block, BUF_GET_IF_IN_POOL,
- __FILE__, __LINE__, m_mtr, &m_err);
+ m_block = buf_page_get_gen(
+ page_id_t(m_index->table->space->id, m_page_no),
+ page_size_t(m_index->table->space->flags),
+ RW_X_LATCH, m_block, BUF_GET_IF_IN_POOL,
+ __FILE__, __LINE__, m_mtr, &m_err);
if (m_err != DB_SUCCESS) {
return (m_err);
@@ -955,13 +950,8 @@ BtrBulk::finish(dberr_t err)
rec_t* first_rec;
mtr_t mtr;
buf_block_t* last_block;
- page_t* last_page;
- page_id_t page_id(dict_index_get_space(m_index),
- last_page_no);
- page_size_t page_size(dict_table_page_size(m_index->table));
- ulint root_page_no = dict_index_get_page(m_index);
PageBulk root_page_bulk(m_index, m_trx_id,
- root_page_no, m_root_level,
+ m_index->page, m_root_level,
m_flush_observer);
mtr.start();
@@ -969,10 +959,12 @@ BtrBulk::finish(dberr_t err)
mtr_x_lock(&m_index->lock, &mtr);
ut_ad(last_page_no != FIL_NULL);
- last_block = btr_block_get(page_id, page_size,
- RW_X_LATCH, m_index, &mtr);
- last_page = buf_block_get_frame(last_block);
- first_rec = page_rec_get_next(page_get_infimum_rec(last_page));
+ last_block = btr_block_get(
+ page_id_t(m_index->table->space->id, last_page_no),
+ page_size_t(m_index->table->space->flags),
+ RW_X_LATCH, m_index, &mtr);
+ first_rec = page_rec_get_next(
+ page_get_infimum_rec(last_block->frame));
ut_ad(page_rec_is_user_rec(first_rec));
/* Copy last page to root page. */
diff --git a/storage/innobase/btr/btr0cur.cc b/storage/innobase/btr/btr0cur.cc
index 47d982fd728..982a80edcea 100644
--- a/storage/innobase/btr/btr0cur.cc
+++ b/storage/innobase/btr/btr0cur.cc
@@ -651,13 +651,11 @@ btr_cur_optimistic_latch_leaves(
rw_lock_s_unlock(&block->lock);
if (left_page_no != FIL_NULL) {
- const page_id_t page_id(
- dict_index_get_space(cursor->index),
- left_page_no);
-
cursor->left_block = btr_block_get(
- page_id,
- dict_table_page_size(cursor->index->table),
+ page_id_t(cursor->index->table->space->id,
+ left_page_no),
+ page_size_t(cursor->index->table->space
+ ->flags),
mode, cursor->index, mtr);
} else {
cursor->left_block = NULL;
@@ -1223,11 +1221,10 @@ btr_cur_search_to_nth_level_func(
page_cursor = btr_cur_get_page_cur(cursor);
- const ulint space = dict_index_get_space(index);
- const page_size_t page_size(dict_table_page_size(index->table));
+ const page_size_t page_size(index->table->space->flags);
/* Start with the root page. */
- page_id_t page_id(space, dict_index_get_page(index));
+ page_id_t page_id(index->table->space->id, index->page);
if (root_leaf_rw_latch == RW_X_LATCH) {
node_ptr_max_size = dict_index_node_ptr_max_size(index);
@@ -1777,7 +1774,7 @@ need_opposite_intention:
lock_intention = BTR_INTENTION_BOTH;
- page_id.reset(space, dict_index_get_page(index));
+ page_id.set_page_no(index->page);
up_match = 0;
low_match = 0;
height = ULINT_UNDEFINED;
@@ -1993,8 +1990,7 @@ need_opposite_intention:
ulint idx = n_blocks
- (leftmost_from_level - 1);
- page_id.reset(
- space,
+ page_id.set_page_no(
tree_blocks[idx]->page.id.page_no());
for (ulint i = n_blocks
@@ -2028,8 +2024,7 @@ need_opposite_intention:
}
/* Go to the child node */
- page_id.reset(
- space,
+ page_id.set_page_no(
btr_node_ptr_get_child_page_no(node_ptr, offsets));
n_blocks++;
@@ -2337,9 +2332,8 @@ btr_cur_open_at_index_side_func(
page_cursor = btr_cur_get_page_cur(cursor);
cursor->index = index;
- page_id_t page_id(dict_index_get_space(index),
- dict_index_get_page(index));
- const page_size_t& page_size = dict_table_page_size(index->table);
+ page_id_t page_id(index->table->space->id, index->page);
+ const page_size_t page_size(index->table->space->flags);
if (root_leaf_rw_latch == RW_X_LATCH) {
node_ptr_max_size = dict_index_node_ptr_max_size(index);
@@ -2695,9 +2689,8 @@ btr_cur_open_at_rnd_pos_func(
page_cursor = btr_cur_get_page_cur(cursor);
cursor->index = index;
- page_id_t page_id(dict_index_get_space(index),
- dict_index_get_page(index));
- const page_size_t& page_size = dict_table_page_size(index->table);
+ page_id_t page_id(index->table->space->id, index->page);
+ const page_size_t page_size(index->table->space->flags);
dberr_t err = DB_SUCCESS;
if (root_leaf_rw_latch == RW_X_LATCH) {
@@ -3471,10 +3464,7 @@ btr_cur_pessimistic_insert(
if (big_rec_vec == NULL) {
- if (n_reserved > 0) {
- fil_space_release_free_extents(
- index->table->space, n_reserved);
- }
+ index->table->space->release_free_extents(n_reserved);
return(DB_TOO_BIG_RECORD);
}
}
@@ -3547,11 +3537,7 @@ btr_cur_pessimistic_insert(
}
}
- if (n_reserved > 0) {
- fil_space_release_free_extents(index->table->space,
- n_reserved);
- }
-
+ index->table->space->release_free_extents(n_reserved);
*big_rec = big_rec_vec;
return(DB_SUCCESS);
@@ -4585,11 +4571,7 @@ btr_cur_pessimistic_update(
ut_a(!page_zip
|| page_zip_validate(page_zip, page, index));
#endif /* UNIV_ZIP_DEBUG */
- if (n_reserved > 0) {
- fil_space_release_free_extents(
- index->table->space, n_reserved);
- }
-
+ index->table->space->release_free_extents(n_reserved);
err = DB_TOO_BIG_RECORD;
goto err_exit;
}
@@ -4859,13 +4841,8 @@ return_after_reservations:
ut_a(!page_zip || page_zip_validate(page_zip, page, index));
#endif /* UNIV_ZIP_DEBUG */
- if (n_reserved > 0) {
- fil_space_release_free_extents(index->table->space,
- n_reserved);
- }
-
+ index->table->space->release_free_extents(n_reserved);
*big_rec = big_rec_vec;
-
return(err);
}
@@ -5720,11 +5697,7 @@ return_after_reservations:
has segment header and already modified in most of cases.*/
}
- if (n_reserved > 0) {
- fil_space_release_free_extents(index->table->space,
- n_reserved);
- }
-
+ index->table->space->release_free_extents(n_reserved);
return(ret);
}
@@ -5835,10 +5808,8 @@ btr_estimate_n_rows_in_range_on_level(
average from the pages scanned so far. */
# define N_PAGES_READ_LIMIT 10
- page_id_t page_id(
- dict_index_get_space(index), slot1->page_no);
- const fil_space_t* space = fil_space_get(index->table->space);
- ut_ad(space);
+ const fil_space_t* space = index->table->space;
+ page_id_t page_id(space->id, slot1->page_no);
const page_size_t page_size(space->flags);
level = slot1->page_level;
@@ -7081,19 +7052,16 @@ struct btr_blob_log_check_t {
m_mtr->set_flush_observer(observer);
if (m_op == BTR_STORE_INSERT_BULK) {
- page_id_t page_id(dict_index_get_space(index),
- page_no);
- page_size_t page_size(dict_table_page_size(
- index->table));
- page_cur_t* page_cur = &m_pcur->btr_cur.page_cur;
-
mtr_x_lock(dict_index_get_lock(index), m_mtr);
- page_cur->block = btr_block_get(
- page_id, page_size, RW_X_LATCH, index, m_mtr);
- page_cur->rec = buf_block_get_frame(page_cur->block)
+ m_pcur->btr_cur.page_cur.block = btr_block_get(
+ page_id_t(index->table->space->id, page_no),
+ page_size_t(index->table->space->flags),
+ RW_X_LATCH, index, m_mtr);
+ m_pcur->btr_cur.page_cur.rec
+ = m_pcur->btr_cur.page_cur.block->frame
+ offs;
- buf_block_buf_fix_dec(page_cur->block);
+ buf_block_buf_fix_dec(m_pcur->btr_cur.page_cur.block);
} else {
ut_ad(m_pcur->rel_pos == BTR_PCUR_ON);
bool ret = btr_pcur_restore_position(
@@ -7304,7 +7272,8 @@ btr_store_big_rec_extern_fields(
alloc_mtr = &mtr;
}
- if (!fsp_reserve_free_extents(&r_extents, space_id, 1,
+ if (!fsp_reserve_free_extents(&r_extents,
+ index->table->space, 1,
FSP_BLOB, alloc_mtr,
1)) {
@@ -7316,7 +7285,7 @@ btr_store_big_rec_extern_fields(
block = btr_page_alloc(index, hint_page_no, FSP_NO_DIR,
0, alloc_mtr, &mtr);
- alloc_mtr->release_free_extents(r_extents);
+ index->table->space->release_free_extents(r_extents);
if (op == BTR_STORE_INSERT_BULK) {
mtr_bulk.commit();
@@ -7689,7 +7658,7 @@ btr_free_externally_stored_field(
ut_ad(!(mach_read_from_4(field_ref + BTR_EXTERN_LEN)
& ~((BTR_EXTERN_OWNER_FLAG
| BTR_EXTERN_INHERITED_FLAG) << 24)));
- ut_ad(space_id == index->table->space);
+ ut_ad(space_id == index->table->space->id);
const page_size_t ext_page_size(dict_table_page_size(index->table));
const page_size_t& rec_page_size(rec == NULL
diff --git a/storage/innobase/btr/btr0defragment.cc b/storage/innobase/btr/btr0defragment.cc
index 1ca8a43e2f7..e56df37107a 100644
--- a/storage/innobase/btr/btr0defragment.cc
+++ b/storage/innobase/btr/btr0defragment.cc
@@ -212,14 +212,14 @@ btr_defragment_add_index(
dberr_t* err) /*!< out: error code */
{
mtr_t mtr;
- ulint page_no = dict_index_get_page(index);
*err = DB_SUCCESS;
mtr_start(&mtr);
// Load index rood page.
- const page_id_t page_id(dict_index_get_space(index), page_no);
- const page_size_t page_size(dict_table_page_size(index->table));
- buf_block_t* block = btr_block_get(page_id, page_size, RW_NO_LATCH, index, &mtr);
+ buf_block_t* block = btr_block_get(
+ page_id_t(index->table->space->id, index->page),
+ page_size_t(index->table->space->flags),
+ RW_NO_LATCH, index, &mtr);
page_t* page = NULL;
if (block) {
@@ -365,7 +365,7 @@ btr_defragment_save_defrag_stats_if_needed(
dict_index_t* index) /*!< in: index */
{
if (srv_defragment_stats_accuracy != 0 // stats tracking disabled
- && dict_index_get_space(index) != 0 // do not track system tables
+ && index->table->space->id != 0 // do not track system tables
&& index->stat_defrag_modified_counter
>= srv_defragment_stats_accuracy) {
dict_stats_defrag_pool_add(index);
@@ -437,7 +437,6 @@ btr_defragment_merge_pages(
{
page_t* from_page = buf_block_get_frame(from_block);
page_t* to_page = buf_block_get_frame(to_block);
- ulint space = dict_index_get_space(index);
ulint level = btr_page_get_level(from_page);
ulint n_recs = page_get_n_recs(from_page);
ulint new_data_size = page_get_data_size(to_page);
@@ -540,7 +539,9 @@ btr_defragment_merge_pages(
lock_update_merge_left(to_block, orig_pred,
from_block);
btr_search_drop_page_hash_index(from_block);
- btr_level_list_remove(space, page_size, (page_t*)from_page, index, mtr);
+ btr_level_list_remove(
+ index->table->space->id,
+ page_size, from_page, index, mtr);
btr_node_ptr_delete(index, from_block, mtr);
/* btr_blob_dbg_remove(from_page, index,
"btr_defragment_n_pages"); */
@@ -591,7 +592,6 @@ btr_defragment_n_pages(
uint n_pages,/*!< in: number of pages to defragment */
mtr_t* mtr) /*!< in/out: mini-transaction */
{
- ulint space;
/* We will need to load the n+1 block because if the last page is freed
and we need to modify the prev_page_no of that block. */
buf_block_t* blocks[BTR_DEFRAGMENT_MAX_N_PAGES + 1];
@@ -602,7 +602,6 @@ btr_defragment_n_pages(
ulint data_size_per_rec;
ulint optimal_page_size;
ulint reserved_space;
- ulint level;
ulint max_data_size = 0;
uint n_defragmented = 0;
uint n_new_slots;
@@ -612,8 +611,11 @@ btr_defragment_n_pages(
/* It doesn't make sense to call this function with n_pages = 1. */
ut_ad(n_pages > 1);
- space = dict_index_get_space(index);
- if (space == 0) {
+ if (!page_is_leaf(block->frame)) {
+ return NULL;
+ }
+
+ if (!index->table->space || !index->table->space->id) {
/* Ignore space 0. */
return NULL;
}
@@ -623,12 +625,7 @@ btr_defragment_n_pages(
}
first_page = buf_block_get_frame(block);
- level = btr_page_get_level(first_page);
- const page_size_t page_size(dict_table_page_size(index->table));
-
- if (level != 0) {
- return NULL;
- }
+ const page_size_t page_size(index->table->space->flags);
/* 1. Load the pages and calculate the total data size. */
blocks[0] = block;
@@ -643,9 +640,8 @@ btr_defragment_n_pages(
break;
}
- const page_id_t page_id(dict_index_get_space(index), page_no);
-
- blocks[i] = btr_block_get(page_id, page_size,
+ blocks[i] = btr_block_get(page_id_t(index->table->space->id,
+ page_no), page_size,
RW_X_LATCH, index, mtr);
}
diff --git a/storage/innobase/btr/btr0scrub.cc b/storage/innobase/btr/btr0scrub.cc
index 8fe1375808f..df3435828be 100644
--- a/storage/innobase/btr/btr0scrub.cc
+++ b/storage/innobase/btr/btr0scrub.cc
@@ -432,12 +432,9 @@ btr_pessimistic_scrub(
/* read block variables */
const ulint page_no = mach_read_from_4(page + FIL_PAGE_OFFSET);
- const page_id_t page_id(dict_index_get_space(index), page_no);
- const ulint left_page_no = btr_page_get_prev(page, mtr);
- const ulint right_page_no = btr_page_get_next(page, mtr);
- const page_id_t lpage_id(dict_index_get_space(index), left_page_no);
- const page_id_t rpage_id(dict_index_get_space(index), right_page_no);
- const page_size_t page_size(dict_table_page_size(index->table));
+ const ulint left_page_no = mach_read_from_4(page + FIL_PAGE_PREV);
+ const ulint right_page_no = mach_read_from_4(page + FIL_PAGE_NEXT);
+ const page_size_t page_size(index->table->space->flags);
/**
* When splitting page, we need X-latches on left/right brothers
@@ -453,15 +450,15 @@ btr_pessimistic_scrub(
mtr->release_block_at_savepoint(scrub_data->savepoint, block);
buf_block_t* get_block __attribute__((unused)) = btr_block_get(
- lpage_id, page_size,
- RW_X_LATCH, index, mtr);
+ page_id_t(index->table->space->id, left_page_no),
+ page_size, RW_X_LATCH, index, mtr);
/**
* Refetch block and re-initialize page
*/
block = btr_block_get(
- page_id, page_size,
- RW_X_LATCH, index, mtr);
+ page_id_t(index->table->space->id, page_no),
+ page_size, RW_X_LATCH, index, mtr);
page = buf_block_get_frame(block);
@@ -474,8 +471,8 @@ btr_pessimistic_scrub(
if (right_page_no != FIL_NULL) {
buf_block_t* get_block __attribute__((unused))= btr_block_get(
- rpage_id, page_size,
- RW_X_LATCH, index, mtr);
+ page_id_t(index->table->space->id, right_page_no),
+ page_size, RW_X_LATCH, index, mtr);
}
/* arguments to btr_page_split_and_insert */
@@ -522,11 +519,7 @@ btr_pessimistic_scrub(
mem_heap_free(heap);
}
- if (n_reserved > 0) {
- fil_space_release_free_extents(index->table->space,
- n_reserved);
- }
-
+ index->table->space->release_free_extents(n_reserved);
scrub_data->scrub_stat.page_splits++;
return DB_SUCCESS;
}
@@ -793,13 +786,14 @@ btr_scrub_page(
/* check that table/index still match now that they are loaded */
- if (scrub_data->current_table->space != scrub_data->space) {
+ if (!scrub_data->current_table->space
+ || scrub_data->current_table->space->id != scrub_data->space) {
/* this is truncate table */
mtr_commit(mtr);
return BTR_SCRUB_SKIP_PAGE_AND_CLOSE_TABLE;
}
- if (scrub_data->current_index->table->space != scrub_data->space) {
+ if (scrub_data->current_index->table != scrub_data->current_table) {
/* this is truncate table */
mtr_commit(mtr);
return BTR_SCRUB_SKIP_PAGE_AND_CLOSE_TABLE;
diff --git a/storage/innobase/btr/btr0sea.cc b/storage/innobase/btr/btr0sea.cc
index fac42229a5c..53272c80834 100644
--- a/storage/innobase/btr/btr0sea.cc
+++ b/storage/innobase/btr/btr0sea.cc
@@ -432,7 +432,7 @@ btr_search_info_get_ref_count(
{
ulint ret = 0;
- if (!btr_search_enabled) {
+ if (!btr_search_enabled || !index->table->space) {
return(ret);
}
@@ -666,7 +666,7 @@ btr_search_update_hash_ref(
return;
}
- ut_ad(block->page.id.space() == index->table->space);
+ ut_ad(block->page.id.space() == index->table->space->id);
ut_ad(index == cursor->index);
ut_ad(!dict_index_is_ibuf(index));
@@ -1151,7 +1151,7 @@ retry:
#endif
ut_ad(btr_search_enabled);
- ut_ad(block->page.id.space() == index->table->space);
+ ut_ad(block->page.id.space() == index->table->space->id);
ut_a(index_id == index->id);
ut_a(!dict_index_is_ibuf(index));
#ifdef UNIV_DEBUG
@@ -1366,7 +1366,7 @@ btr_search_build_page_hash_index(
rec_offs_init(offsets_);
ut_ad(ahi_latch == btr_get_search_latch(index));
ut_ad(index);
- ut_ad(block->page.id.space() == index->table->space);
+ ut_ad(block->page.id.space() == index->table->space->id);
ut_a(!dict_index_is_ibuf(index));
ut_ad(page_is_leaf(block->frame));
@@ -1684,7 +1684,7 @@ btr_search_update_hash_on_delete(btr_cur_t* cursor)
return;
}
- ut_ad(block->page.id.space() == index->table->space);
+ ut_ad(block->page.id.space() == index->table->space->id);
ut_a(index == cursor->index);
ut_a(block->curr_n_fields > 0 || block->curr_n_bytes > 0);
ut_a(!dict_index_is_ibuf(index));
@@ -1841,7 +1841,7 @@ btr_search_update_hash_on_insert(btr_cur_t* cursor, rw_lock_t* ahi_latch)
return;
}
- ut_ad(block->page.id.space() == index->table->space);
+ ut_ad(block->page.id.space() == index->table->space->id);
btr_search_check_free_space_in_heap(index);
table = btr_get_search_table(index);
@@ -2063,7 +2063,7 @@ btr_search_hash_table_validate(ulint hash_table_id)
ut_a(!dict_index_is_ibuf(block->index));
ut_ad(block->page.id.space()
- == block->index->table->space);
+ == block->index->table->space->id);
page_index_id = btr_page_get_index_id(block->frame);
diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc
index 65d7a112ac3..d87459b151d 100644
--- a/storage/innobase/buf/buf0buf.cc
+++ b/storage/innobase/buf/buf0buf.cc
@@ -2194,7 +2194,7 @@ buf_page_realloc(
memset(block->frame + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID, 0xff, 4);
UNIV_MEM_INVALID(block->frame, UNIV_PAGE_SIZE);
buf_block_set_state(block, BUF_BLOCK_REMOVE_HASH);
- block->page.id.reset(ULINT32_UNDEFINED, ULINT32_UNDEFINED);
+ block->page.id.reset();
/* Relocate buf_pool->flush_list. */
if (block->page.oldest_modification) {
@@ -4005,12 +4005,15 @@ err_exit:
ib::info() << "Row compressed page could be encrypted"
" with key_version " << key_version;
block->page.encrypted = true;
- dict_set_encrypted_by_space(block->page.id.space());
- } else {
- dict_set_corrupted_by_space(block->page.id.space());
}
if (space) {
+ if (encrypted) {
+ dict_set_encrypted_by_space(space);
+ } else {
+ dict_set_corrupted_by_space(space);
+ }
+
fil_space_release_for_io(space);
}
@@ -4409,9 +4412,16 @@ loop:
/* Try to set table as corrupted instead of
asserting. */
- if (page_id.space() != TRX_SYS_SPACE &&
- dict_set_corrupted_by_space(page_id.space())) {
- return (NULL);
+ if (page_id.space() == TRX_SYS_SPACE) {
+ } else if (page_id.space() == SRV_TMP_SPACE_ID) {
+ } else if (fil_space_t* space
+ = fil_space_acquire_for_io(
+ page_id.space())) {
+ bool set = dict_set_corrupted_by_space(space);
+ fil_space_release_for_io(space);
+ if (set) {
+ return NULL;
+ }
}
ib::fatal() << "Unable to read page " << page_id
@@ -4424,9 +4434,7 @@ loop:
}
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
- ut_a(fsp_skip_sanity_check(page_id.space())
- || ++buf_dbg_counter % 5771
- || buf_validate());
+ ut_a(++buf_dbg_counter % 5771 || buf_validate());
#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
goto loop;
} else {
@@ -4818,9 +4826,7 @@ evict_from_pool:
}
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
- ut_a(fsp_skip_sanity_check(page_id.space())
- || ++buf_dbg_counter % 5771
- || buf_validate());
+ ut_a(++buf_dbg_counter % 5771 || buf_validate());
ut_a(buf_block_get_state(fix_block) == BUF_BLOCK_FILE_PAGE);
#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
@@ -4967,9 +4973,7 @@ buf_page_optimistic_get(
mtr_memo_push(mtr, block, fix_type);
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
- ut_a(fsp_skip_sanity_check(block->page.id.space())
- || ++buf_dbg_counter % 5771
- || buf_validate());
+ ut_a(++buf_dbg_counter % 5771 || buf_validate());
ut_a(block->page.buf_fix_count > 0);
ut_a(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
@@ -5172,9 +5176,7 @@ buf_page_try_get_func(
mtr_memo_push(mtr, block, fix_type);
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
- ut_a(fsp_skip_sanity_check(block->page.id.space())
- || ++buf_dbg_counter % 5771
- || buf_validate());
+ ut_a(++buf_dbg_counter % 5771 || buf_validate());
ut_a(block->page.buf_fix_count > 0);
ut_a(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
@@ -5801,24 +5803,22 @@ buf_page_monitor(
MONITOR_INC_NOCHECK(counter);
}
-/********************************************************************//**
-Mark a table with the specified space pointed by bpage->id.space() corrupted.
-Also remove the bpage from LRU list.
-@param[in,out] bpage Block */
+/** Mark a table corrupted.
+Also remove the bpage from LRU list. */
static
void
-buf_mark_space_corrupt(buf_page_t* bpage)
+buf_mark_space_corrupt(buf_page_t* bpage, const fil_space_t* space)
{
buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
const ibool uncompressed = (buf_page_get_state(bpage)
== BUF_BLOCK_FILE_PAGE);
- uint32_t space = bpage->id.space();
/* First unfix and release lock on the bpage */
buf_pool_mutex_enter(buf_pool);
mutex_enter(buf_page_get_mutex(bpage));
ut_ad(buf_page_get_io_fix(bpage) == BUF_IO_READ);
ut_ad(bpage->buf_fix_count == 0);
+ ut_ad(bpage->id.space() == space->id);
/* Set BUF_IO_NONE before we remove the block from LRU list */
buf_page_set_io_fix(bpage, BUF_IO_NONE);
@@ -6041,7 +6041,7 @@ database_corrupted:
"buf_page_import_corrupt_failure",
if (!is_predefined_tablespace(
bpage->id.space())) {
- buf_mark_space_corrupt(bpage);
+ buf_mark_space_corrupt(bpage, space);
ib::info() << "Simulated IMPORT "
"corruption";
fil_space_release_for_io(space);
@@ -6085,7 +6085,7 @@ database_corrupted:
" a corrupt database page.";
}
- buf_mark_space_corrupt(bpage);
+ buf_mark_space_corrupt(bpage, space);
fil_space_release_for_io(space);
return(err);
}
diff --git a/storage/innobase/buf/buf0dblwr.cc b/storage/innobase/buf/buf0dblwr.cc
index eb36476cdd3..505aebc7217 100644
--- a/storage/innobase/buf/buf0dblwr.cc
+++ b/storage/innobase/buf/buf0dblwr.cc
@@ -198,17 +198,13 @@ start_again:
buf_dblwr_being_created = FALSE;
return(true);
} else {
- fil_space_t* space = fil_space_acquire(TRX_SYS_SPACE);
- const bool fail = UT_LIST_GET_FIRST(space->chain)->size
- < 3 * FSP_EXTENT_SIZE;
- fil_space_release(space);
-
- if (fail) {
+ if (UT_LIST_GET_FIRST(fil_system.sys_space->chain)->size
+ < 3 * FSP_EXTENT_SIZE) {
goto too_small;
}
}
- block2 = fseg_create(TRX_SYS_SPACE, TRX_SYS_PAGE_NO,
+ block2 = fseg_create(fil_system.sys_space, TRX_SYS_PAGE_NO,
TRX_SYS_DOUBLEWRITE
+ TRX_SYS_DOUBLEWRITE_FSEG, &mtr);
diff --git a/storage/innobase/buf/buf0flu.cc b/storage/innobase/buf/buf0flu.cc
index c23ffe306ae..10d7c727fac 100644
--- a/storage/innobase/buf/buf0flu.cc
+++ b/storage/innobase/buf/buf0flu.cc
@@ -1010,7 +1010,7 @@ buf_flush_write_block_low(
|| space->purpose == FIL_TYPE_IMPORT
|| space->purpose == FIL_TYPE_TABLESPACE);
ut_ad((space->purpose == FIL_TYPE_TEMPORARY)
- == fsp_is_system_temporary(space->id));
+ == (space == fil_system.temp_space));
page_t* frame = NULL;
#ifdef UNIV_DEBUG
buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
@@ -3727,17 +3727,17 @@ buf_flush_get_dirty_pages_count(
}
/** FlushObserver constructor
-@param[in] space_id table space id
+@param[in] space tablespace
@param[in] trx trx instance
@param[in] stage performance schema accounting object,
used by ALTER TABLE. It is passed to log_preflush_pool_modified_pages()
for accounting. */
FlushObserver::FlushObserver(
- ulint space_id,
+ fil_space_t* space,
trx_t* trx,
ut_stage_alter_t* stage)
:
- m_space_id(space_id),
+ m_space(space),
m_trx(trx),
m_stage(stage),
m_interrupted(false)
@@ -3756,7 +3756,7 @@ FlushObserver::FlushObserver(
/** FlushObserver deconstructor */
FlushObserver::~FlushObserver()
{
- ut_ad(buf_flush_get_dirty_pages_count(m_space_id, this) == 0);
+ ut_ad(buf_flush_get_dirty_pages_count(m_space->id, this) == 0);
UT_DELETE(m_flushed);
UT_DELETE(m_removed);
@@ -3820,10 +3820,10 @@ FlushObserver::flush()
if (!m_interrupted && m_stage) {
m_stage->begin_phase_flush(buf_flush_get_dirty_pages_count(
- m_space_id, this));
+ m_space->id, this));
}
- buf_LRU_flush_or_remove_pages(m_space_id, this);
+ buf_LRU_flush_or_remove_pages(m_space->id, this);
/* Wait for all dirty pages were flushed. */
for (ulint i = 0; i < srv_buf_pool_instances; i++) {
diff --git a/storage/innobase/buf/buf0lru.cc b/storage/innobase/buf/buf0lru.cc
index 3c04d6f280a..7cc61294b8f 100644
--- a/storage/innobase/buf/buf0lru.cc
+++ b/storage/innobase/buf/buf0lru.cc
@@ -2146,7 +2146,7 @@ buf_LRU_block_free_hashed_page(
buf_page_mutex_enter(block);
if (buf_pool->flush_rbt == NULL) {
- block->page.id.reset(ULINT32_UNDEFINED, ULINT32_UNDEFINED);
+ block->page.id.reset();
}
buf_block_set_state(block, BUF_BLOCK_MEMORY);
diff --git a/storage/innobase/dict/dict0boot.cc b/storage/innobase/dict/dict0boot.cc
index c4bb5f8adb0..047cc3abe14 100644
--- a/storage/innobase/dict/dict0boot.cc
+++ b/storage/innobase/dict/dict0boot.cc
@@ -179,10 +179,11 @@ dict_hdr_create(
ulint root_page_no;
ut_ad(mtr);
+ compile_time_assert(DICT_HDR_SPACE == 0);
/* Create the dictionary header file block in a new, allocated file
segment in the system tablespace */
- block = fseg_create(DICT_HDR_SPACE, 0,
+ block = fseg_create(fil_system.sys_space, 0,
DICT_HDR + DICT_HDR_FSEG_HEADER, mtr);
ut_a(DICT_HDR_PAGE_NO == block->page.id.page_no());
@@ -211,8 +212,8 @@ dict_hdr_create(
system tables */
/*--------------------------*/
- root_page_no = btr_create(DICT_CLUSTERED | DICT_UNIQUE, DICT_HDR_SPACE,
- univ_page_size, DICT_TABLES_ID,
+ root_page_no = btr_create(DICT_CLUSTERED | DICT_UNIQUE,
+ fil_system.sys_space, DICT_TABLES_ID,
dict_ind_redundant, NULL, mtr);
if (root_page_no == FIL_NULL) {
@@ -222,8 +223,8 @@ dict_hdr_create(
mlog_write_ulint(dict_header + DICT_HDR_TABLES, root_page_no,
MLOG_4BYTES, mtr);
/*--------------------------*/
- root_page_no = btr_create(DICT_UNIQUE, DICT_HDR_SPACE,
- univ_page_size, DICT_TABLE_IDS_ID,
+ root_page_no = btr_create(DICT_UNIQUE,
+ fil_system.sys_space, DICT_TABLE_IDS_ID,
dict_ind_redundant, NULL, mtr);
if (root_page_no == FIL_NULL) {
@@ -233,8 +234,8 @@ dict_hdr_create(
mlog_write_ulint(dict_header + DICT_HDR_TABLE_IDS, root_page_no,
MLOG_4BYTES, mtr);
/*--------------------------*/
- root_page_no = btr_create(DICT_CLUSTERED | DICT_UNIQUE, DICT_HDR_SPACE,
- univ_page_size, DICT_COLUMNS_ID,
+ root_page_no = btr_create(DICT_CLUSTERED | DICT_UNIQUE,
+ fil_system.sys_space, DICT_COLUMNS_ID,
dict_ind_redundant, NULL, mtr);
if (root_page_no == FIL_NULL) {
@@ -244,8 +245,8 @@ dict_hdr_create(
mlog_write_ulint(dict_header + DICT_HDR_COLUMNS, root_page_no,
MLOG_4BYTES, mtr);
/*--------------------------*/
- root_page_no = btr_create(DICT_CLUSTERED | DICT_UNIQUE, DICT_HDR_SPACE,
- univ_page_size, DICT_INDEXES_ID,
+ root_page_no = btr_create(DICT_CLUSTERED | DICT_UNIQUE,
+ fil_system.sys_space, DICT_INDEXES_ID,
dict_ind_redundant, NULL, mtr);
if (root_page_no == FIL_NULL) {
@@ -255,8 +256,8 @@ dict_hdr_create(
mlog_write_ulint(dict_header + DICT_HDR_INDEXES, root_page_no,
MLOG_4BYTES, mtr);
/*--------------------------*/
- root_page_no = btr_create(DICT_CLUSTERED | DICT_UNIQUE, DICT_HDR_SPACE,
- univ_page_size, DICT_FIELDS_ID,
+ root_page_no = btr_create(DICT_CLUSTERED | DICT_UNIQUE,
+ fil_system.sys_space, DICT_FIELDS_ID,
dict_ind_redundant, NULL, mtr);
if (root_page_no == FIL_NULL) {
@@ -331,7 +332,8 @@ dict_boot(void)
/* Insert into the dictionary cache the descriptions of the basic
system tables */
/*-------------------------*/
- table = dict_mem_table_create("SYS_TABLES", DICT_HDR_SPACE, 8, 0, 0, 0);
+ table = dict_mem_table_create("SYS_TABLES", fil_system.sys_space,
+ 8, 0, 0, 0);
dict_mem_table_add_col(table, heap, "NAME", DATA_BINARY, 0,
MAX_FULL_NAME_LEN);
@@ -378,7 +380,7 @@ dict_boot(void)
ut_a(index);
/*-------------------------*/
- table = dict_mem_table_create("SYS_COLUMNS", DICT_HDR_SPACE,
+ table = dict_mem_table_create("SYS_COLUMNS", fil_system.sys_space,
7, 0, 0, 0);
dict_mem_table_add_col(table, heap, "TABLE_ID", DATA_BINARY, 0, 8);
@@ -411,7 +413,7 @@ dict_boot(void)
table->indexes.start->n_nullable);
/*-------------------------*/
- table = dict_mem_table_create("SYS_INDEXES", DICT_HDR_SPACE,
+ table = dict_mem_table_create("SYS_INDEXES", fil_system.sys_space,
DICT_NUM_COLS__SYS_INDEXES, 0, 0, 0);
dict_mem_table_add_col(table, heap, "TABLE_ID", DATA_BINARY, 0, 8);
@@ -454,7 +456,8 @@ dict_boot(void)
table->indexes.start->n_nullable);
/*-------------------------*/
- table = dict_mem_table_create("SYS_FIELDS", DICT_HDR_SPACE, 3, 0, 0, 0);
+ table = dict_mem_table_create("SYS_FIELDS", fil_system.sys_space,
+ 3, 0, 0, 0);
dict_mem_table_add_col(table, heap, "INDEX_ID", DATA_BINARY, 0, 8);
dict_mem_table_add_col(table, heap, "POS", DATA_INT, 0, 4);
diff --git a/storage/innobase/dict/dict0crea.cc b/storage/innobase/dict/dict0crea.cc
index 4da02a2a292..9d664913cc3 100644
--- a/storage/innobase/dict/dict0crea.cc
+++ b/storage/innobase/dict/dict0crea.cc
@@ -65,6 +65,7 @@ dict_create_sys_tables_tuple(
ulint type;
ut_ad(table);
+ ut_ad(!table->space || table->space->id == table->space_id);
ut_ad(heap);
ut_ad(table->n_cols >= DATA_N_SYS_COLS);
@@ -150,7 +151,7 @@ dict_create_sys_tables_tuple(
entry, DICT_COL__SYS_TABLES__SPACE);
ptr = static_cast<byte*>(mem_heap_alloc(heap, 4));
- mach_write_to_4(ptr, table->space);
+ mach_write_to_4(ptr, table->space_id);
dfield_set_data(dfield, ptr, 4);
/*----------------------------------*/
@@ -356,6 +357,8 @@ dict_build_table_def_step(
ut_ad(mutex_own(&dict_sys->mutex));
dict_table_t* table = node->table;
ut_ad(!table->is_temporary());
+ ut_ad(!table->space);
+ ut_ad(table->space_id == ULINT_UNDEFINED);
dict_table_assign_new_id(table, thr_get_trx(thr));
/* Always set this bit for all new created tables */
@@ -382,7 +385,6 @@ dict_build_table_def_step(
if (space_id == ULINT_UNDEFINED) {
return(DB_ERROR);
}
- table->space = unsigned(space_id);
/* Determine the tablespace flags. */
bool has_data_dir = DICT_TF_HAS_DATA_DIR(table->flags);
@@ -403,27 +405,29 @@ dict_build_table_def_step(
the table we create here. */
dberr_t err;
- fil_space_t* space = fil_ibd_create(
+ table->space = fil_ibd_create(
space_id, table->name.m_name, filepath, fsp_flags,
FIL_IBD_FILE_INITIAL_SIZE,
node->mode, node->key_id, &err);
ut_free(filepath);
- if (!space) {
+ if (!table->space) {
ut_ad(err != DB_SUCCESS);
return err;
}
+ table->space_id = space_id;
mtr_t mtr;
mtr.start();
- mtr.set_named_space(space);
- fsp_header_init(space, FIL_IBD_FILE_INITIAL_SIZE, &mtr);
+ mtr.set_named_space(table->space);
+ fsp_header_init(table->space, FIL_IBD_FILE_INITIAL_SIZE, &mtr);
mtr.commit();
} else {
ut_ad(dict_tf_get_rec_format(table->flags)
!= REC_FORMAT_COMPRESSED);
- ut_ad(table->space == TRX_SYS_SPACE);
+ table->space = fil_system.sys_space;
+ table->space_id = TRX_SYS_SPACE;
DBUG_EXECUTE_IF("ib_ddl_crash_during_tablespace_alloc",
DBUG_SUICIDE(););
}
@@ -468,6 +472,9 @@ dict_create_sys_indexes_tuple(
ut_ad(mutex_own(&dict_sys->mutex));
ut_ad(index);
+ ut_ad(index->table->space || index->table->file_unreadable);
+ ut_ad(!index->table->space
+ || index->table->space->id == index->table->space_id);
ut_ad(heap);
sys_indexes = dict_sys->sys_indexes;
@@ -536,7 +543,7 @@ dict_create_sys_indexes_tuple(
entry, DICT_COL__SYS_INDEXES__SPACE);
ptr = static_cast<byte*>(mem_heap_alloc(heap, 4));
- mach_write_to_4(ptr, index->table->space);
+ mach_write_to_4(ptr, index->table->space_id);
dfield_set_data(dfield, ptr, 4);
@@ -833,7 +840,6 @@ dict_create_index_tree_step(
node->page_no = btr_create(
index->type, index->table->space,
- dict_table_page_size(index->table),
index->id, index, NULL, &mtr);
if (node->page_no == FIL_NULL) {
@@ -867,7 +873,6 @@ dict_create_index_tree_in_mem(
const trx_t* trx) /*!< in: InnoDB transaction handle */
{
mtr_t mtr;
- ulint page_no = FIL_NULL;
ut_ad(mutex_own(&dict_sys->mutex));
@@ -879,28 +884,18 @@ dict_create_index_tree_in_mem(
mtr_start(&mtr);
mtr_set_log_mode(&mtr, MTR_LOG_NO_REDO);
- dberr_t err = DB_SUCCESS;
-
/* Currently this function is being used by temp-tables only.
Import/Discard of temp-table is blocked and so this assert. */
ut_ad(index->is_readable());
ut_ad(!dict_table_is_discarded(index->table));
- page_no = btr_create(
- index->type, index->table->space,
- dict_table_page_size(index->table),
- index->id, index, NULL, &mtr);
+ index->page = btr_create(index->type, index->table->space,
+ index->id, index, NULL, &mtr);
+ mtr_commit(&mtr);
- index->page = page_no;
index->trx_id = trx->id;
- if (page_no == FIL_NULL) {
- err = DB_OUT_OF_FILE_SPACE;
- }
-
- mtr_commit(&mtr);
-
- return(err);
+ return index->page == FIL_NULL ? DB_OUT_OF_FILE_SPACE : DB_SUCCESS;
}
/** Drop the index tree associated with a row in SYS_INDEXES table.
@@ -975,31 +970,6 @@ dict_drop_index_tree(
}
/*******************************************************************//**
-Drops the index tree but don't update SYS_INDEXES table. */
-void
-dict_drop_index_tree_in_mem(
-/*========================*/
- const dict_index_t* index, /*!< in: index */
- ulint page_no) /*!< in: index page-no */
-{
- ut_ad(mutex_own(&dict_sys->mutex));
- ut_ad(dict_table_is_temporary(index->table));
-
- ulint root_page_no = page_no;
- ulint space = index->table->space;
- bool found;
- const page_size_t page_size(fil_space_get_page_size(space,
- &found));
-
- /* If tree has already been freed or it is a single table
- tablespace and the .ibd file is missing do nothing,
- else free the all the pages */
- if (root_page_no != FIL_NULL && found) {
- btr_free(page_id_t(space, root_page_no), page_size);
- }
-}
-
-/*******************************************************************//**
Recreate the index tree associated with a row in SYS_INDEXES table.
@return new root page number, or FIL_NULL on failure */
ulint
@@ -1016,6 +986,7 @@ dict_recreate_index_tree(
{
ut_ad(mutex_own(&dict_sys->mutex));
ut_a(!dict_table_is_comp(dict_sys->sys_indexes));
+ ut_ad(!table->space || table->space->id == table->space_id);
ulint len;
const rec_t* rec = btr_pcur_get_rec(pcur);
@@ -1025,20 +996,12 @@ dict_recreate_index_tree(
ut_ad(len == 4);
- ptr = rec_get_nth_field_old(rec, DICT_FLD__SYS_INDEXES__SPACE, &len);
+ ut_ad(table->space_id == mach_read_from_4(
+ rec_get_nth_field_old(rec, DICT_FLD__SYS_INDEXES__SPACE,
+ &len)));
ut_ad(len == 4);
- ut_a(table->space == mtr_read_ulint(ptr, MLOG_4BYTES, mtr));
-
- mutex_enter(&fil_system.mutex);
- fil_space_t* space = fil_space_get_by_id(table->space);
- /* 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);
-
- if (!space) {
+ if (!table->space) {
/* It is a single table tablespae and the .ibd file is
missing: do nothing. */
@@ -1064,7 +1027,7 @@ dict_recreate_index_tree(
mtr_commit(mtr);
mtr_start(mtr);
- mtr->set_named_space(space);
+ mtr->set_named_space(table->space);
btr_pcur_restore_position(BTR_MODIFY_LEAF, pcur, mtr);
/* Find the index corresponding to this SYS_INDEXES record. */
@@ -1074,8 +1037,7 @@ dict_recreate_index_tree(
if (index->id == index_id) {
ulint root_page_no = (index->type & DICT_FTS)
? FIL_NULL
- : btr_create(type, space->id,
- page_size_t(space->flags),
+ : btr_create(type, table->space,
index_id, index, NULL, mtr);
index->page = unsigned(root_page_no);
return root_page_no;
@@ -1088,73 +1050,6 @@ dict_recreate_index_tree(
return(FIL_NULL);
}
-/*******************************************************************//**
-Truncates the index tree but don't update SYSTEM TABLES.
-@return DB_SUCCESS or error */
-dberr_t
-dict_truncate_index_tree_in_mem(
-/*============================*/
- dict_index_t* index) /*!< in/out: index */
-{
- mtr_t mtr;
- bool truncate;
- ulint space = index->table->space;
-
- ut_ad(mutex_own(&dict_sys->mutex));
- ut_ad(dict_table_is_temporary(index->table));
-
- ulint type = index->type;
- ulint root_page_no = index->page;
-
- if (root_page_no == FIL_NULL) {
-
- /* The tree has been freed. */
- ib::warn() << "Trying to TRUNCATE a missing index of table "
- << index->table->name << "!";
-
- truncate = false;
- } else {
- truncate = true;
- }
-
- bool found;
- const page_size_t page_size(fil_space_get_page_size(space,
- &found));
-
- if (!found) {
-
- /* It is a single table tablespace and the .ibd file is
- missing: do nothing */
-
- ib::warn()
- << "Trying to TRUNCATE a missing .ibd file of table "
- << index->table->name << "!";
- }
-
- /* If table to truncate resides in its on own tablespace that will
- be re-created on truncate then we can ignore freeing of existing
- tablespace objects. */
-
- if (truncate) {
- btr_free(page_id_t(space, root_page_no), page_size);
- }
-
- mtr_start(&mtr);
- mtr_set_log_mode(&mtr, MTR_LOG_NO_REDO);
-
- root_page_no = btr_create(
- type, space, page_size, index->id, index, NULL, &mtr);
-
- DBUG_EXECUTE_IF("ib_err_trunc_temp_recreate_index",
- root_page_no = FIL_NULL;);
-
- index->page = root_page_no;
-
- mtr_commit(&mtr);
-
- return(index->page == FIL_NULL ? DB_ERROR : DB_SUCCESS);
-}
-
/*********************************************************************//**
Creates a table create graph.
@return own: table create node */
diff --git a/storage/innobase/dict/dict0dict.cc b/storage/innobase/dict/dict0dict.cc
index da9d94b3391..db3dc2c2e0c 100644
--- a/storage/innobase/dict/dict0dict.cc
+++ b/storage/innobase/dict/dict0dict.cc
@@ -1624,7 +1624,7 @@ dict_table_rename_in_cache(
return(DB_OUT_OF_MEMORY);
}
- fil_delete_tablespace(table->space
+ fil_delete_tablespace(table->space->id
#ifdef BTR_CUR_HASH_ADAPT
, true
#endif /* BTR_CUR_HASH_ADAPT */
@@ -1641,8 +1641,9 @@ dict_table_rename_in_cache(
ut_free(filepath);
} else if (dict_table_is_file_per_table(table)) {
- char* new_path = NULL;
- char* old_path = fil_space_get_first_path(table->space);
+ char* new_path;
+ const char* old_path = UT_LIST_GET_FIRST(table->space->chain)
+ ->name;
ut_ad(!dict_table_is_temporary(table));
@@ -1654,7 +1655,6 @@ dict_table_rename_in_cache(
if (err != DB_SUCCESS) {
ut_free(new_path);
- ut_free(old_path);
return(DB_TABLESPACE_EXISTS);
}
} else {
@@ -1663,31 +1663,18 @@ dict_table_rename_in_cache(
}
/* New filepath must not exist. */
- err = fil_rename_tablespace_check(
- table->space, old_path, new_path, false);
- if (err != DB_SUCCESS) {
- ut_free(old_path);
- ut_free(new_path);
- return(err);
- }
-
- fil_name_write_rename(table->space, old_path, new_path);
-
- bool success = fil_rename_tablespace(
- table->space, old_path, new_name, new_path);
-
- ut_free(old_path);
+ err = table->space->rename(new_name, new_path, true);
ut_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 (DICT_TF_HAS_DATA_DIR(table->flags)) {
RemoteDatafile::delete_link_file(
- success ? old_name : new_name);
+ err == DB_SUCCESS ? old_name : new_name);
}
- if (!success) {
- return(DB_ERROR);
+ if (err != DB_SUCCESS) {
+ return err;
}
}
@@ -2234,7 +2221,7 @@ dict_index_too_big_for_tree(
comp = dict_table_is_comp(table);
- const page_size_t page_size(dict_table_page_size(table));
+ const page_size_t page_size(dict_tf_get_page_size(table->flags));
if (page_size.is_compressed()
&& page_size.physical() < univ_page_size.physical()) {
@@ -5890,18 +5877,17 @@ dict_print_info_on_foreign_keys(
/** Given a space_id of a file-per-table tablespace, search the
dict_sys->table_LRU list and return the dict_table_t* pointer for it.
-@param space_id Tablespace ID
+@param space tablespace
@return table if found, NULL if not */
static
dict_table_t*
-dict_find_single_table_by_space(
- ulint space_id)
+dict_find_single_table_by_space(const fil_space_t* space)
{
dict_table_t* table;
ulint num_item;
ulint count = 0;
- ut_ad(space_id > 0);
+ ut_ad(space->id > 0);
if (dict_sys == NULL) {
/* This could happen when it's in redo processing. */
@@ -5916,7 +5902,7 @@ dict_find_single_table_by_space(
killing the server, so it worth to risk some consequences for
the action. */
while (table && count < num_item) {
- if (table->space == space_id) {
+ if (table->space == space) {
if (dict_table_is_file_per_table(table)) {
return(table);
}
@@ -5933,41 +5919,28 @@ dict_find_single_table_by_space(
/**********************************************************************//**
Flags a table with specified space_id corrupted in the data dictionary
cache
-@return TRUE if successful */
-ibool
-dict_set_corrupted_by_space(
-/*========================*/
- ulint space_id) /*!< in: space ID */
+@return true if successful */
+bool dict_set_corrupted_by_space(const fil_space_t* space)
{
dict_table_t* table;
- table = dict_find_single_table_by_space(space_id);
+ table = dict_find_single_table_by_space(space);
if (!table) {
- return(FALSE);
+ return false;
}
/* mark the table->corrupted bit only, since the caller
could be too deep in the stack for SYS_INDEXES update */
table->corrupted = true;
table->file_unreadable = true;
-
- return(TRUE);
+ return true;
}
-
-/** Flag a table with specified space_id encrypted in the data dictionary
-cache
-@param[in] space_id Tablespace id */
-UNIV_INTERN
-void
-dict_set_encrypted_by_space(ulint space_id)
+/** Flag a table encrypted in the data dictionary cache. */
+void dict_set_encrypted_by_space(const fil_space_t* space)
{
- dict_table_t* table;
-
- table = dict_find_single_table_by_space(space_id);
-
- if (table) {
+ if (dict_table_t* table = dict_find_single_table_by_space(space)) {
table->file_unreadable = true;
}
}
@@ -6219,7 +6192,7 @@ dict_ind_init()
dict_table_t* table;
/* create dummy table and index for REDUNDANT infimum and supremum */
- table = dict_mem_table_create("SYS_DUMMY1", DICT_HDR_SPACE, 1, 0, 0, 0);
+ table = dict_mem_table_create("SYS_DUMMY1", NULL, 1, 0, 0, 0);
dict_mem_table_add_col(table, NULL, NULL, DATA_CHAR,
DATA_ENGLISH | DATA_NOT_NULL, 8);
@@ -6472,8 +6445,7 @@ dict_table_schema_check(
}
}
- if (!table->is_readable() &&
- fil_space_get(table->space) == NULL) {
+ if (!table->is_readable() && !table->space) {
/* missing tablespace */
snprintf(errstr, errstr_sz,
diff --git a/storage/innobase/dict/dict0load.cc b/storage/innobase/dict/dict0load.cc
index 465de71bf2e..03e87e5df09 100644
--- a/storage/innobase/dict/dict0load.cc
+++ b/storage/innobase/dict/dict0load.cc
@@ -91,9 +91,9 @@ dict_load_table_one(
/** Load a table definition from a SYS_TABLES record to dict_table_t.
Do not load any columns or indexes.
-@param[in] name Table name
-@param[in] rec SYS_TABLES record
-@param[out,own] table table, or NULL
+@param[in] name Table name
+@param[in] rec SYS_TABLES record
+@param[out,own] table table, or NULL
@return error message
@retval NULL on success */
static
@@ -384,16 +384,12 @@ dict_process_sys_tables_rec_and_mtr_commit(
mem_heap_t* heap, /*!< in/out: temporary memory heap */
const rec_t* rec, /*!< in: SYS_TABLES record */
dict_table_t** table, /*!< out: dict_table_t to fill */
- dict_table_info_t status, /*!< in: status bit controls
- options such as whether we shall
- look for dict_table_t from cache
- first */
+ bool cached, /*!< in: whether to load from cache */
mtr_t* mtr) /*!< in/out: mini-transaction,
will be committed */
{
ulint len;
const char* field;
- const char* err_msg = NULL;
table_name_t table_name;
field = (const char*) rec_get_nth_field_old(
@@ -406,28 +402,17 @@ dict_process_sys_tables_rec_and_mtr_commit(
/* Get the table name */
table_name.m_name = mem_heap_strdupl(heap, field, len);
- /* If DICT_TABLE_LOAD_FROM_CACHE is set, first check
- whether there is cached dict_table_t struct */
- if (status & DICT_TABLE_LOAD_FROM_CACHE) {
-
+ if (cached) {
/* Commit before load the table again */
mtr_commit(mtr);
*table = dict_table_get_low(table_name.m_name);
-
- if (!(*table)) {
- err_msg = "Table not found in cache";
- }
+ return *table ? NULL : "Table not found in cache";
} else {
- err_msg = dict_load_table_low(table_name, rec, table);
+ const char* err = dict_load_table_low(table_name, rec, table);
mtr_commit(mtr);
+ return err;
}
-
- if (err_msg) {
- return(err_msg);
- }
-
- return(NULL);
}
/********************************************************************//**
@@ -1440,20 +1425,19 @@ dict_check_sys_tables(
/* Now that we have the proper name for this tablespace,
look to see if it is already in the tablespace cache. */
- if (fil_space_for_table_exists_in_mem(
- space_id, table_name.m_name,
- false, NULL, flags)) {
+ if (const fil_space_t* space
+ = fil_space_for_table_exists_in_mem(
+ space_id, table_name.m_name, false, flags)) {
/* Recovery can open a datafile that does not
match SYS_DATAFILES. If they don't match, update
SYS_DATAFILES. */
char *dict_path = dict_get_first_path(space_id);
- char *fil_path = fil_space_get_first_path(space_id);
- if (dict_path && fil_path
+ const char *fil_path = space->chain.start->name;
+ if (dict_path
&& strcmp(dict_path, fil_path)) {
dict_update_filepath(space_id, fil_path);
}
ut_free(dict_path);
- ut_free(fil_path);
ut_free(table_name.m_name);
continue;
}
@@ -1466,15 +1450,12 @@ dict_check_sys_tables(
char* filepath = dict_get_first_path(space_id);
/* Check that the .ibd file exists. */
- dberr_t err = fil_ibd_open(
- validate,
- !srv_read_only_mode && srv_log_file_size != 0,
- FIL_TYPE_TABLESPACE,
- space_id, dict_tf_to_fsp_flags(flags),
- table_name.m_name,
- filepath);
-
- if (err != DB_SUCCESS) {
+ if (!fil_ibd_open(
+ validate,
+ !srv_read_only_mode && srv_log_file_size != 0,
+ FIL_TYPE_TABLESPACE,
+ space_id, dict_tf_to_fsp_flags(flags),
+ table_name, filepath)) {
ib::warn() << "Ignoring tablespace for "
<< table_name
<< " because it could not be opened.";
@@ -2638,9 +2619,9 @@ func_exit:
/** Load a table definition from a SYS_TABLES record to dict_table_t.
Do not load any columns or indexes.
-@param[in] name Table name
-@param[in] rec SYS_TABLES record
-@param[out,own] table table, or NULL
+@param[in] name Table name
+@param[in] rec SYS_TABLES record
+@param[out,own] table table, or NULL
@return error message
@retval NULL on success */
static
@@ -2667,7 +2648,8 @@ dict_load_table_low(table_name_t& name, const rec_t* rec, dict_table_t** table)
dict_table_decode_n_col(t_num, &n_cols, &n_v_col);
*table = dict_mem_table_create(
- name.m_name, space_id, n_cols + n_v_col, n_v_col, flags, flags2);
+ name.m_name, NULL, n_cols + n_v_col, n_v_col, flags, flags2);
+ (*table)->space_id = space_id;
(*table)->id = table_id;
(*table)->file_unreadable = false;
@@ -2685,7 +2667,7 @@ void
dict_save_data_dir_path(
/*====================*/
dict_table_t* table, /*!< in/out: table */
- char* filepath) /*!< in: filepath of tablespace */
+ const char* filepath) /*!< in: filepath of tablespace */
{
ut_ad(mutex_own(&dict_sys->mutex));
ut_a(DICT_TF_HAS_DATA_DIR(table->flags));
@@ -2720,20 +2702,19 @@ dict_get_and_save_data_dir_path(
dict_table_t* table,
bool dict_mutex_own)
{
- ut_ad(!dict_table_is_temporary(table));
-
- if (!table->data_dir_path && table->space) {
- char* path = fil_space_get_first_path(table->space);
+ ut_ad(!table->is_temporary());
+ ut_ad(!table->space || table->space->id == table->space_id);
+ if (!table->data_dir_path && table->space_id) {
if (!dict_mutex_own) {
dict_mutex_enter_for_mysql();
}
- if (path == NULL) {
- path = dict_get_first_path(table->space);
- }
-
- if (path != NULL) {
+ if (const char* p = table->space
+ ? table->space->chain.start->name : NULL) {
+ table->flags |= (1 << DICT_TF_POS_DATA_DIR);
+ dict_save_data_dir_path(table, p);
+ } else if (char* path = dict_get_first_path(table->space_id)) {
table->flags |= (1 << DICT_TF_POS_DATA_DIR);
dict_save_data_dir_path(table, path);
ut_free(path);
@@ -2808,19 +2789,20 @@ dict_load_table(
/** Opens a tablespace for dict_load_table_one()
@param[in,out] table A table that refers to the tablespace to open
-@param[in] heap A memory heap
@param[in] ignore_err Whether to ignore an error. */
UNIV_INLINE
void
dict_load_tablespace(
dict_table_t* table,
- mem_heap_t* heap,
dict_err_ignore_t ignore_err)
{
- ut_ad(!dict_table_is_temporary(table));
+ ut_ad(!table->is_temporary());
+ ut_ad(!table->space);
+ ut_ad(table->space_id < SRV_LOG_SPACE_FIRST_ID);
+ ut_ad(fil_system.sys_space);
- /* The system tablespace is always available. */
- if (is_system_tablespace(table->space)) {
+ if (table->space_id == TRX_SYS_SPACE) {
+ table->space = fil_system.sys_space;
return;
}
@@ -2831,11 +2813,10 @@ dict_load_tablespace(
return;
}
- char* space_name = table->name.m_name;
-
/* The tablespace may already be open. */
- if (fil_space_for_table_exists_in_mem(
- table->space, space_name, false, heap, table->flags)) {
+ table->space = fil_space_for_table_exists_in_mem(
+ table->space_id, table->name.m_name, false, table->flags);
+ if (table->space) {
return;
}
@@ -2843,12 +2824,12 @@ dict_load_tablespace(
ib::error() << "Failed to find tablespace for table "
<< table->name << " in the cache. Attempting"
" to load the tablespace with space id "
- << table->space;
+ << table->space_id;
}
/* Use the remote filepath if needed. This parameter is optional
in the call to fil_ibd_open(). If not supplied, it will be built
- from the space_name. */
+ from the table->name. */
char* filepath = NULL;
if (DICT_TF_HAS_DATA_DIR(table->flags)) {
/* This will set table->data_dir_path from either
@@ -2864,12 +2845,12 @@ dict_load_tablespace(
/* Try to open the tablespace. We set the 2nd param (fix_dict) to
false because we do not have an x-lock on dict_operation_lock */
- dberr_t err = fil_ibd_open(
- true, false, FIL_TYPE_TABLESPACE, table->space,
+ table->space = fil_ibd_open(
+ true, false, FIL_TYPE_TABLESPACE, table->space_id,
dict_tf_to_fsp_flags(table->flags),
- space_name, filepath);
+ table->name, filepath);
- if (err != DB_SUCCESS) {
+ if (!table->space) {
/* We failed to find a sensible tablespace file */
table->file_unreadable = true;
}
@@ -2904,7 +2885,6 @@ dict_load_table_one(
dict_names_t& fk_tables)
{
dberr_t err;
- dict_table_t* table;
dict_table_t* sys_tables;
btr_pcur_t pcur;
dict_index_t* sys_index;
@@ -2970,6 +2950,7 @@ err_exit:
goto err_exit;
}
+ dict_table_t* table;
if (const char* err_msg = dict_load_table_low(name, rec, &table)) {
if (err_msg != dict_load_table_flags) {
ib::error() << err_msg;
@@ -2980,7 +2961,7 @@ err_exit:
btr_pcur_close(&pcur);
mtr_commit(&mtr);
- dict_load_tablespace(table, heap, ignore_err);
+ dict_load_tablespace(table, ignore_err);
dict_load_columns(table, heap);
@@ -3033,7 +3014,7 @@ err_exit:
}
if (err == DB_SUCCESS && cached && table->is_readable()) {
- if (table->space && !fil_space_get_size(table->space)) {
+ if (table->space && !fil_space_get_size(table->space->id)) {
table->corrupted = true;
table->file_unreadable = true;
} else if (table->supports_instant()) {
diff --git a/storage/innobase/dict/dict0mem.cc b/storage/innobase/dict/dict0mem.cc
index 8ed4089023c..951959451a1 100644
--- a/storage/innobase/dict/dict0mem.cc
+++ b/storage/innobase/dict/dict0mem.cc
@@ -127,8 +127,7 @@ dict_table_t*
dict_mem_table_create(
/*==================*/
const char* name, /*!< in: table name */
- ulint space, /*!< in: space where the clustered index of
- the table is placed */
+ fil_space_t* space, /*!< in: tablespace */
ulint n_cols, /*!< in: total number of columns including
virtual and non-virtual columns */
ulint n_v_cols,/*!< in: number of virtual columns */
@@ -139,6 +138,10 @@ dict_mem_table_create(
mem_heap_t* heap;
ut_ad(name);
+ ut_ad(!space
+ || space->purpose == FIL_TYPE_TABLESPACE
+ || space->purpose == FIL_TYPE_TEMPORARY
+ || space->purpose == FIL_TYPE_IMPORT);
ut_a(dict_tf2_is_valid(flags, flags2));
ut_a(!(flags2 & DICT_TF2_UNUSED_BIT_MASK));
@@ -159,7 +162,8 @@ dict_mem_table_create(
table->flags2 = (unsigned int) flags2;
table->name.m_name = mem_strdup(name);
table->is_system_db = dict_mem_table_is_system(table->name.m_name);
- table->space = (unsigned int) space;
+ table->space = space;
+ table->space_id = space ? space->id : ULINT_UNDEFINED;
table->n_t_cols = unsigned(n_cols + DATA_N_SYS_COLS);
table->n_v_cols = (unsigned int) (n_v_cols);
table->n_cols = table->n_t_cols - table->n_v_cols;
diff --git a/storage/innobase/dict/dict0stats.cc b/storage/innobase/dict/dict0stats.cc
index ddb77309535..9148fe9125f 100644
--- a/storage/innobase/dict/dict0stats.cc
+++ b/storage/innobase/dict/dict0stats.cc
@@ -1510,10 +1510,10 @@ dict_stats_analyze_index_below_cur(
offsets_rec = rec_get_offsets(rec, index, offsets1, false,
ULINT_UNDEFINED, &heap);
- page_id_t page_id(dict_index_get_space(index),
+ page_id_t page_id(index->table->space->id,
btr_node_ptr_get_child_page_no(
rec, offsets_rec));
- const page_size_t page_size(dict_table_page_size(index->table));
+ const page_size_t page_size(index->table->space->flags);
/* assume no external pages by default - in case we quit from this
function without analyzing any leaf pages */
@@ -2401,10 +2401,9 @@ dict_stats_report_error(dict_table_t* table, bool defragment)
{
dberr_t err;
- FilSpace space(table->space);
const char* df = defragment ? " defragment" : "";
- if (!space()) {
+ if (!table->space) {
ib::warn() << "Cannot save" << df << " statistics for table "
<< table->name
<< " because the .ibd file is missing. "
@@ -2413,7 +2412,8 @@ dict_stats_report_error(dict_table_t* table, bool defragment)
} else {
ib::warn() << "Cannot save" << df << " statistics for table "
<< table->name
- << " because file " << space()->chain.start->name
+ << " because file "
+ << table->space->chain.start->name
<< (table->corrupted
? " is corrupted."
: " cannot be decrypted.");
diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc
index fbcb75f696f..0e95fdc5a16 100644
--- a/storage/innobase/fil/fil0fil.cc
+++ b/storage/innobase/fil/fil0fil.cc
@@ -69,6 +69,33 @@ static
bool
fil_try_to_close_file_in_LRU(bool print_info);
+/** 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] old_path old filepath
+@param[in] new_path new filepath
+@param[in] is_discarded whether the tablespace is discarded
+@return innodb error code */
+static dberr_t
+fil_rename_tablespace_check(
+ const char* old_path,
+ const char* new_path,
+ bool is_discarded);
+/** Rename a single-table tablespace.
+The tablespace must exist in the memory cache.
+@param[in] id tablespace identifier
+@param[in] old_path old file name
+@param[in] new_name new table name in the
+databasename/tablename format
+@param[in] new_path_in new file name,
+or NULL if it is located in the normal data directory
+@return true if success */
+static bool
+fil_rename_tablespace(
+ ulint id,
+ const char* old_path,
+ const char* new_name,
+ const char* new_path_in);
+
/*
IMPLEMENTATION OF THE TABLESPACE MEMORY CACHE
=============================================
@@ -370,31 +397,18 @@ fil_space_get_latch(
return(&(space->latch));
}
-/** Note that a tablespace has been imported.
-It is initially marked as FIL_TYPE_IMPORT so that no logging is
-done during the import process when the space ID is stamped to each page.
-Now we change it to FIL_SPACE_TABLESPACE to start redo and undo logging.
-NOTE: temporary tablespaces are never imported.
-@param[in] id tablespace identifier */
-void
-fil_space_set_imported(
- ulint id)
+/** Note that the tablespace has been imported.
+Initially, purpose=FIL_TYPE_IMPORT so that no redo log is
+written while the space ID is being updated in each page. */
+void fil_space_t::set_imported()
{
- ut_ad(fil_system.is_initialised());
-
- mutex_enter(&fil_system.mutex);
-
- fil_space_t* space = fil_space_get_by_id(id);
- const fil_node_t* node = UT_LIST_GET_FIRST(space->chain);
-
- ut_ad(space->purpose == FIL_TYPE_IMPORT);
- space->purpose = FIL_TYPE_TABLESPACE;
- space->atomic_write_supported = node->atomic_write
+ ut_ad(purpose == FIL_TYPE_IMPORT);
+ const fil_node_t* node = UT_LIST_GET_FIRST(chain);
+ atomic_write_supported = node->atomic_write
&& srv_use_atomic_writes
&& my_test_if_atomic_write(node->handle,
- int(page_size_t(space->flags)
- .physical()));
- mutex_exit(&fil_system.mutex);
+ int(page_size_t(flags).physical()));
+ purpose = FIL_TYPE_TABLESPACE;
}
/**********************************************************************//**
@@ -1656,44 +1670,6 @@ fil_space_get_space(
return(space);
}
-/** Returns the path from the first fil_node_t found with this space ID.
-The caller is responsible for freeing the memory allocated here for the
-value returned.
-@param[in] id Tablespace ID
-@return own: A copy of fil_node_t::path, NULL if space ID is zero
-or not found. */
-char*
-fil_space_get_first_path(
- ulint id)
-{
- fil_space_t* space;
- fil_node_t* node;
- char* path;
-
- ut_ad(fil_system.is_initialised());
- ut_a(id);
-
- fil_mutex_enter_and_prepare_for_io(id);
-
- space = fil_space_get_space(id);
-
- if (space == NULL) {
- mutex_exit(&fil_system.mutex);
-
- return(NULL);
- }
-
- ut_ad(mutex_own(&fil_system.mutex));
-
- node = UT_LIST_GET_FIRST(space->chain);
-
- path = mem_strdup(node->name);
-
- mutex_exit(&fil_system.mutex);
-
- return(path);
-}
-
/** Set the recovered size of a tablespace in pages.
@param id tablespace ID
@param size recovered size in pages */
@@ -2300,7 +2276,7 @@ fil_name_write_rename_low(
@param[in] space_id tablespace id
@param[in] old_name tablespace file name
@param[in] new_name tablespace file name after renaming */
-void
+static void
fil_name_write_rename(
ulint space_id,
const char* old_name,
@@ -2405,7 +2381,7 @@ fil_op_replay_rename(
/* New path must not exist. */
dberr_t err = fil_rename_tablespace_check(
- space_id, name, new_name, false);
+ name, new_name, false);
if (err != DB_SUCCESS) {
ib::error() << " Cannot replay file rename."
" Remove either file and try again.";
@@ -2640,7 +2616,7 @@ fil_close_tablespace(
fil_flush() from being applied to this tablespace. */
{
- FlushObserver observer(id, trx, NULL);
+ FlushObserver observer(space, trx, NULL);
buf_LRU_flush_or_remove_pages(id, &observer);
}
@@ -2682,16 +2658,11 @@ fil_table_accessible(const dict_table_t* table)
return(false);
}
- if (fil_space_t* space = fil_space_acquire(table->space)) {
- bool accessible = !space->is_stopping();
- fil_space_release(space);
- ut_ad(accessible || dict_table_is_file_per_table(table));
- return(accessible);
- } else {
- /* The tablespace may momentarily be missing during
- TRUNCATE TABLE. */
- return(false);
- }
+ mutex_enter(&fil_system.mutex);
+ bool accessible = table->space && !table->space->is_stopping();
+ mutex_exit(&fil_system.mutex);
+ ut_ad(accessible || dict_table_is_file_per_table(table));
+ return accessible;
}
/** Delete a tablespace and associated .ibd file.
@@ -2824,29 +2795,25 @@ fil_delete_tablespace(
}
/** Truncate the tablespace to needed size.
-@param[in] space_id id of tablespace to truncate
+@param[in,out] space tablespace truncate
@param[in] size_in_pages truncate size.
@return true if truncate was successful. */
-bool
-fil_truncate_tablespace(
- ulint space_id,
- ulint size_in_pages)
+bool fil_truncate_tablespace(fil_space_t* space, ulint size_in_pages)
{
/* Step-1: Prepare tablespace for truncate. This involves
stopping all the new operations + IO on that tablespace
and ensuring that related pages are flushed to disk. */
- if (fil_prepare_for_truncate(space_id) != DB_SUCCESS) {
+ if (fil_prepare_for_truncate(space->id) != DB_SUCCESS) {
return(false);
}
/* Step-2: Invalidate buffer pool pages belonging to the tablespace
to re-create. Remove all insert buffer entries for the tablespace */
- buf_LRU_flush_or_remove_pages(space_id, NULL);
+ buf_LRU_flush_or_remove_pages(space->id, NULL);
/* Step-3: Truncate the tablespace and accordingly update
the fil_space_t handler that is used to access this tablespace. */
mutex_enter(&fil_system.mutex);
- fil_space_t* space = fil_space_get_by_id(space_id);
/* The following code must change when InnoDB supports
multiple datafiles per tablespace. */
@@ -2907,47 +2874,6 @@ fil_prepare_for_truncate(
return(err);
}
-#ifdef UNIV_DEBUG
-/** Increase redo skipped count for a tablespace.
-@param[in] id space id */
-void
-fil_space_inc_redo_skipped_count(
- ulint id)
-{
- fil_space_t* space;
-
- mutex_enter(&fil_system.mutex);
-
- space = fil_space_get_by_id(id);
-
- ut_a(space != NULL);
-
- space->redo_skipped_count++;
-
- mutex_exit(&fil_system.mutex);
-}
-
-/** Decrease redo skipped count for a tablespace.
-@param[in] id space id */
-void
-fil_space_dec_redo_skipped_count(
- ulint id)
-{
- fil_space_t* space;
-
- mutex_enter(&fil_system.mutex);
-
- space = fil_space_get_by_id(id);
-
- ut_a(space != NULL);
- ut_a(space->redo_skipped_count > 0);
-
- space->redo_skipped_count--;
-
- mutex_exit(&fil_system.mutex);
-}
-#endif /* UNIV_DEBUG */
-
/*******************************************************************//**
Allocates and builds a file name from a path, a table or tablespace name
and a suffix. The string must be freed by caller with ut_free().
@@ -3054,14 +2980,12 @@ fil_make_filepath(
/** 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
+static dberr_t
fil_rename_tablespace_check(
- ulint space_id,
const char* old_path,
const char* new_path,
bool is_discarded)
@@ -3074,8 +2998,7 @@ fil_rename_tablespace_check(
&& !exists) {
ib::error() << "Cannot rename '" << old_path
<< "' to '" << new_path
- << "' for space ID " << space_id
- << " because the source file"
+ << "' because the source file"
<< " does not exist.";
return(DB_TABLESPACE_NOT_FOUND);
}
@@ -3084,8 +3007,7 @@ fil_rename_tablespace_check(
if (!os_file_status(new_path, &exists, &ftype) || exists) {
ib::error() << "Cannot rename '" << old_path
<< "' to '" << new_path
- << "' for space ID " << space_id
- << " because the target file exists."
+ << "' because the target file exists."
" Remove the target file and try again.";
return(DB_TABLESPACE_EXISTS);
}
@@ -3093,6 +3015,24 @@ fil_rename_tablespace_check(
return(DB_SUCCESS);
}
+dberr_t fil_space_t::rename(const char* name, const char* path, bool log)
+{
+ ut_ad(UT_LIST_GET_LEN(chain) == 1);
+ ut_ad(!is_system_tablespace(id));
+
+ if (log) {
+ dberr_t err = fil_rename_tablespace_check(
+ chain.start->name, path, false);
+ if (err != DB_SUCCESS) {
+ return(err);
+ }
+ fil_name_write_rename(id, chain.start->name, path);
+ }
+
+ return fil_rename_tablespace(id, chain.start->name, name, path)
+ ? DB_SUCCESS : DB_ERROR;
+}
+
/** Rename a single-table tablespace.
The tablespace must exist in the memory cache.
@param[in] id tablespace identifier
@@ -3102,7 +3042,7 @@ databasename/tablename format
@param[in] new_path_in new file name,
or NULL if it is located in the normal data directory
@return true if success */
-bool
+static bool
fil_rename_tablespace(
ulint id,
const char* old_path,
@@ -3487,38 +3427,41 @@ statement to update the dictionary tables if they are incorrect.
@param[in] space_name tablespace name of the datafile
If file-per-table, it is the table name in the databasename/tablename format
@param[in] path_in expected filepath, usually read from dictionary
-@return DB_SUCCESS or error code */
-dberr_t
+@param[out] err DB_SUCCESS or error code
+@return tablespace
+@retval NULL if the tablespace could not be opened */
+fil_space_t*
fil_ibd_open(
- bool validate,
- bool fix_dict,
- fil_type_t purpose,
- ulint id,
- ulint flags,
- const char* space_name,
- const char* path_in)
+ bool validate,
+ bool fix_dict,
+ fil_type_t purpose,
+ ulint id,
+ ulint flags,
+ const table_name_t& tablename,
+ const char* path_in,
+ dberr_t* err)
{
- dberr_t err = DB_SUCCESS;
-
mutex_enter(&fil_system.mutex);
if (fil_space_t* space = fil_space_get_by_id(id)) {
- if (strcmp(space->name, space_name)) {
+ if (strcmp(space->name, tablename.m_name)) {
+ table_name_t space_name;
+ space_name.m_name = space->name;
ib::error()
- << "Trying to open tablespace '" << space_name
- << "' with id " << id
- << " while tablespace '"
- << space->name << "' exists!";
- err = DB_TABLESPACE_EXISTS;
- }
+ << "Trying to open table " << tablename
+ << " with id " << id
+ << ", conflicting with " << space_name;
+ space = NULL;
+ if (err) *err = DB_TABLESPACE_EXISTS;
+ } else if (err) *err = DB_SUCCESS;
mutex_exit(&fil_system.mutex);
- if (err == DB_SUCCESS && validate && !srv_read_only_mode) {
+ if (space && validate && !srv_read_only_mode) {
fsp_flags_try_adjust(space,
flags & ~FSP_FLAGS_MEM_MASK);
}
- return err;
+ return space;
}
mutex_exit(&fil_system.mutex);
@@ -3541,19 +3484,21 @@ fil_ibd_open(
/* Table flags can be ULINT_UNDEFINED if
dict_tf_to_fsp_flags_failure is set. */
if (flags == ULINT_UNDEFINED) {
- return(DB_CORRUPTION);
+corrupted:
+ if (err) *err = DB_CORRUPTION;
+ return NULL;
}
ut_ad(fsp_flags_is_valid(flags & ~FSP_FLAGS_MEM_MASK, id));
- df_default.init(space_name, flags);
- df_dict.init(space_name, flags);
- df_remote.init(space_name, flags);
+ df_default.init(tablename.m_name, flags);
+ df_dict.init(tablename.m_name, flags);
+ df_remote.init(tablename.m_name, flags);
/* Discover the correct file by looking in three possible locations
while avoiding unecessary effort. */
/* We will always look for an ibd in the default location. */
- df_default.make_filepath(NULL, space_name, IBD);
+ df_default.make_filepath(NULL, tablename.m_name, IBD);
/* Look for a filepath embedded in an ISL where the default file
would be. */
@@ -3637,8 +3582,8 @@ fil_ibd_open(
if (valid_tablespaces_found == 0) {
os_file_get_last_error(true);
ib::error() << "Could not find a valid tablespace file for `"
- << space_name << "`. " << TROUBLESHOOT_DATADICT_MSG;
- return(DB_CORRUPTION);
+ << tablename << "`. " << TROUBLESHOOT_DATADICT_MSG;
+ goto corrupted;
}
if (!validate) {
goto skip_validate;
@@ -3647,7 +3592,7 @@ fil_ibd_open(
/* Do not open any tablespaces if more than one tablespace with
the correct space ID and flags were found. */
if (tablespaces_found > 1) {
- ib::error() << "A tablespace for `" << space_name
+ ib::error() << "A tablespace for `" << tablename
<< "` has been found in multiple places;";
if (df_default.is_open()) {
@@ -3678,7 +3623,7 @@ fil_ibd_open(
any bad tablespaces. */
if (valid_tablespaces_found > 1 || srv_force_recovery > 0) {
ib::error() << "Will not open tablespace `"
- << space_name << "`";
+ << tablename << "`";
/* If the file is not open it cannot be valid. */
ut_ad(df_default.is_open() || !df_default.is_valid());
@@ -3690,9 +3635,11 @@ fil_ibd_open(
if (df_default.is_open() != df_default.is_valid()
|| df_dict.is_open() != df_dict.is_valid()
|| df_remote.is_open() != df_remote.is_valid()) {
- return(DB_CORRUPTION);
+ goto corrupted;
}
- return(DB_ERROR);
+error:
+ if (err) *err = DB_ERROR;
+ return NULL;
}
/* There is only one valid tablespace found and we did
@@ -3746,7 +3693,8 @@ fil_ibd_open(
ut_ad(!dict_filepath_same_as_default);
dict_update_filepath(id, df_default.filepath());
if (link_file_is_bad) {
- RemoteDatafile::delete_link_file(space_name);
+ RemoteDatafile::delete_link_file(
+ tablename.m_name);
}
} else if (!link_file_found || link_file_is_bad) {
@@ -3754,9 +3702,9 @@ fil_ibd_open(
/* Fix the link file if we got our filepath
from the dictionary but a link file did not
exist or it did not point to a valid file. */
- RemoteDatafile::delete_link_file(space_name);
+ RemoteDatafile::delete_link_file(tablename.m_name);
RemoteDatafile::create_link_file(
- space_name, df_dict.filepath());
+ tablename.m_name, df_dict.filepath());
}
} else if (df_remote.is_open()) {
@@ -3767,7 +3715,8 @@ fil_ibd_open(
/* SYS_DATAFILES record for this space ID
was not found. */
dict_replace_tablespace_and_filepath(
- id, space_name, df_remote.filepath(), flags);
+ id, tablename.m_name,
+ df_remote.filepath(), flags);
}
} else if (df_default.is_open()) {
@@ -3782,47 +3731,44 @@ fil_ibd_open(
|| (path_in == NULL && DICT_TF_HAS_DATA_DIR(flags))
|| df_remote.filepath() != NULL) {
dict_replace_tablespace_and_filepath(
- id, space_name, df_default.filepath(), flags);
+ id, tablename.m_name, df_default.filepath(),
+ flags);
}
}
skip_validate:
- if (err == DB_SUCCESS) {
- const byte* first_page =
- df_default.is_open() ? df_default.get_first_page() :
- df_dict.is_open() ? df_dict.get_first_page() :
- df_remote.get_first_page();
-
- fil_space_crypt_t* crypt_data = first_page
- ? fil_space_read_crypt_data(page_size_t(flags),
- first_page)
- : NULL;
-
- fil_space_t* space = fil_space_create(
- space_name, id, flags, purpose, crypt_data);
-
- /* We do not measure the size of the file, that is why
- we pass the 0 below */
-
- if (fil_node_create_low(
- df_remote.is_open() ? df_remote.filepath() :
- df_dict.is_open() ? df_dict.filepath() :
- df_default.filepath(), 0, space, false,
- true) == NULL) {
- err = DB_ERROR;
- }
+ const byte* first_page =
+ df_default.is_open() ? df_default.get_first_page() :
+ df_dict.is_open() ? df_dict.get_first_page() :
+ df_remote.get_first_page();
- if (err == DB_SUCCESS && validate
- && purpose != FIL_TYPE_IMPORT && !srv_read_only_mode) {
- df_remote.close();
- df_dict.close();
- df_default.close();
- fsp_flags_try_adjust(space,
- flags & ~FSP_FLAGS_MEM_MASK);
- }
+ fil_space_crypt_t* crypt_data = first_page
+ ? fil_space_read_crypt_data(page_size_t(flags), first_page)
+ : NULL;
+
+ fil_space_t* space = fil_space_create(
+ tablename.m_name, id, flags, purpose, crypt_data);
+
+ /* We do not measure the size of the file, that is why
+ we pass the 0 below */
+
+ if (fil_node_create_low(
+ df_remote.is_open() ? df_remote.filepath() :
+ df_dict.is_open() ? df_dict.filepath() :
+ df_default.filepath(), 0, space, false,
+ true) == NULL) {
+ goto error;
}
- return(err);
+ if (validate && purpose != FIL_TYPE_IMPORT && !srv_read_only_mode) {
+ df_remote.close();
+ df_dict.close();
+ df_default.close();
+ fsp_flags_try_adjust(space, flags & ~FSP_FLAGS_MEM_MASK);
+ }
+
+ if (err) *err = DB_SUCCESS;
+ return space;
}
/** Looks for a pre-existing fil_space_t with the given tablespace ID
@@ -4264,15 +4210,14 @@ startup, there may be many tablespaces which are not yet in the memory cache.
@param[in] print_error_if_does_not_exist
Print detailed error information to the
error log if a matching tablespace is not found from memory.
-@param[in] heap Heap memory
@param[in] table_flags table flags
-@return true if a matching tablespace exists in the memory cache */
-bool
+@return the tablespace
+@retval NULL if no matching tablespace exists in the memory cache */
+fil_space_t*
fil_space_for_table_exists_in_mem(
ulint id,
const char* name,
bool print_error_if_does_not_exist,
- mem_heap_t* heap,
ulint table_flags)
{
fil_space_t* space;
@@ -4330,66 +4275,7 @@ func_exit:
expected_flags & ~FSP_FLAGS_MEM_MASK);
}
- return(valid);
-}
-
-/*========== RESERVE FREE EXTENTS (for a B-tree split, for example) ===*/
-
-/*******************************************************************//**
-Tries to reserve free extents in a file space.
-@return true if succeed */
-bool
-fil_space_reserve_free_extents(
-/*===========================*/
- ulint id, /*!< in: space id */
- ulint n_free_now, /*!< in: number of free extents now */
- ulint n_to_reserve) /*!< in: how many one wants to reserve */
-{
- fil_space_t* space;
- bool success;
-
- ut_ad(fil_system.is_initialised());
-
- mutex_enter(&fil_system.mutex);
-
- space = fil_space_get_by_id(id);
-
- ut_a(space);
-
- if (space->n_reserved_extents + n_to_reserve > n_free_now) {
- success = false;
- } else {
- space->n_reserved_extents += n_to_reserve;
- success = true;
- }
-
- mutex_exit(&fil_system.mutex);
-
- return(success);
-}
-
-/*******************************************************************//**
-Releases free extents in a file space. */
-void
-fil_space_release_free_extents(
-/*===========================*/
- ulint id, /*!< in: space id */
- ulint n_reserved) /*!< in: how many one reserved */
-{
- fil_space_t* space;
-
- ut_ad(fil_system.is_initialised());
-
- mutex_enter(&fil_system.mutex);
-
- space = fil_space_get_by_id(id);
-
- ut_a(space);
- ut_a(space->n_reserved_extents >= n_reserved);
-
- space->n_reserved_extents -= n_reserved;
-
- mutex_exit(&fil_system.mutex);
+ return valid ? space : NULL;
}
/*============================ FILE I/O ================================*/
@@ -4454,7 +4340,7 @@ fil_node_complete_io(fil_node_t* node, const IORequest& type)
if (type.is_write()) {
ut_ad(!srv_read_only_mode
- || fsp_is_system_temporary(node->space->id));
+ || node->space->purpose == FIL_TYPE_TEMPORARY);
++fil_system.modification_counter;
@@ -5167,88 +5053,67 @@ fil_mtr_rename_log(
const char* tmp_name,
mtr_t* mtr)
{
- dberr_t err;
-
- bool old_is_file_per_table =
- !is_system_tablespace(old_table->space);
-
- bool new_is_file_per_table =
- !is_system_tablespace(new_table->space);
+ ut_ad(old_table->space != fil_system.temp_space);
+ ut_ad(new_table->space != fil_system.temp_space);
+ ut_ad(old_table->space_id == old_table->space->id);
+ ut_ad(new_table->space_id == new_table->space->id);
/* If neither table is file-per-table,
there will be no renaming of files. */
- if (!old_is_file_per_table && !new_is_file_per_table) {
+ if (!old_table->space_id && !new_table->space_id) {
return(DB_SUCCESS);
}
- const char* old_dir = DICT_TF_HAS_DATA_DIR(old_table->flags)
- ? old_table->data_dir_path
- : NULL;
+ const bool has_data_dir = DICT_TF_HAS_DATA_DIR(old_table->flags);
- char* old_path = fil_make_filepath(
- old_dir, old_table->name.m_name, IBD, (old_dir != NULL));
- if (old_path == NULL) {
- return(DB_OUT_OF_MEMORY);
- }
-
- if (old_is_file_per_table) {
+ if (old_table->space_id) {
char* tmp_path = fil_make_filepath(
- old_dir, tmp_name, IBD, (old_dir != NULL));
+ has_data_dir ? old_table->data_dir_path : NULL,
+ tmp_name, IBD, has_data_dir);
if (tmp_path == NULL) {
- ut_free(old_path);
return(DB_OUT_OF_MEMORY);
}
+ const char* old_path = old_table->space->chain.start->name;
/* Temp filepath must not exist. */
- err = fil_rename_tablespace_check(
- old_table->space, old_path, tmp_path,
+ dberr_t err = fil_rename_tablespace_check(
+ old_path, tmp_path,
dict_table_is_discarded(old_table));
if (err != DB_SUCCESS) {
- ut_free(old_path);
ut_free(tmp_path);
return(err);
}
fil_name_write_rename_low(
- old_table->space, 0, old_path, tmp_path, mtr);
+ old_table->space_id, 0, old_path, tmp_path, mtr);
ut_free(tmp_path);
}
- if (new_is_file_per_table) {
- const char* new_dir = DICT_TF_HAS_DATA_DIR(new_table->flags)
- ? new_table->data_dir_path
- : NULL;
- char* new_path = fil_make_filepath(
- new_dir, new_table->name.m_name,
- IBD, (new_dir != NULL));
- if (new_path == NULL) {
- ut_free(old_path);
- return(DB_OUT_OF_MEMORY);
- }
+ if (new_table->space_id) {
+ const char* new_path = new_table->space->chain.start->name;
+ char* old_path = fil_make_filepath(
+ has_data_dir ? old_table->data_dir_path : NULL,
+ old_table->name.m_name, IBD, has_data_dir);
/* Destination filepath must not exist unless this ALTER
TABLE starts and ends with a file_per-table tablespace. */
- if (!old_is_file_per_table) {
- err = fil_rename_tablespace_check(
- new_table->space, new_path, old_path,
+ if (!old_table->space_id) {
+ dberr_t err = fil_rename_tablespace_check(
+ new_path, old_path,
dict_table_is_discarded(new_table));
if (err != DB_SUCCESS) {
ut_free(old_path);
- ut_free(new_path);
return(err);
}
}
fil_name_write_rename_low(
- new_table->space, 0, new_path, old_path, mtr);
-
- ut_free(new_path);
+ new_table->space_id, 0, new_path, old_path, mtr);
+ ut_free(old_path);
}
- ut_free(old_path);
-
- return(DB_SUCCESS);
+ return DB_SUCCESS;
}
#ifdef UNIV_DEBUG
@@ -5474,8 +5339,8 @@ truncate_t::truncate(
node->handle = os_file_create_simple_no_error_handling(
innodb_data_file_key, path, OS_FILE_OPEN,
OS_FILE_READ_WRITE,
- fsp_is_system_temporary(space_id)
- ? false : srv_read_only_mode, &ret);
+ space->purpose != FIL_TYPE_TEMPORARY
+ && srv_read_only_mode, &ret);
if (!ret) {
ib::error() << "Failed to open tablespace file "
@@ -5574,17 +5439,6 @@ test_make_filepath()
#endif /* UNIV_ENABLE_UNIT_TEST_MAKE_FILEPATH */
/* @} */
-/** Release the reserved free extents.
-@param[in] n_reserved number of reserved extents */
-void
-fil_space_t::release_free_extents(ulint n_reserved)
-{
- ut_ad(rw_lock_own(&latch, RW_LOCK_X));
-
- ut_a(n_reserved_extents >= n_reserved);
- n_reserved_extents -= n_reserved;
-}
-
/** Return the next fil_space_t.
Once started, the caller must keep calling this until it returns NULL.
fil_space_acquire() and fil_space_release() are invoked here which
diff --git a/storage/innobase/fsp/fsp0fsp.cc b/storage/innobase/fsp/fsp0fsp.cc
index 452f814fc29..0c25fae9626 100644
--- a/storage/innobase/fsp/fsp0fsp.cc
+++ b/storage/innobase/fsp/fsp0fsp.cc
@@ -176,20 +176,6 @@ fsp_get_space_header(
return(header);
}
-#ifdef UNIV_DEBUG
-/** Skip some of the sanity checks that are time consuming even in debug mode
-and can affect frequent verification runs that are done to ensure stability of
-the product.
-@return true if check should be skipped for given space. */
-bool
-fsp_skip_sanity_check(
- ulint space_id)
-{
- return(srv_skip_temp_table_checks_debug
- && fsp_is_system_temporary(space_id));
-}
-#endif /* UNIV_DEBUG */
-
/**********************************************************************//**
Gets a descriptor bit of a page.
@return TRUE if free */
@@ -638,7 +624,7 @@ fsp_space_modify_check(
case MTR_LOG_NO_REDO:
ut_ad(space->purpose == FIL_TYPE_TEMPORARY
|| space->purpose == FIL_TYPE_IMPORT
- || space->redo_skipped_count
+ || my_atomic_loadlint(&space->redo_skipped_count)
|| space->is_being_truncated
|| srv_is_tablespace_truncated(space->id));
return;
@@ -1975,22 +1961,21 @@ Creates a new segment.
@return the block where the segment header is placed, x-latched, NULL
if could not create segment because of lack of space */
buf_block_t*
-fseg_create_general(
-/*================*/
- ulint space_id,/*!< in: space id */
+fseg_create(
+ fil_space_t* space, /*!< in,out: tablespace */
ulint page, /*!< in: page where the segment header is placed: if
this is != 0, the page must belong to another segment,
if this is 0, a new page will be allocated and it
will belong to the created segment */
ulint byte_offset, /*!< in: byte offset of the created segment header
on the page */
- ibool has_done_reservation, /*!< in: TRUE if the caller has already
- done the reservation for the pages with
+ mtr_t* mtr,
+ bool has_done_reservation) /*!< in: whether the caller
+ has already done the reservation for the pages with
fsp_reserve_free_extents (at least 2 extents: one for
the inode and the other for the segment) then there is
no need to do the check for this individual
operation */
- mtr_t* mtr) /*!< in/out: mini-transaction */
{
fsp_header_t* space_header;
fseg_inode_t* inode;
@@ -2000,23 +1985,23 @@ fseg_create_general(
ulint n_reserved;
ulint i;
- DBUG_ENTER("fseg_create_general");
+ DBUG_ENTER("fseg_create");
ut_ad(mtr);
ut_ad(byte_offset + FSEG_HEADER_SIZE
<= UNIV_PAGE_SIZE - FIL_PAGE_DATA_END);
- fil_space_t* space = mtr_x_lock_space(space_id, mtr);
+ mtr_x_lock(&space->latch, mtr);
const page_size_t page_size(space->flags);
ut_d(fsp_space_modify_check(space, mtr));
if (page != 0) {
- block = buf_page_get(page_id_t(space_id, page), page_size,
+ block = buf_page_get(page_id_t(space->id, page), page_size,
RW_SX_LATCH, mtr);
header = byte_offset + buf_block_get_frame(block);
- const ulint type = space_id == TRX_SYS_SPACE
+ const ulint type = space->id == TRX_SYS_SPACE
&& page == TRX_SYS_PAGE_NO
? FIL_PAGE_TYPE_TRX_SYS
: FIL_PAGE_TYPE_SYS;
@@ -2025,7 +2010,7 @@ fseg_create_general(
}
if (!has_done_reservation
- && !fsp_reserve_free_extents(&n_reserved, space_id, 2,
+ && !fsp_reserve_free_extents(&n_reserved, space, 2,
FSP_NORMAL, mtr)) {
DBUG_RETURN(NULL);
}
@@ -2092,37 +2077,17 @@ fseg_create_general(
page_get_page_no(page_align(inode)),
MLOG_4BYTES, mtr);
- mlog_write_ulint(header + FSEG_HDR_SPACE, space_id, MLOG_4BYTES, mtr);
+ mlog_write_ulint(header + FSEG_HDR_SPACE, space->id, MLOG_4BYTES, mtr);
funct_exit:
if (!has_done_reservation) {
-
- fil_space_release_free_extents(space_id, n_reserved);
+ space->release_free_extents(n_reserved);
}
DBUG_RETURN(block);
}
/**********************************************************************//**
-Creates a new segment.
-@return the block where the segment header is placed, x-latched, NULL
-if could not create segment because of lack of space */
-buf_block_t*
-fseg_create(
-/*========*/
- ulint space, /*!< in: space id */
- ulint page, /*!< in: page where the segment header is placed: if
- this is != 0, the page must belong to another segment,
- if this is 0, a new page will be allocated and it
- will belong to the created segment */
- ulint byte_offset, /*!< in: byte offset of the created segment header
- on the page */
- mtr_t* mtr) /*!< in/out: mini-transaction */
-{
- return(fseg_create_general(space, page, byte_offset, FALSE, mtr));
-}
-
-/**********************************************************************//**
Calculates the number of pages reserved by a segment, and how many pages are
currently used.
@return number of reserved pages */
@@ -2609,7 +2574,7 @@ fseg_alloc_free_page_general(
fil_block_check_type(iblock, FIL_PAGE_INODE, mtr);
if (!has_done_reservation
- && !fsp_reserve_free_extents(&n_reserved, space_id, 2,
+ && !fsp_reserve_free_extents(&n_reserved, space, 2,
FSP_NORMAL, mtr)) {
return(NULL);
}
@@ -2627,7 +2592,7 @@ fseg_alloc_free_page_general(
ut_ad(!has_done_reservation || block != NULL);
if (!has_done_reservation) {
- fil_space_release_free_extents(space_id, n_reserved);
+ space->release_free_extents(n_reserved);
}
return(block);
@@ -2676,7 +2641,7 @@ fsp_reserve_free_pages(
use several pages from the tablespace should call this function beforehand
and reserve enough free extents so that they certainly will be able
to do their operation, like a B-tree page split, fully. Reservations
-must be released with function fil_space_release_free_extents!
+must be released with function fil_space_t::release_free_extents()!
The alloc_type below has the following meaning: FSP_NORMAL means an
operation which will probably result in more space usage, like an
@@ -2702,7 +2667,7 @@ free pages available.
return true and the tablespace size is <
FSP_EXTENT_SIZE pages, then this can be 0,
otherwise it is n_ext
-@param[in] space_id tablespace identifier
+@param[in,out] space tablespace
@param[in] n_ext number of extents to reserve
@param[in] alloc_type page reservation type (FSP_BLOB, etc)
@param[in,out] mtr the mini transaction
@@ -2713,7 +2678,7 @@ free pages available.
bool
fsp_reserve_free_extents(
ulint* n_reserved,
- ulint space_id,
+ fil_space_t* space,
ulint n_ext,
fsp_reserve_t alloc_type,
mtr_t* mtr,
@@ -2731,7 +2696,7 @@ fsp_reserve_free_extents(
ut_ad(mtr);
*n_reserved = n_ext;
- fil_space_t* space = mtr_x_lock_space(space_id, mtr);
+ mtr_x_lock(&space->latch, mtr);
const page_size_t page_size(space->flags);
space_header = fsp_get_space_header(space, page_size, mtr);
@@ -2803,7 +2768,7 @@ try_again:
ut_error;
}
- if (fil_space_reserve_free_extents(space_id, n_free, n_ext)) {
+ if (space->reserve_free_extents(n_free, n_ext)) {
return(true);
}
try_to_extend:
diff --git a/storage/innobase/fsp/fsp0sysspace.cc b/storage/innobase/fsp/fsp0sysspace.cc
index b7bdb8609da..1344e02bcfb 100644
--- a/storage/innobase/fsp/fsp0sysspace.cc
+++ b/storage/innobase/fsp/fsp0sysspace.cc
@@ -50,14 +50,6 @@ SysTablespace srv_tmp_space;
at a time. We have to make this public because it is a config variable. */
ulong sys_tablespace_auto_extend_increment;
-#ifdef UNIV_DEBUG
-/** Control if extra debug checks need to be done for temporary tablespace.
-Default = true that is disable such checks.
-This variable is not exposed to end-user but still kept as variable for
-developer to enable it during debug. */
-bool srv_skip_temp_table_checks_debug = true;
-#endif /* UNIV_DEBUG */
-
/** Convert a numeric string that optionally ends in G or M or K,
to a number containing megabytes.
@param[in] str String with a quantity in bytes
diff --git a/storage/innobase/fts/fts0fts.cc b/storage/innobase/fts/fts0fts.cc
index 50480313a1a..04e10551cb2 100644
--- a/storage/innobase/fts/fts0fts.cc
+++ b/storage/innobase/fts/fts0fts.cc
@@ -1756,9 +1756,9 @@ fts_create_in_mem_aux_table(
ulint n_cols)
{
dict_table_t* new_table = dict_mem_table_create(
- aux_table_name, table->space, n_cols, 0, table->flags,
- table->space == TRX_SYS_SPACE
- ? 0 : table->space == SRV_TMP_SPACE_ID
+ aux_table_name, NULL, n_cols, 0, table->flags,
+ table->space->id == TRX_SYS_SPACE
+ ? 0 : table->space->purpose == FIL_TYPE_TEMPORARY
? DICT_TF2_TEMPORARY : DICT_TF2_USE_FILE_PER_TABLE);
if (DICT_TF_HAS_DATA_DIR(table->flags)) {
diff --git a/storage/innobase/gis/gis0rtree.cc b/storage/innobase/gis/gis0rtree.cc
index a7a35369f8c..ee0817947fc 100644
--- a/storage/innobase/gis/gis0rtree.cc
+++ b/storage/innobase/gis/gis0rtree.cc
@@ -746,7 +746,7 @@ rtr_adjust_upper_level(
parent_prdt.op = 0;
lock_prdt_update_parent(block, new_block, &prdt, &new_prdt,
- &parent_prdt, dict_index_get_space(index),
+ &parent_prdt, index->table->space->id,
page_cursor->block->page.id.page_no());
mem_heap_free(heap);
@@ -1269,7 +1269,7 @@ after_insert:
/* Check any predicate locks need to be moved/copied to the
new page */
lock_prdt_update_split(block, new_block, &prdt, &new_prdt,
- dict_index_get_space(cursor->index), page_no);
+ cursor->index->table->space->id, page_no);
/* Adjust the upper level. */
rtr_adjust_upper_level(cursor, flags, block, new_block,
@@ -1886,9 +1886,6 @@ rtr_estimate_n_rows_in_range(
* (range_mbr.ymax - range_mbr.ymin);
/* Get index root page. */
- page_size_t page_size(dict_table_page_size(index->table));
- page_id_t page_id(dict_index_get_space(index),
- dict_index_get_page(index));
mtr_t mtr;
buf_block_t* block;
page_t* page;
@@ -1898,7 +1895,10 @@ rtr_estimate_n_rows_in_range(
index->set_modified(mtr);
mtr_s_lock(&index->lock, &mtr);
- block = btr_block_get(page_id, page_size, RW_S_LATCH, index, &mtr);
+ block = btr_block_get(
+ page_id_t(index->table->space->id, index->page),
+ page_size_t(index->table->space->flags),
+ RW_S_LATCH, index, &mtr);
page = buf_block_get_frame(block);
n_recs = page_header_get_field(page, PAGE_N_RECS);
diff --git a/storage/innobase/gis/gis0sea.cc b/storage/innobase/gis/gis0sea.cc
index 2f8c9c26288..095b421dc48 100644
--- a/storage/innobase/gis/gis0sea.cc
+++ b/storage/innobase/gis/gis0sea.cc
@@ -96,7 +96,6 @@ rtr_pcur_getnext_from_path(
{
dict_index_t* index = btr_cur->index;
bool found = false;
- ulint space = dict_index_get_space(index);
page_cur_t* page_cursor;
ulint level = 0;
node_visit_t next_rec;
@@ -146,7 +145,7 @@ rtr_pcur_getnext_from_path(
| MTR_MEMO_X_LOCK));
}
- const page_size_t& page_size = dict_table_page_size(index->table);
+ const page_size_t page_size(index->table->space->flags);
/* Pop each node/page to be searched from "path" structure
and do a search on it. Please note, any pages that are in
@@ -267,11 +266,11 @@ rtr_pcur_getnext_from_path(
btr_cur->page_cur.block)));
#endif /* UNIV_RTR_DEBUG */
- page_id_t page_id(space, next_rec.page_no);
dberr_t err = DB_SUCCESS;
block = buf_page_get_gen(
- page_id, page_size,
+ page_id_t(index->table->space->id,
+ next_rec.page_no), page_size,
rw_latch, NULL, BUF_GET, __FILE__, __LINE__, mtr, &err);
if (block == NULL) {
@@ -300,7 +299,8 @@ rtr_pcur_getnext_from_path(
&& mode != PAGE_CUR_RTREE_LOCATE) {
ut_ad(rtr_info->thr);
lock_place_prdt_page_lock(
- space, next_page_no, index,
+ index->table->space->id,
+ next_page_no, index,
rtr_info->thr);
}
new_split = true;
@@ -422,11 +422,11 @@ rtr_pcur_getnext_from_path(
if (my_latch_mode == BTR_MODIFY_TREE
&& level == 0) {
ut_ad(rw_latch == RW_NO_LATCH);
- page_id_t my_page_id(
- space, block->page.id.page_no());
btr_cur_latch_leaves(
- block, my_page_id,
+ block,
+ page_id_t(index->table->space->id,
+ block->page.id.page_no()),
page_size, BTR_MODIFY_TREE,
btr_cur, mtr);
}
@@ -1346,9 +1346,8 @@ rtr_cur_restore_position(
const page_t* page;
page_cur_t* page_cursor;
node_visit_t* node = rtr_get_parent_node(btr_cur, level, false);
- ulint space = dict_index_get_space(index);
node_seq_t path_ssn = node->seq_no;
- page_size_t page_size = dict_table_page_size(index->table);
+ const page_size_t page_size(index->table->space->flags);
ulint page_no = node->page_no;
@@ -1361,11 +1360,11 @@ rtr_cur_restore_position(
ut_ad(r_cursor == node->cursor);
search_again:
- page_id_t page_id(space, page_no);
dberr_t err = DB_SUCCESS;
block = buf_page_get_gen(
- page_id, page_size, RW_X_LATCH, NULL,
+ page_id_t(index->table->space->id, page_no),
+ page_size, RW_X_LATCH, NULL,
BUF_GET, __FILE__, __LINE__, mtr, &err);
ut_ad(block);
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index 92d0648dfaf..d8d99d4fc33 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -6145,10 +6145,6 @@ no_such_table:
MONITOR_INC(MONITOR_TABLE_OPEN);
- bool no_tablespace = false;
- bool encrypted = false;
- FilSpace space;
-
if (dict_table_is_discarded(ib_table)) {
ib_senderrf(thd,
@@ -6159,78 +6155,38 @@ no_such_table:
all the flags and index root page numbers to FIL_NULL that
should prevent any DML from running but it should allow DDL
operations. */
-
- no_tablespace = false;
-
} else if (!ib_table->is_readable()) {
- space = fil_space_acquire_silent(ib_table->space);
-
- if (space()) {
- if (space()->crypt_data && space()->crypt_data->is_encrypted()) {
- /* This means that tablespace was found but we could not
- decrypt encrypted page. */
- no_tablespace = true;
- encrypted = true;
- } else {
- no_tablespace = true;
- }
- } else {
+ const fil_space_t* space = ib_table->space;
+ if (!space) {
ib_senderrf(
thd, IB_LOG_LEVEL_WARN,
ER_TABLESPACE_MISSING, norm_name);
-
- /* This means we have no idea what happened to the tablespace
- file, best to play it safe. */
-
- no_tablespace = true;
}
- } else {
- no_tablespace = false;
- }
-
- if (!thd_tablespace_op(thd) && no_tablespace) {
- free_share(m_share);
- set_my_errno(ENOENT);
- int ret_err = HA_ERR_NO_SUCH_TABLE;
- /* If table has no talespace but it has crypt data, check
- is tablespace made unaccessible because encryption service
- or used key_id is not available. */
- if (encrypted) {
- bool warning_pushed = false;
+ if (!thd_tablespace_op(thd)) {
+ free_share(m_share);
+ set_my_errno(ENOENT);
+ int ret_err = HA_ERR_NO_SUCH_TABLE;
- if (!encryption_key_id_exists(space()->crypt_data->key_id)) {
+ if (space && space->crypt_data
+ && space->crypt_data->is_encrypted()) {
push_warning_printf(
- thd, Sql_condition::WARN_LEVEL_WARN,
+ thd,
+ Sql_condition::WARN_LEVEL_WARN,
HA_ERR_DECRYPTION_FAILED,
- "Table %s in file %s is encrypted but encryption service or"
+ "Table %s in file %s is encrypted"
+ " but encryption service or"
" used key_id %u is not available. "
" Can't continue reading table.",
table_share->table_name.str,
- space()->chain.start->name,
- space()->crypt_data->key_id);
+ space->chain.start->name,
+ space->crypt_data->key_id);
ret_err = HA_ERR_DECRYPTION_FAILED;
- warning_pushed = true;
}
- /* If table is marked as encrypted then we push
- warning if it has not been already done as used
- key_id might be found but it is incorrect. */
- if (!warning_pushed) {
- push_warning_printf(
- thd, Sql_condition::WARN_LEVEL_WARN,
- HA_ERR_DECRYPTION_FAILED,
- "Table %s in file %s is encrypted but encryption service or"
- " used key_id is not available. "
- " Can't continue reading table.",
- table_share->table_name.str,
- space()->chain.start->name);
- ret_err = HA_ERR_DECRYPTION_FAILED;
- }
+ dict_table_close(ib_table, FALSE, FALSE);
+ DBUG_RETURN(ret_err);
}
-
- dict_table_close(ib_table, FALSE, FALSE);
- DBUG_RETURN(ret_err);
}
m_prebuilt = row_create_prebuilt(ib_table, table->s->reclength);
@@ -9633,9 +9589,7 @@ ha_innobase::general_fetch(
} else if (m_prebuilt->table->corrupted) {
DBUG_RETURN(HA_ERR_CRASHED);
} else {
- FilSpace space(m_prebuilt->table->space, true);
-
- DBUG_RETURN(space()
+ DBUG_RETURN(m_prebuilt->table->space
? HA_ERR_DECRYPTION_FAILED
: HA_ERR_NO_SUCH_TABLE);
}
@@ -10930,7 +10884,6 @@ create_table_info_t::create_table_def()
ibool has_doc_id_col = FALSE;
mem_heap_t* heap;
ulint num_v = 0;
- ulint space_id = 0;
ulint actual_n_cols;
ha_table_option_struct *options= m_form->s->option_struct;
dberr_t err = DB_SUCCESS;
@@ -10985,16 +10938,13 @@ create_table_info_t::create_table_def()
}
}
- /* For single-table tablespaces, we pass 0 as the space id, and then
- determine the actual space id when the tablespace is created. */
-
/* Adjust the number of columns for the FTS hidden field */
actual_n_cols = n_cols;
if (m_flags2 & DICT_TF2_FTS && !has_doc_id_col) {
actual_n_cols += 1;
}
- table = dict_mem_table_create(m_table_name, space_id,
+ table = dict_mem_table_create(m_table_name, NULL,
actual_n_cols, num_v, m_flags, m_flags2);
/* Set the hidden doc_id column. */
@@ -11202,7 +11152,8 @@ err_col:
dict_table_assign_new_id(table, m_trx);
ut_ad(dict_tf_get_rec_format(table->flags)
!= REC_FORMAT_COMPRESSED);
- table->space = SRV_TMP_SPACE_ID;
+ table->space_id = SRV_TMP_SPACE_ID;
+ table->space = fil_system.temp_space;
table->add_to_cache();
} else {
if (err == DB_SUCCESS) {
@@ -12799,7 +12750,7 @@ ha_innobase::discard_or_import_tablespace(
DBUG_RETURN(HA_ERR_TABLE_NEEDS_UPGRADE);
}
- if (dict_table->space == srv_sys_space.space_id()) {
+ if (dict_table->space == fil_system.sys_space) {
ib_senderrf(
m_prebuilt->trx->mysql_thd, IB_LOG_LEVEL_ERROR,
ER_TABLE_IN_SYSTEM_TABLESPACE,
@@ -13831,8 +13782,6 @@ been acquired by the caller who holds it for the calculation,
static uintmax_t
fsp_get_available_space_in_free_extents(const fil_space_t& space)
{
- ut_ad(space.n_pending_ops > 0);
-
ulint size_in_header = space.size_in_header;
if (size_in_header < FSP_EXTENT_SIZE) {
return 0; /* TODO: count free frag pages and
@@ -13995,8 +13944,7 @@ ha_innobase::info_low(
stats.records = (ha_rows) n_rows;
stats.deleted = 0;
- if (fil_space_t* space = fil_space_acquire_silent(
- ib_table->space)) {
+ if (fil_space_t* space = ib_table->space) {
const ulint size = page_size_t(space->flags)
.physical();
stats.data_file_length
@@ -14008,7 +13956,6 @@ ha_innobase::info_low(
stats.delete_length = 1024
* fsp_get_available_space_in_free_extents(
*space);
- fil_space_release(space);
}
stats.check_time = 0;
stats.mrr_length_per_rec= (uint)ref_length + 8; // 8 = max(sizeof(void *));
@@ -14454,7 +14401,7 @@ ha_innobase::check(
DBUG_RETURN(HA_ADMIN_CORRUPT);
} else if (!m_prebuilt->table->is_readable() &&
- !fil_space_get(m_prebuilt->table->space)) {
+ !m_prebuilt->table->space) {
ib_senderrf(
thd, IB_LOG_LEVEL_ERROR,
@@ -14701,12 +14648,10 @@ ha_innobase::update_table_comment(
#define SSTR( x ) reinterpret_cast< std::ostringstream & >( \
( std::ostringstream() << std::dec << x ) ).str()
- if (fil_space_t* space = fil_space_acquire_silent(
- m_prebuilt->table->space)) {
+ if (m_prebuilt->table->space) {
fk_str.append("InnoDB free: ");
fk_str.append(SSTR(fsp_get_available_space_in_free_extents(
- *space)));
- fil_space_release(space);
+ *m_prebuilt->table->space)));
}
fk_str.append(dict_print_info_on_foreign_keys(
diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc
index 66198afb1f7..d2c5ed748fe 100644
--- a/storage/innobase/handler/handler0alter.cc
+++ b/storage/innobase/handler/handler0alter.cc
@@ -4932,7 +4932,6 @@ new_clustered_failed:
ulint n_cols = 0;
ulint n_v_cols = 0;
dtuple_t* add_cols;
- ulint space_id = 0;
ulint z = 0;
for (uint i = 0; i < altered_table->s->fields; i++) {
@@ -4958,10 +4957,8 @@ new_clustered_failed:
DBUG_ASSERT(!add_fts_doc_id_idx || (flags2 & DICT_TF2_FTS));
- /* The initial space id 0 may be overridden later if this
- table is going to be a file_per_table tablespace. */
ctx->new_table = dict_mem_table_create(
- new_table_name, space_id, n_cols + n_v_cols, n_v_cols,
+ new_table_name, NULL, n_cols + n_v_cols, n_v_cols,
flags, flags2);
/* The rebuilt indexed_table will use the renamed
@@ -5351,12 +5348,11 @@ not_instant_add_column:
uint32_t key_id = FIL_DEFAULT_ENCRYPTION_KEY;
fil_encryption_t mode = FIL_ENCRYPTION_DEFAULT;
- if (fil_space_t* s = fil_space_acquire(user_table->space)) {
+ if (fil_space_t* s = user_table->space) {
if (const fil_space_crypt_t* c = s->crypt_data) {
key_id = c->key_id;
mode = c->encryption;
}
- fil_space_release(s);
}
if (ha_alter_info->handler_flags
@@ -6183,7 +6179,7 @@ ha_innobase::prepare_inplace_alter_table(
NULL,
NULL);
- info.set_tablespace_type(indexed_table->space != TRX_SYS_SPACE);
+ info.set_tablespace_type(indexed_table->space != fil_system.sys_space);
if (ha_alter_info->handler_flags & ALTER_ADD_NON_UNIQUE_NON_PRIM_INDEX) {
if (info.gcols_in_fulltext_or_spatial()) {
@@ -6196,9 +6192,7 @@ ha_innobase::prepare_inplace_alter_table(
if (indexed_table->corrupted) {
/* Handled below */
} else {
- FilSpace space(indexed_table->space, true);
-
- if (space()) {
+ if (const fil_space_t* space = indexed_table->space) {
String str;
const char* engine= table_type();
@@ -6210,7 +6204,7 @@ ha_innobase::prepare_inplace_alter_table(
" used key_id is not available. "
" Can't continue reading table.",
table_share->table_name.str,
- space()->chain.start->name);
+ space->chain.start->name);
my_error(ER_GET_ERRMSG, MYF(0), HA_ERR_DECRYPTION_FAILED, str.c_ptr(), engine);
DBUG_RETURN(true);
@@ -7333,7 +7327,8 @@ rollback_inplace_alter_table(
goto func_exit;
}
- trx_start_for_ddl(ctx->trx, TRX_DICT_OP_INDEX);
+ trx_start_for_ddl(ctx->trx, ctx->need_rebuild()
+ ? TRX_DICT_OP_TABLE : TRX_DICT_OP_INDEX);
row_mysql_lock_data_dictionary(ctx->trx);
if (ctx->need_rebuild()) {
@@ -9109,9 +9104,9 @@ ha_innobase::commit_inplace_alter_table(
/* If decryption failed for old table or new table
fail here. */
if ((!ctx->old_table->is_readable()
- && fil_space_get(ctx->old_table->space))
+ && ctx->old_table->space)
|| (!ctx->new_table->is_readable()
- && fil_space_get(ctx->new_table->space))) {
+ && ctx->new_table->space)) {
String str;
const char* engine= table_type();
get_error_message(HA_ERR_DECRYPTION_FAILED, &str);
diff --git a/storage/innobase/handler/i_s.cc b/storage/innobase/handler/i_s.cc
index f51565a4660..1e3cd18e069 100644
--- a/storage/innobase/handler/i_s.cc
+++ b/storage/innobase/handler/i_s.cc
@@ -6027,7 +6027,6 @@ i_s_dict_fill_sys_tables(
table->flags);
const page_size_t& page_size = dict_tf_get_page_size(table->flags);
const char* row_format;
- const char* space_type;
if (!compact) {
row_format = "Redundant";
@@ -6039,12 +6038,6 @@ i_s_dict_fill_sys_tables(
row_format = "Dynamic";
}
- if (is_system_tablespace(table->space)) {
- space_type = "System";
- } else {
- space_type = "Single";
- }
-
DBUG_ENTER("i_s_dict_fill_sys_tables");
fields = table_to_fill->field;
@@ -6057,7 +6050,7 @@ i_s_dict_fill_sys_tables(
OK(fields[SYS_TABLES_NUM_COLUMN]->store(table->n_cols));
- OK(fields[SYS_TABLES_SPACE]->store(table->space));
+ OK(fields[SYS_TABLES_SPACE]->store(table->space_id, true));
OK(field_store_string(fields[SYS_TABLES_ROW_FORMAT], row_format));
@@ -6066,7 +6059,8 @@ i_s_dict_fill_sys_tables(
? page_size.physical()
: 0, true));
- OK(field_store_string(fields[SYS_TABLES_SPACE_TYPE], space_type));
+ OK(field_store_string(fields[SYS_TABLES_SPACE_TYPE],
+ table->space_id ? "Single" : "System"));
OK(schema_table_store_record(thd, table_to_fill));
@@ -6110,23 +6104,19 @@ i_s_sys_tables_fill_table(
/* Create and populate a dict_table_t structure with
information from SYS_TABLES row */
err_msg = dict_process_sys_tables_rec_and_mtr_commit(
- heap, rec, &table_rec,
- DICT_TABLE_LOAD_FROM_RECORD, &mtr);
+ heap, rec, &table_rec, false, &mtr);
mutex_exit(&dict_sys->mutex);
if (!err_msg) {
- i_s_dict_fill_sys_tables(thd, table_rec, tables->table);
+ i_s_dict_fill_sys_tables(thd, table_rec,
+ tables->table);
} else {
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
ER_CANT_FIND_SYSTEM_REC, "%s",
err_msg);
}
- /* Since dict_process_sys_tables_rec_and_mtr_commit()
- is called with DICT_TABLE_LOAD_FROM_RECORD, the table_rec
- is created in dict_process_sys_tables_rec(), we will
- need to free it */
if (table_rec) {
dict_mem_table_free(table_rec);
}
@@ -6411,8 +6401,7 @@ i_s_sys_tables_fill_table_stats(
/* Fetch the dict_table_t structure corresponding to
this SYS_TABLES record */
err_msg = dict_process_sys_tables_rec_and_mtr_commit(
- heap, rec, &table_rec,
- DICT_TABLE_LOAD_FROM_CACHE, &mtr);
+ heap, rec, &table_rec, true, &mtr);
ulint ref_count = table_rec ? table_rec->get_ref_count() : 0;
mutex_exit(&dict_sys->mutex);
diff --git a/storage/innobase/ibuf/ibuf0ibuf.cc b/storage/innobase/ibuf/ibuf0ibuf.cc
index 07c4f0de4bc..1ff3cb594c6 100644
--- a/storage/innobase/ibuf/ibuf0ibuf.cc
+++ b/storage/innobase/ibuf/ibuf0ibuf.cc
@@ -561,7 +561,7 @@ ibuf_init_at_db_start(void)
ibuf->index = dict_mem_index_create(
dict_mem_table_create("innodb_change_buffer",
- IBUF_SPACE_ID, 1, 0, 0, 0),
+ fil_system.sys_space, 1, 0, 0, 0),
"CLUST_IND",
DICT_CLUSTERED | DICT_IBUF, 1);
ibuf->index->id = DICT_IBUF_ID_MIN + IBUF_SPACE_ID;
@@ -910,7 +910,8 @@ ibuf_set_free_bits_func(
}
mtr_start(&mtr);
- const fil_space_t* space = mtr.set_named_space(block->page.id.space());
+ const fil_space_t* space = mtr.set_named_space_id(
+ block->page.id.space());
bitmap_page = ibuf_bitmap_get_map_page(block->page.id,
block->page.size, &mtr);
@@ -1494,8 +1495,7 @@ ibuf_dummy_index_create(
dict_table_t* table;
dict_index_t* index;
- table = dict_mem_table_create("IBUF_DUMMY",
- DICT_HDR_SPACE, n, 0,
+ table = dict_mem_table_create("IBUF_DUMMY", NULL, n, 0,
comp ? DICT_TF_COMPACT : 0, 0);
index = dict_mem_index_create(table, "IBUF_DUMMY", 0, n);
@@ -2580,8 +2580,6 @@ ibuf_merge_space(
ut_ad(space < SRV_LOG_SPACE_FIRST_ID);
- ut_ad(space < SRV_LOG_SPACE_FIRST_ID);
-
ibuf_mtr_start(&mtr);
/* Position the cursor on the first matching record. */
@@ -3384,6 +3382,7 @@ ibuf_insert_low(
ut_ad(!dict_index_is_spatial(index));
ut_ad(dtuple_check_typed(entry));
ut_ad(!no_counter || op == IBUF_OP_INSERT);
+ ut_ad(page_id.space() == index->table->space->id);
ut_a(op < IBUF_OP_COUNT);
do_merge = FALSE;
@@ -3506,7 +3505,7 @@ fail_exit:
ut_a((buffered == 0) || ibuf_count_get(page_id));
#endif
ibuf_mtr_start(&bitmap_mtr);
- bitmap_mtr.set_named_space(page_id.space());
+ index->set_modified(bitmap_mtr);
bitmap_page = ibuf_bitmap_get_map_page(page_id, page_size,
&bitmap_mtr);
@@ -4574,7 +4573,7 @@ loop:
if (block != NULL) {
ibool success;
- mtr.set_named_space(page_id.space());
+ mtr.set_named_space(space);
success = buf_page_get_known_nowait(
RW_X_LATCH, block,
@@ -4590,7 +4589,7 @@ loop:
latch an io-fixed block. */
buf_block_dbg_add_level(block, SYNC_IBUF_TREE_NODE);
} else if (update_ibuf_bitmap) {
- mtr.set_named_space(page_id.space());
+ mtr.set_named_space(space);
}
if (!btr_pcur_is_on_user_rec(&pcur)) {
@@ -4641,6 +4640,9 @@ loop:
entry = ibuf_build_entry_from_ibuf_rec(
&mtr, rec, heap, &dummy_index);
+ ut_ad(!dummy_index->table->space);
+ dummy_index->table->space = space;
+ dummy_index->table->space_id = space->id;
ut_ad(page_validate(block->frame, dummy_index));
@@ -4692,7 +4694,7 @@ loop:
ibuf_btr_pcur_commit_specify_mtr(&pcur, &mtr);
ibuf_mtr_start(&mtr);
- mtr.set_named_space(page_id.space());
+ mtr.set_named_space(space);
success = buf_page_get_known_nowait(
RW_X_LATCH, block,
@@ -4947,25 +4949,15 @@ ibuf_print(
mutex_exit(&ibuf_mutex);
}
-/******************************************************************//**
-Checks the insert buffer bitmaps on IMPORT TABLESPACE.
+/** Check the insert buffer bitmaps on IMPORT TABLESPACE.
+@param[in] trx transaction
+@param[in,out] space tablespace being imported
@return DB_SUCCESS or error code */
-dberr_t
-ibuf_check_bitmap_on_import(
-/*========================*/
- const trx_t* trx, /*!< in: transaction */
- ulint space_id) /*!< in: tablespace identifier */
+dberr_t ibuf_check_bitmap_on_import(const trx_t* trx, fil_space_t* space)
{
ulint page_no;
-
- ut_ad(space_id);
ut_ad(trx->mysql_thd);
-
- FilSpace space(space_id);
- if (!space()) {
- return(DB_TABLE_NOT_FOUND);
- }
-
+ ut_ad(space->purpose == FIL_TYPE_IMPORT);
const page_size_t page_size(space->flags);
/* fil_space_t::size and fil_space_t::free_limit would still be 0
at this point. So, we will have to read page 0. */
@@ -4975,7 +4967,7 @@ ibuf_check_bitmap_on_import(
mtr_t mtr;
ulint size;
mtr.start();
- if (buf_block_t* sp = buf_page_get(page_id_t(space_id, 0), page_size,
+ if (buf_block_t* sp = buf_page_get(page_id_t(space->id, 0), page_size,
RW_S_LATCH, &mtr)) {
size = std::min(
mach_read_from_4(FSP_HEADER_OFFSET + FSP_FREE_LIMIT
@@ -5015,7 +5007,7 @@ ibuf_check_bitmap_on_import(
ibuf_enter(&mtr);
bitmap_page = ibuf_bitmap_get_map_page(
- page_id_t(space_id, page_no), page_size, &mtr);
+ page_id_t(space->id, page_no), page_size, &mtr);
if (buf_page_is_zeroes(bitmap_page, page_size)) {
/* This means we got all-zero page instead of
@@ -5026,9 +5018,8 @@ ibuf_check_bitmap_on_import(
curr_page < page_size.physical(); curr_page++) {
buf_block_t* block = buf_page_get(
- page_id_t(space_id, curr_page),
- page_size,
- RW_S_LATCH, &mtr);
+ page_id_t(space->id, curr_page),
+ page_size, RW_S_LATCH, &mtr);
page_t* page = buf_block_get_frame(block);
ut_ad(buf_page_is_zeroes(page, page_size));
}
@@ -5044,7 +5035,7 @@ ibuf_check_bitmap_on_import(
const ulint offset = page_no + i;
- const page_id_t cur_page_id(space_id, offset);
+ const page_id_t cur_page_id(space->id, offset);
if (ibuf_bitmap_page_get_bits(
bitmap_page, cur_page_id, page_size,
@@ -5057,12 +5048,10 @@ ibuf_check_bitmap_on_import(
ib_errf(trx->mysql_thd,
IB_LOG_LEVEL_ERROR,
ER_INNODB_INDEX_CORRUPT,
- "Space %u page %u"
+ "File %s page " ULINTPF
" is wrongly flagged to belong to the"
" insert buffer",
- (unsigned) space_id,
- (unsigned) offset);
-
+ space->chain.start->name, offset);
return(DB_CORRUPTION);
}
@@ -5074,9 +5063,9 @@ ibuf_check_bitmap_on_import(
IB_LOG_LEVEL_WARN,
ER_INNODB_INDEX_CORRUPT,
"Buffered changes"
- " for space %u page %u are lost",
- (unsigned) space_id,
- (unsigned) offset);
+ " for file %s page " ULINTPF
+ " are lost",
+ space->chain.start->name, offset);
/* Tolerate this error, so that
slightly corrupted tables can be
@@ -5112,7 +5101,7 @@ ibuf_set_bitmap_for_bulk_load(
free_val = ibuf_index_page_calc_free(block);
mtr_start(&mtr);
- mtr.set_named_space(block->page.id.space());
+ mtr.set_named_space_id(block->page.id.space());
bitmap_page = ibuf_bitmap_get_map_page(block->page.id,
block->page.size, &mtr);
diff --git a/storage/innobase/include/btr0btr.h b/storage/innobase/include/btr0btr.h
index 336ee68ee59..a4f93280ff1 100644
--- a/storage/innobase/include/btr0btr.h
+++ b/storage/innobase/include/btr0btr.h
@@ -355,8 +355,7 @@ btr_node_ptr_get_child_page_no(
/** Create the root node for a new index tree.
@param[in] type type of the index
-@param[in] space space where created
-@param[in] page_size page size
+@param[in,out] space tablespace where created
@param[in] index_id index id
@param[in] index index, or NULL when applying TRUNCATE
log record during recovery
@@ -367,8 +366,7 @@ record during recovery
ulint
btr_create(
ulint type,
- ulint space,
- const page_size_t& page_size,
+ fil_space_t* space,
index_id_t index_id,
dict_index_t* index,
const btr_create_t* btr_redo_create_info,
diff --git a/storage/innobase/include/btr0bulk.h b/storage/innobase/include/btr0bulk.h
index 1567c98c386..0f0051131a6 100644
--- a/storage/innobase/include/btr0bulk.h
+++ b/storage/innobase/include/btr0bulk.h
@@ -284,9 +284,8 @@ public:
m_flush_observer(observer)
{
ut_ad(m_flush_observer != NULL);
-#ifdef UNIV_DEBUG
- fil_space_inc_redo_skipped_count(m_index->table->space);
-#endif /* UNIV_DEBUG */
+ ut_d(my_atomic_addlint(
+ &m_index->table->space->redo_skipped_count, 1));
}
/** Destructor */
@@ -294,10 +293,8 @@ public:
{
mem_heap_free(m_heap);
UT_DELETE(m_page_bulks);
-
-#ifdef UNIV_DEBUG
- fil_space_dec_redo_skipped_count(m_index->table->space);
-#endif /* UNIV_DEBUG */
+ ut_d(my_atomic_addlint(
+ &m_index->table->space->redo_skipped_count, -1));
}
/** Initialization
diff --git a/storage/innobase/include/btr0sea.ic b/storage/innobase/include/btr0sea.ic
index 23024f7f7f6..fba97835395 100644
--- a/storage/innobase/include/btr0sea.ic
+++ b/storage/innobase/include/btr0sea.ic
@@ -168,9 +168,10 @@ rw_lock_t*
btr_get_search_latch(const dict_index_t* index)
{
ut_ad(index != NULL);
+ ut_ad(index->table->space->id == index->table->space_id);
ulint ifold = ut_fold_ulint_pair(ulint(index->id),
- index->table->space);
+ index->table->space_id);
return(btr_search_latches[ifold % btr_ahi_parts]);
}
@@ -184,9 +185,10 @@ hash_table_t*
btr_get_search_table(const dict_index_t* index)
{
ut_ad(index != NULL);
+ ut_ad(index->table->space->id == index->table->space_id);
ulint ifold = ut_fold_ulint_pair(ulint(index->id),
- index->table->space);
+ index->table->space_id);
return(btr_search_sys->hash_tables[ifold % btr_ahi_parts]);
}
diff --git a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h
index 32b964c406d..4c2f04996da 100644
--- a/storage/innobase/include/buf0buf.h
+++ b/storage/innobase/include/buf0buf.h
@@ -267,18 +267,8 @@ public:
m_fold = src.fold();
}
- /** Reset the values from a (space, page_no).
- @param[in] space tablespace id
- @param[in] page_no page number */
- inline void reset(ulint space, ulint page_no)
- {
- m_space = static_cast<ib_uint32_t>(space);
- m_page_no = static_cast<ib_uint32_t>(page_no);
- m_fold = ULINT_UNDEFINED;
-
- ut_ad(space <= 0xFFFFFFFFU);
- ut_ad(page_no <= 0xFFFFFFFFU);
- }
+ /** Reset the object. */
+ void reset() { m_space= ~0U; m_page_no= ~0U; m_fold= ULINT_UNDEFINED; }
/** Reset the page number only.
@param[in] page_no page number */
diff --git a/storage/innobase/include/buf0flu.h b/storage/innobase/include/buf0flu.h
index 76fa65c70f4..198f122e5a4 100644
--- a/storage/innobase/include/buf0flu.h
+++ b/storage/innobase/include/buf0flu.h
@@ -345,12 +345,12 @@ flushed to disk before any redo logged operations go to the index. */
class FlushObserver {
public:
/** Constructor
- @param[in] space_id table space id
+ @param[in,out] space tablespace
@param[in] trx trx instance
@param[in] stage performance schema accounting object,
used by ALTER TABLE. It is passed to log_preflush_pool_modified_pages()
for accounting. */
- FlushObserver(ulint space_id, trx_t* trx, ut_stage_alter_t* stage);
+ FlushObserver(fil_space_t* space, trx_t* trx, ut_stage_alter_t* stage);
/** Deconstructor */
~FlushObserver();
@@ -397,8 +397,8 @@ public:
buf_pool_t* buf_pool,
buf_page_t* bpage);
private:
- /** Table space id */
- const ulint m_space_id;
+ /** Tablespace */
+ fil_space_t* m_space;
/** Trx instance */
trx_t* const m_trx;
diff --git a/storage/innobase/include/buf0lru.h b/storage/innobase/include/buf0lru.h
index f6a7695a2b5..547a09ae319 100644
--- a/storage/innobase/include/buf0lru.h
+++ b/storage/innobase/include/buf0lru.h
@@ -33,6 +33,7 @@ Created 11/5/1995 Heikki Tuuri
// Forward declaration
struct trx_t;
+struct fil_space_t;
/******************************************************************//**
Returns TRUE if less than 25 % of the buffer pool is available. This can be
diff --git a/storage/innobase/include/dict0crea.h b/storage/innobase/include/dict0crea.h
index 64bab80b6e0..dc48aa59809 100644
--- a/storage/innobase/include/dict0crea.h
+++ b/storage/innobase/include/dict0crea.h
@@ -144,22 +144,6 @@ dict_create_index_tree_in_mem(
dict_index_t* index, /*!< in/out: index */
const trx_t* trx); /*!< in: InnoDB transaction handle */
-/*******************************************************************//**
-Truncates the index tree but don't update SYSTEM TABLES.
-@return DB_SUCCESS or error */
-dberr_t
-dict_truncate_index_tree_in_mem(
-/*============================*/
- dict_index_t* index); /*!< in/out: index */
-
-/*******************************************************************//**
-Drops the index tree but don't update SYS_INDEXES table. */
-void
-dict_drop_index_tree_in_mem(
-/*========================*/
- const dict_index_t* index, /*!< in: index */
- ulint page_no);/*!< in: index page-no */
-
/****************************************************************//**
Creates the foreign key constraints system tables inside InnoDB
at server bootstrap or server start if they are not found or are
diff --git a/storage/innobase/include/dict0dict.h b/storage/innobase/include/dict0dict.h
index c503a3f0bce..af8684ff08d 100644
--- a/storage/innobase/include/dict0dict.h
+++ b/storage/innobase/include/dict0dict.h
@@ -986,14 +986,8 @@ ulint
dict_table_extent_size(
const dict_table_t* table);
-/** Get the table page size.
-@param[in] table table
-@return compressed page size, or 0 if not compressed */
-UNIV_INLINE
-const page_size_t
-dict_table_page_size(
- const dict_table_t* table)
- MY_ATTRIBUTE((warn_unused_result));
+/** Get the table page size. */
+#define dict_table_page_size(table) page_size_t(table->space->flags)
/*********************************************************************//**
Obtain exclusive locks on all index trees of the table. This is to prevent
@@ -1419,15 +1413,6 @@ dict_index_build_data_tuple(
MY_ATTRIBUTE((nonnull, warn_unused_result));
/*********************************************************************//**
-Gets the space id of the root of the index tree.
-@return space id */
-UNIV_INLINE
-ulint
-dict_index_get_space(
-/*=================*/
- const dict_index_t* index) /*!< in: index */
- MY_ATTRIBUTE((nonnull, warn_unused_result));
-/*********************************************************************//**
Gets the page number of the root of the index tree.
@return page number */
UNIV_INLINE
@@ -1819,18 +1804,10 @@ dict_set_corrupted_index_cache_only(
Flags a table with specified space_id corrupted in the table dictionary
cache.
@return TRUE if successful */
-ibool
-dict_set_corrupted_by_space(
-/*========================*/
- ulint space_id); /*!< in: space ID */
+bool dict_set_corrupted_by_space(const fil_space_t* space);
-/** Flag a table with specified space_id encrypted in the data dictionary
-cache
-@param[in] space_id Tablespace id */
-UNIV_INTERN
-void
-dict_set_encrypted_by_space(
- ulint space_id);
+/** Flag a table encrypted in the data dictionary cache. */
+void dict_set_encrypted_by_space(const fil_space_t* space);
/** Sets merge_threshold in the SYS_INDEXES
@param[in,out] index index
diff --git a/storage/innobase/include/dict0dict.ic b/storage/innobase/include/dict0dict.ic
index 0787017317e..01710a0e93a 100644
--- a/storage/innobase/include/dict0dict.ic
+++ b/storage/innobase/include/dict0dict.ic
@@ -860,20 +860,6 @@ dict_tf_get_page_size(
return(page_size_t(zip_size, univ_page_size.logical(), true));
}
-/** Get the table page size.
-@param[in] table table
-@return a structure containing the compressed and uncompressed
-page sizes and a boolean indicating if the page is compressed */
-UNIV_INLINE
-const page_size_t
-dict_table_page_size(
- const dict_table_t* table)
-{
- ut_ad(table != NULL);
-
- return(dict_tf_get_page_size(table->flags));
-}
-
/*********************************************************************//**
Obtain exclusive locks on all index trees of the table. This is to prevent
accessing index trees while InnoDB is updating internal metadata for
@@ -1162,21 +1148,6 @@ dict_index_get_min_size(
}
/*********************************************************************//**
-Gets the space id of the root of the index tree.
-@return space id */
-UNIV_INLINE
-ulint
-dict_index_get_space(
-/*=================*/
- const dict_index_t* index) /*!< in: index */
-{
- ut_ad(index);
- ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
-
- return(index->table->space);
-}
-
-/*********************************************************************//**
Gets the page number of the root of the index tree.
@return page number */
UNIV_INLINE
@@ -1479,8 +1450,8 @@ bool
dict_table_is_file_per_table(
const dict_table_t* table) /*!< in: table to check */
{
- bool is_file_per_table =
- !is_system_tablespace(table->space);
+ bool is_file_per_table = table->space != fil_system.sys_space
+ && table->space != fil_system.temp_space;
/* If the table is file-per-table and it is not redundant, then
it should have the flags2 bit for DICT_TF2_USE_FILE_PER_TABLE. */
diff --git a/storage/innobase/include/dict0load.h b/storage/innobase/include/dict0load.h
index 9ba42007568..8256ebb24cd 100644
--- a/storage/innobase/include/dict0load.h
+++ b/storage/innobase/include/dict0load.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation.
+Copyright (c) 2017, 2018, 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
@@ -57,15 +57,6 @@ enum dict_system_id_t {
SYS_NUM_SYSTEM_TABLES
};
-/** Status bit for dict_process_sys_tables_rec_and_mtr_commit() */
-enum dict_table_info_t {
- DICT_TABLE_LOAD_FROM_RECORD = 0,/*!< Directly populate a dict_table_t
- structure with information from
- a SYS_TABLES record */
- DICT_TABLE_LOAD_FROM_CACHE = 1 /*!< Check first whether dict_table_t
- is in the cache, if so, return it */
-};
-
/** Check each tablespace found in the data dictionary.
Look at each table defined in SYS_TABLES that has a space_id > 0.
If the tablespace is not yet in the fil_system cache, look up the
@@ -201,10 +192,7 @@ dict_process_sys_tables_rec_and_mtr_commit(
mem_heap_t* heap, /*!< in: temporary memory heap */
const rec_t* rec, /*!< in: SYS_TABLES record */
dict_table_t** table, /*!< out: dict_table_t to fill */
- dict_table_info_t status, /*!< in: status bit controls
- options such as whether we shall
- look for dict_table_t from cache
- first */
+ bool cached, /*!< in: whether to load from cache */
mtr_t* mtr); /*!< in/out: mini-transaction,
will be committed */
/********************************************************************//**
diff --git a/storage/innobase/include/dict0mem.h b/storage/innobase/include/dict0mem.h
index 01755787bb7..abb2e6aaa15 100644
--- a/storage/innobase/include/dict0mem.h
+++ b/storage/innobase/include/dict0mem.h
@@ -306,8 +306,7 @@ dict_table_t*
dict_mem_table_create(
/*==================*/
const char* name, /*!< in: table name */
- ulint space, /*!< in: space where the clustered index
- of the table is placed */
+ fil_space_t* space, /*!< in: tablespace */
ulint n_cols, /*!< in: total number of columns
including virtual and non-virtual
columns */
@@ -545,36 +544,6 @@ private:
const char* m_name;
};
-/** Table name wrapper for pretty-printing */
-struct table_name_t
-{
- /** The name in internal representation */
- char* m_name;
-
- /** @return the end of the schema name */
- const char* dbend() const
- {
- const char* sep = strchr(m_name, '/');
- ut_ad(sep);
- return sep;
- }
-
- /** @return the length of the schema name, in bytes */
- size_t dblen() const { return dbend() - m_name; }
-
- /** Determine the filename-safe encoded table name.
- @return the filename-safe encoded table name */
- const char* basename() const { return dbend() + 1; }
-
- /** The start of the table basename suffix for partitioned tables */
- static const char part_suffix[4];
-
- /** Determine the partition or subpartition name suffix.
- @return the partition name
- @retval NULL if the table is not partitioned */
- const char* part() const { return strstr(basename(), part_suffix); }
-};
-
/** Data structure for a column in a table */
struct dict_col_t{
/*----------------------*/
@@ -1494,6 +1463,7 @@ struct dict_table_t {
page cannot be read or decrypted */
bool is_readable() const
{
+ ut_ad(file_unreadable || space);
return(UNIV_LIKELY(!file_unreadable));
}
@@ -1573,8 +1543,10 @@ struct dict_table_t {
/** NULL or the directory path specified by DATA DIRECTORY. */
char* data_dir_path;
- /** Space where the clustered index of the table is placed. */
- uint32_t space;
+ /** The tablespace of the table */
+ fil_space_t* space;
+ /** Tablespace ID */
+ ulint space_id;
/** Stores information about:
1 row format (redundant or compact),
diff --git a/storage/innobase/include/dict0types.h b/storage/innobase/include/dict0types.h
index 6984351cc06..f9ecf9b341d 100644
--- a/storage/innobase/include/dict0types.h
+++ b/storage/innobase/include/dict0types.h
@@ -99,6 +99,36 @@ typedef ib_mutex_t DictSysMutex;
#define TEMP_TABLE_PREFIX "#sql"
#define TEMP_TABLE_PATH_PREFIX "/" TEMP_TABLE_PREFIX
+/** Table name wrapper for pretty-printing */
+struct table_name_t
+{
+ /** The name in internal representation */
+ char* m_name;
+
+ /** @return the end of the schema name */
+ const char* dbend() const
+ {
+ const char* sep = strchr(m_name, '/');
+ ut_ad(sep);
+ return sep;
+ }
+
+ /** @return the length of the schema name, in bytes */
+ size_t dblen() const { return dbend() - m_name; }
+
+ /** Determine the filename-safe encoded table name.
+ @return the filename-safe encoded table name */
+ const char* basename() const { return dbend() + 1; }
+
+ /** The start of the table basename suffix for partitioned tables */
+ static const char part_suffix[4];
+
+ /** Determine the partition or subpartition name suffix.
+ @return the partition name
+ @retval NULL if the table is not partitioned */
+ const char* part() const { return strstr(basename(), part_suffix); }
+};
+
#if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG
/** Flag to control insert buffer debugging. */
extern uint ibuf_debug;
diff --git a/storage/innobase/include/fil0fil.h b/storage/innobase/include/fil0fil.h
index c111a0ef647..e4d803370ae 100644
--- a/storage/innobase/include/fil0fil.h
+++ b/storage/innobase/include/fil0fil.h
@@ -109,7 +109,8 @@ struct fil_space_t {
ulint redo_skipped_count;
/*!< reference count for operations who want
to skip redo log in the file space in order
- to make fsp_space_modify_check pass. */
+ to make fsp_space_modify_check pass.
+ Uses my_atomic_loadlint() and friends. */
#endif
fil_type_t purpose;/*!< purpose */
UT_LIST_BASE_NODE_T(fil_node_t) chain;
@@ -181,10 +182,6 @@ struct fil_space_t {
/** True if the device this filespace is on supports atomic writes */
bool atomic_write_supported;
- /** Release the reserved free extents.
- @param[in] n_reserved number of reserved extents */
- void release_free_extents(ulint n_reserved);
-
/** True if file system storing this tablespace supports
punch hole */
bool punch_hole;
@@ -205,6 +202,44 @@ struct fil_space_t {
&& srv_use_doublewrite_buf && buf_dblwr;
}
+ /** Try to reserve free extents.
+ @param[in] n_free_now current number of free extents
+ @param[in] n_to_reserve number of extents to reserve
+ @return whether the reservation succeeded */
+ bool reserve_free_extents(ulint n_free_now, ulint n_to_reserve)
+ {
+ ut_ad(rw_lock_own(&latch, RW_LOCK_X));
+ if (n_reserved_extents + n_to_reserve > n_free_now) {
+ return false;
+ }
+
+ n_reserved_extents += n_to_reserve;
+ return true;
+ }
+
+ /** Release the reserved free extents.
+ @param[in] n_reserved number of reserved extents */
+ void release_free_extents(ulint n_reserved)
+ {
+ if (!n_reserved) return;
+ ut_ad(rw_lock_own(&latch, RW_LOCK_X));
+ ut_a(n_reserved_extents >= n_reserved);
+ n_reserved_extents -= n_reserved;
+ }
+
+ /** Rename a file.
+ @param[in] name table name after renaming
+ @param[in] path tablespace file name after renaming
+ @param[in] log whether to write redo log
+ @return error code
+ @retval DB_SUCCESS on success */
+ dberr_t rename(const char* name, const char* path, bool log);
+
+ /** Note that the tablespace has been imported.
+ Initially, purpose=FIL_TYPE_IMPORT so that no redo log is
+ written while the space ID is being updated in each page. */
+ void set_imported();
+
/** Open each file. Only invoked on fil_system.temp_space.
@return whether all files were opened */
bool open();
@@ -586,16 +621,6 @@ fil_space_get_latch(
ulint id,
ulint* flags);
-/** Note that a tablespace has been imported.
-It is initially marked as FIL_TYPE_IMPORT so that no logging is
-done during the import process when the space ID is stamped to each page.
-Now we change it to FIL_SPACE_TABLESPACE to start redo and undo logging.
-NOTE: temporary tablespaces are never imported.
-@param[in] id tablespace identifier */
-void
-fil_space_set_imported(
- ulint id);
-
/** Append a file to the chain of files of a space.
@param[in] name file name of a file that is not open
@param[in] size file size in entire database blocks
@@ -657,16 +682,6 @@ fil_space_free(
ulint id,
bool x_latched);
-/** Returns the path from the first fil_node_t found with this space ID.
-The caller is responsible for freeing the memory allocated here for the
-value returned.
-@param[in] id Tablespace ID
-@return own: A copy of fil_node_t::path, NULL if space ID is zero
-or not found. */
-char*
-fil_space_get_first_path(
- ulint id);
-
/** Set the recovered size of a tablespace in pages.
@param id tablespace ID
@param size recovered size in pages */
@@ -821,68 +836,6 @@ fil_space_keyrotate_next(
fil_space_t* prev_space)
MY_ATTRIBUTE((warn_unused_result));
-/** Wrapper with reference-counting for a fil_space_t. */
-class FilSpace
-{
-public:
- /** Default constructor: Use this when reference counting
- is done outside this wrapper. */
- FilSpace() : m_space(NULL) {}
-
- /** Constructor: Look up the tablespace and increment the
- reference count if found.
- @param[in] space_id tablespace ID
- @param[in] silent whether not to display errors */
- explicit FilSpace(ulint space_id, bool silent = false)
- : m_space(fil_space_acquire_low(space_id, silent)) {}
-
- /** Assignment operator: This assumes that fil_space_acquire()
- has already been done for the fil_space_t. The caller must
- assign NULL if it calls fil_space_release().
- @param[in] space tablespace to assign */
- class FilSpace& operator=(fil_space_t* space)
- {
- /* fil_space_acquire() must have been invoked. */
- ut_ad(space == NULL || space->n_pending_ops > 0);
- m_space = space;
- return(*this);
- }
-
- /** Destructor - Decrement the reference count if a fil_space_t
- is still assigned. */
- ~FilSpace()
- {
- if (m_space != NULL) {
- fil_space_release(m_space);
- }
- }
-
- /** Implicit type conversion
- @return the wrapped object */
- operator const fil_space_t*() const
- {
- return(m_space);
- }
-
- /** Member accessor
- @return the wrapped object */
- const fil_space_t* operator->() const
- {
- return(m_space);
- }
-
- /** Explicit type conversion
- @return the wrapped object */
- const fil_space_t* operator()() const
- {
- return(m_space);
- }
-
-private:
- /** The wrapped pointer */
- fil_space_t* m_space;
-};
-
/********************************************************//**
Creates the database directory for a table if it does not exist yet. */
void
@@ -890,15 +843,6 @@ fil_create_directory_for_tablename(
/*===============================*/
const char* name); /*!< in: name in the standard
'databasename/tablename' format */
-/** Write redo log for renaming a file.
-@param[in] space_id tablespace id
-@param[in] old_name tablespace file name
-@param[in] new_name tablespace file name after renaming */
-void
-fil_name_write_rename(
- ulint space_id,
- const char* old_name,
- const char* new_name);
/** Replay a file rename operation if possible.
@param[in] space_id tablespace identifier
@param[in] first_page_no first page number in the file
@@ -938,13 +882,10 @@ fil_delete_tablespace(
);
/** Truncate the tablespace to needed size.
-@param[in] space_id id of tablespace to truncate
+@param[in,out] space tablespace truncate
@param[in] size_in_pages truncate size.
@return true if truncate was successful. */
-bool
-fil_truncate_tablespace(
- ulint space_id,
- ulint size_in_pages);
+bool fil_truncate_tablespace(fil_space_t* space, ulint size_in_pages);
/*******************************************************************//**
Prepare for truncating a single-table tablespace. The tablespace
@@ -967,36 +908,6 @@ fil_close_tablespace(
trx_t* trx, /*!< in/out: Transaction covering the close */
ulint id); /*!< in: space id */
-/** 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);
-
-/** Rename a single-table tablespace.
-The tablespace must exist in the memory cache.
-@param[in] id tablespace identifier
-@param[in] old_path old file name
-@param[in] new_name new table name in the
-databasename/tablename format
-@param[in] new_path_in new file name,
-or NULL if it is located in the normal data directory
-@return true if success */
-bool
-fil_rename_tablespace(
- ulint id,
- const char* old_path,
- const char* new_name,
- const char* new_path_in);
-
/*******************************************************************//**
Allocates and builds a file name from a path, a table or tablespace name
and a suffix. The string must be freed by caller with ut_free().
@@ -1066,19 +977,22 @@ statement to update the dictionary tables if they are incorrect.
@param[in] purpose FIL_TYPE_TABLESPACE or FIL_TYPE_TEMPORARY
@param[in] id tablespace ID
@param[in] flags expected FSP_SPACE_FLAGS
-@param[in] space_name tablespace name of the datafile
+@param[in] tablename table name
If file-per-table, it is the table name in the databasename/tablename format
@param[in] path_in expected filepath, usually read from dictionary
-@return DB_SUCCESS or error code */
-dberr_t
+@param[out] err DB_SUCCESS or error code
+@return tablespace
+@retval NULL if the tablespace could not be opened */
+fil_space_t*
fil_ibd_open(
- bool validate,
- bool fix_dict,
- fil_type_t purpose,
- ulint id,
- ulint flags,
- const char* tablename,
- const char* path_in)
+ bool validate,
+ bool fix_dict,
+ fil_type_t purpose,
+ ulint id,
+ ulint flags,
+ const table_name_t& tablename,
+ const char* path_in,
+ dberr_t* err = NULL)
MY_ATTRIBUTE((warn_unused_result));
enum fil_load_status {
@@ -1128,15 +1042,14 @@ startup, there may be many tablespaces which are not yet in the memory cache.
@param[in] print_error_if_does_not_exist
Print detailed error information to the
error log if a matching tablespace is not found from memory.
-@param[in] heap Heap memory
@param[in] table_flags table flags
-@return true if a matching tablespace exists in the memory cache */
-bool
+@return the tablespace
+@retval NULL if no matching tablespace exists in the memory cache */
+fil_space_t*
fil_space_for_table_exists_in_mem(
ulint id,
const char* name,
bool print_error_if_does_not_exist,
- mem_heap_t* heap,
ulint table_flags);
/** Try to extend a tablespace if it is smaller than the specified size.
@@ -1147,22 +1060,6 @@ bool
fil_space_extend(
fil_space_t* space,
ulint size);
-/*******************************************************************//**
-Tries to reserve free extents in a file space.
-@return true if succeed */
-bool
-fil_space_reserve_free_extents(
-/*===========================*/
- ulint id, /*!< in: space id */
- ulint n_free_now, /*!< in: number of free extents now */
- ulint n_to_reserve); /*!< in: how many one wants to reserve */
-/*******************************************************************//**
-Releases free extents in a file space. */
-void
-fil_space_release_free_extents(
-/*===========================*/
- ulint id, /*!< in: space id */
- ulint n_reserved); /*!< in: how many one reserved */
/** Reads or writes data. This operation could be asynchronous (aio).
@@ -1318,20 +1215,6 @@ Any other pages were written with uninitialized bytes in FIL_PAGE_TYPE.
#define fil_block_check_type(block, type, mtr) \
fil_page_check_type(block->page.id, block->frame, type, mtr)
-#ifdef UNIV_DEBUG
-/** Increase redo skipped of a tablespace.
-@param[in] id space id */
-void
-fil_space_inc_redo_skipped_count(
- ulint id);
-
-/** Decrease redo skipped of a tablespace.
-@param[in] id space id */
-void
-fil_space_dec_redo_skipped_count(
- ulint id);
-#endif
-
/********************************************************************//**
Delete the tablespace file and any related files like .cfg.
This should not be called for temporary tables. */
diff --git a/storage/innobase/include/fsp0fsp.h b/storage/innobase/include/fsp0fsp.h
index e1bd0a5ce6e..888020c8f85 100644
--- a/storage/innobase/include/fsp0fsp.h
+++ b/storage/innobase/include/fsp0fsp.h
@@ -393,36 +393,21 @@ Creates a new segment.
if could not create segment because of lack of space */
buf_block_t*
fseg_create(
-/*========*/
- ulint space_id,/*!< in: space id */
+ fil_space_t* space, /*!< in,out: tablespace */
ulint page, /*!< in: page where the segment header is placed: if
this is != 0, the page must belong to another segment,
if this is 0, a new page will be allocated and it
will belong to the created segment */
ulint byte_offset, /*!< in: byte offset of the created segment header
on the page */
- mtr_t* mtr); /*!< in/out: mini-transaction */
-/**********************************************************************//**
-Creates a new segment.
-@return the block where the segment header is placed, x-latched, NULL
-if could not create segment because of lack of space */
-buf_block_t*
-fseg_create_general(
-/*================*/
- ulint space_id,/*!< in: space id */
- ulint page, /*!< in: page where the segment header is placed: if
- this is != 0, the page must belong to another segment,
- if this is 0, a new page will be allocated and it
- will belong to the created segment */
- ulint byte_offset, /*!< in: byte offset of the created segment header
- on the page */
- ibool has_done_reservation, /*!< in: TRUE if the caller has already
- done the reservation for the pages with
+ mtr_t* mtr,
+ bool has_done_reservation = false); /*!< in: whether the caller
+ has already done the reservation for the pages with
fsp_reserve_free_extents (at least 2 extents: one for
the inode and the other for the segment) then there is
no need to do the check for this individual
operation */
- mtr_t* mtr); /*!< in/out: mini-transaction */
+
/**********************************************************************//**
Calculates the number of pages reserved by a segment, and how many pages are
currently used.
@@ -484,7 +469,7 @@ fseg_alloc_free_page_general(
use several pages from the tablespace should call this function beforehand
and reserve enough free extents so that they certainly will be able
to do their operation, like a B-tree page split, fully. Reservations
-must be released with function fil_space_release_free_extents!
+must be released with function fil_space_t::release_free_extents()!
The alloc_type below has the following meaning: FSP_NORMAL means an
operation which will probably result in more space usage, like an
@@ -510,7 +495,7 @@ free pages available.
return true and the tablespace size is <
FSP_EXTENT_SIZE pages, then this can be 0,
otherwise it is n_ext
-@param[in] space_id tablespace identifier
+@param[in,out] space tablespace
@param[in] n_ext number of extents to reserve
@param[in] alloc_type page reservation type (FSP_BLOB, etc)
@param[in,out] mtr the mini transaction
@@ -521,7 +506,7 @@ free pages available.
bool
fsp_reserve_free_extents(
ulint* n_reserved,
- ulint space_id,
+ fil_space_t* space,
ulint n_ext,
fsp_reserve_t alloc_type,
mtr_t* mtr,
diff --git a/storage/innobase/include/fsp0sysspace.h b/storage/innobase/include/fsp0sysspace.h
index efbd4fc3f24..de83e64d285 100644
--- a/storage/innobase/include/fsp0sysspace.h
+++ b/storage/innobase/include/fsp0sysspace.h
@@ -33,14 +33,6 @@ Created 2013-7-26 by Kevin Lewis
at a time. We have to make this public because it is a config variable. */
extern ulong sys_tablespace_auto_extend_increment;
-#ifdef UNIV_DEBUG
-/** Control if extra debug checks need to be done for temporary tablespace.
-Default = true that is disable such checks.
-This variable is not exposed to end-user but still kept as variable for
-developer to enable it during debug. */
-extern bool srv_skip_temp_table_checks_debug;
-#endif /* UNIV_DEBUG */
-
/** Data structure that contains the information about shared tablespaces.
Currently this can be the system tablespace or a temporary table tablespace */
class SysTablespace : public Tablespace
diff --git a/storage/innobase/include/fsp0types.h b/storage/innobase/include/fsp0types.h
index c6b81986320..080311e010c 100644
--- a/storage/innobase/include/fsp0types.h
+++ b/storage/innobase/include/fsp0types.h
@@ -196,17 +196,6 @@ fsp_is_system_temporary(ulint space_id)
{
return(space_id == SRV_TMP_SPACE_ID);
}
-
-#ifdef UNIV_DEBUG
-/** Skip some of the sanity checks that are time consuming even in debug mode
-and can affect frequent verification runs that are done to ensure stability of
-the product.
-@return true if check should be skipped for given space. */
-bool
-fsp_skip_sanity_check(
- ulint space_id);
-#endif /* UNIV_DEBUG */
-
#endif /* !UNIV_INNOCHECKSUM */
/* @defgroup fsp_flags InnoDB Tablespace Flag Constants @{ */
diff --git a/storage/innobase/include/ibuf0ibuf.h b/storage/innobase/include/ibuf0ibuf.h
index 6cff26635bd..446000a39de 100644
--- a/storage/innobase/include/ibuf0ibuf.h
+++ b/storage/innobase/include/ibuf0ibuf.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2016, 2017, MariaDB Corporation.
+Copyright (c) 2016, 2018, 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
@@ -421,14 +421,11 @@ void
ibuf_close(void);
/*============*/
-/******************************************************************//**
-Checks the insert buffer bitmaps on IMPORT TABLESPACE.
+/** Check the insert buffer bitmaps on IMPORT TABLESPACE.
+@param[in] trx transaction
+@param[in,out] space tablespace being imported
@return DB_SUCCESS or error code */
-dberr_t
-ibuf_check_bitmap_on_import(
-/*========================*/
- const trx_t* trx, /*!< in: transaction */
- ulint space_id) /*!< in: tablespace identifier */
+dberr_t ibuf_check_bitmap_on_import(const trx_t* trx, fil_space_t* space)
MY_ATTRIBUTE((nonnull, warn_unused_result));
/** Updates free bits and buffered bits for bulk loaded page.
diff --git a/storage/innobase/include/mtr0mtr.h b/storage/innobase/include/mtr0mtr.h
index 20d9d2066a0..79ff7638ab7 100644
--- a/storage/innobase/include/mtr0mtr.h
+++ b/storage/innobase/include/mtr0mtr.h
@@ -212,13 +212,6 @@ struct mtr_t {
~mtr_t() { }
- /** Release the free extents that was reserved using
- fsp_reserve_free_extents(). This is equivalent to calling
- fil_space_release_free_extents(). This is intended for use
- with index pages.
- @param[in] n_reserved number of reserved extents */
- void release_free_extents(ulint n_reserved);
-
/** Start a mini-transaction.
@param sync true if it is a synchronous mini-transaction
@param read_only true if read only mini-transaction */
@@ -308,7 +301,7 @@ struct mtr_t {
(needed for generating a MLOG_FILE_NAME record)
@param[in] space_id user or system tablespace ID
@return the tablespace */
- fil_space_t* set_named_space(ulint space_id)
+ fil_space_t* set_named_space_id(ulint space_id)
{
ut_ad(!m_impl.m_user_space_id);
ut_d(m_impl.m_user_space_id = space_id);
@@ -341,6 +334,11 @@ struct mtr_t {
@param[in] space tablespace
@return whether the mini-transaction is associated with the space */
bool is_named_space(ulint space) const;
+ /** Check the tablespace associated with the mini-transaction
+ (needed for generating a MLOG_FILE_NAME record)
+ @param[in] space tablespace
+ @return whether the mini-transaction is associated with the space */
+ bool is_named_space(const fil_space_t* space) const;
#endif /* UNIV_DEBUG */
/** Read 1 - 4 bytes from a file page buffered in the buffer pool.
diff --git a/storage/innobase/include/row0import.h b/storage/innobase/include/row0import.h
index c6dfca9d7e8..5eb5425b983 100644
--- a/storage/innobase/include/row0import.h
+++ b/storage/innobase/include/row0import.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2012, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation.
+Copyright (c) 2017, 2018, 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
@@ -47,21 +47,13 @@ row_import_for_mysql(
in MySQL */
MY_ATTRIBUTE((nonnull, warn_unused_result));
-/*****************************************************************//**
-Update the DICT_TF2_DISCARDED flag in SYS_TABLES.
-@return DB_SUCCESS or error code. */
-dberr_t
-row_import_update_discarded_flag(
-/*=============================*/
- trx_t* trx, /*!< in/out: transaction that
- covers the update */
- table_id_t table_id, /*!< in: Table for which we want
- to set the root table->flags2 */
- bool discarded, /*!< in: set MIX_LEN column bit
- to discarded, if true */
- bool dict_locked) /*!< in: Set to true if the
- caller already owns the
- dict_sys_t:: mutex. */
+/** Update the DICT_TF2_DISCARDED flag in SYS_TABLES.MIX_LEN.
+@param[in,out] trx dictionary transaction
+@param[in] table_id table identifier
+@param[in] discarded whether to set or clear the flag
+@return DB_SUCCESS or error code */
+dberr_t row_import_update_discarded_flag(trx_t* trx, table_id_t table_id,
+ bool discarded)
MY_ATTRIBUTE((nonnull, warn_unused_result));
/*****************************************************************//**
diff --git a/storage/innobase/include/row0row.h b/storage/innobase/include/row0row.h
index eb6690d1e0d..4f329f0d675 100644
--- a/storage/innobase/include/row0row.h
+++ b/storage/innobase/include/row0row.h
@@ -398,7 +398,7 @@ row_mtr_start(mtr_t* mtr, dict_index_t* index, bool pessimistic)
{
mtr->start();
- switch (index->table->space) {
+ switch (index->table->space->id) {
case IBUF_SPACE_ID:
if (pessimistic
&& !(index->type & (DICT_UNIQUE | DICT_SPATIAL))) {
diff --git a/storage/innobase/include/row0trunc.h b/storage/innobase/include/row0trunc.h
index 5f7b499502c..94b6b7046b4 100644
--- a/storage/innobase/include/row0trunc.h
+++ b/storage/innobase/include/row0trunc.h
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 2013, 2015, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2018, 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
@@ -181,9 +182,7 @@ public:
/** 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] page_size page size of the .ibd file
+ @param[in,out] space tablespace
@param[in] index_type type of index to truncate
@param[in] index_id id of index to truncate
@param[in] btr_redo_create_info control info for ::btr_create()
@@ -192,8 +191,7 @@ public:
@return root page no or FIL_NULL on failure */
inline ulint 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,
@@ -202,31 +200,27 @@ public:
/** 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 create_indexes(
const char* table_name,
- ulint space_id,
- const page_size_t& page_size,
- ulint flags,
+ fil_space_t* space,
ulint format_flags);
/** Check if index has been modified since TRUNCATE log snapshot
was recorded.
- @param space_id space_id where table/indexes resides.
+ @param[in] space tablespace
+ @param[in] root_page_no index root page number
@return true if modified else false */
- bool is_index_modified_since_logged(
- ulint space_id,
- ulint root_page_no) const;
+ inline bool is_index_modified_since_logged(
+ const fil_space_t* space,
+ ulint root_page_no) const;
/** Drop indexes for a table.
- @param space_id space_id where table/indexes resides.
+ @param[in,out] space tablespace
@return DB_SUCCESS or error code. */
- void drop_indexes(ulint space_id) const;
+ void drop_indexes(fil_space_t* space) const;
/**
Parses log record during recovery
diff --git a/storage/innobase/include/trx0rseg.h b/storage/innobase/include/trx0rseg.h
index ff8e8c864cf..65e5124a2db 100644
--- a/storage/innobase/include/trx0rseg.h
+++ b/storage/innobase/include/trx0rseg.h
@@ -69,17 +69,17 @@ ulint
trx_rsegf_undo_find_free(const trx_rsegf_t* rsegf);
/** Create a rollback segment header.
-@param[in] space system, undo, or temporary tablespace
+@param[in,out] space system, undo, or temporary tablespace
@param[in] rseg_id rollback segment identifier
@param[in,out] sys_header the TRX_SYS page (NULL for temporary rseg)
@param[in,out] mtr mini-transaction
@return page number of the created segment, FIL_NULL if fail */
ulint
trx_rseg_header_create(
- const fil_space_t* space,
- ulint rseg_id,
- buf_block_t* sys_header,
- mtr_t* mtr);
+ fil_space_t* space,
+ ulint rseg_id,
+ buf_block_t* sys_header,
+ mtr_t* mtr);
/** Initialize the rollback segments in memory at database startup. */
void
diff --git a/storage/innobase/mtr/mtr0log.cc b/storage/innobase/mtr/mtr0log.cc
index 2eb3244e7ab..92ab6466fc3 100644
--- a/storage/innobase/mtr/mtr0log.cc
+++ b/storage/innobase/mtr/mtr0log.cc
@@ -588,7 +588,7 @@ mlog_parse_index(
} else {
n = n_uniq = 1;
}
- table = dict_mem_table_create("LOG_DUMMY", DICT_HDR_SPACE, n, 0,
+ table = dict_mem_table_create("LOG_DUMMY", NULL, n, 0,
comp ? DICT_TF_COMPACT : 0, 0);
ind = dict_mem_index_create(table, "LOG_DUMMY", 0, n);
ind->n_uniq = (unsigned int) n_uniq;
diff --git a/storage/innobase/mtr/mtr0mtr.cc b/storage/innobase/mtr/mtr0mtr.cc
index 7926ac312ef..86540a3bc2d 100644
--- a/storage/innobase/mtr/mtr0mtr.cc
+++ b/storage/innobase/mtr/mtr0mtr.cc
@@ -652,6 +652,28 @@ mtr_t::is_named_space(ulint space) const
ut_error;
return(false);
}
+/** Check if a tablespace is associated with the mini-transaction
+(needed for generating a MLOG_FILE_NAME record)
+@param[in] space tablespace
+@return whether the mini-transaction is associated with the space */
+bool mtr_t::is_named_space(const fil_space_t* space) const
+{
+ ut_ad(!m_impl.m_user_space
+ || m_impl.m_user_space->id != TRX_SYS_SPACE);
+
+ switch (get_log_mode()) {
+ case MTR_LOG_NONE:
+ case MTR_LOG_NO_REDO:
+ return true;
+ case MTR_LOG_ALL:
+ case MTR_LOG_SHORT_INSERTS:
+ return(m_impl.m_user_space == space
+ || is_predefined_tablespace(space->id));
+ }
+
+ ut_error;
+ return false;
+}
#endif /* UNIV_DEBUG */
/** Acquire a tablespace X-latch.
@@ -676,7 +698,7 @@ mtr_t::x_lock_space(ulint space_id, const char* file, unsigned line)
ut_ad(get_log_mode() != MTR_LOG_NO_REDO
|| space->purpose == FIL_TYPE_TEMPORARY
|| space->purpose == FIL_TYPE_IMPORT
- || space->redo_skipped_count > 0
+ || my_atomic_loadlint(&space->redo_skipped_count) > 0
|| srv_is_tablespace_truncated(space->id));
}
@@ -918,29 +940,6 @@ mtr_t::Command::execute()
release_resources();
}
-/** Release the free extents that was reserved using
-fsp_reserve_free_extents(). This is equivalent to calling
-fil_space_release_free_extents(). This is intended for use
-with index pages.
-@param[in] n_reserved number of reserved extents */
-void
-mtr_t::release_free_extents(ulint n_reserved)
-{
- fil_space_t* space;
-
- if (m_impl.m_user_space != NULL) {
- ut_ad(m_impl.m_user_space->id
- == m_impl.m_user_space_id);
- space = m_impl.m_user_space;
- } else {
- space = fil_system.sys_space;
- }
-
- ut_ad(memo_contains(get_memo(), &space->latch, MTR_MEMO_X_LOCK));
-
- space->release_free_extents(n_reserved);
-}
-
#ifdef UNIV_DEBUG
/** Check if memo contains the given item.
@return true if contains */
diff --git a/storage/innobase/page/page0page.cc b/storage/innobase/page/page0page.cc
index 24cdccf4145..c02bdb74ce6 100644
--- a/storage/innobase/page/page0page.cc
+++ b/storage/innobase/page/page0page.cc
@@ -240,7 +240,7 @@ page_set_autoinc(
mtr, block, MTR_MEMO_PAGE_X_FIX | MTR_MEMO_PAGE_SX_FIX));
ut_ad(index->is_primary());
ut_ad(index->page == block->page.id.page_no());
- ut_ad(index->table->space == block->page.id.space());
+ ut_ad(index->table->space->id == block->page.id.space());
byte* field = PAGE_HEADER + PAGE_ROOT_AUTO_INC
+ buf_block_get_frame(block);
diff --git a/storage/innobase/page/page0zip.cc b/storage/innobase/page/page0zip.cc
index 1db1771dfa8..9b6856ff2c5 100644
--- a/storage/innobase/page/page0zip.cc
+++ b/storage/innobase/page/page0zip.cc
@@ -1707,7 +1707,7 @@ page_zip_fields_decode(
return(NULL);
}
- table = dict_mem_table_create("ZIP_DUMMY", DICT_HDR_SPACE, n, 0,
+ table = dict_mem_table_create("ZIP_DUMMY", NULL, n, 0,
DICT_TF_COMPACT, 0);
index = dict_mem_index_create(table, "ZIP_DUMMY", 0, n);
index->n_uniq = unsigned(n);
diff --git a/storage/innobase/pars/pars0pars.cc b/storage/innobase/pars/pars0pars.cc
index 8595f341d26..fbe55d1df03 100644
--- a/storage/innobase/pars/pars0pars.cc
+++ b/storage/innobase/pars/pars0pars.cc
@@ -1915,7 +1915,7 @@ pars_create_table(
n_cols = que_node_list_get_len(column_defs);
table = dict_mem_table_create(
- table_sym->name, 0, n_cols, 0, flags, flags2);
+ table_sym->name, NULL, n_cols, 0, flags, flags2);
mem_heap_t* heap = pars_sym_tab_global->heap;
column = column_defs;
diff --git a/storage/innobase/row/row0ftsort.cc b/storage/innobase/row/row0ftsort.cc
index 49462e8c22c..8edb6a33fea 100644
--- a/storage/innobase/row/row0ftsort.cc
+++ b/storage/innobase/row/row0ftsort.cc
@@ -906,7 +906,7 @@ loop:
merge_file[t_ctx.buf_used]->offset++,
block[t_ctx.buf_used],
crypt_block[t_ctx.buf_used],
- table->space)) {
+ table->space->id)) {
error = DB_TEMP_FILE_WRITE_FAIL;
goto func_exit;
}
@@ -1000,7 +1000,7 @@ exit:
merge_file[i]->offset++,
block[i],
crypt_block[i],
- table->space)) {
+ table->space->id)) {
error = DB_TEMP_FILE_WRITE_FAIL;
goto func_exit;
}
@@ -1038,7 +1038,7 @@ exit:
psort_info->psort_common->dup,
merge_file[i], block[i], &tmpfd[i],
false, 0.0/* pct_progress */, 0.0/* pct_cost */,
- crypt_block[i], table->space);
+ crypt_block[i], table->space->id);
if (error != DB_SUCCESS) {
close(tmpfd[i]);
@@ -1710,7 +1710,7 @@ row_fts_merge_insert(
#ifdef UNIV_DEBUG
ins_ctx.aux_index_id = id;
#endif
- const ulint space = table->space;
+ const ulint space = table->space->id;
for (i = 0; i < fts_sort_pll_degree; i++) {
if (psort_info[i].merge_file[id]->n_rec == 0) {
diff --git a/storage/innobase/row/row0import.cc b/storage/innobase/row/row0import.cc
index 172d35c14c2..806c7ce104f 100644
--- a/storage/innobase/row/row0import.cc
+++ b/storage/innobase/row/row0import.cc
@@ -350,11 +350,11 @@ class AbstractCallback
public:
/** Constructor
@param trx covering transaction */
- AbstractCallback(trx_t* trx)
+ AbstractCallback(trx_t* trx, ulint space_id)
:
m_page_size(0, 0, false),
m_trx(trx),
- m_space(ULINT_UNDEFINED),
+ m_space(space_id),
m_xdes(),
m_xdes_page_no(ULINT_UNDEFINED),
m_space_flags(ULINT_UNDEFINED) UNIV_NOTHROW { }
@@ -412,9 +412,8 @@ public:
os_offset_t offset,
buf_block_t* block) UNIV_NOTHROW = 0;
- /**
- @return the space id of the tablespace */
- virtual ulint get_space_id() const UNIV_NOTHROW = 0;
+ /** @return the tablespace identifier */
+ ulint get_space_id() const { return m_space; }
bool is_interrupted() const { return trx_is_interrupted(m_trx); }
@@ -587,11 +586,12 @@ AbstractCallback::init(
return(DB_CORRUPTION);
}
- ut_a(m_space == ULINT_UNDEFINED);
-
m_size = mach_read_from_4(page + FSP_SIZE);
m_free_limit = mach_read_from_4(page + FSP_FREE_LIMIT);
- m_space = mach_read_from_4(page + FSP_HEADER_OFFSET + FSP_SPACE_ID);
+ if (m_space == ULINT_UNDEFINED) {
+ m_space = mach_read_from_4(FSP_HEADER_OFFSET + FSP_SPACE_ID
+ + page);
+ }
return set_current_xdes(0, page);
}
@@ -620,19 +620,12 @@ struct FetchIndexRootPages : public AbstractCallback {
@param table table definition in server .*/
FetchIndexRootPages(const dict_table_t* table, trx_t* trx)
:
- AbstractCallback(trx),
+ AbstractCallback(trx, ULINT_UNDEFINED),
m_table(table) UNIV_NOTHROW { }
/** Destructor */
virtual ~FetchIndexRootPages() UNIV_NOTHROW { }
- /**
- @retval the space id of the tablespace being iterated over */
- virtual ulint get_space_id() const UNIV_NOTHROW
- {
- return(m_space);
- }
-
/** Called for each block as it is read from the file.
@param offset physical offset in the file
@param block block to convert, it is not from the buffer pool.
@@ -806,8 +799,23 @@ class PageConverter : public AbstractCallback {
public:
/** Constructor
@param cfg config of table being imported.
+ @param space_id tablespace identifier
@param trx transaction covering the import */
- PageConverter(row_import* cfg, trx_t* trx) UNIV_NOTHROW;
+ PageConverter(row_import* cfg, ulint space_id, trx_t* trx)
+ :
+ AbstractCallback(trx, space_id),
+ m_cfg(cfg),
+ m_index(cfg->m_indexes),
+ m_current_lsn(log_get_lsn()),
+ m_page_zip_ptr(0),
+ m_rec_iter(),
+ m_offsets_(), m_offsets(m_offsets_),
+ m_heap(0),
+ m_cluster_index(dict_table_get_first_index(cfg->m_table))
+ {
+ ut_ad(m_current_lsn);
+ rec_offs_init(m_offsets_);
+ }
virtual ~PageConverter() UNIV_NOTHROW
{
@@ -816,13 +824,6 @@ public:
}
}
- /**
- @retval the server space id of the tablespace being iterated over */
- virtual ulint get_space_id() const UNIV_NOTHROW
- {
- return(m_cfg->m_table->space);
- }
-
/** Called for each block as it is read from the file.
@param offset physical offset in the file
@param block block to convert, it is not from the buffer pool.
@@ -1527,28 +1528,6 @@ IndexPurge::purge() UNIV_NOTHROW
btr_pcur_restore_position(BTR_MODIFY_LEAF, &m_pcur, &m_mtr);
}
-/** Constructor
-@param cfg config of table being imported.
-@param trx transaction covering the import */
-inline
-PageConverter::PageConverter(
- row_import* cfg,
- trx_t* trx)
- :
- AbstractCallback(trx),
- m_cfg(cfg),
- m_index(cfg->m_indexes),
- m_current_lsn(log_get_lsn()),
- m_page_zip_ptr(0),
- m_rec_iter(),
- m_offsets_(), m_offsets(m_offsets_),
- m_heap(0),
- m_cluster_index(dict_table_get_first_index(cfg->m_table)) UNIV_NOTHROW
-{
- ut_a(m_current_lsn > 0);
- rec_offs_init(m_offsets_);
-}
-
/** Adjust the BLOB reference for a single column that is externally stored
@param rec record to update
@param offsets column offsets for the record
@@ -2054,8 +2033,10 @@ row_import_discard_changes(
}
table->file_unreadable = true;
-
- fil_close_tablespace(trx, table->space);
+ if (table->space) {
+ fil_close_tablespace(trx, table->space->id);
+ table->space = NULL;
+ }
}
/*****************************************************************//**
@@ -3087,6 +3068,8 @@ row_import_update_index_root(
que_t* graph = 0;
dberr_t err = DB_SUCCESS;
+ ut_ad(reset || table->space->id == table->space_id);
+
static const char sql[] = {
"PROCEDURE UPDATE_INDEX_ROOT() IS\n"
"BEGIN\n"
@@ -3124,7 +3107,7 @@ row_import_update_index_root(
mach_write_to_4(
reinterpret_cast<byte*>(&space),
- reset ? FIL_NULL : index->table->space);
+ reset ? FIL_NULL : index->table->space_id);
mach_write_to_8(
reinterpret_cast<byte*>(&index_id),
@@ -3227,22 +3210,13 @@ row_import_set_discarded(
return(FALSE);
}
-/*****************************************************************//**
-Update the DICT_TF2_DISCARDED flag in SYS_TABLES.
-@return DB_SUCCESS or error code. */
-dberr_t
-row_import_update_discarded_flag(
-/*=============================*/
- trx_t* trx, /*!< in/out: transaction that
- covers the update */
- table_id_t table_id, /*!< in: Table for which we want
- to set the root table->flags2 */
- bool discarded, /*!< in: set MIX_LEN column bit
- to discarded, if true */
- bool dict_locked) /*!< in: set to true if the
- caller already owns the
- dict_sys_t:: mutex. */
-
+/** Update the DICT_TF2_DISCARDED flag in SYS_TABLES.MIX_LEN.
+@param[in,out] trx dictionary transaction
+@param[in] table_id table identifier
+@param[in] discarded whether to set or clear the flag
+@return DB_SUCCESS or error code */
+dberr_t row_import_update_discarded_flag(trx_t* trx, table_id_t table_id,
+ bool discarded)
{
pars_info_t* info;
discard_t discard;
@@ -3281,7 +3255,7 @@ row_import_update_discarded_flag(
pars_info_bind_function(
info, "my_func", row_import_set_discarded, &discard);
- dberr_t err = que_eval_sql(info, sql, !dict_locked, trx);
+ dberr_t err = que_eval_sql(info, sql, false, trx);
ut_a(discard.n_recs == 1);
ut_a(discard.flags2 != ULINT32_UNDEFINED);
@@ -3745,11 +3719,12 @@ row_import_for_mysql(
ut_ad(!srv_read_only_mode);
ut_ad(!dict_table_is_temporary(table));
- ut_a(table->space);
+ ut_ad(table->space_id);
+ ut_ad(table->space_id < SRV_LOG_SPACE_FIRST_ID);
ut_ad(prebuilt->trx);
- ut_a(!table->is_readable());
+ ut_ad(!table->is_readable());
- ibuf_delete_for_discarded_space(table->space);
+ ibuf_delete_for_discarded_space(table->space_id);
trx_start_if_not_started(prebuilt->trx, true);
@@ -3880,7 +3855,7 @@ row_import_for_mysql(
/* Iterate over all the pages and do the sanity checking and
the conversion required to import the tablespace. */
- PageConverter converter(&cfg, trx);
+ PageConverter converter(&cfg, table->space_id, trx);
/* Set the IO buffer size in pages. */
@@ -3941,18 +3916,19 @@ row_import_for_mysql(
have an x-lock on dict_operation_lock and dict_sys->mutex.
The tablespace is initially opened as a temporary one, because
we will not be writing any redo log for it before we have invoked
- fil_space_set_imported() to declare it a persistent tablespace. */
+ fil_space_t::set_imported() to declare it a persistent tablespace. */
ulint fsp_flags = dict_tf_to_fsp_flags(table->flags);
- err = fil_ibd_open(
- true, true, FIL_TYPE_IMPORT, table->space,
- fsp_flags, table->name.m_name, filepath);
+ table->space = fil_ibd_open(
+ true, true, FIL_TYPE_IMPORT, table->space_id,
+ fsp_flags, table->name, filepath, &err);
+ ut_ad(!table->space == (err != DB_SUCCESS));
DBUG_EXECUTE_IF("ib_import_open_tablespace_failure",
- err = DB_TABLESPACE_NOT_FOUND;);
+ err = DB_TABLESPACE_NOT_FOUND; table->space = NULL;);
- if (err != DB_SUCCESS) {
+ if (!table->space) {
row_mysql_unlock_data_dictionary(trx);
ib_senderrf(trx->mysql_thd, IB_LOG_LEVEL_ERROR,
@@ -4048,7 +4024,7 @@ row_import_for_mysql(
{
FlushObserver observer(prebuilt->table->space, trx, NULL);
- buf_LRU_flush_or_remove_pages(prebuilt->table->space,
+ buf_LRU_flush_or_remove_pages(prebuilt->table->space_id,
&observer);
if (observer.is_interrupted()) {
@@ -4059,7 +4035,7 @@ row_import_for_mysql(
}
ib::info() << "Phase IV - Flush complete";
- fil_space_set_imported(prebuilt->table->space);
+ prebuilt->table->space->set_imported();
/* The dictionary latches will be released in in row_import_cleanup()
after the transaction commit, for both success and error. */
@@ -4073,8 +4049,7 @@ row_import_for_mysql(
return(row_import_error(prebuilt, trx, err));
}
- /* Update the table's discarded flag, unset it. */
- err = row_import_update_discarded_flag(trx, table->id, false, true);
+ err = row_import_update_discarded_flag(trx, table->id, false);
if (err != DB_SUCCESS) {
return(row_import_error(prebuilt, trx, err));
diff --git a/storage/innobase/row/row0log.cc b/storage/innobase/row/row0log.cc
index cad36e31f28..82f2b740871 100644
--- a/storage/innobase/row/row0log.cc
+++ b/storage/innobase/row/row0log.cc
@@ -403,7 +403,7 @@ row_log_online_op(
if (!log_tmp_block_encrypt(
buf, srv_sort_buf_size,
log->crypt_tail, byte_offset,
- index->table->space)) {
+ index->table->space->id)) {
log->error = DB_DECRYPTION_FAILED;
goto write_failed;
}
@@ -539,7 +539,7 @@ row_log_table_close_func(
if (!log_tmp_block_encrypt(
log->tail.block, srv_sort_buf_size,
log->crypt_tail, byte_offset,
- index->table->space)) {
+ index->table->space->id)) {
log->error = DB_DECRYPTION_FAILED;
goto err_exit;
}
@@ -2878,7 +2878,7 @@ all_done:
if (!log_tmp_block_decrypt(
buf, srv_sort_buf_size,
index->online_log->crypt_head,
- ofs, index->table->space)) {
+ ofs, index->table->space->id)) {
error = DB_DECRYPTION_FAILED;
goto func_exit;
}
@@ -3745,7 +3745,7 @@ all_done:
if (!log_tmp_block_decrypt(
buf, srv_sort_buf_size,
index->online_log->crypt_head,
- ofs, index->table->space)) {
+ ofs, index->table->space->id)) {
error = DB_DECRYPTION_FAILED;
goto func_exit;
}
diff --git a/storage/innobase/row/row0merge.cc b/storage/innobase/row/row0merge.cc
index 681e57eeb4f..c6d71ac0cbd 100644
--- a/storage/innobase/row/row0merge.cc
+++ b/storage/innobase/row/row0merge.cc
@@ -2529,7 +2529,7 @@ write_buffers:
curr_progress,
pct_cost,
crypt_block,
- new_table->space);
+ new_table->space->id);
if (row == NULL) {
err = clust_btr_bulk->finish(
@@ -2640,7 +2640,7 @@ write_buffers:
curr_progress,
pct_cost,
crypt_block,
- new_table->space);
+ new_table->space->id);
err = btr_bulk.finish(err);
@@ -2674,7 +2674,7 @@ write_buffers:
if (!row_merge_write(
file->fd, file->offset++,
block, crypt_block,
- new_table->space)) {
+ new_table->space->id)) {
err = DB_TEMP_FILE_WRITE_FAIL;
trx->error_key_num = i;
break;
@@ -4313,19 +4313,9 @@ row_make_new_pathname(
dict_table_t* table, /*!< in: table to be renamed */
const char* new_name) /*!< in: new name */
{
- char* new_path;
- char* old_path;
-
- ut_ad(!is_system_tablespace(table->space));
-
- old_path = fil_space_get_first_path(table->space);
- ut_a(old_path);
-
- new_path = os_file_make_new_pathname(old_path, new_name);
-
- ut_free(old_path);
-
- return(new_path);
+ ut_ad(!is_system_tablespace(table->space->id));
+ return os_file_make_new_pathname(table->space->chain.start->name,
+ new_name);
}
/*********************************************************************//**
@@ -4377,8 +4367,7 @@ row_merge_rename_tables_dict(
renamed is a single-table tablespace, which must be implicitly
renamed along with the table. */
if (err == DB_SUCCESS
- && dict_table_is_file_per_table(old_table)
- && fil_space_get(old_table->space) != NULL) {
+ && old_table->space_id) {
/* Make pathname to update SYS_DATAFILES. */
char* tmp_path = row_make_new_pathname(old_table, tmp_name);
@@ -4387,7 +4376,7 @@ row_merge_rename_tables_dict(
pars_info_add_str_literal(info, "tmp_name", tmp_name);
pars_info_add_str_literal(info, "tmp_path", tmp_path);
pars_info_add_int4_literal(info, "old_space",
- (lint) old_table->space);
+ lint(old_table->space_id));
err = que_eval_sql(info,
"PROCEDURE RENAME_OLD_SPACE () IS\n"
@@ -4418,7 +4407,7 @@ row_merge_rename_tables_dict(
old_table->name.m_name);
pars_info_add_str_literal(info, "old_path", old_path);
pars_info_add_int4_literal(info, "new_space",
- (lint) new_table->space);
+ lint(new_table->space_id));
err = que_eval_sql(info,
"PROCEDURE RENAME_NEW_SPACE () IS\n"
@@ -4436,7 +4425,7 @@ row_merge_rename_tables_dict(
if (err == DB_SUCCESS && dict_table_is_discarded(new_table)) {
err = row_import_update_discarded_flag(
- trx, new_table->id, true, true);
+ trx, new_table->id, true);
}
trx->op_info = "";
@@ -4559,7 +4548,7 @@ row_merge_write_redo(
log_ptr = mlog_open(&mtr, 11 + 8);
log_ptr = mlog_write_initial_log_record_low(
MLOG_INDEX_LOAD,
- index->table->space, index->page, log_ptr, &mtr);
+ index->table->space->id, index->page, log_ptr, &mtr);
mach_write_to_8(log_ptr, index->id);
mlog_close(&mtr, log_ptr + 8);
mtr.commit();
@@ -4913,7 +4902,8 @@ wait_again:
trx, &dup, &merge_files[i],
block, &tmpfd, true,
pct_progress, pct_cost,
- crypt_block, new_table->space, stage);
+ crypt_block, new_table->space->id,
+ stage);
pct_progress += pct_cost;
@@ -4956,7 +4946,8 @@ wait_again:
merge_files[i].fd, block, NULL,
&btr_bulk,
merge_files[i].n_rec, pct_progress, pct_cost,
- crypt_block, new_table->space, stage);
+ crypt_block, new_table->space->id,
+ stage);
error = btr_bulk.finish(error);
diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc
index 940206fe9f8..28814eb2876 100644
--- a/storage/innobase/row/row0mysql.cc
+++ b/storage/innobase/row/row0mysql.cc
@@ -1295,7 +1295,7 @@ row_mysql_get_table_status(
bool push_warning = true)
{
dberr_t err;
- if (fil_space_t* space = fil_space_acquire_silent(table->space)) {
+ if (const fil_space_t* space = table->space) {
if (space->crypt_data && space->crypt_data->is_encrypted()) {
// maybe we cannot access the table due to failing
// to decrypt
@@ -1317,8 +1317,6 @@ row_mysql_get_table_status(
err = DB_CORRUPTION;
}
-
- fil_space_release(space);
} else {
ib::error() << ".ibd file is missing for table "
<< table->name;
@@ -2415,18 +2413,10 @@ err_exit:
/* Update SYS_TABLESPACES and SYS_DATAFILES if a new file-per-table
tablespace was created. */
if (err == DB_SUCCESS && dict_table_is_file_per_table(table)) {
-
- ut_ad(dict_table_is_file_per_table(table));
-
- char* path;
- path = fil_space_get_first_path(table->space);
-
err = dict_replace_tablespace_in_dictionary(
- table->space, table->name.m_name,
- fil_space_get_flags(table->space),
- path, trx);
-
- ut_free(path);
+ table->space_id, table->name.m_name,
+ table->space->flags,
+ table->space->chain.start->name, trx);
if (err != DB_SUCCESS) {
@@ -2461,7 +2451,7 @@ err_exit:
/* We already have .ibd file here. it should be deleted. */
if (dict_table_is_file_per_table(table)
- && fil_delete_tablespace(table->space) != DB_SUCCESS) {
+ && fil_delete_tablespace(table->space->id) != DB_SUCCESS) {
ib::error() << "Not able to delete tablespace "
<< table->space << " of table "
@@ -3008,7 +2998,7 @@ row_discard_tablespace_begin(
if (table) {
dict_stats_wait_bg_to_stop_using_table(table, trx);
- ut_a(!is_system_tablespace(table->space));
+ ut_a(!is_system_tablespace(table->space_id));
ut_ad(!table->n_foreign_key_checks_running);
}
@@ -3130,14 +3120,13 @@ row_discard_tablespace(
3) Insert buffer: we remove all entries for the tablespace in
the insert buffer tree. */
- ibuf_delete_for_discarded_space(table->space);
+ ibuf_delete_for_discarded_space(table->space_id);
table_id_t new_id;
/* Set the TABLESPACE DISCARD flag in the table definition
on disk. */
- err = row_import_update_discarded_flag(
- trx, table->id, true, true);
+ err = row_import_update_discarded_flag(trx, table->id, true);
if (err != DB_SUCCESS) {
return(err);
@@ -3167,7 +3156,7 @@ row_discard_tablespace(
}
/* Discard the physical file that is used for the tablespace. */
- err = fil_delete_tablespace(table->space
+ err = fil_delete_tablespace(table->space_id
#ifdef BTR_CUR_HASH_ADAPT
, true
#endif /* BTR_CUR_HASH_ADAPT */
@@ -3191,6 +3180,7 @@ row_discard_tablespace(
data dictionary memory cache. */
table->file_unreadable = true;
+ table->space = NULL;
table->flags2 |= DICT_TF2_DISCARDED;
dict_table_change_id_in_cache(table, new_id);
@@ -3234,7 +3224,7 @@ row_discard_tablespace_for_mysql(
err = DB_ERROR;
- } else if (table->space == TRX_SYS_SPACE) {
+ } else if (table->space_id == TRX_SYS_SPACE) {
char table_name[MAX_FULL_NAME_LEN + 1];
innobase_format_name(
@@ -3408,7 +3398,7 @@ row_drop_table_from_cache(
trx_t* trx)
{
dberr_t err = DB_SUCCESS;
- bool is_temp = dict_table_is_temporary(table);
+ ut_ad(!table->is_temporary());
/* Remove the pointer to this table object from the list
of modified tables by the transaction because the object
@@ -3417,9 +3407,7 @@ row_drop_table_from_cache(
dict_table_remove_from_cache(table);
- if (!is_temp
- && dict_load_table(tablename, true,
- DICT_ERR_IGNORE_NONE) != NULL) {
+ if (dict_load_table(tablename, true, DICT_ERR_IGNORE_NONE)) {
ib::error() << "Not able to remove table "
<< ut_get_name(trx, tablename)
<< " from the dictionary cache!";
@@ -3429,45 +3417,6 @@ row_drop_table_from_cache(
return(err);
}
-/** Drop a single-table tablespace as part of dropping or renaming a table.
-This deletes the fil_space_t if found and the file on disk.
-@param[in] space_id Tablespace ID
-@param[in] tablename Table name, same as the tablespace name
-@param[in] filepath File path of tablespace to delete
-@param[in] table_flags table flags
-@return error code or DB_SUCCESS */
-UNIV_INLINE
-dberr_t
-row_drop_single_table_tablespace(
- ulint space_id,
- const char* tablename,
- const char* filepath,
- ulint table_flags)
-{
- dberr_t err = DB_SUCCESS;
-
- /* If the tablespace is not in the cache, just delete the file. */
- if (!fil_space_for_table_exists_in_mem(
- space_id, tablename, true, NULL, table_flags)) {
-
- /* Force a delete of any discarded or temporary files. */
- fil_delete_file(filepath);
-
- ib::info() << "Removed datafile " << filepath
- << " for table " << tablename;
- } else if (fil_delete_tablespace(space_id) != DB_SUCCESS) {
-
- ib::error() << "We removed the InnoDB internal data"
- " dictionary entry of table " << tablename
- << " but we are not able to delete the tablespace "
- << space_id << " file " << filepath << "!";
-
- err = DB_ERROR;
- }
-
- return(err);
-}
-
/** Drop a table for MySQL.
If the data dictionary was not already locked by the transaction,
the transaction will be committed. Otherwise, the data dictionary
@@ -3491,7 +3440,6 @@ row_drop_table_for_mysql(
dberr_t err;
dict_foreign_t* foreign;
dict_table_t* table;
- char* filepath = NULL;
char* tablename = NULL;
bool locked_dictionary = false;
pars_info_t* info = NULL;
@@ -3528,17 +3476,30 @@ row_drop_table_for_mysql(
if (!table) {
err = DB_TABLE_NOT_FOUND;
- goto funct_exit;
+ goto funct_exit_all_freed;
+ }
+
+ if (table->is_temporary()) {
+ ut_ad(table->space == fil_system.temp_space);
+ for (dict_index_t* index = dict_table_get_first_index(table);
+ index != NULL;
+ index = dict_table_get_next_index(index)) {
+ btr_free(page_id_t(SRV_TMP_SPACE_ID, index->page),
+ univ_page_size);
+ }
+ /* Remove the pointer to this table object from the list
+ of modified tables by the transaction because the object
+ is going to be destroyed below. */
+ trx->mod_tables.erase(table);
+ table->release();
+ dict_table_remove_from_cache(table);
+ err = DB_SUCCESS;
+ goto funct_exit_all_freed;
}
/* This function is called recursively via fts_drop_tables(). */
if (!trx_is_started(trx)) {
-
- if (!dict_table_is_temporary(table)) {
- trx_start_for_ddl(trx, TRX_DICT_OP_TABLE);
- } else {
- trx_set_dict_operation(trx, TRX_DICT_OP_TABLE);
- }
+ trx_start_for_ddl(trx, TRX_DICT_OP_TABLE);
}
/* Turn on this drop bit before we could release the dictionary
@@ -3568,13 +3529,7 @@ row_drop_table_for_mysql(
row_mysql_lock_data_dictionary(trx);
}
- /* Do not bother to deal with persistent stats for temp
- tables since we know temp tables do not use persistent
- stats. */
- if (!dict_table_is_temporary(table)) {
- dict_stats_wait_bg_to_stop_using_table(
- table, trx);
- }
+ dict_stats_wait_bg_to_stop_using_table(table, trx);
}
/* make sure background stats thread is not running on the table */
@@ -3585,8 +3540,7 @@ row_drop_table_for_mysql(
RemoteDatafile::delete_link_file(name);
}
- if (!dict_table_is_temporary(table) && !table->no_rollback()) {
-
+ if (!table->no_rollback()) {
dict_stats_recalc_pool_del(table);
dict_stats_defrag_pool_del(table, NULL);
if (btr_defragment_thread_active) {
@@ -3728,10 +3682,8 @@ defer:
case TRX_DICT_OP_INDEX:
/* If the transaction was previously flagged as
TRX_DICT_OP_INDEX, we should be dropping auxiliary
- tables for full-text indexes or temp tables. */
- ut_ad(strstr(table->name.m_name, "/FTS_") != NULL
- || strstr(table->name.m_name,
- TEMP_TABLE_PATH_PREFIX) != NULL);
+ tables for full-text indexes. */
+ ut_ad(strstr(table->name.m_name, "/FTS_"));
}
/* Mark all indexes unavailable in the data dictionary cache
@@ -3760,143 +3712,115 @@ defer:
rw_lock_x_unlock(dict_index_get_lock(index));
}
- /* As we don't insert entries to SYSTEM TABLES for temp-tables
- we need to avoid running removal of these entries. */
- if (!dict_table_is_temporary(table)) {
-
- /* We use the private SQL parser of Innobase to generate the
- query graphs needed in deleting the dictionary data from system
- tables in Innobase. Deleting a row from SYS_INDEXES table also
- frees the file segments of the B-tree associated with the
- index. */
-
- info = pars_info_create();
-
- pars_info_add_str_literal(info, "table_name", name);
-
- err = que_eval_sql(
- info,
- "PROCEDURE DROP_TABLE_PROC () IS\n"
- "sys_foreign_id CHAR;\n"
- "table_id CHAR;\n"
- "index_id CHAR;\n"
- "foreign_id CHAR;\n"
- "space_id INT;\n"
- "found INT;\n"
-
- "DECLARE CURSOR cur_fk IS\n"
- "SELECT ID FROM SYS_FOREIGN\n"
- "WHERE FOR_NAME = :table_name\n"
- "AND TO_BINARY(FOR_NAME)\n"
- " = TO_BINARY(:table_name)\n"
- "LOCK IN SHARE MODE;\n"
-
- "DECLARE CURSOR cur_idx IS\n"
- "SELECT ID FROM SYS_INDEXES\n"
- "WHERE TABLE_ID = table_id\n"
- "LOCK IN SHARE MODE;\n"
-
- "BEGIN\n"
+ /* Deleting a row from SYS_INDEXES table will invoke
+ dict_drop_index_tree(). */
+ info = pars_info_create();
+ pars_info_add_str_literal(info, "table_name", name);
+ err = que_eval_sql(
+ info,
+ "PROCEDURE DROP_TABLE_PROC () IS\n"
+ "sys_foreign_id CHAR;\n"
+ "table_id CHAR;\n"
+ "index_id CHAR;\n"
+ "foreign_id CHAR;\n"
+ "space_id INT;\n"
+ "found INT;\n"
+
+ "DECLARE CURSOR cur_fk IS\n"
+ "SELECT ID FROM SYS_FOREIGN\n"
+ "WHERE FOR_NAME = :table_name\n"
+ "AND TO_BINARY(FOR_NAME)\n"
+ " = TO_BINARY(:table_name)\n"
+ "LOCK IN SHARE MODE;\n"
+
+ "DECLARE CURSOR cur_idx IS\n"
+ "SELECT ID FROM SYS_INDEXES\n"
+ "WHERE TABLE_ID = table_id\n"
+ "LOCK IN SHARE MODE;\n"
- "SELECT ID INTO table_id\n"
- "FROM SYS_TABLES\n"
- "WHERE NAME = :table_name\n"
- "LOCK IN SHARE MODE;\n"
- "IF (SQL % NOTFOUND) THEN\n"
- " RETURN;\n"
- "END IF;\n"
-
- "SELECT SPACE INTO space_id\n"
- "FROM SYS_TABLES\n"
- "WHERE NAME = :table_name;\n"
- "IF (SQL % NOTFOUND) THEN\n"
- " RETURN;\n"
- "END IF;\n"
+ "BEGIN\n"
- "found := 1;\n"
- "SELECT ID INTO sys_foreign_id\n"
- "FROM SYS_TABLES\n"
- "WHERE NAME = 'SYS_FOREIGN'\n"
- "LOCK IN SHARE MODE;\n"
- "IF (SQL % NOTFOUND) THEN\n"
- " found := 0;\n"
- "END IF;\n"
- "IF (:table_name = 'SYS_FOREIGN') THEN\n"
- " found := 0;\n"
- "END IF;\n"
- "IF (:table_name = 'SYS_FOREIGN_COLS') \n"
- "THEN\n"
- " found := 0;\n"
- "END IF;\n"
-
- "OPEN cur_fk;\n"
- "WHILE found = 1 LOOP\n"
- " FETCH cur_fk INTO foreign_id;\n"
- " IF (SQL % NOTFOUND) THEN\n"
- " found := 0;\n"
- " ELSE\n"
- " DELETE FROM \n"
- " SYS_FOREIGN_COLS\n"
- " WHERE ID = foreign_id;\n"
- " DELETE FROM SYS_FOREIGN\n"
- " WHERE ID = foreign_id;\n"
- " END IF;\n"
- "END LOOP;\n"
- "CLOSE cur_fk;\n"
-
- "found := 1;\n"
- "OPEN cur_idx;\n"
- "WHILE found = 1 LOOP\n"
- " FETCH cur_idx INTO index_id;\n"
- " IF (SQL % NOTFOUND) THEN\n"
- " found := 0;\n"
- " ELSE\n"
- " DELETE FROM SYS_FIELDS\n"
- " WHERE INDEX_ID = index_id;\n"
- " DELETE FROM SYS_INDEXES\n"
- " WHERE ID = index_id\n"
- " AND TABLE_ID = table_id;\n"
- " END IF;\n"
- "END LOOP;\n"
- "CLOSE cur_idx;\n"
-
- "DELETE FROM SYS_COLUMNS\n"
- "WHERE TABLE_ID = table_id;\n"
- "DELETE FROM SYS_TABLES\n"
- "WHERE NAME = :table_name;\n"
-
- "DELETE FROM SYS_TABLESPACES\n"
- "WHERE SPACE = space_id;\n"
- "DELETE FROM SYS_DATAFILES\n"
- "WHERE SPACE = space_id;\n"
-
- "DELETE FROM SYS_VIRTUAL\n"
- "WHERE TABLE_ID = table_id;\n"
- "END;\n",
- FALSE, trx);
- } else {
- page_no = page_nos;
- for (dict_index_t* index = dict_table_get_first_index(table);
- index != NULL;
- index = dict_table_get_next_index(index)) {
- /* remove the index object associated. */
- dict_drop_index_tree_in_mem(index, *page_no++);
- }
- err = row_drop_table_from_cache(tablename, table, trx);
- goto funct_exit;
- }
+ "SELECT ID INTO table_id\n"
+ "FROM SYS_TABLES\n"
+ "WHERE NAME = :table_name\n"
+ "LOCK IN SHARE MODE;\n"
+ "IF (SQL % NOTFOUND) THEN\n"
+ " RETURN;\n"
+ "END IF;\n"
+
+ "SELECT SPACE INTO space_id\n"
+ "FROM SYS_TABLES\n"
+ "WHERE NAME = :table_name;\n"
+ "IF (SQL % NOTFOUND) THEN\n"
+ " RETURN;\n"
+ "END IF;\n"
+
+ "found := 1;\n"
+ "SELECT ID INTO sys_foreign_id\n"
+ "FROM SYS_TABLES\n"
+ "WHERE NAME = 'SYS_FOREIGN'\n"
+ "LOCK IN SHARE MODE;\n"
+ "IF (SQL % NOTFOUND) THEN\n"
+ " found := 0;\n"
+ "END IF;\n"
+ "IF (:table_name = 'SYS_FOREIGN') THEN\n"
+ " found := 0;\n"
+ "END IF;\n"
+ "IF (:table_name = 'SYS_FOREIGN_COLS') \n"
+ "THEN\n"
+ " found := 0;\n"
+ "END IF;\n"
+
+ "OPEN cur_fk;\n"
+ "WHILE found = 1 LOOP\n"
+ " FETCH cur_fk INTO foreign_id;\n"
+ " IF (SQL % NOTFOUND) THEN\n"
+ " found := 0;\n"
+ " ELSE\n"
+ " DELETE FROM \n"
+ " SYS_FOREIGN_COLS\n"
+ " WHERE ID = foreign_id;\n"
+ " DELETE FROM SYS_FOREIGN\n"
+ " WHERE ID = foreign_id;\n"
+ " END IF;\n"
+ "END LOOP;\n"
+ "CLOSE cur_fk;\n"
+
+ "found := 1;\n"
+ "OPEN cur_idx;\n"
+ "WHILE found = 1 LOOP\n"
+ " FETCH cur_idx INTO index_id;\n"
+ " IF (SQL % NOTFOUND) THEN\n"
+ " found := 0;\n"
+ " ELSE\n"
+ " DELETE FROM SYS_FIELDS\n"
+ " WHERE INDEX_ID = index_id;\n"
+ " DELETE FROM SYS_INDEXES\n"
+ " WHERE ID = index_id\n"
+ " AND TABLE_ID = table_id;\n"
+ " END IF;\n"
+ "END LOOP;\n"
+ "CLOSE cur_idx;\n"
+
+ "DELETE FROM SYS_COLUMNS\n"
+ "WHERE TABLE_ID = table_id;\n"
+ "DELETE FROM SYS_TABLES\n"
+ "WHERE NAME = :table_name;\n"
+
+ "DELETE FROM SYS_TABLESPACES\n"
+ "WHERE SPACE = space_id;\n"
+ "DELETE FROM SYS_DATAFILES\n"
+ "WHERE SPACE = space_id;\n"
+
+ "DELETE FROM SYS_VIRTUAL\n"
+ "WHERE TABLE_ID = table_id;\n"
+ "END;\n",
+ FALSE, trx);
switch (err) {
- ulint space_id;
- bool is_discarded;
- ulint table_flags;
-
+ fil_space_t* space;
+ char* filepath;
case DB_SUCCESS:
- space_id = table->space;
- is_discarded = dict_table_is_discarded(table);
- table_flags = table->flags;
- ut_ad(!dict_table_is_temporary(table));
-
if (!table->no_rollback()) {
err = row_drop_ancillary_fts_tables(table, trx);
if (err != DB_SUCCESS) {
@@ -3904,34 +3828,41 @@ defer:
}
}
+ space = table->space;
+ ut_ad(!space || space->id == table->space_id);
/* Determine the tablespace filename before we drop
- dict_table_t. Free this memory before returning. */
+ dict_table_t. */
if (DICT_TF_HAS_DATA_DIR(table->flags)) {
dict_get_and_save_data_dir_path(table, true);
ut_a(table->data_dir_path);
- filepath = fil_make_filepath(
+ filepath = space ? NULL : fil_make_filepath(
table->data_dir_path,
table->name.m_name, IBD, true);
} else {
- filepath = fil_make_filepath(
+ filepath = space ? NULL : fil_make_filepath(
NULL, table->name.m_name, IBD, false);
}
/* Free the dict_table_t object. */
err = row_drop_table_from_cache(tablename, table, trx);
if (err != DB_SUCCESS) {
+ ut_free(filepath);
break;
}
/* Do not attempt to drop known-to-be-missing tablespaces,
nor the system tablespace. */
- if (is_discarded || is_system_tablespace(space_id)) {
+ if (!space) {
+ fil_delete_file(filepath);
+ ut_free(filepath);
break;
}
- /* We can now drop the single-table tablespace. */
- err = row_drop_single_table_tablespace(
- space_id, tablename, filepath, table_flags);
+ ut_ad(!filepath);
+
+ if (space->id != TRX_SYS_SPACE) {
+ err = fil_delete_tablespace(space->id);
+ }
break;
case DB_OUT_OF_FILE_SPACE:
@@ -3994,8 +3925,7 @@ funct_exit:
mem_heap_free(heap);
}
- ut_free(filepath);
-
+funct_exit_all_freed:
if (locked_dictionary) {
if (trx_is_started(trx)) {
@@ -4158,8 +4088,7 @@ loop:
<< table->name << ".frm' was lost.";
}
- if (!table->is_readable()
- && !fil_space_get(table->space)) {
+ if (!table->is_readable() && !table->space) {
ib::warn() << "Missing .ibd file for table "
<< table->name << ".";
}
@@ -4413,8 +4342,7 @@ row_rename_table_for_mysql(
err = DB_TABLE_NOT_FOUND;
goto funct_exit;
- } else if (!table->is_readable()
- && fil_space_get(table->space) == NULL
+ } else if (!table->is_readable() && !table->space
&& !dict_table_is_discarded(table)) {
err = DB_TABLE_NOT_FOUND;
@@ -4490,22 +4418,18 @@ row_rename_table_for_mysql(
if (err == DB_SUCCESS
&& dict_table_is_file_per_table(table)) {
/* Make a new pathname to update SYS_DATAFILES. */
- char* new_path = row_make_new_pathname(table, new_name);
- char* old_path = fil_space_get_first_path(table->space);
-
/* If old path and new path are the same means tablename
has not changed and only the database name holding the table
has changed so we need to make the complete filepath again. */
- if (!dict_tables_have_same_db(old_name, new_name)) {
- ut_free(new_path);
- new_path = fil_make_filepath(NULL, new_name, IBD, false);
- }
+ char* new_path = dict_tables_have_same_db(old_name, new_name)
+ ? row_make_new_pathname(table, new_name)
+ : fil_make_filepath(NULL, new_name, IBD, false);
info = pars_info_create();
pars_info_add_str_literal(info, "new_table_name", new_name);
pars_info_add_str_literal(info, "new_path_name", new_path);
- pars_info_add_int4_literal(info, "space_id", table->space);
+ pars_info_add_int4_literal(info, "space_id", table->space_id);
err = que_eval_sql(info,
"PROCEDURE RENAME_SPACE () IS\n"
@@ -4519,7 +4443,6 @@ row_rename_table_for_mysql(
"END;\n"
, FALSE, trx);
- ut_free(old_path);
ut_free(new_path);
}
if (err != DB_SUCCESS) {
diff --git a/storage/innobase/row/row0quiesce.cc b/storage/innobase/row/row0quiesce.cc
index e6532ffd5e0..dc0cb5f5424 100644
--- a/storage/innobase/row/row0quiesce.cc
+++ b/storage/innobase/row/row0quiesce.cc
@@ -145,7 +145,7 @@ row_quiesce_write_indexes(
mach_write_to_8(ptr, index->id);
ptr += sizeof(index_id_t);
- mach_write_to_4(ptr, table->space);
+ mach_write_to_4(ptr, table->space->id);
ptr += sizeof(ib_uint32_t);
mach_write_to_4(ptr, index->page);
@@ -521,7 +521,7 @@ row_quiesce_table_start(
ut_a(trx->mysql_thd != 0);
- ut_ad(fil_space_get(table->space) != NULL);
+ ut_ad(table->space != NULL);
ib::info() << "Sync to disk of " << table->name << " started.";
if (srv_undo_sources) {
@@ -529,7 +529,7 @@ row_quiesce_table_start(
}
for (ulint count = 0;
- ibuf_merge_space(table->space) != 0
+ ibuf_merge_space(table->space->id) != 0
&& !trx_is_interrupted(trx);
++count) {
if (!(count % 20)) {
@@ -541,7 +541,8 @@ row_quiesce_table_start(
if (!trx_is_interrupted(trx)) {
{
FlushObserver observer(table->space, trx, NULL);
- buf_LRU_flush_or_remove_pages(table->space, &observer);
+ buf_LRU_flush_or_remove_pages(table->space->id,
+ &observer);
}
if (trx_is_interrupted(trx)) {
@@ -640,7 +641,7 @@ row_quiesce_set_state(
ER_CANNOT_DISCARD_TEMPORARY_TABLE);
return(DB_UNSUPPORTED);
- } else if (table->space == TRX_SYS_SPACE) {
+ } else if (table->space->id == TRX_SYS_SPACE) {
char table_name[MAX_FULL_NAME_LEN + 1];
diff --git a/storage/innobase/row/row0sel.cc b/storage/innobase/row/row0sel.cc
index 503f4537b8d..55be50ba35b 100644
--- a/storage/innobase/row/row0sel.cc
+++ b/storage/innobase/row/row0sel.cc
@@ -126,7 +126,7 @@ row_sel_sec_rec_is_for_blob(
}
len = btr_copy_externally_stored_field_prefix(
- buf, prefix_len, dict_tf_get_page_size(table->flags),
+ buf, prefix_len, page_size_t(table->space->flags),
clust_field, clust_len);
if (len == 0) {
@@ -294,8 +294,8 @@ row_sel_sec_rec_is_for_clust_rec(
if (rec_offs_nth_extern(clust_offs, clust_pos)) {
dptr = btr_copy_externally_stored_field(
&clust_len, dptr,
- dict_tf_get_page_size(
- sec_index->table->flags),
+ page_size_t(clust_index->table->space
+ ->flags),
len, heap);
}
@@ -1112,13 +1112,14 @@ re_scan:
}
mutex_exit(&match->rtr_match_mutex);
+ /* MDEV-14059 FIXME: why re-latch the block?
+ pcur is already positioned on it! */
ulint page_no = page_get_page_no(
- btr_pcur_get_page(pcur));
- page_id_t page_id(dict_index_get_space(index),
- page_no);
+ btr_pcur_get_page(pcur));
cur_block = buf_page_get_gen(
- page_id, dict_table_page_size(index->table),
+ page_id_t(index->table->space->id, page_no),
+ page_size_t(index->table->space->flags),
RW_X_LATCH, NULL, BUF_GET,
__FILE__, __LINE__, mtr, &err);
} else {
@@ -4222,7 +4223,7 @@ row_search_mvcc(
DBUG_RETURN(DB_TABLESPACE_DELETED);
} else if (!prebuilt->table->is_readable()) {
- DBUG_RETURN(fil_space_get(prebuilt->table->space)
+ DBUG_RETURN(prebuilt->table->space
? DB_DECRYPTION_FAILED
: DB_TABLESPACE_NOT_FOUND);
} else if (!prebuilt->index_usable) {
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) {
diff --git a/storage/innobase/row/row0uins.cc b/storage/innobase/row/row0uins.cc
index 64095cb7bc8..0e7acecd77e 100644
--- a/storage/innobase/row/row0uins.cc
+++ b/storage/innobase/row/row0uins.cc
@@ -431,7 +431,7 @@ row_undo_ins_parse_undo_rec(
dict_table_t* table = node->table;
ut_ad(!table->is_temporary());
ut_ad(dict_table_is_file_per_table(table)
- == (table->space != TRX_SYS_SPACE));
+ == !is_system_tablespace(table->space->id));
size_t len = mach_read_from_2(node->undo_rec)
+ node->undo_rec - ptr - 2;
ptr[len] = 0;
diff --git a/storage/innobase/row/row0upd.cc b/storage/innobase/row/row0upd.cc
index 35ccb04d6f1..3ca98fac7cd 100644
--- a/storage/innobase/row/row0upd.cc
+++ b/storage/innobase/row/row0upd.cc
@@ -303,26 +303,20 @@ row_upd_check_references_constraints(
undergoing a truncate, ignore the FK check. */
if (foreign_table) {
- mutex_enter(&fil_system.mutex);
- const fil_space_t* space = fil_space_get_by_id(
- foreign_table->space);
- const bool being_truncated = space
- && space->is_being_truncated;
- mutex_exit(&fil_system.mutex);
- if (being_truncated) {
+ if (foreign_table->space
+ && foreign_table->space
+ ->is_being_truncated) {
continue;
}
+
+ foreign_table->inc_fk_checks();
}
/* NOTE that if the thread ends up waiting for a lock
we will release dict_operation_lock temporarily!
- But the counter on the table protects 'foreign' from
+ But the inc_fk_checks() protects foreign_table from
being dropped while the check is running. */
- if (foreign_table) {
- foreign_table->inc_fk_checks();
- }
-
err = row_ins_check_foreign_constraint(
FALSE, foreign, table, entry, thr);
@@ -2313,7 +2307,7 @@ row_upd_sec_index_entry(
mtr.start();
- switch (index->table->space) {
+ switch (index->table->space->id) {
case SRV_TMP_SPACE_ID:
mtr.set_log_mode(MTR_LOG_NO_REDO);
flags = BTR_NO_LOCKING_FLAG;
diff --git a/storage/innobase/srv/srv0start.cc b/storage/innobase/srv/srv0start.cc
index 135ae1953a6..754ebddb157 100644
--- a/storage/innobase/srv/srv0start.cc
+++ b/storage/innobase/srv/srv0start.cc
@@ -1096,9 +1096,9 @@ srv_undo_tablespaces_init(bool create_new_db)
= undo::Truncate::s_fix_up_spaces.begin();
it != undo::Truncate::s_fix_up_spaces.end();
++it) {
- FlushObserver dummy(TRX_SYS_SPACE, NULL, NULL);
+ FlushObserver dummy(fil_system.sys_space, NULL, NULL);
buf_LRU_flush_or_remove_pages(TRX_SYS_SPACE, &dummy);
- FlushObserver dummy2(*it, NULL, NULL);
+ FlushObserver dummy2(fil_space_get(*it), NULL, NULL);
buf_LRU_flush_or_remove_pages(*it, &dummy2);
/* Remove the truncate redo log file. */
@@ -2132,9 +2132,8 @@ files_checked:
fsp_header_init(fil_system.sys_space, sum_of_new_sizes, &mtr);
ulint ibuf_root = btr_create(
- DICT_CLUSTERED | DICT_IBUF,
- 0, univ_page_size, DICT_IBUF_ID_MIN,
- dict_ind_redundant, NULL, &mtr);
+ DICT_CLUSTERED | DICT_IBUF, fil_system.sys_space,
+ DICT_IBUF_ID_MIN, dict_ind_redundant, NULL, &mtr);
mtr_commit(&mtr);
diff --git a/storage/innobase/trx/trx0rseg.cc b/storage/innobase/trx/trx0rseg.cc
index 33a9d4c2f37..d5058809703 100644
--- a/storage/innobase/trx/trx0rseg.cc
+++ b/storage/innobase/trx/trx0rseg.cc
@@ -262,17 +262,17 @@ void trx_rseg_format_upgrade(trx_rsegf_t* rseg_header, mtr_t* mtr)
}
/** Create a rollback segment header.
-@param[in] space system, undo, or temporary tablespace
+@param[in,out] space system, undo, or temporary tablespace
@param[in] rseg_id rollback segment identifier
@param[in,out] sys_header the TRX_SYS page (NULL for temporary rseg)
@param[in,out] mtr mini-transaction
@return page number of the created segment, FIL_NULL if fail */
ulint
trx_rseg_header_create(
- const fil_space_t* space,
- ulint rseg_id,
- buf_block_t* sys_header,
- mtr_t* mtr)
+ fil_space_t* space,
+ ulint rseg_id,
+ buf_block_t* sys_header,
+ mtr_t* mtr)
{
ulint page_no;
trx_rsegf_t* rsegf;
@@ -282,8 +282,7 @@ trx_rseg_header_create(
ut_ad(!sys_header == (space == fil_system.temp_space));
/* Allocate a new file segment for the rollback segment */
- block = fseg_create(space->id, 0, TRX_RSEG + TRX_RSEG_FSEG_HEADER,
- mtr);
+ block = fseg_create(space, 0, TRX_RSEG + TRX_RSEG_FSEG_HEADER, mtr);
if (block == NULL) {
/* No space left */
diff --git a/storage/innobase/trx/trx0sys.cc b/storage/innobase/trx/trx0sys.cc
index 3063ae58831..8f889ae8780 100644
--- a/storage/innobase/trx/trx0sys.cc
+++ b/storage/innobase/trx/trx0sys.cc
@@ -163,9 +163,11 @@ trx_sysf_create(
to the latching order rules. */
mtr_x_lock(&fil_system.sys_space->latch, mtr);
+ compile_time_assert(TRX_SYS_SPACE == 0);
/* Create the trx sys file block in a new allocated file segment */
- block = fseg_create(TRX_SYS_SPACE, 0, TRX_SYS + TRX_SYS_FSEG_HEADER,
+ block = fseg_create(fil_system.sys_space, 0,
+ TRX_SYS + TRX_SYS_FSEG_HEADER,
mtr);
buf_block_dbg_add_level(block, SYNC_TRX_SYS_HEADER);
diff --git a/storage/innobase/trx/trx0undo.cc b/storage/innobase/trx/trx0undo.cc
index 6f764bfe105..f5984de02b9 100644
--- a/storage/innobase/trx/trx0undo.cc
+++ b/storage/innobase/trx/trx0undo.cc
@@ -489,6 +489,7 @@ trx_undo_page_init(
}
/** Create an undo log segment.
+@param[in,out] space tablespace
@param[in,out] rseg_hdr rollback segment header (x-latched)
@param[out] id undo slot number
@param[out] err error code
@@ -497,10 +498,10 @@ trx_undo_page_init(
@retval NULL on failure */
static MY_ATTRIBUTE((nonnull, warn_unused_result))
buf_block_t*
-trx_undo_seg_create(trx_rsegf_t* rseg_hdr, ulint* id, dberr_t* err, mtr_t* mtr)
+trx_undo_seg_create(fil_space_t* space, trx_rsegf_t* rseg_hdr, ulint* id,
+ dberr_t* err, mtr_t* mtr)
{
ulint slot_no;
- ulint space;
buf_block_t* block;
ulint n_reserved;
bool success;
@@ -516,8 +517,6 @@ trx_undo_seg_create(trx_rsegf_t* rseg_hdr, ulint* id, dberr_t* err, mtr_t* mtr)
return NULL;
}
- space = page_get_space_id(page_align(rseg_hdr));
-
success = fsp_reserve_free_extents(&n_reserved, space, 2, FSP_UNDO,
mtr);
if (!success) {
@@ -526,11 +525,10 @@ trx_undo_seg_create(trx_rsegf_t* rseg_hdr, ulint* id, dberr_t* err, mtr_t* mtr)
}
/* Allocate a new file segment for the undo log */
- block = fseg_create_general(space, 0,
- TRX_UNDO_SEG_HDR
- + TRX_UNDO_FSEG_HEADER, TRUE, mtr);
+ block = fseg_create(space, 0, TRX_UNDO_SEG_HDR + TRX_UNDO_FSEG_HEADER,
+ mtr, true);
- fil_space_release_free_extents(space, n_reserved);
+ space->release_free_extents(n_reserved);
if (block == NULL) {
*err = DB_OUT_OF_FILE_SPACE;
@@ -784,7 +782,7 @@ trx_undo_add_page(trx_t* trx, trx_undo_t* undo, mtr_t* mtr)
header_page = trx_undo_page_get(
page_id_t(undo->rseg->space->id, undo->hdr_page_no), mtr);
- if (!fsp_reserve_free_extents(&n_reserved, undo->rseg->space->id, 1,
+ if (!fsp_reserve_free_extents(&n_reserved, undo->rseg->space, 1,
FSP_UNDO, mtr)) {
goto func_exit;
}
@@ -794,7 +792,7 @@ trx_undo_add_page(trx_t* trx, trx_undo_t* undo, mtr_t* mtr)
+ header_page,
undo->top_page_no + 1, FSP_UP, TRUE, mtr, mtr);
- fil_space_release_free_extents(undo->rseg->space->id, n_reserved);
+ rseg->space->release_free_extents(n_reserved);
if (!new_block) {
goto func_exit;
@@ -1271,10 +1269,11 @@ trx_undo_create(trx_t* trx, trx_rseg_t* rseg, trx_undo_t** undo,
ut_ad(mutex_own(&(rseg->mutex)));
buf_block_t* block = trx_undo_seg_create(
+ rseg->space,
trx_rsegf_get(rseg->space, rseg->page_no, mtr), &id, err, mtr);
if (!block) {
- return block;
+ return NULL;
}
rseg->curr_size++;
@@ -1699,7 +1698,7 @@ trx_undo_truncate_tablespace(
/* Step-1: Truncate tablespace. */
if (!fil_truncate_tablespace(
- space->id, SRV_UNDO_TABLESPACE_SIZE_IN_PAGES)) {
+ space, SRV_UNDO_TABLESPACE_SIZE_IN_PAGES)) {
fil_space_release(space);
return false;
}