summaryrefslogtreecommitdiff
path: root/storage/innobase/fil/fil0fil.cc
diff options
context:
space:
mode:
Diffstat (limited to 'storage/innobase/fil/fil0fil.cc')
-rw-r--r--storage/innobase/fil/fil0fil.cc197
1 files changed, 72 insertions, 125 deletions
diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc
index dceaad099ca..a8299b8afc4 100644
--- a/storage/innobase/fil/fil0fil.cc
+++ b/storage/innobase/fil/fil0fil.cc
@@ -887,18 +887,22 @@ bool fil_space_free(uint32_t id, bool x_latched)
}
if (!recv_recovery_is_on()) {
- mysql_mutex_lock(&log_sys.mutex);
- }
-
- mysql_mutex_assert_owner(&log_sys.mutex);
+ log_sys.latch.wr_lock(SRW_LOCK_CALL);
- if (space->max_lsn != 0) {
- ut_d(space->max_lsn = 0);
- fil_system.named_spaces.remove(*space);
- }
+ if (space->max_lsn) {
+ ut_d(space->max_lsn = 0);
+ fil_system.named_spaces.remove(*space);
+ }
- if (!recv_recovery_is_on()) {
- mysql_mutex_unlock(&log_sys.mutex);
+ log_sys.latch.wr_unlock();
+ } else {
+#ifndef SUX_LOCK_GENERIC
+ ut_ad(log_sys.latch.is_write_locked());
+#endif
+ if (space->max_lsn) {
+ ut_d(space->max_lsn = 0);
+ fil_system.named_spaces.remove(*space);
+ }
}
fil_space_free_low(space);
@@ -1393,46 +1397,6 @@ void fil_set_max_space_id_if_bigger(uint32_t max_id)
mysql_mutex_unlock(&fil_system.mutex);
}
-/** Write the flushed LSN to the page header of the first page in the
-system tablespace.
-@param[in] lsn flushed LSN
-@return DB_SUCCESS or error number */
-dberr_t
-fil_write_flushed_lsn(
- lsn_t lsn)
-{
- byte* buf;
- ut_ad(!srv_read_only_mode);
-
- if (!fil_system.sys_space->acquire()) {
- return DB_ERROR;
- }
-
- buf = static_cast<byte*>(aligned_malloc(srv_page_size, srv_page_size));
-
- auto fio = fil_system.sys_space->io(IORequestRead, 0, srv_page_size,
- buf);
-
- if (fio.err == DB_SUCCESS) {
- mach_write_to_8(buf + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION,
- lsn);
-
- uint32_t fsp_flags = mach_read_from_4(
- buf + FSP_HEADER_OFFSET + FSP_SPACE_FLAGS);
-
- if (fil_space_t::full_crc32(fsp_flags)) {
- buf_flush_assign_full_crc32_checksum(buf);
- }
-
- fio = fil_system.sys_space->io(IORequestWrite,
- 0, srv_page_size, buf);
- fil_flush_file_spaces();
- }
-
- aligned_free(buf);
- return fio.err;
-}
-
/** Acquire a tablespace reference.
@param id tablespace identifier
@return tablespace
@@ -1505,7 +1469,7 @@ inline void mtr_t::log_file_op(mfile_type_t type, uint32_t space_id,
{
ut_ad(strchr(new_path, '/'));
m_log.push(reinterpret_cast<const byte*>(path), uint32_t(len + 1));
- m_log.push(reinterpret_cast<const byte*>(new_path), uint32_t(new_len));
+ m_log.push(reinterpret_cast<const byte*>(new_path), uint32_t(new_len - 1));
}
else
m_log.push(reinterpret_cast<const byte*>(path), uint32_t(len));
@@ -1523,6 +1487,15 @@ static void fil_name_write_rename_low(uint32_t space_id, const char *old_name,
mtr->log_file_op(FILE_RENAME, space_id, old_name, new_name);
}
+static void fil_name_commit_durable(mtr_t *mtr)
+{
+ log_sys.latch.wr_lock(SRW_LOCK_CALL);
+ auto lsn= mtr->commit_files();
+ log_sys.latch.wr_unlock();
+ mtr->flag_wr_unlock();
+ log_write_up_to(lsn, true);
+}
+
/** Write redo log for renaming a file.
@param[in] space_id tablespace id
@param[in] old_name tablespace file name
@@ -1533,8 +1506,7 @@ static void fil_name_write_rename(uint32_t space_id,
mtr_t mtr;
mtr.start();
fil_name_write_rename_low(space_id, old_name, new_name, &mtr);
- mtr.commit();
- log_write_up_to(mtr.commit_lsn(), true);
+ fil_name_commit_durable(&mtr);
}
/** Write FILE_MODIFY for a file.
@@ -1664,8 +1636,7 @@ pfs_os_file_t fil_delete_tablespace(uint32_t id)
mtr_t mtr;
mtr.start();
mtr.log_file_op(FILE_DELETE, id, space->chain.start->name);
- mtr.commit();
- log_write_up_to(mtr.commit_lsn(), true);
+ fil_name_commit_durable(&mtr);
/* Remove any additional files. */
if (char *cfg_name= fil_make_filepath(space->chain.start->name,
@@ -1692,13 +1663,13 @@ pfs_os_file_t fil_delete_tablespace(uint32_t id)
handle= fil_system.detach(space, true);
mysql_mutex_unlock(&fil_system.mutex);
- mysql_mutex_lock(&log_sys.mutex);
+ log_sys.latch.wr_lock(SRW_LOCK_CALL);
if (space->max_lsn)
{
ut_d(space->max_lsn = 0);
fil_system.named_spaces.remove(*space);
}
- mysql_mutex_unlock(&log_sys.mutex);
+ log_sys.latch.wr_unlock();
fil_space_free_low(space);
}
@@ -1899,11 +1870,14 @@ static bool fil_rename_tablespace(uint32_t id, const char *old_path,
ut_ad(strchr(new_file_name, '/'));
if (!recv_recovery_is_on()) {
- mysql_mutex_lock(&log_sys.mutex);
+ log_sys.latch.wr_lock(SRW_LOCK_CALL);
}
- /* log_sys.mutex is above fil_system.mutex in the latching order */
- mysql_mutex_assert_owner(&log_sys.mutex);
+ /* log_sys.latch is above fil_system.mutex in the latching order */
+#ifndef SUX_LOCK_GENERIC
+ ut_ad(log_sys.latch.is_write_locked() ||
+ srv_operation == SRV_OPERATION_RESTORE_DELTA);
+#endif
mysql_mutex_lock(&fil_system.mutex);
space->release();
ut_ad(node->name == old_file_name);
@@ -1926,7 +1900,7 @@ skip_second_rename:
}
if (!recv_recovery_is_on()) {
- mysql_mutex_unlock(&log_sys.mutex);
+ log_sys.latch.wr_unlock();
}
mysql_mutex_unlock(&fil_system.mutex);
@@ -1979,8 +1953,7 @@ fil_ibd_create(
mtr.start();
mtr.log_file_op(FILE_CREATE, space_id, path);
- mtr.commit();
- log_write_up_to(mtr.commit_lsn(), true);
+ fil_name_commit_durable(&mtr);
ulint type;
static_assert(((UNIV_ZIP_SIZE_MIN >> 1) << 3) == 4096,
@@ -2779,8 +2752,8 @@ fil_io_t fil_space_t::io(const IORequest &type, os_offset_t offset, size_t len,
void *buf, buf_page_t *bpage)
{
ut_ad(referenced());
- ut_ad(offset % OS_FILE_LOG_BLOCK_SIZE == 0);
- ut_ad((len % OS_FILE_LOG_BLOCK_SIZE) == 0);
+ ut_ad(offset % UNIV_ZIP_SIZE_MIN == 0);
+ ut_ad(len % 512 == 0); /* page_compressed */
ut_ad(fil_validate_skip());
ut_ad(type.is_read() || type.is_write());
ut_ad(type.type != IORequest::DBLWR_BATCH);
@@ -3079,19 +3052,6 @@ fil_space_validate_for_mtr_commit(
}
#endif /* UNIV_DEBUG */
-/** Write a FILE_MODIFY record for a persistent tablespace.
-@param[in] space tablespace
-@param[in,out] mtr mini-transaction */
-static
-void
-fil_names_write(
- const fil_space_t* space,
- mtr_t* mtr)
-{
- ut_ad(UT_LIST_GET_LEN(space->chain) == 1);
- fil_name_write(space->id, UT_LIST_GET_FIRST(space->chain)->name, mtr);
-}
-
/** Note that a non-predefined persistent tablespace has been modified
by redo log.
@param[in,out] space tablespace */
@@ -3099,7 +3059,9 @@ void
fil_names_dirty(
fil_space_t* space)
{
- mysql_mutex_assert_owner(&log_sys.mutex);
+#ifndef SUX_LOCK_GENERIC
+ ut_ad(log_sys.latch.is_write_locked());
+#endif
ut_ad(recv_recovery_is_on());
ut_ad(log_sys.get_lsn() != 0);
ut_ad(space->max_lsn == 0);
@@ -3109,56 +3071,48 @@ fil_names_dirty(
space->max_lsn = log_sys.get_lsn();
}
-/** Write FILE_MODIFY records when a non-predefined persistent
-tablespace was modified for the first time since the latest
-fil_names_clear().
-@param[in,out] space tablespace */
-void fil_names_dirty_and_write(fil_space_t* space)
+/** Write a FILE_MODIFY record when a non-predefined persistent
+tablespace was modified for the first time since fil_names_clear(). */
+ATTRIBUTE_NOINLINE ATTRIBUTE_COLD void mtr_t::name_write()
{
- mysql_mutex_assert_owner(&log_sys.mutex);
- ut_d(fil_space_validate_for_mtr_commit(space));
- ut_ad(space->max_lsn == log_sys.get_lsn());
-
- fil_system.named_spaces.push_back(*space);
- mtr_t mtr;
- mtr.start();
- fil_names_write(space, &mtr);
+#ifndef SUX_LOCK_GENERIC
+ ut_ad(log_sys.latch.is_write_locked());
+#endif
+ ut_d(fil_space_validate_for_mtr_commit(m_user_space));
+ ut_ad(!m_user_space->max_lsn);
+ m_user_space->max_lsn= log_sys.get_lsn();
- DBUG_EXECUTE_IF("fil_names_write_bogus",
- {
- char bogus_name[] = "./test/bogus file.ibd";
- fil_name_write(
- SRV_SPACE_ID_UPPER_BOUND,
- bogus_name, &mtr);
- });
+ fil_system.named_spaces.push_back(*m_user_space);
+ ut_ad(UT_LIST_GET_LEN(m_user_space->chain) == 1);
- mtr.commit_files();
+ mtr_t mtr;
+ mtr.start();
+ fil_name_write(m_user_space->id,
+ UT_LIST_GET_FIRST(m_user_space->chain)->name,
+ &mtr);
+ mtr.commit_files();
}
/** On a log checkpoint, reset fil_names_dirty_and_write() flags
-and write out FILE_MODIFY and FILE_CHECKPOINT if needed.
-@param[in] lsn checkpoint LSN
-@param[in] do_write whether to always write FILE_CHECKPOINT
-@return whether anything was written to the redo log
-@retval false if no flags were set and nothing written
-@retval true if anything was written to the redo log */
-bool
-fil_names_clear(
- lsn_t lsn,
- bool do_write)
+and write out FILE_MODIFY if needed, and write FILE_CHECKPOINT.
+@param lsn checkpoint LSN
+@return current LSN */
+lsn_t fil_names_clear(lsn_t lsn)
{
mtr_t mtr;
- mysql_mutex_assert_owner(&log_sys.mutex);
+#ifndef SUX_LOCK_GENERIC
+ ut_ad(log_sys.latch.is_write_locked());
+#endif
ut_ad(lsn);
+ ut_ad(log_sys.is_latest());
mtr.start();
for (auto it = fil_system.named_spaces.begin();
it != fil_system.named_spaces.end(); ) {
- if (mtr.get_log_size()
- + strlen(it->chain.start->name)
- >= RECV_SCAN_SIZE - (3 + 5 + 1)) {
+ if (mtr.get_log_size() + strlen(it->chain.start->name)
+ >= recv_sys.MTR_SIZE_MAX - (3 + 5)) {
/* Prevent log parse buffer overflow */
mtr.commit_files();
mtr.start();
@@ -3181,20 +3135,13 @@ fil_names_clear(
was called. If we kept track of "min_lsn" (the first LSN
where max_lsn turned nonzero), we could avoid the
fil_names_write() call if min_lsn > lsn. */
-
- fil_names_write(&*it, &mtr);
- do_write = true;
-
+ ut_ad(UT_LIST_GET_LEN((*it).chain) == 1);
+ fil_name_write((*it).id, UT_LIST_GET_FIRST((*it).chain)->name,
+ &mtr);
it = next;
}
- if (do_write) {
- mtr.commit_files(lsn);
- } else {
- ut_ad(!mtr.has_modifications());
- }
-
- return(do_write);
+ return mtr.commit_files(lsn);
}
/* Unit Tests */