MDEV-35494 fil_space_t::fil_space_t() may be unsafe with GCC -flifetime-dse

fil_space_t::create(): Instead of invoking the default fil_space_t
constructor on a zero-filled buffer, allocate an uninitialized buffer
and invoke an explicitly defined constructor on it. Also, specify
initializer expressions for all constant data members, so that all of them
will be initialized in the constructor.

fil_space_t::being_imported: Replaces part of fil_space_t::purpose.

fil_space_t::is_being_imported(), fil_space_t::is_temporary():
Replaces fil_space_t::purpose.

fil_space_t:🆔 Changed the type from ulint to uint32_t to reduce
incompatibility with later branches that include
commit ca501ffb04 (MDEV-26195).

fil_space_t::try_to_close(): Do not attempt to close files that are
in an I/O bound phase of ALTER TABLE…IMPORT TABLESPACE.

log_file_op, first_page_init: recv_spaces_t:
Use uint32_t for the tablespace id.

Reviewed by: Debarun Banerjee
This commit is contained in:
Marko Mäkelä 2024-12-11 14:44:42 +02:00
parent 7372ecc396
commit bfe7c8ff0a
21 changed files with 310 additions and 376 deletions

View file

@ -730,13 +730,15 @@ datafiles_iter_next(datafiles_iter_t *it)
fil_system.space_list.begin() : fil_system.space_list.begin() :
std::next(it->space); std::next(it->space);
while (it->space != fil_system.space_list.end() && while (it->space != fil_system.space_list.end()
(it->space->purpose != FIL_TYPE_TABLESPACE || && UT_LIST_GET_LEN(it->space->chain) == 0)
UT_LIST_GET_LEN(it->space->chain) == 0))
++it->space; ++it->space;
if (it->space == fil_system.space_list.end()) if (it->space == fil_system.space_list.end())
goto end; goto end;
ut_ad(!it->space->is_temporary());
ut_ad(!it->space->is_being_imported());
it->node = UT_LIST_GET_FIRST(it->space->chain); it->node = UT_LIST_GET_FIRST(it->space->chain);
end: end:
@ -907,7 +909,7 @@ err:
@param[in] len length of name, in bytes @param[in] len length of name, in bytes
@param[in] new_name new file name (NULL if not rename) @param[in] new_name new file name (NULL if not rename)
@param[in] new_len length of new_name, in bytes (0 if NULL) */ @param[in] new_len length of new_name, in bytes (0 if NULL) */
static void backup_file_op(ulint space_id, int type, static void backup_file_op(uint32_t space_id, int type,
const byte* name, ulint len, const byte* name, ulint len,
const byte* new_name, ulint new_len) const byte* new_name, ulint new_len)
{ {
@ -923,7 +925,8 @@ static void backup_file_op(ulint space_id, int type,
std::string space_name = filename_to_spacename(name, len); std::string space_name = filename_to_spacename(name, len);
ddl_tracker.id_to_name[space_id] = space_name; ddl_tracker.id_to_name[space_id] = space_name;
ddl_tracker.delete_defer(space_id, space_name); ddl_tracker.delete_defer(space_id, space_name);
msg("DDL tracking : create %zu \"%.*s\"", space_id, int(len), name); msg("DDL tracking : create %" PRIu32 " \"%.*s\"",
space_id, int(len), name);
} }
break; break;
case FILE_MODIFY: case FILE_MODIFY:
@ -939,7 +942,7 @@ static void backup_file_op(ulint space_id, int type,
ddl_tracker.id_to_name[space_id] = new_space_name; ddl_tracker.id_to_name[space_id] = new_space_name;
ddl_tracker.rename_defer(space_id, old_space_name, ddl_tracker.rename_defer(space_id, old_space_name,
new_space_name); new_space_name);
msg("DDL tracking : rename %zu \"%.*s\",\"%.*s\"", msg("DDL tracking : rename %" PRIu32 " \"%.*s\",\"%.*s\"",
space_id, int(len), name, int(new_len), new_name); space_id, int(len), name, int(new_len), new_name);
} }
break; break;
@ -947,7 +950,8 @@ static void backup_file_op(ulint space_id, int type,
ddl_tracker.drops.insert(space_id); ddl_tracker.drops.insert(space_id);
ddl_tracker.delete_defer( ddl_tracker.delete_defer(
space_id, filename_to_spacename(name, len)); space_id, filename_to_spacename(name, len));
msg("DDL tracking : delete %zu \"%.*s\"", space_id, int(len), name); msg("DDL tracking : delete %" PRIu32 " \"%.*s\"",
space_id, int(len), name);
break; break;
default: default:
ut_ad(0); ut_ad(0);
@ -966,21 +970,22 @@ static void backup_file_op(ulint space_id, int type,
We will abort backup in this case. We will abort backup in this case.
*/ */
static void backup_file_op_fail(ulint space_id, int type, static void backup_file_op_fail(uint32_t space_id, int type,
const byte* name, ulint len, const byte* name, ulint len,
const byte* new_name, ulint new_len) const byte* new_name, ulint new_len)
{ {
bool fail = false; bool fail = false;
switch(type) { switch(type) {
case FILE_CREATE: case FILE_CREATE:
msg("DDL tracking : create %zu \"%.*s\"", space_id, int(len), name); msg("DDL tracking : create %" PRIu32 " \"%.*s\"",
space_id, int(len), name);
fail = !check_if_skip_table( fail = !check_if_skip_table(
filename_to_spacename(name, len).c_str()); filename_to_spacename(name, len).c_str());
break; break;
case FILE_MODIFY: case FILE_MODIFY:
break; break;
case FILE_RENAME: case FILE_RENAME:
msg("DDL tracking : rename %zu \"%.*s\",\"%.*s\"", msg("DDL tracking : rename %" PRIu32 " \"%.*s\",\"%.*s\"",
space_id, int(len), name, int(new_len), new_name); space_id, int(len), name, int(new_len), new_name);
fail = !check_if_skip_table( fail = !check_if_skip_table(
filename_to_spacename(name, len).c_str()) filename_to_spacename(name, len).c_str())
@ -990,7 +995,8 @@ static void backup_file_op_fail(ulint space_id, int type,
case FILE_DELETE: case FILE_DELETE:
fail = !check_if_skip_table( fail = !check_if_skip_table(
filename_to_spacename(name, len).c_str()); filename_to_spacename(name, len).c_str());
msg("DDL tracking : delete %zu \"%.*s\"", space_id, int(len), name); msg("DDL tracking : delete %" PRIu32 " \"%.*s\"",
space_id, int(len), name);
break; break;
default: default:
ut_ad(0); ut_ad(0);
@ -1011,7 +1017,7 @@ static void backup_undo_trunc(uint32_t space_id)
/* Function to store the space id of page0 INIT_PAGE /* Function to store the space id of page0 INIT_PAGE
@param space_id space id which has page0 init page */ @param space_id space id which has page0 init page */
static void backup_first_page_op(ulint space_id) static void backup_first_page_op(uint32_t space_id)
{ {
first_page_init_ids.insert(space_id); first_page_init_ids.insert(space_id);
} }
@ -3532,8 +3538,8 @@ static void xb_load_single_table_tablespace(const char *dirname,
if (err == DB_SUCCESS && file->space_id() != SRV_TMP_SPACE_ID) { if (err == DB_SUCCESS && file->space_id() != SRV_TMP_SPACE_ID) {
mysql_mutex_lock(&fil_system.mutex); mysql_mutex_lock(&fil_system.mutex);
space = fil_space_t::create( space = fil_space_t::create(
file->space_id(), file->flags(), uint32_t(file->space_id()), file->flags(), false,
FIL_TYPE_TABLESPACE, nullptr/* TODO: crypt_data */, nullptr/* TODO: crypt_data */,
FIL_ENCRYPTION_DEFAULT, FIL_ENCRYPTION_DEFAULT,
file->handle() != OS_FILE_CLOSED); file->handle() != OS_FILE_CLOSED);
ut_ad(space); ut_ad(space);
@ -4998,8 +5004,8 @@ void CorruptedPages::backup_fix_ddl(ds_ctxt *ds_data, ds_ctxt *ds_meta)
iter != ddl_tracker.tables_in_backup.end(); iter != ddl_tracker.tables_in_backup.end();
iter++) { iter++) {
const std::string name = iter->second; uint32_t id = iter->first;
ulint id = iter->first; const std::string &name = iter->second;
if (ddl_tracker.drops.find(id) != ddl_tracker.drops.end()) { if (ddl_tracker.drops.find(id) != ddl_tracker.drops.end()) {
dropped_tables.insert(name); dropped_tables.insert(name);
@ -5025,8 +5031,8 @@ void CorruptedPages::backup_fix_ddl(ds_ctxt *ds_data, ds_ctxt *ds_meta)
iter != ddl_tracker.id_to_name.end(); iter != ddl_tracker.id_to_name.end();
iter++) { iter++) {
ulint id = iter->first; uint32_t id = iter->first;
std::string name = iter->second; const std::string &name = iter->second;
if (ddl_tracker.tables_in_backup.find(id) != ddl_tracker.tables_in_backup.end()) { if (ddl_tracker.tables_in_backup.find(id) != ddl_tracker.tables_in_backup.end()) {
/* already processed above */ /* already processed above */
@ -5322,8 +5328,8 @@ exit:
char tmpname[FN_REFLEN]; char tmpname[FN_REFLEN];
snprintf(tmpname, FN_REFLEN, "%s/xtrabackup_tmp_#" ULINTPF, snprintf(tmpname, FN_REFLEN, "%s/xtrabackup_tmp_#%"
dbname, fil_space->id); PRIu32, dbname, fil_space->id);
msg("mariabackup: Renaming %s to %s.ibd", msg("mariabackup: Renaming %s to %s.ibd",
fil_space->chain.start->name, tmpname); fil_space->chain.start->name, tmpname);
@ -5378,8 +5384,8 @@ exit:
ut_ad(fil_space_t::physical_size(flags) == info.page_size); ut_ad(fil_space_t::physical_size(flags) == info.page_size);
mysql_mutex_lock(&fil_system.mutex); mysql_mutex_lock(&fil_system.mutex);
fil_space_t* space = fil_space_t::create(info.space_id, flags, fil_space_t* space = fil_space_t::create(uint32_t(info.space_id),
FIL_TYPE_TABLESPACE, 0, flags, false, 0,
FIL_ENCRYPTION_DEFAULT, true); FIL_ENCRYPTION_DEFAULT, true);
mysql_mutex_unlock(&fil_system.mutex); mysql_mutex_unlock(&fil_system.mutex);
if (space) { if (space) {

View file

@ -3643,8 +3643,7 @@ static dberr_t buf_page_check_corrupt(buf_page_t *bpage,
const bool seems_encrypted = !node.space->full_crc32() && key_version const bool seems_encrypted = !node.space->full_crc32() && key_version
&& node.space->crypt_data && node.space->crypt_data
&& node.space->crypt_data->type != CRYPT_SCHEME_UNENCRYPTED; && node.space->crypt_data->type != CRYPT_SCHEME_UNENCRYPTED;
ut_ad(node.space->purpose != FIL_TYPE_TEMPORARY || ut_ad(!node.space->is_temporary() || node.space->full_crc32());
node.space->full_crc32());
/* If traditional checksums match, we assume that page is /* If traditional checksums match, we assume that page is
not anymore encrypted. */ not anymore encrypted. */
@ -3652,7 +3651,7 @@ static dberr_t buf_page_check_corrupt(buf_page_t *bpage,
&& !buf_is_zeroes(span<const byte>(dst_frame, && !buf_is_zeroes(span<const byte>(dst_frame,
node.space->physical_size())) node.space->physical_size()))
&& (key_version || node.space->is_compressed() && (key_version || node.space->is_compressed()
|| node.space->purpose == FIL_TYPE_TEMPORARY)) { || node.space->is_temporary())) {
if (buf_page_full_crc32_is_corrupted( if (buf_page_full_crc32_is_corrupted(
bpage->id().space(), dst_frame, bpage->id().space(), dst_frame,
node.space->is_compressed())) { node.space->is_compressed())) {

View file

@ -750,7 +750,8 @@ void buf_dblwr_t::add_to_batch(const IORequest &request, size_t size)
ut_ad(request.bpage); ut_ad(request.bpage);
ut_ad(request.bpage->in_file()); ut_ad(request.bpage->in_file());
ut_ad(request.node); ut_ad(request.node);
ut_ad(request.node->space->purpose == FIL_TYPE_TABLESPACE); ut_ad(!request.node->space->is_temporary());
ut_ad(!request.node->space->is_being_imported());
ut_ad(request.node->space->id == request.bpage->id().space()); ut_ad(request.node->space->id == request.bpage->id().space());
ut_ad(request.node->space->referenced()); ut_ad(request.node->space->referenced());
ut_ad(!srv_read_only_mode); ut_ad(!srv_read_only_mode);

View file

@ -639,7 +639,7 @@ static byte *buf_page_encrypt(fil_space_t* space, buf_page_t* bpage, byte* s,
fil_space_crypt_t *crypt_data= space->crypt_data; fil_space_crypt_t *crypt_data= space->crypt_data;
bool encrypted, page_compressed; bool encrypted, page_compressed;
if (space->purpose == FIL_TYPE_TEMPORARY) if (space->is_temporary())
{ {
ut_ad(!crypt_data); ut_ad(!crypt_data);
encrypted= innodb_encrypt_temporary_tables; encrypted= innodb_encrypt_temporary_tables;
@ -685,13 +685,13 @@ static byte *buf_page_encrypt(fil_space_t* space, buf_page_t* bpage, byte* s,
if (!page_compressed) if (!page_compressed)
{ {
not_compressed: not_compressed:
d= space->purpose == FIL_TYPE_TEMPORARY d= space->is_temporary()
? buf_tmp_page_encrypt(page_no, s, d) ? buf_tmp_page_encrypt(page_no, s, d)
: fil_space_encrypt(space, page_no, s, d); : fil_space_encrypt(space, page_no, s, d);
} }
else else
{ {
ut_ad(space->purpose != FIL_TYPE_TEMPORARY); ut_ad(!space->is_temporary());
/* First we compress the page content */ /* First we compress the page content */
buf_tmp_reserve_compression_buf(*slot); buf_tmp_reserve_compression_buf(*slot);
byte *tmp= (*slot)->comp_buf; byte *tmp= (*slot)->comp_buf;
@ -768,8 +768,7 @@ bool buf_page_t::flush(fil_space_t *space)
mysql_mutex_assert_not_owner(&buf_pool.flush_list_mutex); mysql_mutex_assert_not_owner(&buf_pool.flush_list_mutex);
ut_ad(in_file()); ut_ad(in_file());
ut_ad(in_LRU_list); ut_ad(in_LRU_list);
ut_ad((space->purpose == FIL_TYPE_TEMPORARY) == ut_ad((space->is_temporary()) == (space == fil_system.temp_space));
(space == fil_system.temp_space));
ut_ad(space->referenced()); ut_ad(space->referenced());
const auto s= state(); const auto s= state();
@ -779,12 +778,12 @@ bool buf_page_t::flush(fil_space_t *space)
(FIL_PAGE_LSN + (zip.data ? zip.data : frame))); (FIL_PAGE_LSN + (zip.data ? zip.data : frame)));
ut_ad(lsn ut_ad(lsn
? lsn >= oldest_modification() || oldest_modification() == 2 ? lsn >= oldest_modification() || oldest_modification() == 2
: space->purpose != FIL_TYPE_TABLESPACE); : (space->is_temporary() || space->is_being_imported()));
if (s < UNFIXED) if (s < UNFIXED)
{ {
ut_a(s >= FREED); ut_a(s >= FREED);
if (UNIV_LIKELY(space->purpose == FIL_TYPE_TABLESPACE)) if (!space->is_temporary() && !space->is_being_imported())
{ {
freed: freed:
if (lsn > log_sys.get_flushed_lsn()) if (lsn > log_sys.get_flushed_lsn())
@ -800,7 +799,8 @@ bool buf_page_t::flush(fil_space_t *space)
if (UNIV_UNLIKELY(lsn < space->get_create_lsn())) if (UNIV_UNLIKELY(lsn < space->get_create_lsn()))
{ {
ut_ad(space->purpose == FIL_TYPE_TABLESPACE); ut_ad(!space->is_temporary());
ut_ad(!space->is_being_imported());
goto freed; goto freed;
} }
@ -884,7 +884,7 @@ bool buf_page_t::flush(fil_space_t *space)
if ((s & LRU_MASK) == REINIT || !space->use_doublewrite()) if ((s & LRU_MASK) == REINIT || !space->use_doublewrite())
{ {
if (UNIV_LIKELY(space->purpose == FIL_TYPE_TABLESPACE) && if (!space->is_temporary() && !space->is_being_imported() &&
lsn > log_sys.get_flushed_lsn()) lsn > log_sys.get_flushed_lsn())
log_write_up_to(lsn, true); log_write_up_to(lsn, true);
space->io(IORequest{type, this, slot}, physical_offset(), size, space->io(IORequest{type, this, slot}, physical_offset(), size,
@ -1735,7 +1735,7 @@ done:
if (acquired) if (acquired)
space->release(); space->release();
if (space->purpose == FIL_TYPE_IMPORT) if (space->is_being_imported())
os_aio_wait_until_no_pending_writes(true); os_aio_wait_until_no_pending_writes(true);
else else
buf_dblwr.flush_buffered_writes(); buf_dblwr.flush_buffered_writes();

View file

@ -972,8 +972,10 @@ void dict_check_tablespaces_and_store_max_id(const std::set<uint32_t> *spaces)
const bool not_dropped{!rec_get_deleted_flag(rec, 0)}; const bool not_dropped{!rec_get_deleted_flag(rec, 0)};
/* Check that the .ibd file exists. */ /* Check that the .ibd file exists. */
if (fil_ibd_open(not_dropped, FIL_TYPE_TABLESPACE, if (fil_ibd_open(space_id, dict_tf_to_fsp_flags(flags),
space_id, dict_tf_to_fsp_flags(flags), not_dropped
? fil_space_t::VALIDATE_NOTHING
: fil_space_t::MAYBE_MISSING,
name, filepath)) { name, filepath)) {
} else if (!not_dropped) { } else if (!not_dropped) {
} else if (srv_operation == SRV_OPERATION_NORMAL } else if (srv_operation == SRV_OPERATION_NORMAL
@ -2291,8 +2293,8 @@ dict_load_tablespace(
} }
table->space = fil_ibd_open( table->space = fil_ibd_open(
2, FIL_TYPE_TABLESPACE, table->space_id, table->space_id, dict_tf_to_fsp_flags(table->flags),
dict_tf_to_fsp_flags(table->flags), fil_space_t::VALIDATE_SPACE_ID,
{table->name.m_name, strlen(table->name.m_name)}, filepath); {table->name.m_name, strlen(table->name.m_name)}, filepath);
if (!table->space) { if (!table->space) {

View file

@ -136,9 +136,6 @@ dict_table_t *dict_table_t::create(const span<const char> &name,
ulint n_cols, ulint n_v_cols, ulint flags, ulint n_cols, ulint n_v_cols, ulint flags,
ulint flags2) ulint flags2)
{ {
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(dict_tf2_is_valid(flags, flags2));
ut_a(!(flags2 & DICT_TF2_UNUSED_BIT_MASK)); ut_a(!(flags2 & DICT_TF2_UNUSED_BIT_MASK));

View file

@ -1067,7 +1067,8 @@ default_encrypt_list only when
default encrypt */ default encrypt */
static bool fil_crypt_must_remove(const fil_space_t &space) static bool fil_crypt_must_remove(const fil_space_t &space)
{ {
ut_ad(space.purpose == FIL_TYPE_TABLESPACE); ut_ad(!space.is_temporary());
ut_ad(!space.is_being_imported());
fil_space_crypt_t *crypt_data = space.crypt_data; fil_space_crypt_t *crypt_data = space.crypt_data;
mysql_mutex_assert_owner(&fil_system.mutex); mysql_mutex_assert_owner(&fil_system.mutex);
const ulong encrypt_tables= srv_encrypt_tables; const ulong encrypt_tables= srv_encrypt_tables;
@ -1103,7 +1104,8 @@ fil_crypt_space_needs_rotation(
fil_space_t* space = &*state->space; fil_space_t* space = &*state->space;
ut_ad(space->referenced()); ut_ad(space->referenced());
ut_ad(space->purpose == FIL_TYPE_TABLESPACE); ut_ad(!space->is_temporary());
ut_ad(!space->is_being_imported());
fil_space_crypt_t *crypt_data = space->crypt_data; fil_space_crypt_t *crypt_data = space->crypt_data;
@ -1455,7 +1457,7 @@ space_list_t::iterator fil_space_t::next(space_list_t::iterator space,
for (; space != fil_system.space_list.end(); ++space) for (; space != fil_system.space_list.end(); ++space)
{ {
if (space->purpose != FIL_TYPE_TABLESPACE) if (space->is_temporary() || space->is_being_imported())
continue; continue;
const uint32_t n= space->acquire_low(); const uint32_t n= space->acquire_low();
if (UNIV_LIKELY(!(n & (STOPPING | CLOSING)))) if (UNIV_LIKELY(!(n & (STOPPING | CLOSING))))
@ -2137,9 +2139,9 @@ static void fil_crypt_default_encrypt_tables_fill()
mysql_mutex_assert_owner(&fil_system.mutex); mysql_mutex_assert_owner(&fil_system.mutex);
for (fil_space_t& space : fil_system.space_list) { for (fil_space_t& space : fil_system.space_list) {
if (space.purpose != FIL_TYPE_TABLESPACE if (space.is_in_default_encrypt
|| space.is_in_default_encrypt
|| UT_LIST_GET_LEN(space.chain) == 0 || UT_LIST_GET_LEN(space.chain) == 0
|| space.is_temporary() || space.is_being_imported()
|| !space.acquire_if_not_stopped()) { || !space.acquire_if_not_stopped()) {
continue; continue;
} }

View file

@ -81,17 +81,10 @@ bool fil_space_t::try_to_close(fil_space_t *ignore_space, bool print_info)
mysql_mutex_assert_owner(&fil_system.mutex); mysql_mutex_assert_owner(&fil_system.mutex);
for (fil_space_t &space : fil_system.space_list) for (fil_space_t &space : fil_system.space_list)
{ {
if (&space == ignore_space) if (&space == ignore_space || space.is_being_imported() ||
!fil_is_user_tablespace_id(space.id))
continue; continue;
switch (space.purpose) { ut_ad(!space.is_temporary());
case FIL_TYPE_TEMPORARY:
continue;
case FIL_TYPE_IMPORT:
break;
case FIL_TYPE_TABLESPACE:
if (!fil_is_user_tablespace_id(space.id))
continue;
}
/* We are using an approximation of LRU replacement policy. In /* We are using an approximation of LRU replacement policy. In
fil_node_open_file_low(), newly opened files are moved to the end fil_node_open_file_low(), newly opened files are moved to the end
@ -432,7 +425,7 @@ static bool fil_node_open_file(fil_node_t *node, const byte *page, bool no_lsn)
srv_operation == SRV_OPERATION_BACKUP || srv_operation == SRV_OPERATION_BACKUP ||
srv_operation == SRV_OPERATION_RESTORE || srv_operation == SRV_OPERATION_RESTORE ||
srv_operation == SRV_OPERATION_RESTORE_DELTA); srv_operation == SRV_OPERATION_RESTORE_DELTA);
ut_ad(node->space->purpose != FIL_TYPE_TEMPORARY); ut_ad(!node->space->is_temporary());
ut_ad(node->space->referenced()); ut_ad(node->space->referenced());
const auto old_time= fil_system.n_open_exceeded_time; const auto old_time= fil_system.n_open_exceeded_time;
@ -493,7 +486,7 @@ void fil_node_t::prepare_to_close_or_detach()
srv_operation == SRV_OPERATION_RESTORE_DELTA); srv_operation == SRV_OPERATION_RESTORE_DELTA);
ut_a(is_open()); ut_a(is_open());
ut_a(!being_extended); ut_a(!being_extended);
ut_a(space->is_ready_to_close() || space->purpose == FIL_TYPE_TEMPORARY || ut_a(space->is_ready_to_close() || space->is_temporary() ||
srv_fast_shutdown == 2 || !srv_was_started); srv_fast_shutdown == 2 || !srv_was_started);
ut_a(fil_system.n_open > 0); ut_a(fil_system.n_open > 0);
@ -650,14 +643,13 @@ fil_space_extend_must_retry(
mysql_mutex_lock(&fil_system.mutex); mysql_mutex_lock(&fil_system.mutex);
break; break;
default: default:
ut_ad(space->purpose == FIL_TYPE_TABLESPACE ut_ad(!space->is_temporary());
|| space->purpose == FIL_TYPE_IMPORT); if (!space->is_being_imported()) {
if (space->purpose == FIL_TYPE_TABLESPACE) {
goto do_flush; goto do_flush;
} }
break; break;
case SRV_TMP_SPACE_ID: case SRV_TMP_SPACE_ID:
ut_ad(space->purpose == FIL_TYPE_TEMPORARY); ut_ad(space->is_temporary());
srv_tmp_space.set_last_file_size(pages_in_MiB); srv_tmp_space.set_last_file_size(pages_in_MiB);
break; break;
} }
@ -671,8 +663,7 @@ ATTRIBUTE_COLD bool fil_space_t::prepare_acquired()
ut_ad(referenced()); ut_ad(referenced());
mysql_mutex_assert_owner(&fil_system.mutex); mysql_mutex_assert_owner(&fil_system.mutex);
fil_node_t *node= UT_LIST_GET_LAST(chain); fil_node_t *node= UT_LIST_GET_LAST(chain);
ut_ad(!id || purpose == FIL_TYPE_TEMPORARY || ut_ad(!id || is_temporary() || node == UT_LIST_GET_FIRST(chain));
node == UT_LIST_GET_FIRST(chain));
const bool is_open= node && const bool is_open= node &&
(node->is_open() || fil_node_open_file(node, nullptr, false)); (node->is_open() || fil_node_open_file(node, nullptr, false));
@ -734,7 +725,7 @@ ATTRIBUTE_COLD bool fil_space_t::acquire_and_prepare()
@return whether the tablespace is at least as big as requested */ @return whether the tablespace is at least as big as requested */
bool fil_space_extend(fil_space_t *space, uint32_t size) bool fil_space_extend(fil_space_t *space, uint32_t size)
{ {
ut_ad(!srv_read_only_mode || space->purpose == FIL_TYPE_TEMPORARY); ut_ad(!srv_read_only_mode || space->is_temporary());
bool success= false; bool success= false;
const bool acquired= space->acquire(); const bool acquired= space->acquire();
mysql_mutex_lock(&fil_system.mutex); mysql_mutex_lock(&fil_system.mutex);
@ -942,62 +933,44 @@ fil_space_free(
return(space != NULL); return(space != NULL);
} }
/** Create a tablespace in fil_system. fil_space_t::fil_space_t(uint32_t id, ulint flags, bool being_imported,
@param name tablespace name fil_space_crypt_t *crypt_data) noexcept :
@param id tablespace identifier id(id), crypt_data(crypt_data), being_imported(being_imported), flags(flags)
@param flags tablespace flags {
@param purpose tablespace purpose UT_LIST_INIT(chain, &fil_node_t::chain);
@param crypt_data encryption information #ifndef SUX_LOCK_GENERIC
@param mode encryption mode memset((void*) &latch, 0, sizeof latch);
@param opened true if space files are opened #endif
@return pointer to created tablespace, to be filled in with add() latch.SRW_LOCK_INIT(fil_space_latch_key);
@retval nullptr on failure (such as when the same tablespace exists) */ }
fil_space_t *fil_space_t::create(ulint id, ulint flags,
fil_type_t purpose, fil_space_t *fil_space_t::create(uint32_t id, ulint flags,
bool being_imported,
fil_space_crypt_t *crypt_data, fil_space_crypt_t *crypt_data,
fil_encryption_t mode, fil_encryption_t mode,
bool opened) bool opened) noexcept
{ {
fil_space_t* space;
mysql_mutex_assert_owner(&fil_system.mutex); mysql_mutex_assert_owner(&fil_system.mutex);
ut_ad(fil_system.is_initialised()); ut_ad(fil_system.is_initialised());
ut_ad(fil_space_t::is_valid_flags(flags & ~FSP_FLAGS_MEM_MASK, id)); ut_ad(fil_space_t::is_valid_flags(flags & ~FSP_FLAGS_MEM_MASK, id));
ut_ad(srv_page_size == UNIV_PAGE_SIZE_ORIG || flags != 0); ut_ad(srv_page_size == UNIV_PAGE_SIZE_ORIG || flags != 0);
DBUG_EXECUTE_IF("fil_space_create_failure", return(NULL);); DBUG_EXECUTE_IF("fil_space_create_failure", return nullptr;);
fil_space_t** after = reinterpret_cast<fil_space_t**>( fil_space_t** after= fil_system.spaces.cell_get(id)->search
&fil_system.spaces.cell_get(id)->node); (&fil_space_t::hash, [id](const fil_space_t *space)
for (; *after; after = &(*after)->hash) { { return !space || space->id == id; });
ut_a((*after)->id != id); ut_a(!*after);
} fil_space_t *space= new (ut_malloc_nokey(sizeof(*space)))
fil_space_t(id, flags, being_imported, crypt_data);
*after= space;
/* FIXME: if calloc() is defined as an inline function that calls if (crypt_data)
memset() or bzero(), then GCC 6 -flifetime-dse can optimize it away */ DBUG_PRINT("crypt", ("Tablespace %" PRIu32 " encryption %d key id %" PRIu32
*after = space = new (ut_zalloc_nokey(sizeof(*space))) fil_space_t; ":%s %s",
id, crypt_data->encryption, crypt_data->key_id,
space->id = id; fil_crypt_get_mode(crypt_data),
fil_crypt_get_type(crypt_data)));
UT_LIST_INIT(space->chain, &fil_node_t::chain);
space->purpose = purpose;
space->flags = flags;
space->crypt_data = crypt_data;
space->n_pending.store(CLOSING, std::memory_order_relaxed);
DBUG_LOG("tablespace", "Created metadata for " << id);
if (crypt_data) {
DBUG_LOG("crypt",
"Tablespace " << id
<< " encryption " << crypt_data->encryption
<< " key id " << crypt_data->key_id
<< ":" << fil_crypt_get_mode(crypt_data)
<< " " << fil_crypt_get_type(crypt_data));
}
space->latch.SRW_LOCK_INIT(fil_space_latch_key);
if (opened) if (opened)
fil_system.add_opened_last_to_space_list(space); fil_system.add_opened_last_to_space_list(space);
@ -1007,46 +980,40 @@ fil_space_t *fil_space_t::create(ulint id, ulint flags,
switch (id) { switch (id) {
case 0: case 0:
ut_ad(!fil_system.sys_space); ut_ad(!fil_system.sys_space);
fil_system.sys_space = space; fil_system.sys_space= space;
break; break;
case SRV_TMP_SPACE_ID: case SRV_TMP_SPACE_ID:
ut_ad(!fil_system.temp_space); ut_ad(!fil_system.temp_space);
fil_system.temp_space = space; fil_system.temp_space= space;
break; return space;
default: default:
ut_ad(purpose != FIL_TYPE_TEMPORARY); if (UNIV_LIKELY(id <= fil_system.max_assigned_id))
if (UNIV_LIKELY(id <= fil_system.max_assigned_id)) {
break; break;
} if (UNIV_UNLIKELY(srv_operation == SRV_OPERATION_BACKUP))
if (UNIV_UNLIKELY(srv_operation == SRV_OPERATION_BACKUP)) {
break; break;
} if (!fil_system.space_id_reuse_warned)
if (!fil_system.space_id_reuse_warned) { sql_print_warning("InnoDB: Allocated tablespace ID %" PRIu32
ib::warn() << "Allocated tablespace ID " << id ", old maximum was %" PRIu32,
<< ", old maximum was " id, fil_system.max_assigned_id);
<< fil_system.max_assigned_id;
}
fil_system.max_assigned_id = id; fil_system.max_assigned_id = id;
} }
const bool rotate = purpose == FIL_TYPE_TABLESPACE if ((mode == FIL_ENCRYPTION_ON ||
&& (mode == FIL_ENCRYPTION_ON || mode == FIL_ENCRYPTION_OFF (mode == FIL_ENCRYPTION_OFF || srv_encrypt_tables)) &&
|| srv_encrypt_tables) !space->is_being_imported() && fil_crypt_must_default_encrypt())
&& fil_crypt_must_default_encrypt(); {
if (rotate) {
fil_system.default_encrypt_tables.push_back(*space); fil_system.default_encrypt_tables.push_back(*space);
space->is_in_default_encrypt = true; space->is_in_default_encrypt= true;
if (srv_n_fil_crypt_threads_started) { if (srv_n_fil_crypt_threads_started)
{
mysql_mutex_unlock(&fil_system.mutex); mysql_mutex_unlock(&fil_system.mutex);
fil_crypt_threads_signal(); fil_crypt_threads_signal();
mysql_mutex_lock(&fil_system.mutex); mysql_mutex_lock(&fil_system.mutex);
} }
} }
return(space); return space;
} }
/*******************************************************************//** /*******************************************************************//**
@ -1580,6 +1547,7 @@ fil_name_write(
fil_space_t *fil_space_t::drop(ulint id, pfs_os_file_t *detached_handle) fil_space_t *fil_space_t::drop(ulint id, pfs_os_file_t *detached_handle)
{ {
ut_a(!is_system_tablespace(id)); ut_a(!is_system_tablespace(id));
ut_ad(id != SRV_TMP_SPACE_ID);
mysql_mutex_lock(&fil_system.mutex); mysql_mutex_lock(&fil_system.mutex);
fil_space_t *space= fil_space_get_by_id(id); fil_space_t *space= fil_space_get_by_id(id);
@ -1622,7 +1590,7 @@ fil_space_t *fil_space_t::drop(ulint id, pfs_os_file_t *detached_handle)
if (space->crypt_data) if (space->crypt_data)
fil_space_crypt_close_tablespace(space); fil_space_crypt_close_tablespace(space);
if (space->purpose == FIL_TYPE_TABLESPACE) if (!space->is_being_imported())
{ {
/* Before deleting the file, persistently write a log record. */ /* Before deleting the file, persistently write a log record. */
mtr_t mtr; mtr_t mtr;
@ -1635,8 +1603,6 @@ fil_space_t *fil_space_t::drop(ulint id, pfs_os_file_t *detached_handle)
os_file_delete(innodb_data_file_key, space->chain.start->name); os_file_delete(innodb_data_file_key, space->chain.start->name);
} }
else
ut_ad(space->purpose == FIL_TYPE_IMPORT);
if (char *cfg_name= fil_make_filepath(space->chain.start->name, if (char *cfg_name= fil_make_filepath(space->chain.start->name,
fil_space_t::name_type{}, CFG, false)) fil_space_t::name_type{}, CFG, false))
@ -1935,7 +1901,7 @@ fil_ibd_create(
uint32_t size, uint32_t size,
fil_encryption_t mode, fil_encryption_t mode,
uint32_t key_id, uint32_t key_id,
dberr_t* err) dberr_t* err) noexcept
{ {
pfs_os_file_t file; pfs_os_file_t file;
bool success; bool success;
@ -2055,8 +2021,8 @@ err_exit:
log_make_checkpoint();); log_make_checkpoint(););
mysql_mutex_lock(&fil_system.mutex); mysql_mutex_lock(&fil_system.mutex);
if (fil_space_t* space = fil_space_t::create(space_id, flags, if (fil_space_t* space = fil_space_t::create(uint32_t(space_id),
FIL_TYPE_TABLESPACE, flags, false,
crypt_data, mode, true)) { crypt_data, mode, true)) {
fil_node_t* node = space->add(path, file, size, false, true); fil_node_t* node = space->add(path, file, size, false, true);
node->find_metadata(IF_WIN(,true)); node->find_metadata(IF_WIN(,true));
@ -2078,51 +2044,17 @@ err_exit:
goto err_exit; goto err_exit;
} }
/** Try to open a single-table tablespace and optionally check that the fil_space_t *fil_ibd_open(ulint id, ulint flags,
space id in it is correct. If this does not succeed, print an error message fil_space_t::validate validate,
to the .err log. This function is used to open a tablespace when we start
mysqld after the dictionary has been booted, and also in IMPORT TABLESPACE.
NOTE that we assume this operation is used either at the database startup
or under the protection of dict_sys.latch, so that two users cannot
race here. This operation does not leave the file associated with the
tablespace open, but closes it after we have looked at the space id in it.
If the validate boolean is set, we read the first page of the file and
check that the space id in the file is what we expect. We assume that
this function runs much faster if no check is made, since accessing the
file inode probably is much faster (the OS caches them) than accessing
the first page of the file. This boolean may be initially false, but if
a remote tablespace is found it will be changed to true.
If the fix_dict boolean is set, then it is safe to use an internal SQL
statement to update the dictionary tables if they are incorrect.
@param[in] validate 0=maybe missing, 1=do not validate, 2=validate
@param[in] purpose FIL_TYPE_TABLESPACE or FIL_TYPE_TEMPORARY
@param[in] id tablespace ID
@param[in] flags expected FSP_SPACE_FLAGS
@param[in] name 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
@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(
unsigned validate,
fil_type_t purpose,
ulint id,
ulint flags,
fil_space_t::name_type name, fil_space_t::name_type name,
const char* path_in, const char *path_in, dberr_t *err) noexcept
dberr_t* err)
{ {
mysql_mutex_lock(&fil_system.mutex); mysql_mutex_lock(&fil_system.mutex);
fil_space_t* space = fil_space_get_by_id(id); fil_space_t* space = fil_space_get_by_id(id);
mysql_mutex_unlock(&fil_system.mutex); mysql_mutex_unlock(&fil_system.mutex);
if (space) { if (space) {
if (validate > 1 && !srv_read_only_mode) { if (validate == fil_space_t::VALIDATE_SPACE_ID
&& !srv_read_only_mode) {
fsp_flags_try_adjust(space, fsp_flags_try_adjust(space,
flags & ~FSP_FLAGS_MEM_MASK); flags & ~FSP_FLAGS_MEM_MASK);
} }
@ -2148,8 +2080,8 @@ func_exit:
ulint tablespaces_found = 0; ulint tablespaces_found = 0;
ulint valid_tablespaces_found = 0; ulint valid_tablespaces_found = 0;
df_default.init(flags); df_default.init(uint32_t(flags));
df_remote.init(flags); df_remote.init(uint32_t(flags));
/* Discover the correct file by looking in three possible locations /* Discover the correct file by looking in three possible locations
while avoiding unecessary effort. */ while avoiding unecessary effort. */
@ -2178,7 +2110,7 @@ func_exit:
/* Dict path is not the default path. Always validate /* Dict path is not the default path. Always validate
remote files. If default is opened, it was moved. */ remote files. If default is opened, it was moved. */
must_validate = true; must_validate = true;
} else if (validate > 1) { } else if (validate >= fil_space_t::VALIDATE_SPACE_ID) {
must_validate = true; must_validate = true;
} }
@ -2195,7 +2127,8 @@ func_exit:
the first server startup. The tables ought to be dropped by the first server startup. The tables ought to be dropped by
drop_garbage_tables_after_restore() a little later. */ drop_garbage_tables_after_restore() a little later. */
const bool strict = validate && !tablespaces_found const bool strict = (validate != fil_space_t::MAYBE_MISSING)
&& !tablespaces_found
&& operation_not_for_export && operation_not_for_export
&& !(srv_operation == SRV_OPERATION_NORMAL && !(srv_operation == SRV_OPERATION_NORMAL
&& srv_start_after_restore && srv_start_after_restore
@ -2326,7 +2259,9 @@ skip_validate:
: NULL; : NULL;
mysql_mutex_lock(&fil_system.mutex); mysql_mutex_lock(&fil_system.mutex);
space = fil_space_t::create(id, flags, purpose, crypt_data); space = fil_space_t::create(uint32_t(id), flags,
validate == fil_space_t::VALIDATE_IMPORT,
crypt_data);
if (!space) { if (!space) {
mysql_mutex_unlock(&fil_system.mutex); mysql_mutex_unlock(&fil_system.mutex);
goto error; goto error;
@ -2344,7 +2279,7 @@ skip_validate:
df_remote.close(); df_remote.close();
df_default.close(); df_default.close();
if (space->acquire()) { if (space->acquire()) {
if (purpose != FIL_TYPE_IMPORT) { if (validate < fil_space_t::VALIDATE_IMPORT) {
fsp_flags_try_adjust(space, flags fsp_flags_try_adjust(space, flags
& ~FSP_FLAGS_MEM_MASK); & ~FSP_FLAGS_MEM_MASK);
} }
@ -2632,8 +2567,8 @@ tablespace_check:
mysql_mutex_lock(&fil_system.mutex); mysql_mutex_lock(&fil_system.mutex);
space = fil_space_t::create( space = fil_space_t::create(uint32_t(space_id), flags, false,
space_id, flags, FIL_TYPE_TABLESPACE, crypt_data); crypt_data);
if (space == NULL) { if (space == NULL) {
mysql_mutex_unlock(&fil_system.mutex); mysql_mutex_unlock(&fil_system.mutex);
@ -2661,16 +2596,14 @@ void fsp_flags_try_adjust(fil_space_t* space, ulint flags)
{ {
ut_ad(!srv_read_only_mode); ut_ad(!srv_read_only_mode);
ut_ad(fil_space_t::is_valid_flags(flags, space->id)); ut_ad(fil_space_t::is_valid_flags(flags, space->id));
ut_ad(!space->is_being_imported());
ut_ad(!space->is_temporary());
if (space->full_crc32() || fil_space_t::full_crc32(flags)) { if (space->full_crc32() || fil_space_t::full_crc32(flags)) {
return; return;
} }
if (!space->size && (space->purpose != FIL_TYPE_TABLESPACE if (!space->size || !space->get_size()) {
|| !space->get_size())) {
return; return;
} }
/* This code is executed during server startup while no
connections are allowed. We do not need to protect against
DROP TABLE by fil_space_acquire(). */
mtr_t mtr; mtr_t mtr;
mtr.start(); mtr.start();
if (buf_block_t* b = buf_page_get( if (buf_block_t* b = buf_page_get(
@ -2760,7 +2693,7 @@ inline void fil_node_t::complete_write()
{ {
mysql_mutex_assert_not_owner(&fil_system.mutex); mysql_mutex_assert_not_owner(&fil_system.mutex);
if (space->purpose != FIL_TYPE_TEMPORARY && if (!space->is_temporary() &&
srv_file_flush_method != SRV_O_DIRECT_NO_FSYNC && srv_file_flush_method != SRV_O_DIRECT_NO_FSYNC &&
space->set_needs_flush()) space->set_needs_flush())
{ {
@ -3074,8 +3007,8 @@ fil_space_validate_for_mtr_commit(
{ {
mysql_mutex_assert_not_owner(&fil_system.mutex); mysql_mutex_assert_not_owner(&fil_system.mutex);
ut_ad(space != NULL); ut_ad(space != NULL);
ut_ad(space->purpose == FIL_TYPE_TABLESPACE);
ut_ad(!is_predefined_tablespace(space->id)); ut_ad(!is_predefined_tablespace(space->id));
ut_ad(!space->is_being_imported());
/* We are serving mtr_commit(). While there is an active /* We are serving mtr_commit(). While there is an active
mini-transaction, we should have !space->is_stopping(). This is mini-transaction, we should have !space->is_stopping(). This is
@ -3290,7 +3223,7 @@ fil_space_t::name_type fil_space_t::name() const
if (!UT_LIST_GET_FIRST(chain) || srv_is_undo_tablespace(id)) if (!UT_LIST_GET_FIRST(chain) || srv_is_undo_tablespace(id))
return name_type{}; return name_type{};
ut_ad(purpose != FIL_TYPE_TEMPORARY); ut_ad(!is_temporary());
ut_ad(UT_LIST_GET_LEN(chain) == 1); ut_ad(UT_LIST_GET_LEN(chain) == 1);
const char *path= UT_LIST_GET_FIRST(chain)->name; const char *path= UT_LIST_GET_FIRST(chain)->name;

View file

@ -352,7 +352,7 @@ xdes_get_descriptor_with_space_hdr(
ut_ad(limit == space->free_limit ut_ad(limit == space->free_limit
|| (space->free_limit == 0 || (space->free_limit == 0
&& (init_space && (init_space
|| space->purpose == FIL_TYPE_TEMPORARY || space->is_temporary()
|| (srv_startup_is_before_trx_rollback_phase || (srv_startup_is_before_trx_rollback_phase
&& (space->id == TRX_SYS_SPACE && (space->id == TRX_SYS_SPACE
|| srv_is_undo_tablespace(space->id)))))); || srv_is_undo_tablespace(space->id))))));
@ -490,14 +490,15 @@ void fil_space_t::modify_check(const mtr_t& mtr) const
case MTR_LOG_NONE: case MTR_LOG_NONE:
/* These modes are only allowed within a non-bitmap page /* These modes are only allowed within a non-bitmap page
when there is a higher-level redo log record written. */ when there is a higher-level redo log record written. */
ut_ad(purpose == FIL_TYPE_TABLESPACE || purpose == FIL_TYPE_TEMPORARY); ut_ad(!is_being_imported());
break; break;
case MTR_LOG_NO_REDO: case MTR_LOG_NO_REDO:
ut_ad(purpose == FIL_TYPE_TEMPORARY || purpose == FIL_TYPE_IMPORT); ut_ad(is_temporary() || is_being_imported());
break; break;
default: default:
/* We may only write redo log for a persistent tablespace. */ /* We may only write redo log for a persistent tablespace. */
ut_ad(purpose == FIL_TYPE_TABLESPACE); ut_ad(!is_temporary());
ut_ad(!is_being_imported());
ut_ad(mtr.is_named_space(id)); ut_ad(mtr.is_named_space(id));
} }
} }
@ -857,7 +858,7 @@ fsp_fill_free_list(
FIL_PAGE_TYPE_XDES); FIL_PAGE_TYPE_XDES);
} }
if (space->purpose != FIL_TYPE_TEMPORARY) if (!space->is_temporary())
{ {
buf_block_t *f= buf_LRU_get_free_block(false); buf_block_t *f= buf_LRU_get_free_block(false);
buf_block_t *block= buf_block_t *block=

View file

@ -132,10 +132,8 @@ Tablespace::open_or_create(bool is_temp)
mysql_mutex_lock(&fil_system.mutex); mysql_mutex_lock(&fil_system.mutex);
space = fil_space_t::create( space = fil_space_t::create(
m_space_id, fsp_flags, uint32_t(m_space_id), fsp_flags,
is_temp false, nullptr);
? FIL_TYPE_TEMPORARY : FIL_TYPE_TABLESPACE,
NULL);
if (!space) { if (!space) {
mysql_mutex_unlock(&fil_system.mutex); mysql_mutex_unlock(&fil_system.mutex);
return DB_ERROR; return DB_ERROR;

View file

@ -936,8 +936,7 @@ SysTablespace::open_or_create(
} else if (is_temp) { } else if (is_temp) {
ut_ad(space_id() == SRV_TMP_SPACE_ID); ut_ad(space_id() == SRV_TMP_SPACE_ID);
space = fil_space_t::create( space = fil_space_t::create(
SRV_TMP_SPACE_ID, flags(), SRV_TMP_SPACE_ID, flags(), false, nullptr);
FIL_TYPE_TEMPORARY, NULL);
ut_ad(space == fil_system.temp_space); ut_ad(space == fil_system.temp_space);
if (!space) { if (!space) {
err = DB_ERROR; err = DB_ERROR;
@ -948,8 +947,7 @@ SysTablespace::open_or_create(
} else { } else {
ut_ad(space_id() == TRX_SYS_SPACE); ut_ad(space_id() == TRX_SYS_SPACE);
space = fil_space_t::create( space = fil_space_t::create(
TRX_SYS_SPACE, it->flags(), TRX_SYS_SPACE, it->flags(), false, nullptr);
FIL_TYPE_TABLESPACE, NULL);
ut_ad(space == fil_system.sys_space); ut_ad(space == fil_system.sys_space);
if (!space) { if (!space) {
err = DB_ERROR; err = DB_ERROR;

View file

@ -6562,7 +6562,8 @@ static int i_s_sys_tablespaces_fill_table(THD *thd, TABLE_LIST *tables, Item*)
for (fil_space_t &space : fil_system.space_list) for (fil_space_t &space : fil_system.space_list)
{ {
if (space.purpose == FIL_TYPE_TABLESPACE && !space.is_stopping() && if (!space.is_temporary() && !space.is_being_imported() &&
!space.is_stopping() &&
space.chain.start) space.chain.start)
{ {
space.reacquire(); space.reacquire();
@ -6734,7 +6735,7 @@ i_s_dict_fill_tablespaces_encryption(
} else if (srv_is_undo_tablespace(space->id)) { } else if (srv_is_undo_tablespace(space->id)) {
char undo_name[sizeof "innodb_undo000"]; char undo_name[sizeof "innodb_undo000"];
snprintf(undo_name, sizeof(undo_name), snprintf(undo_name, sizeof(undo_name),
"innodb_undo%03zu",space->id); "innodb_undo%03" PRIu32, space->id);
OK(fields[TABLESPACES_ENCRYPTION_NAME]->store( OK(fields[TABLESPACES_ENCRYPTION_NAME]->store(
undo_name, strlen(undo_name), undo_name, strlen(undo_name),
system_charset_info)); system_charset_info));
@ -6802,7 +6803,7 @@ i_s_tablespaces_encryption_fill_table(
fil_system.freeze_space_list++; fil_system.freeze_space_list++;
for (fil_space_t& space : fil_system.space_list) { for (fil_space_t& space : fil_system.space_list) {
if (space.purpose == FIL_TYPE_TABLESPACE if (!space.is_temporary() && !space.is_being_imported()
&& !space.is_stopping()) { && !space.is_stopping()) {
space.reacquire(); space.reacquire();
mysql_mutex_unlock(&fil_system.mutex); mysql_mutex_unlock(&fil_system.mutex);

View file

@ -738,13 +738,15 @@ ibuf_set_free_bits_func(
mtr.start(); mtr.start();
const page_id_t id(block->page.id()); const page_id_t id(block->page.id());
const fil_space_t *space= mtr.set_named_space_id(id.space()); const fil_space_t *space= mtr.set_named_space_id(id.space());
/* all callers of ibuf_update_free_bits_if_full() or ibuf_reset_free_bits()
check this */
ut_ad(!space->is_temporary());
if (buf_block_t *bitmap_page= if (buf_block_t *bitmap_page=
ibuf_bitmap_get_map_page(id, block->zip_size(), &mtr)) ibuf_bitmap_get_map_page(id, block->zip_size(), &mtr))
{ {
if (space->purpose != FIL_TYPE_TABLESPACE) if (space->is_being_imported()) /* IndexPurge may invoke this */
mtr.set_log_mode(MTR_LOG_NO_REDO); mtr.set_log_mode(MTR_LOG_NO_REDO);
#ifdef UNIV_IBUF_DEBUG #ifdef UNIV_IBUF_DEBUG
if (max_val != ULINT_UNDEFINED) if (max_val != ULINT_UNDEFINED)
{ {
@ -925,8 +927,7 @@ ibuf_page_low(
return(false); return(false);
} }
compile_time_assert(IBUF_SPACE_ID == 0); static_assert(IBUF_SPACE_ID == 0, "compatiblity");
ut_ad(fil_system.sys_space->purpose == FIL_TYPE_TABLESPACE);
#ifdef UNIV_DEBUG #ifdef UNIV_DEBUG
if (x_latch) { if (x_latch) {
@ -4498,7 +4499,7 @@ ibuf_print(
dberr_t ibuf_check_bitmap_on_import(const trx_t* trx, fil_space_t* space) dberr_t ibuf_check_bitmap_on_import(const trx_t* trx, fil_space_t* space)
{ {
ut_ad(trx->mysql_thd); ut_ad(trx->mysql_thd);
ut_ad(space->purpose == FIL_TYPE_IMPORT); ut_ad(space->is_being_imported());
const unsigned zip_size = space->zip_size(); const unsigned zip_size = space->zip_size();
const unsigned physical_size = space->physical_size(); const unsigned physical_size = space->physical_size();

View file

@ -100,16 +100,6 @@ class page_id_t;
/** Structure containing encryption specification */ /** Structure containing encryption specification */
struct fil_space_crypt_t; struct fil_space_crypt_t;
/** File types */
enum fil_type_t {
/** temporary tablespace (temporary undo log or tables) */
FIL_TYPE_TEMPORARY,
/** a tablespace that is being imported (no logging until finished) */
FIL_TYPE_IMPORT,
/** persistent tablespace (for system, undo log or tables) */
FIL_TYPE_TABLESPACE,
};
struct fil_node_t; struct fil_node_t;
/** Structure to store first and last value of range */ /** Structure to store first and last value of range */
@ -344,42 +334,43 @@ struct fil_space_t final
{ {
#ifndef UNIV_INNOCHECKSUM #ifndef UNIV_INNOCHECKSUM
friend fil_node_t; friend fil_node_t;
/** Constructor; see @fil_space_t::create() */
inline explicit fil_space_t(uint32_t id, ulint flags, bool being_imported,
fil_space_crypt_t *crypt_data) noexcept;
~fil_space_t() ~fil_space_t()
{ {
ut_ad(!latch_owner); ut_ad(!latch_owner);
latch.destroy(); latch.destroy();
} }
ulint id; /*!< space id */ /** tablespace identifier */
uint32_t id;
/** fil_system.spaces chain node */ /** fil_system.spaces chain node */
fil_space_t *hash; fil_space_t *hash= nullptr;
lsn_t max_lsn; /** log_sys.get_lsn() of the most recent fil_names_write_if_was_clean().
/*!< LSN of the most recent Reset to 0 by fil_names_clear(). Protected by log_sys.mutex.
fil_names_write_if_was_clean(). If and only if this is nonzero, the tablespace will be in named_spaces. */
Reset to 0 by fil_names_clear(). lsn_t max_lsn= 0;
Protected by log_sys.mutex. /** base node for the chain of data files; multiple entries are
If and only if this is nonzero, the only possible for is_temporary() or id==0 */
tablespace will be in named_spaces. */
fil_type_t purpose;/*!< purpose */
UT_LIST_BASE_NODE_T(fil_node_t) chain; UT_LIST_BASE_NODE_T(fil_node_t) chain;
/*!< base node for the file chain */ /** tablespace size in pages; 0 if not determined yet */
uint32_t size; /*!< tablespace file size in pages; uint32_t size= 0;
0 if not known yet */ /** FSP_SIZE in the tablespace header; 0 if not determined yet */
uint32_t size_in_header; uint32_t size_in_header= 0;
/* FSP_SIZE in the tablespace header; /** length of the FSP_FREE list */
0 if not known yet */ uint32_t free_len= 0;
uint32_t free_len; /** contents of FSP_FREE_LIMIT */
/*!< length of the FSP_FREE list */ uint32_t free_limit= 0;
uint32_t free_limit; /** recovered tablespace size in pages; 0 if no size change was read
/*!< contents of FSP_FREE_LIMIT */ from the redo log, or if the size change was applied */
uint32_t recv_size; uint32_t recv_size= 0;
/*!< recovered tablespace size in pages; /** number of reserved free extents for ongoing operations like
0 if no size change was read from the redo log, B-tree page split */
or if the size change was implemented */ uint32_t n_reserved_extents= 0;
uint32_t n_reserved_extents;
/*!< number of reserved free extents for
ongoing operations like B-tree page split */
private: private:
#ifdef UNIV_DEBUG #ifdef UNIV_DEBUG
fil_space_t *next_in_space_list(); fil_space_t *next_in_space_list();
@ -390,10 +381,10 @@ private:
#endif #endif
/** the committed size of the tablespace in pages */ /** the committed size of the tablespace in pages */
Atomic_relaxed<uint32_t> committed_size; Atomic_relaxed<uint32_t> committed_size{0};
/** Number of pending operations on the file. /** Number of pending operations on the file.
The tablespace cannot be freed while (n_pending & PENDING) != 0. */ The tablespace cannot be freed while (n_pending & PENDING) != 0. */
std::atomic<uint32_t> n_pending; std::atomic<uint32_t> n_pending{CLOSING};
/** Flag in n_pending that indicates that the tablespace is about to be /** Flag in n_pending that indicates that the tablespace is about to be
deleted, and no further operations should be performed */ deleted, and no further operations should be performed */
static constexpr uint32_t STOPPING_READS= 1U << 31; static constexpr uint32_t STOPPING_READS= 1U << 31;
@ -415,20 +406,23 @@ private:
/** latch protecting all page allocation bitmap pages */ /** latch protecting all page allocation bitmap pages */
IF_DBUG(srw_lock_debug, srw_lock) latch; IF_DBUG(srw_lock_debug, srw_lock) latch;
/** the thread that holds the exclusive latch, or 0 */ /** the thread that holds the exclusive latch, or 0 */
pthread_t latch_owner; pthread_t latch_owner= 0;
public: public:
/** MariaDB encryption data */ /** MariaDB encryption data */
fil_space_crypt_t *crypt_data; fil_space_crypt_t *crypt_data= nullptr;
/** Whether needs_flush(), or this is in fil_system.unflushed_spaces */ /** Whether needs_flush(), or this is in fil_system.unflushed_spaces */
bool is_in_unflushed_spaces; bool is_in_unflushed_spaces= false;
/** Whether this in fil_system.default_encrypt_tables (needs key rotation) */ /** Whether this in fil_system.default_encrypt_tables (needs key rotation) */
bool is_in_default_encrypt; bool is_in_default_encrypt= false;
private: private:
/** Whether the tablespace is being imported */
bool being_imported= false;
/** Whether any corrupton of this tablespace has been reported */ /** Whether any corrupton of this tablespace has been reported */
mutable std::atomic_flag is_corrupted; mutable std::atomic_flag is_corrupted{false};
/** mutex to protect freed_ranges and last_freed_lsn */ /** mutex to protect freed_ranges and last_freed_lsn */
std::mutex freed_range_mutex; std::mutex freed_range_mutex;
@ -437,11 +431,18 @@ private:
range_set freed_ranges; range_set freed_ranges;
/** LSN of freeing last page; protected by freed_range_mutex */ /** LSN of freeing last page; protected by freed_range_mutex */
lsn_t last_freed_lsn; lsn_t last_freed_lsn= 0;
/** LSN of undo tablespace creation or 0; protected by latch */ /** LSN of undo tablespace creation or 0; protected by latch */
lsn_t create_lsn; lsn_t create_lsn= 0;
public: public:
/** @return whether this is the temporary tablespace */
bool is_temporary() const noexcept
{ return UNIV_UNLIKELY(id == SRV_TMP_SPACE_ID); }
/** @return whether this tablespace is being imported */
bool is_being_imported() const noexcept
{ return UNIV_UNLIKELY(being_imported); }
/** @return whether doublewrite buffering is needed */ /** @return whether doublewrite buffering is needed */
inline bool use_doublewrite() const; inline bool use_doublewrite() const;
@ -511,7 +512,7 @@ public:
MY_ATTRIBUTE((nonnull)); MY_ATTRIBUTE((nonnull));
/** Note that the tablespace has been imported. /** Note that the tablespace has been imported.
Initially, purpose=FIL_TYPE_IMPORT so that no redo log is Initially, purpose=IMPORT so that no redo log is
written while the space ID is being updated in each page. */ written while the space ID is being updated in each page. */
inline void set_imported(); inline void set_imported();
@ -948,16 +949,16 @@ public:
/** Create a tablespace in fil_system. /** Create a tablespace in fil_system.
@param id tablespace identifier @param id tablespace identifier
@param flags tablespace flags @param flags tablespace flags
@param purpose tablespace purpose @param being_imported whether this is IMPORT TABLESPACE
@param crypt_data encryption information @param crypt_data encryption information
@param mode encryption mode @param mode encryption mode
@param opened true if space files are opened @param opened whether the tablespace files are open
@return pointer to created tablespace, to be filled in with add() @return pointer to created tablespace, to be filled in with add()
@retval nullptr on failure (such as when the same tablespace exists) */ @retval nullptr on failure (such as when the same tablespace exists) */
static fil_space_t *create(ulint id, ulint flags, static fil_space_t *create(uint32_t id, ulint flags, bool being_imported,
fil_type_t purpose, fil_space_crypt_t *crypt_data, fil_space_crypt_t *crypt_data,
fil_encryption_t mode= FIL_ENCRYPTION_DEFAULT, fil_encryption_t mode= FIL_ENCRYPTION_DEFAULT,
bool opened= false); bool opened= false) noexcept;
MY_ATTRIBUTE((warn_unused_result)) MY_ATTRIBUTE((warn_unused_result))
/** Acquire a tablespace reference. /** Acquire a tablespace reference.
@ -1079,6 +1080,18 @@ public:
/** @return the tablespace name (databasename/tablename) */ /** @return the tablespace name (databasename/tablename) */
name_type name() const; name_type name() const;
/** How to validate tablespace files that are being opened */
enum validate {
/** the file may be missing */
MAYBE_MISSING= 0,
/** do not validate */
VALIDATE_NOTHING,
/** validate the tablespace ID */
VALIDATE_SPACE_ID,
/** opening a file for ALTER TABLE...IMPORT TABLESPACE */
VALIDATE_IMPORT
};
private: private:
/** @return whether the file is usable for io() */ /** @return whether the file is usable for io() */
ATTRIBUTE_COLD bool prepare_acquired(); ATTRIBUTE_COLD bool prepare_acquired();
@ -1163,8 +1176,8 @@ inline bool fil_space_t::use_doublewrite() const
inline void fil_space_t::set_imported() inline void fil_space_t::set_imported()
{ {
ut_ad(purpose == FIL_TYPE_IMPORT); ut_ad(being_imported);
purpose= FIL_TYPE_TABLESPACE; being_imported= false;
UT_LIST_GET_FIRST(chain)->find_metadata(); UT_LIST_GET_FIRST(chain)->find_metadata();
} }
@ -1478,12 +1491,9 @@ public:
ulint n_open; ulint n_open;
/** last time we noted n_open exceeding the limit; protected by mutex */ /** last time we noted n_open exceeding the limit; protected by mutex */
time_t n_open_exceeded_time; time_t n_open_exceeded_time;
ulint max_assigned_id;/*!< maximum space id in the existing /** maximum space id in the existing tables; on InnoDB startup this is
tables, or assigned during the time initialized based on the data dictionary contents */
mysqld has been up; at an InnoDB ulint max_assigned_id;
startup we scan the data dictionary
and set here the maximum of the
space id's of the tables there */
/** nonzero if fil_node_open_file_low() should avoid moving the tablespace /** nonzero if fil_node_open_file_low() should avoid moving the tablespace
to the end of space_list, for FIFO policy of try_to_close() */ to the end of space_list, for FIFO policy of try_to_close() */
ulint freeze_space_list; ulint freeze_space_list;
@ -1588,7 +1598,7 @@ template<bool have_reference> inline void fil_space_t::flush()
{ {
mysql_mutex_assert_not_owner(&fil_system.mutex); mysql_mutex_assert_not_owner(&fil_system.mutex);
ut_ad(!have_reference || (pending() & PENDING)); ut_ad(!have_reference || (pending() & PENDING));
ut_ad(purpose == FIL_TYPE_TABLESPACE || purpose == FIL_TYPE_IMPORT); ut_ad(!is_temporary());
if (srv_file_flush_method == SRV_O_DIRECT_NO_FSYNC) if (srv_file_flush_method == SRV_O_DIRECT_NO_FSYNC)
{ {
ut_ad(!is_in_unflushed_spaces); ut_ad(!is_in_unflushed_spaces);
@ -1729,7 +1739,7 @@ fil_ibd_create(
uint32_t size, uint32_t size,
fil_encryption_t mode, fil_encryption_t mode,
uint32_t key_id, uint32_t key_id,
dberr_t* err) dberr_t* err) noexcept
MY_ATTRIBUTE((nonnull, warn_unused_result)); MY_ATTRIBUTE((nonnull, warn_unused_result));
/** Try to adjust FSP_SPACE_FLAGS if they differ from the expectations. /** Try to adjust FSP_SPACE_FLAGS if they differ from the expectations.
@ -1738,43 +1748,28 @@ fil_ibd_create(
@param[in] flags desired tablespace flags */ @param[in] flags desired tablespace flags */
void fsp_flags_try_adjust(fil_space_t* space, ulint flags); void fsp_flags_try_adjust(fil_space_t* space, ulint flags);
/********************************************************************//** /**
Tries to open a single-table tablespace and optionally checks the space id is Tries to open a single-table tablespace and optionally checks the space id is
right in it. If does not succeed, prints an error message to the .err log. This right in it. If does not succeed, prints an error message to the .err log. This
function is used to open a tablespace when we start up mysqld, and also in function is used to open a tablespace when we start up mysqld, and also in
IMPORT TABLESPACE. IMPORT TABLESPACE.
NOTE that we assume this operation is used either at the database startup
or under the protection of dict_sys.latch, so that two users cannot
race here. This operation does not leave the file associated with the
tablespace open, but closes it after we have looked at the space id in it.
If the validate boolean is set, we read the first page of the file and NOTE that we assume this operation is used either at the database
check that the space id in the file is what we expect. We assume that startup or under the protection of MDL, to prevent concurrent access
this function runs much faster if no check is made, since accessing the to the same tablespace.
file inode probably is much faster (the OS caches them) than accessing
the first page of the file. This boolean may be initially false, but if
a remote tablespace is found it will be changed to true.
@param[in] validate 0=maybe missing, 1=do not validate, 2=validate @param id tablespace identifier
@param[in] purpose FIL_TYPE_TABLESPACE or FIL_TYPE_TEMPORARY @param flags expected FSP_SPACE_FLAGS
@param[in] id tablespace ID @param validate how to validate files
@param[in] flags expected FSP_SPACE_FLAGS @param name the table name in databasename/tablename format
@param[in] name table name @param path_in expected filepath, usually read from dictionary
If file-per-table, it is the table name in the databasename/tablename format @param err DB_SUCCESS or error code
@param[in] path_in expected filepath, usually read from dictionary
@param[out] err DB_SUCCESS or error code
@return tablespace @return tablespace
@retval NULL if the tablespace could not be opened */ @retval nullptr if the tablespace could not be opened */
fil_space_t* fil_space_t *fil_ibd_open(ulint id, ulint flags,
fil_ibd_open( fil_space_t::validate validate,
unsigned validate,
fil_type_t purpose,
ulint id,
ulint flags,
fil_space_t::name_type name, fil_space_t::name_type name,
const char* path_in, const char *path_in, dberr_t *err= nullptr) noexcept;
dberr_t* err = NULL)
MY_ATTRIBUTE((warn_unused_result));
enum fil_load_status { enum fil_load_status {
/** The tablespace file(s) were found and valid. */ /** The tablespace file(s) were found and valid. */

View file

@ -93,9 +93,9 @@ void recv_sys_justify_left_parsing_buf();
@param[in] len length of name, in bytes @param[in] len length of name, in bytes
@param[in] new_name new file name (NULL if not rename) @param[in] new_name new file name (NULL if not rename)
@param[in] new_len length of new_name, in bytes (0 if NULL) */ @param[in] new_len length of new_name, in bytes (0 if NULL) */
extern void (*log_file_op)(ulint space_id, int type, extern void (*log_file_op)(uint32_t space_id, int type,
const byte* name, ulint len, const byte* name, size_t len,
const byte* new_name, ulint new_len); const byte* new_name, size_t new_len);
/** Report an operation which does undo log tablespace truncation /** Report an operation which does undo log tablespace truncation
during backup during backup
@ -104,7 +104,7 @@ extern void (*undo_space_trunc)(uint32_t space_id);
/** Report an operation which does INIT_PAGE for page0 during backup. /** Report an operation which does INIT_PAGE for page0 during backup.
@param space_id tablespace identifier */ @param space_id tablespace identifier */
extern void (*first_page_init)(ulint space_id); extern void (*first_page_init)(uint32_t space_id);
/** Stored redo log record */ /** Stored redo log record */
struct log_rec_t struct log_rec_t

View file

@ -598,10 +598,10 @@ struct file_name_t {
/** Map of dirty tablespaces during recovery */ /** Map of dirty tablespaces during recovery */
typedef std::map< typedef std::map<
ulint, uint32_t,
file_name_t, file_name_t,
std::less<ulint>, std::less<ulint>,
ut_allocator<std::pair<const ulint, file_name_t> > > recv_spaces_t; ut_allocator<std::pair<const uint32_t, file_name_t> > > recv_spaces_t;
static recv_spaces_t recv_spaces; static recv_spaces_t recv_spaces;
@ -820,8 +820,8 @@ processed:
if (crypt_data && !fil_crypt_check(crypt_data, name.c_str())) if (crypt_data && !fil_crypt_check(crypt_data, name.c_str()))
return nullptr; return nullptr;
mysql_mutex_lock(&fil_system.mutex); mysql_mutex_lock(&fil_system.mutex);
fil_space_t *space= fil_space_t::create(it->first, flags, fil_space_t *space= fil_space_t::create(it->first, flags, false,
FIL_TYPE_TABLESPACE, crypt_data); crypt_data);
ut_ad(space); ut_ad(space);
const char *filename= name.c_str(); const char *filename= name.c_str();
if (srv_operation == SRV_OPERATION_RESTORE) if (srv_operation == SRV_OPERATION_RESTORE)
@ -939,13 +939,13 @@ deferred_spaces;
@param[in] len length of name, in bytes @param[in] len length of name, in bytes
@param[in] new_name new file name (NULL if not rename) @param[in] new_name new file name (NULL if not rename)
@param[in] new_len length of new_name, in bytes (0 if NULL) */ @param[in] new_len length of new_name, in bytes (0 if NULL) */
void (*log_file_op)(ulint space_id, int type, void (*log_file_op)(uint32_t space_id, int type,
const byte* name, ulint len, const byte* name, size_t len,
const byte* new_name, ulint new_len); const byte* new_name, size_t new_len);
void (*undo_space_trunc)(uint32_t space_id); void (*undo_space_trunc)(uint32_t space_id);
void (*first_page_init)(ulint space_id); void (*first_page_init)(uint32_t space_id);
/** Information about initializing page contents during redo log processing. /** Information about initializing page contents during redo log processing.
FIXME: Rely on recv_sys.pages! */ FIXME: Rely on recv_sys.pages! */
@ -4203,7 +4203,7 @@ recv_validate_tablespace(bool rescan, bool& missing_tablespace)
for (recv_sys_t::map::iterator p = recv_sys.pages.begin(); for (recv_sys_t::map::iterator p = recv_sys.pages.begin();
p != recv_sys.pages.end();) { p != recv_sys.pages.end();) {
ut_ad(!p->second.log.empty()); ut_ad(!p->second.log.empty());
const ulint space = p->first.space(); const uint32_t space = p->first.space();
if (is_predefined_tablespace(space)) { if (is_predefined_tablespace(space)) {
next: next:
p++; p++;
@ -4213,7 +4213,7 @@ next:
recv_spaces_t::iterator i = recv_spaces.find(space); recv_spaces_t::iterator i = recv_spaces.find(space);
ut_ad(i != recv_spaces.end()); ut_ad(i != recv_spaces.end());
if (deferred_spaces.find(static_cast<uint32_t>(space))) { if (deferred_spaces.find(space)) {
/* Skip redo logs belonging to /* Skip redo logs belonging to
incomplete tablespaces */ incomplete tablespaces */
goto next; goto next;

View file

@ -488,8 +488,7 @@ mtr_t::x_lock_space(ulint space_id)
} else { } else {
space = fil_space_get(space_id); space = fil_space_get(space_id);
ut_ad(m_log_mode != MTR_LOG_NO_REDO ut_ad(m_log_mode != MTR_LOG_NO_REDO
|| space->purpose == FIL_TYPE_TEMPORARY || space->is_temporary() || space->is_being_imported());
|| space->purpose == FIL_TYPE_IMPORT);
} }
ut_ad(space); ut_ad(space);
@ -502,9 +501,6 @@ mtr_t::x_lock_space(ulint space_id)
@param space tablespace */ @param space tablespace */
void mtr_t::x_lock_space(fil_space_t *space) void mtr_t::x_lock_space(fil_space_t *space)
{ {
ut_ad(space->purpose == FIL_TYPE_TEMPORARY ||
space->purpose == FIL_TYPE_IMPORT ||
space->purpose == FIL_TYPE_TABLESPACE);
if (!memo_contains(*space)) if (!memo_contains(*space))
{ {
memo_push(space, MTR_MEMO_SPACE_X_LOCK); memo_push(space, MTR_MEMO_SPACE_X_LOCK);

View file

@ -3947,13 +3947,19 @@ void fil_node_t::find_metadata(IF_WIN(,bool create)) noexcept
punch_hole= 2; punch_hole= 2;
else else
punch_hole= IF_WIN(, !create ||) os_is_sparse_file_supported(file); punch_hole= IF_WIN(, !create ||) os_is_sparse_file_supported(file);
if (space->purpose != FIL_TYPE_TABLESPACE)
{
/* For temporary tablespace or during IMPORT TABLESPACE, we /* For temporary tablespace or during IMPORT TABLESPACE, we
disable neighbour flushing and do not care about atomicity. */ disable neighbour flushing and do not care about atomicity. */
if (space->is_temporary())
{
on_ssd= true; on_ssd= true;
atomic_write= true; atomic_write= true;
if (space->purpose == FIL_TYPE_TEMPORARY || !space->is_compressed()) return;
}
if (space->is_being_imported())
{
on_ssd= true;
atomic_write= true;
if (!space->is_compressed())
return; return;
} }
#ifdef _WIN32 #ifdef _WIN32

View file

@ -4841,11 +4841,10 @@ import_error:
we will not be writing any redo log for it before we have invoked we will not be writing any redo log for it before we have invoked
fil_space_t::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); table->space = fil_ibd_open(table->space_id,
dict_tf_to_fsp_flags(table->flags),
table->space = fil_ibd_open( fil_space_t::VALIDATE_IMPORT,
2, FIL_TYPE_IMPORT, table->space_id, name, filepath, &err);
fsp_flags, name, filepath, &err);
ut_ad((table->space == NULL) == (err != DB_SUCCESS)); ut_ad((table->space == NULL) == (err != DB_SUCCESS));
DBUG_EXECUTE_IF("ib_import_open_tablespace_failure", DBUG_EXECUTE_IF("ib_import_open_tablespace_failure",
@ -4947,8 +4946,6 @@ import_error:
} }
ib::info() << "Phase IV - Flush complete"; ib::info() << "Phase IV - Flush complete";
/* Set tablespace purpose as FIL_TYPE_TABLESPACE,
so that rollback can go ahead smoothly */
table->space->set_imported(); table->space->set_imported();
err = lock_sys_tables(trx); err = lock_sys_tables(trx);

View file

@ -575,8 +575,8 @@ err_exit:
fil_set_max_space_id_if_bigger(space_id); fil_set_max_space_id_if_bigger(space_id);
mysql_mutex_lock(&fil_system.mutex); mysql_mutex_lock(&fil_system.mutex);
fil_space_t *space= fil_space_t::create(space_id, fsp_flags, fil_space_t *space= fil_space_t::create(uint32_t(space_id),
FIL_TYPE_TABLESPACE, nullptr, fsp_flags, false, nullptr,
FIL_ENCRYPTION_DEFAULT, true); FIL_ENCRYPTION_DEFAULT, true);
ut_ad(space); ut_ad(space);
fil_node_t *file= space->add(name, fh, 0, false, true); fil_node_t *file= space->add(name, fh, 0, false, true);

View file

@ -238,7 +238,8 @@ static trx_rseg_t *trx_rseg_create(ulint space_id)
if (fil_space_t *space= mtr.x_lock_space(space_id)) if (fil_space_t *space= mtr.x_lock_space(space_id))
{ {
ut_ad(space->purpose == FIL_TYPE_TABLESPACE); ut_ad(!space->is_temporary());
ut_ad(!space->is_being_imported());
if (buf_block_t *sys_header= trx_sysf_get(&mtr)) if (buf_block_t *sys_header= trx_sysf_get(&mtr))
{ {
ulint rseg_id= trx_sys_rseg_find_free(sys_header); ulint rseg_id= trx_sys_rseg_find_free(sys_header);