Commit c27e53f4 authored by Marko Mäkelä's avatar Marko Mäkelä

MDEV-23855: Use normal mutex for log_sys.mutex, log_sys.flush_order_mutex

With an unreasonably small innodb_log_file_size, the page cleaner
thread would frequently acquire log_sys.flush_order_mutex and spend
a significant portion of CPU time spinning on that mutex when
determining the checkpoint LSN.
parent a5a2ef07
......@@ -2711,7 +2711,7 @@ static bool xtrabackup_copy_logfile(bool last = false)
xtrabackup_io_throttling();
log_mutex_enter();
mysql_mutex_lock(&log_sys.mutex);
lsn_t lsn= start_lsn;
for (int retries= 0; retries < 100; retries++) {
if (log_sys.log.read_log_seg(&lsn, end_lsn)
......@@ -2735,7 +2735,7 @@ static bool xtrabackup_copy_logfile(bool last = false)
mutex_exit(&recv_sys.mutex);
}
log_mutex_exit();
mysql_mutex_unlock(&log_sys.mutex);
if (!start_lsn) {
const char *reason = recv_sys.found_corrupt_log
......@@ -2795,10 +2795,10 @@ static os_thread_ret_t DECLARE_THREAD(log_copying_thread)(void*)
break;
}
log_mutex_enter();
mysql_mutex_lock(&log_sys.mutex);
bool completed = metadata_to_lsn
&& metadata_to_lsn <= log_copy_scanned_lsn;
log_mutex_exit();
mysql_mutex_unlock(&log_sys.mutex);
if (completed) {
break;
}
......@@ -3848,7 +3848,7 @@ static bool xtrabackup_backup_low()
{
ulint max_cp_field;
log_mutex_enter();
mysql_mutex_lock(&log_sys.mutex);
if (recv_find_max_checkpoint(&max_cp_field) == DB_SUCCESS
&& log_sys.log.format != 0) {
......@@ -3865,7 +3865,7 @@ static bool xtrabackup_backup_low()
} else {
msg("Error: recv_find_max_checkpoint() failed.");
}
log_mutex_exit();
mysql_mutex_unlock(&log_sys.mutex);
}
stop_backup_threads();
......@@ -4037,20 +4037,20 @@ static bool xtrabackup_backup_func()
/* get current checkpoint_lsn */
/* Look for the latest checkpoint from any of the log groups */
log_mutex_enter();
mysql_mutex_lock(&log_sys.mutex);
reread_log_header:
dberr_t err = recv_find_max_checkpoint(&max_cp_field);
if (err != DB_SUCCESS) {
msg("Error: cannot read redo log header");
log_mutex_exit();
mysql_mutex_unlock(&log_sys.mutex);
goto fail;
}
if (log_sys.log.format == 0) {
msg("Error: cannot process redo log before MariaDB 10.2.2");
log_mutex_exit();
mysql_mutex_unlock(&log_sys.mutex);
goto fail;
}
......@@ -4067,7 +4067,7 @@ static bool xtrabackup_backup_func()
!= mach_read_from_8(buf + LOG_CHECKPOINT_OFFSET))
goto reread_log_header;
log_mutex_exit();
mysql_mutex_unlock(&log_sys.mutex);
xtrabackup_init_datasinks();
......@@ -4603,7 +4603,7 @@ xb_delta_open_matching_space(
return OS_FILE_CLOSED;
}
log_mutex_enter();
mysql_mutex_lock(&log_sys.mutex);
if (!fil_is_user_tablespace_id(info.space_id)) {
found:
/* open the file and return its handle */
......@@ -4616,7 +4616,7 @@ xb_delta_open_matching_space(
msg("mariabackup: Cannot open file %s\n", real_name);
}
exit:
log_mutex_exit();
mysql_mutex_unlock(&log_sys.mutex);
return file;
}
......
......@@ -132,7 +132,7 @@ static void buf_flush_validate_skip()
void buf_flush_insert_into_flush_list(buf_block_t* block, lsn_t lsn)
{
mysql_mutex_assert_not_owner(&buf_pool.mutex);
ut_ad(log_flush_order_mutex_own());
mysql_mutex_assert_owner(&log_sys.flush_order_mutex);
ut_ad(lsn);
mysql_mutex_lock(&buf_pool.flush_list_mutex);
......@@ -1564,7 +1564,7 @@ ulint buf_flush_lists(ulint max_n, lsn_t lsn)
static bool log_checkpoint_low(lsn_t oldest_lsn, lsn_t end_lsn)
{
ut_ad(!srv_read_only_mode);
ut_ad(log_mutex_own());
mysql_mutex_assert_owner(&log_sys.mutex);
ut_ad(oldest_lsn <= end_lsn);
ut_ad(end_lsn == log_sys.get_lsn());
ut_ad(!recv_no_log_write);
......@@ -1581,7 +1581,7 @@ static bool log_checkpoint_low(lsn_t oldest_lsn, lsn_t end_lsn)
{
/* Do nothing, because nothing was logged (other than a
FILE_CHECKPOINT record) since the previous checkpoint. */
log_mutex_exit();
mysql_mutex_unlock(&log_sys.mutex);
return true;
}
......@@ -1602,12 +1602,12 @@ static bool log_checkpoint_low(lsn_t oldest_lsn, lsn_t end_lsn)
{
flush_lsn= log_sys.get_lsn();
ut_ad(flush_lsn >= end_lsn + SIZE_OF_FILE_CHECKPOINT);
log_mutex_exit();
mysql_mutex_unlock(&log_sys.mutex);
log_write_up_to(flush_lsn, true, true);
log_mutex_enter();
mysql_mutex_lock(&log_sys.mutex);
if (log_sys.last_checkpoint_lsn >= oldest_lsn)
{
log_mutex_exit();
mysql_mutex_unlock(&log_sys.mutex);
return true;
}
}
......@@ -1619,13 +1619,13 @@ static bool log_checkpoint_low(lsn_t oldest_lsn, lsn_t end_lsn)
if (log_sys.n_pending_checkpoint_writes)
{
/* A checkpoint write is running */
log_mutex_exit();
mysql_mutex_unlock(&log_sys.mutex);
return false;
}
log_sys.next_checkpoint_lsn= oldest_lsn;
log_write_checkpoint_info(end_lsn);
ut_ad(!log_mutex_own());
mysql_mutex_assert_not_owner(&log_sys.mutex);
return true;
}
......@@ -1649,13 +1649,13 @@ static bool log_checkpoint()
fil_flush_file_spaces();
}
log_mutex_enter();
mysql_mutex_lock(&log_sys.mutex);
const lsn_t end_lsn= log_sys.get_lsn();
log_flush_order_mutex_enter();
mysql_mutex_lock(&log_sys.flush_order_mutex);
mysql_mutex_lock(&buf_pool.flush_list_mutex);
const lsn_t oldest_lsn= buf_pool.get_oldest_modification(end_lsn);
mysql_mutex_unlock(&buf_pool.flush_list_mutex);
log_flush_order_mutex_exit();
mysql_mutex_unlock(&log_sys.flush_order_mutex);
return log_checkpoint_low(oldest_lsn, end_lsn);
}
......@@ -1672,7 +1672,7 @@ ATTRIBUTE_COLD void buf_flush_wait_flushed(lsn_t sync_lsn)
{
ut_ad(sync_lsn);
ut_ad(sync_lsn < LSN_MAX);
ut_ad(!log_mutex_own());
mysql_mutex_assert_not_owner(&log_sys.mutex);
ut_ad(!srv_read_only_mode);
if (recv_recovery_is_on())
......@@ -1732,7 +1732,7 @@ ATTRIBUTE_COLD void buf_flush_wait_flushed(lsn_t sync_lsn)
@param lsn buf_pool.get_oldest_modification(LSN_MAX) target */
void buf_flush_ahead(lsn_t lsn)
{
ut_ad(!log_mutex_own());
mysql_mutex_assert_not_owner(&log_sys.mutex);
ut_ad(!srv_read_only_mode);
if (recv_recovery_is_on())
......@@ -1792,12 +1792,12 @@ ATTRIBUTE_COLD static void buf_flush_sync_for_checkpoint(lsn_t lsn)
fil_flush_file_spaces();
}
log_mutex_enter();
mysql_mutex_lock(&log_sys.mutex);
const lsn_t newest_lsn= log_sys.get_lsn();
log_flush_order_mutex_enter();
mysql_mutex_lock(&log_sys.flush_order_mutex);
mysql_mutex_lock(&buf_pool.flush_list_mutex);
lsn_t measure= buf_pool.get_oldest_modification(0);
log_flush_order_mutex_exit();
mysql_mutex_unlock(&log_sys.flush_order_mutex);
const lsn_t checkpoint_lsn= measure ? measure : newest_lsn;
if (checkpoint_lsn > log_sys.last_checkpoint_lsn + SIZE_OF_FILE_CHECKPOINT)
......@@ -1809,12 +1809,12 @@ ATTRIBUTE_COLD static void buf_flush_sync_for_checkpoint(lsn_t lsn)
}
else
{
log_mutex_exit();
mysql_mutex_unlock(&log_sys.mutex);
if (!measure)
measure= LSN_MAX;
}
ut_ad(!log_mutex_own());
mysql_mutex_assert_not_owner(&log_sys.mutex);
/* After attempting log checkpoint, check if we have reached our target. */
const lsn_t target= buf_flush_sync_lsn;
......
......@@ -885,10 +885,10 @@ fil_space_free(
}
if (!recv_recovery_is_on()) {
log_mutex_enter();
mysql_mutex_lock(&log_sys.mutex);
}
ut_ad(log_mutex_own());
mysql_mutex_assert_owner(&log_sys.mutex);
if (space->max_lsn != 0) {
ut_d(space->max_lsn = 0);
......@@ -896,7 +896,7 @@ fil_space_free(
}
if (!recv_recovery_is_on()) {
log_mutex_exit();
mysql_mutex_unlock(&log_sys.mutex);
}
fil_space_free_low(space);
......@@ -1916,14 +1916,14 @@ dberr_t fil_delete_tablespace(ulint id, bool if_exists,
}
mutex_exit(&fil_system.mutex);
log_mutex_enter();
mysql_mutex_lock(&log_sys.mutex);
if (space->max_lsn != 0) {
ut_d(space->max_lsn = 0);
UT_LIST_REMOVE(fil_system.named_spaces, space);
}
log_mutex_exit();
mysql_mutex_unlock(&log_sys.mutex);
fil_space_free_low(space);
if (!os_file_delete(innodb_data_file_key, path)
......@@ -2204,11 +2204,11 @@ fil_rename_tablespace(
if (!recv_recovery_is_on()) {
fil_name_write_rename(id, old_file_name, new_file_name);
log_mutex_enter();
mysql_mutex_lock(&log_sys.mutex);
}
/* log_sys.mutex is above fil_system.mutex in the latching order */
ut_ad(log_mutex_own());
mysql_mutex_assert_owner(&log_sys.mutex);
mutex_enter(&fil_system.mutex);
space->release();
ut_ad(space->name == old_space_name);
......@@ -2230,7 +2230,7 @@ fil_rename_tablespace(
}
if (!recv_recovery_is_on()) {
log_mutex_exit();
mysql_mutex_unlock(&log_sys.mutex);
}
ut_ad(space->name == old_space_name);
......@@ -3667,7 +3667,7 @@ void
fil_names_dirty(
fil_space_t* space)
{
ut_ad(log_mutex_own());
mysql_mutex_assert_owner(&log_sys.mutex);
ut_ad(recv_recovery_is_on());
ut_ad(log_sys.get_lsn() != 0);
ut_ad(space->max_lsn == 0);
......@@ -3683,7 +3683,7 @@ fil_names_clear().
@param[in,out] space tablespace */
void fil_names_dirty_and_write(fil_space_t* space)
{
ut_ad(log_mutex_own());
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());
......@@ -3724,7 +3724,7 @@ fil_names_clear(
mtr_checkpoint_size = 75 * 1024;
);
ut_ad(log_mutex_own());
mysql_mutex_assert_owner(&log_sys.mutex);
ut_ad(lsn);
mtr.start();
......
......@@ -1780,7 +1780,7 @@ for the first time since the latest fil_names_clear().
@return whether any FILE_MODIFY record was written */
inline bool fil_names_write_if_was_clean(fil_space_t* space)
{
ut_ad(log_mutex_own());
mysql_mutex_assert_owner(&log_sys.mutex);
if (space == NULL) {
return(false);
......
......@@ -35,7 +35,6 @@ Created 12/9/1995 Heikki Tuuri
#define log0log_h
#include "log0types.h"
#include "ut0mutex.h"
#include "os0file.h"
#include "span.h"
#include <atomic>
......@@ -127,7 +126,7 @@ ATTRIBUTE_COLD void log_make_checkpoint();
/** Make a checkpoint at the latest lsn on shutdown. */
ATTRIBUTE_COLD void logs_empty_and_mark_files_at_shutdown();
/** Write checkpoint info to the log header and invoke log_mutex_exit().
/** Write checkpoint info to the log header and release log_sys.mutex.
@param[in] end_lsn start LSN of the FILE_CHECKPOINT mini-transaction */
ATTRIBUTE_COLD void log_write_checkpoint_info(lsn_t end_lsn);
......@@ -349,9 +348,6 @@ or the MySQL version that created the redo log file. */
header */
#define LOG_FILE_HDR_SIZE (4 * OS_FILE_LOG_BLOCK_SIZE)
typedef ib_mutex_t LogSysMutex;
typedef ib_mutex_t FlushOrderMutex;
/** Memory mapped file */
class mapped_file_t
{
......@@ -471,7 +467,7 @@ struct log_t{
private:
/** The log sequence number of the last change of durable InnoDB files */
MY_ALIGNED(CACHE_LINE_SIZE)
MY_ALIGNED(CPU_LEVEL1_DCACHE_LINESIZE)
std::atomic<lsn_t> lsn;
/** the first guaranteed-durable log sequence number */
std::atomic<lsn_t> flushed_to_disk_lsn;
......@@ -480,10 +476,8 @@ struct log_t{
This must hold if lsn - last_checkpoint_lsn > max_checkpoint_age. */
std::atomic<bool> check_flush_or_checkpoint_;
public:
/** mutex protecting the log */
MY_ALIGNED(CACHE_LINE_SIZE)
LogSysMutex mutex;
MY_ALIGNED(CPU_LEVEL1_DCACHE_LINESIZE) mysql_mutex_t mutex;
/** first free offset within the log buffer in use */
size_t buf_free;
/** recommended maximum size of buf, after which the buffer is flushed */
......@@ -492,8 +486,7 @@ struct log_t{
dirty blocks in the list. The idea behind this mutex is to be able
to release log_sys.mutex during mtr_commit and still ensure that
insertions in the flush_list happen in the LSN order. */
MY_ALIGNED(CACHE_LINE_SIZE) FlushOrderMutex
log_flush_order_mutex;
MY_ALIGNED(CPU_LEVEL1_DCACHE_LINESIZE) mysql_mutex_t flush_order_mutex;
/** log_buffer, append data here */
byte *buf;
/** log_buffer, writing data to file from this buffer.
......@@ -736,7 +729,9 @@ inline lsn_t log_t::file::calc_lsn_offset(lsn_t lsn) const
ut_ad(this == &log_sys.log);
/* The lsn parameters are updated while holding both the mutexes
and it is ok to have either of them while reading */
ut_ad(log_sys.mutex.is_owned() || log_write_lock_own());
#ifdef SAFE_MUTEX
ut_ad(mysql_mutex_is_owner(&log_sys.mutex) || log_write_lock_own());
#endif /* SAFE_MUTEX */
const lsn_t size = capacity();
lsn_t l= lsn - this->lsn;
if (longlong(l) < 0) {
......@@ -749,41 +744,23 @@ inline lsn_t log_t::file::calc_lsn_offset(lsn_t lsn) const
return l + LOG_FILE_HDR_SIZE * (1 + l / (file_size - LOG_FILE_HDR_SIZE));
}
inline void log_t::file::set_lsn(lsn_t a_lsn) {
ut_ad(log_sys.mutex.is_owned() || log_write_lock_own());
lsn = a_lsn;
inline void log_t::file::set_lsn(lsn_t a_lsn)
{
#ifdef SAFE_MUTEX
ut_ad(mysql_mutex_is_owner(&log_sys.mutex) || log_write_lock_own());
#endif /* SAFE_MUTEX */
lsn= a_lsn;
}
inline void log_t::file::set_lsn_offset(lsn_t a_lsn) {
ut_ad(log_sys.mutex.is_owned() || log_write_lock_own());
ut_ad((lsn % OS_FILE_LOG_BLOCK_SIZE) == (a_lsn % OS_FILE_LOG_BLOCK_SIZE));
lsn_offset = a_lsn;
inline void log_t::file::set_lsn_offset(lsn_t a_lsn)
{
#ifdef SAFE_MUTEX
ut_ad(mysql_mutex_is_owner(&log_sys.mutex) || log_write_lock_own());
#endif /* SAFE_MUTEX */
ut_ad((lsn % OS_FILE_LOG_BLOCK_SIZE) == (a_lsn % OS_FILE_LOG_BLOCK_SIZE));
lsn_offset= a_lsn;
}
/** Test if flush order mutex is owned. */
#define log_flush_order_mutex_own() \
mutex_own(&log_sys.log_flush_order_mutex)
/** Acquire the flush order mutex. */
#define log_flush_order_mutex_enter() do { \
mutex_enter(&log_sys.log_flush_order_mutex); \
} while (0)
/** Release the flush order mutex. */
# define log_flush_order_mutex_exit() do { \
mutex_exit(&log_sys.log_flush_order_mutex); \
} while (0)
/** Test if log sys mutex is owned. */
#define log_mutex_own() mutex_own(&log_sys.mutex)
/** Acquire the log sys mutex. */
#define log_mutex_enter() mutex_enter(&log_sys.mutex)
/** Release the log sys mutex. */
#define log_mutex_exit() mutex_exit(&log_sys.mutex)
#include "log0log.ic"
#endif
......@@ -255,7 +255,7 @@ log_reserve_and_write_fast(
ulint len,
lsn_t* start_lsn)
{
ut_ad(log_mutex_own());
mysql_mutex_assert_owner(&log_sys.mutex);
ut_ad(len > 0);
const ulint data_len = len
......
......@@ -106,7 +106,7 @@ struct mtr_t {
/** Commit a mini-transaction that did not modify any pages,
but generated some redo log on a higher level, such as
FILE_MODIFY records and an optional FILE_CHECKPOINT marker.
The caller must invoke log_mutex_enter() and log_mutex_exit().
The caller must hold log_sys.mutex.
This is to be used at log_checkpoint().
@param checkpoint_lsn the log sequence number of a checkpoint, or 0 */
void commit_files(lsn_t checkpoint_lsn= 0);
......
......@@ -199,8 +199,6 @@ enum latch_level_t {
SYNC_FTS_OPTIMIZE,
SYNC_FTS_CACHE_INIT,
SYNC_RECV,
SYNC_LOG_FLUSH_ORDER,
SYNC_LOG,
SYNC_PURGE_QUEUE,
SYNC_TRX_SYS_HEADER,
SYNC_TRX,
......@@ -271,8 +269,6 @@ enum latch_id_t {
LATCH_ID_IBUF_BITMAP,
LATCH_ID_IBUF,
LATCH_ID_IBUF_PESSIMISTIC_INSERT,
LATCH_ID_LOG_SYS,
LATCH_ID_LOG_FLUSH_ORDER,
LATCH_ID_PURGE_SYS_PQ,
LATCH_ID_RECALC_POOL,
LATCH_ID_RECV_SYS,
......
......@@ -50,6 +50,7 @@ Created 12/9/1995 Heikki Tuuri
#include "trx0trx.h"
#include "trx0roll.h"
#include "srv0mon.h"
#include "sync0sync.h"
#include "buf0dump.h"
#include "log0sync.h"
......@@ -83,11 +84,11 @@ void log_buffer_extend(ulong len)
(ut_malloc_dontdump(new_buf_size, PSI_INSTRUMENT_ME));
TRASH_ALLOC(new_flush_buf, new_buf_size);
log_mutex_enter();
mysql_mutex_lock(&log_sys.mutex);
if (len <= srv_log_buffer_size) {
/* Already extended enough by the others */
log_mutex_exit();
mysql_mutex_unlock(&log_sys.mutex);
ut_free_dodump(new_buf, new_buf_size);
ut_free_dodump(new_flush_buf, new_buf_size);
return;
......@@ -109,7 +110,7 @@ void log_buffer_extend(ulong len)
log_sys.max_buf_free = new_buf_size / LOG_BUF_FLUSH_RATIO
- LOG_BUF_FLUSH_MARGIN;
log_mutex_exit();
mysql_mutex_unlock(&log_sys.mutex);
ut_free_dodump(old_buf, old_buf_size);
ut_free_dodump(old_flush_buf, old_buf_size);
......@@ -158,14 +159,14 @@ log_set_capacity(ulonglong file_size)
margin = smallest_capacity - free;
margin = margin - margin / 10; /* Add still some extra safety */
log_mutex_enter();
mysql_mutex_lock(&log_sys.mutex);
log_sys.log_capacity = smallest_capacity;
log_sys.max_modified_age_async = margin - margin / 8;
log_sys.max_checkpoint_age = margin;
log_mutex_exit();
mysql_mutex_unlock(&log_sys.mutex);
return(true);
}
......@@ -177,8 +178,8 @@ void log_t::create()
ut_ad(!is_initialised());
m_initialised= true;
mutex_create(LATCH_ID_LOG_SYS, &mutex);
mutex_create(LATCH_ID_LOG_FLUSH_ORDER, &log_flush_order_mutex);
mysql_mutex_init(log_sys_mutex_key, &mutex, nullptr);
mysql_mutex_init(log_flush_order_mutex_key, &flush_order_mutex, nullptr);
/* Start the lsn from one log block from zero: this way every
log record has a non-zero start lsn, a fact which we will use */
......@@ -622,7 +623,7 @@ log_write_buf(
}
/** Flush the recently written changes to the log file.
and invoke log_mutex_enter(). */
and invoke mysql_mutex_lock(&log_sys.mutex). */
static void log_write_flush_to_disk_low(lsn_t lsn)
{
if (!log_sys.log.writes_are_durable())
......@@ -638,7 +639,7 @@ static inline
void
log_buffer_switch()
{
ut_ad(log_mutex_own());
mysql_mutex_assert_owner(&log_sys.mutex);
ut_ad(log_write_lock_own());
size_t area_end = ut_calc_align<size_t>(
......@@ -662,18 +663,18 @@ which is the "write" part of log_write_up_to().
This function does not flush anything.
Note : the caller must have log_mutex locked, and this
Note : the caller must have log_sys.mutex locked, and this
mutex is released in the function.
*/
static void log_write(bool rotate_key)
{
ut_ad(log_mutex_own());
mysql_mutex_assert_owner(&log_sys.mutex);
ut_ad(!recv_no_log_write);
lsn_t write_lsn;
if (log_sys.buf_free == log_sys.buf_next_to_write) {
/* Nothing to write */
log_mutex_exit();
mysql_mutex_unlock(&log_sys.mutex);
return;
}
......@@ -710,7 +711,7 @@ static void log_write(bool rotate_key)
log_sys.log.set_fields(log_sys.write_lsn);
log_mutex_exit();
mysql_mutex_unlock(&log_sys.mutex);
/* Erase the end of the last log block. */
memset(write_buf + end_offset, 0,
~end_offset & (OS_FILE_LOG_BLOCK_SIZE - 1));
......@@ -801,7 +802,7 @@ void log_write_up_to(lsn_t lsn, bool flush_to_disk, bool rotate_key)
if (write_lock.acquire(lsn) == group_commit_lock::ACQUIRED)
{
log_mutex_enter();
mysql_mutex_lock(&log_sys.mutex);
lsn_t write_lsn= log_sys.get_lsn();
write_lock.set_pending(write_lsn);
......@@ -844,25 +845,24 @@ ATTRIBUTE_COLD static void log_flush_margin()
{
lsn_t lsn = 0;
log_mutex_enter();
mysql_mutex_lock(&log_sys.mutex);
if (log_sys.buf_free > log_sys.max_buf_free) {
/* We can write during flush */
lsn = log_sys.get_lsn();
}
log_mutex_exit();
mysql_mutex_unlock(&log_sys.mutex);
if (lsn) {
log_write_up_to(lsn, false);
}
}
/** Write checkpoint info to the log header and invoke log_mutex_exit().
/** Write checkpoint info to the log header and release log_sys.mutex.
@param[in] end_lsn start LSN of the FILE_CHECKPOINT mini-transaction */
ATTRIBUTE_COLD void log_write_checkpoint_info(lsn_t end_lsn)
{
ut_ad(log_mutex_own());
ut_ad(!srv_read_only_mode);
ut_ad(end_lsn == 0 || end_lsn >= log_sys.next_checkpoint_lsn);
ut_ad(end_lsn <= log_sys.get_lsn());
......@@ -898,7 +898,7 @@ ATTRIBUTE_COLD void log_write_checkpoint_info(lsn_t end_lsn)
++log_sys.n_pending_checkpoint_writes;
log_mutex_exit();
mysql_mutex_unlock(&log_sys.mutex);
/* Note: We alternate the physical place of the checkpoint info.
See the (next_checkpoint_no & 1) below. */
......@@ -909,7 +909,7 @@ ATTRIBUTE_COLD void log_write_checkpoint_info(lsn_t end_lsn)
log_sys.log.flush();
log_mutex_enter();
mysql_mutex_lock(&log_sys.mutex);
--log_sys.n_pending_checkpoint_writes;
ut_ad(log_sys.n_pending_checkpoint_writes == 0);
......@@ -927,7 +927,7 @@ ATTRIBUTE_COLD void log_write_checkpoint_info(lsn_t end_lsn)
DBUG_EXECUTE_IF("crash_after_checkpoint", DBUG_SUICIDE(););
log_mutex_exit();
mysql_mutex_unlock(&log_sys.mutex);
}
/****************************************************************//**
......@@ -939,13 +939,13 @@ ATTRIBUTE_COLD static void log_checkpoint_margin()
{
while (log_sys.check_flush_or_checkpoint())
{
log_mutex_enter();
mysql_mutex_lock(&log_sys.mutex);
ut_ad(!recv_no_log_write);
if (!log_sys.check_flush_or_checkpoint())
{
func_exit:
log_mutex_exit();
mysql_mutex_unlock(&log_sys.mutex);
return;
}
......@@ -958,7 +958,7 @@ ATTRIBUTE_COLD static void log_checkpoint_margin()
goto func_exit;
}
log_mutex_exit();
mysql_mutex_unlock(&log_sys.mutex);
/* We must wait to prevent the tail of the log overwriting the head. */
buf_flush_wait_flushed(std::min(sync_lsn, checkpoint + (1U << 20)));
......@@ -1108,10 +1108,10 @@ ATTRIBUTE_COLD void logs_empty_and_mark_files_at_shutdown()
}
if (log_sys.is_initialised()) {
log_mutex_enter();
mysql_mutex_lock(&log_sys.mutex);
const ulint n_write = log_sys.n_pending_checkpoint_writes;
const ulint n_flush = log_sys.pending_flushes;
log_mutex_exit();
mysql_mutex_unlock(&log_sys.mutex);
if (n_write || n_flush) {
if (srv_print_verbose_log && count > 600) {
......@@ -1154,7 +1154,7 @@ ATTRIBUTE_COLD void logs_empty_and_mark_files_at_shutdown()
"ensuring dirty buffer pool are written to log");
log_make_checkpoint();
log_mutex_enter();
mysql_mutex_lock(&log_sys.mutex);
lsn = log_sys.get_lsn();
......@@ -1163,7 +1163,7 @@ ATTRIBUTE_COLD void logs_empty_and_mark_files_at_shutdown()
+ SIZE_OF_FILE_CHECKPOINT;
ut_ad(lsn >= log_sys.last_checkpoint_lsn);
log_mutex_exit();
mysql_mutex_unlock(&log_sys.mutex);
if (lsn_changed) {
goto loop;
......@@ -1220,7 +1220,7 @@ log_print(
double time_elapsed;
time_t current_time;
log_mutex_enter();
mysql_mutex_lock(&log_sys.mutex);
const lsn_t lsn= log_sys.get_lsn();
mysql_mutex_lock(&buf_pool.flush_list_mutex);
......@@ -1260,7 +1260,7 @@ log_print(
log_sys.n_log_ios_old = log_sys.n_log_ios;
log_sys.last_printout_time = current_time;
log_mutex_exit();
mysql_mutex_unlock(&log_sys.mutex);
}
/**********************************************************************//**
......@@ -1286,8 +1286,8 @@ void log_t::close()
ut_free_dodump(flush_buf, srv_log_buffer_size);
flush_buf = NULL;
mutex_free(&mutex);
mutex_free(&log_flush_order_mutex);
mysql_mutex_destroy(&mutex);
mysql_mutex_destroy(&flush_order_mutex);
recv_sys.close();
}
......
......@@ -1086,7 +1086,7 @@ bool log_t::file::read_log_seg(lsn_t* start_lsn, lsn_t end_lsn)
{
ulint len;
bool success = true;
ut_ad(log_sys.mutex.is_owned());
mysql_mutex_assert_owner(&log_sys.mutex);
ut_ad(!(*start_lsn % OS_FILE_LOG_BLOCK_SIZE));
ut_ad(!(end_lsn % OS_FILE_LOG_BLOCK_SIZE));
byte* buf = log_sys.buf;
......@@ -1209,7 +1209,7 @@ recv_synchronize_groups()
if (!srv_read_only_mode) {
log_write_checkpoint_info(0);
log_mutex_enter();
mysql_mutex_lock(&log_sys.mutex);
}
}
......@@ -1739,7 +1739,7 @@ static void store_freed_or_init_rec(page_id_t page_id, bool freed)
or corruption was noticed */
bool recv_sys_t::parse(lsn_t checkpoint_lsn, store_t *store, bool apply)
{
ut_ad(log_mutex_own());
mysql_mutex_assert_owner(&log_sys.mutex);
ut_ad(mutex_own(&mutex));
ut_ad(parse_start_lsn);
ut_ad(log_sys.is_physical());
......@@ -2378,9 +2378,9 @@ static void recv_recover_page(buf_block_t* block, mtr_t& mtr,
}
buf_block_modify_clock_inc(block);
log_flush_order_mutex_enter();
mysql_mutex_lock(&log_sys.flush_order_mutex);
buf_flush_note_modification(block, start_lsn, end_lsn);
log_flush_order_mutex_exit();
mysql_mutex_unlock(&log_sys.flush_order_mutex);
} else if (free_page && init) {
/* There have been no operations that modify the page.
Any buffered changes must not be merged. A subsequent
......@@ -2599,7 +2599,9 @@ void recv_sys_t::apply(bool last_batch)
mutex_enter(&mutex);
}
ut_ad(!last_batch == log_mutex_own());
#ifdef SAFE_MUTEX
DBUG_ASSERT(!last_batch == mysql_mutex_is_owner(&log_sys.mutex));
#endif /* SAFE_MUTEX */
recv_no_ibuf_operations = !last_batch ||
srv_operation == SRV_OPERATION_RESTORE ||
......@@ -2703,10 +2705,10 @@ void recv_sys_t::apply(bool last_batch)
else
{
mlog_init.reset();
log_mutex_exit();
mysql_mutex_unlock(&log_sys.mutex);
}
ut_ad(!log_mutex_own());
mysql_mutex_assert_not_owner(&log_sys.mutex);
mutex_exit(&mutex);
/* Instead of flushing, last_batch could sort the buf_pool.flush_list
......@@ -2716,7 +2718,7 @@ void recv_sys_t::apply(bool last_batch)
if (!last_batch)
{
buf_pool_invalidate();
log_mutex_enter();
mysql_mutex_lock(&log_sys.mutex);
}
mutex_enter(&mutex);
......@@ -3305,14 +3307,14 @@ recv_recovery_from_checkpoint_start(lsn_t flush_lsn)
recv_sys.recovery_on = true;
log_mutex_enter();
mysql_mutex_lock(&log_sys.mutex);
err = recv_find_max_checkpoint(&max_cp_field);
if (err != DB_SUCCESS) {
recv_sys.recovered_lsn = log_sys.get_lsn();
log_mutex_exit();
mysql_mutex_unlock(&log_sys.mutex);
return(err);
}
......@@ -3336,7 +3338,7 @@ recv_recovery_from_checkpoint_start(lsn_t flush_lsn)
contiguous_lsn = checkpoint_lsn;
switch (log_sys.log.format) {
case 0:
log_mutex_exit();
mysql_mutex_unlock(&log_sys.mutex);
return DB_SUCCESS;
default:
if (end_lsn == 0) {
......@@ -3347,7 +3349,7 @@ recv_recovery_from_checkpoint_start(lsn_t flush_lsn)
break;
}
recv_sys.found_corrupt_log = true;
log_mutex_exit();
mysql_mutex_unlock(&log_sys.mutex);
return(DB_ERROR);
}
......@@ -3365,12 +3367,12 @@ recv_recovery_from_checkpoint_start(lsn_t flush_lsn)
ut_ad(!recv_sys.found_corrupt_fs);
if (srv_read_only_mode && recv_needed_recovery) {
log_mutex_exit();
mysql_mutex_unlock(&log_sys.mutex);
return(DB_READ_ONLY);
}
if (recv_sys.found_corrupt_log && !srv_force_recovery) {
log_mutex_exit();
mysql_mutex_unlock(&log_sys.mutex);
ib::warn() << "Log scan aborted at LSN " << contiguous_lsn;
return(DB_ERROR);
}
......@@ -3378,7 +3380,7 @@ recv_recovery_from_checkpoint_start(lsn_t flush_lsn)
if (recv_sys.mlog_checkpoint_lsn == 0) {
lsn_t scan_lsn = log_sys.log.scanned_lsn;
if (!srv_read_only_mode && scan_lsn != checkpoint_lsn) {
log_mutex_exit();
mysql_mutex_unlock(&log_sys.mutex);
ib::error err;
err << "Missing FILE_CHECKPOINT";
if (end_lsn) {
......@@ -3397,7 +3399,7 @@ recv_recovery_from_checkpoint_start(lsn_t flush_lsn)
if ((recv_sys.found_corrupt_log && !srv_force_recovery)
|| recv_sys.found_corrupt_fs) {
log_mutex_exit();
mysql_mutex_unlock(&log_sys.mutex);
return(DB_ERROR);
}
}
......@@ -3438,7 +3440,7 @@ recv_recovery_from_checkpoint_start(lsn_t flush_lsn)
if (srv_read_only_mode) {
ib::error() << "innodb_read_only"
" prevents crash recovery";
log_mutex_exit();
mysql_mutex_unlock(&log_sys.mutex);
return(DB_READ_ONLY);
}
......@@ -3460,7 +3462,7 @@ recv_recovery_from_checkpoint_start(lsn_t flush_lsn)
rescan, missing_tablespace);
if (err != DB_SUCCESS) {
log_mutex_exit();
mysql_mutex_unlock(&log_sys.mutex);
return(err);
}
......@@ -3490,7 +3492,7 @@ recv_recovery_from_checkpoint_start(lsn_t flush_lsn)
rescan, missing_tablespace);
if (err != DB_SUCCESS) {
log_mutex_exit();
mysql_mutex_unlock(&log_sys.mutex);
return err;
}
......@@ -3514,7 +3516,7 @@ recv_recovery_from_checkpoint_start(lsn_t flush_lsn)
if ((recv_sys.found_corrupt_log
&& !srv_force_recovery)
|| recv_sys.found_corrupt_fs) {
log_mutex_exit();
mysql_mutex_unlock(&log_sys.mutex);
return(DB_ERROR);
}
}
......@@ -3535,7 +3537,7 @@ recv_recovery_from_checkpoint_start(lsn_t flush_lsn)
}
if (recv_sys.recovered_lsn < checkpoint_lsn) {
log_mutex_exit();
mysql_mutex_unlock(&log_sys.mutex);
ib::error() << "Recovered only to lsn:"
<< recv_sys.recovered_lsn << " checkpoint_lsn: " << checkpoint_lsn;
......@@ -3573,7 +3575,7 @@ recv_recovery_from_checkpoint_start(lsn_t flush_lsn)
mutex_exit(&recv_sys.mutex);
log_mutex_exit();
mysql_mutex_unlock(&log_sys.mutex);
recv_lsn_checks_on = true;
......
......@@ -408,12 +408,12 @@ void mtr_t::commit()
lsns= { m_commit_lsn, false };
if (m_made_dirty)
log_flush_order_mutex_enter();
mysql_mutex_lock(&log_sys.flush_order_mutex);
/* It is now safe to release the log mutex because the
flush_order mutex will ensure that we are the first one
to insert into the flush list. */
log_mutex_exit();
mysql_mutex_unlock(&log_sys.mutex);
if (m_freed_pages)
{
......@@ -445,7 +445,7 @@ void mtr_t::commit()
(ReleaseBlocks(lsns.first, m_commit_lsn,
m_memo)));
if (m_made_dirty)
log_flush_order_mutex_exit();
mysql_mutex_unlock(&log_sys.flush_order_mutex);
m_memo.for_each_block_in_reverse(CIterate<ReleaseLatches>());
......@@ -464,12 +464,12 @@ void mtr_t::commit()
/** Commit a mini-transaction that did not modify any pages,
but generated some redo log on a higher level, such as
FILE_MODIFY records and an optional FILE_CHECKPOINT marker.
The caller must invoke log_mutex_enter() and log_mutex_exit().
The caller must hold log_sys.mutex.
This is to be used at log_checkpoint().
@param[in] checkpoint_lsn log checkpoint LSN, or 0 */
void mtr_t::commit_files(lsn_t checkpoint_lsn)
{
ut_ad(log_mutex_own());
mysql_mutex_assert_owner(&log_sys.mutex);
ut_ad(is_active());
ut_ad(!is_inside_ibuf());
ut_ad(m_log_mode == MTR_LOG_ALL);
......@@ -643,7 +643,7 @@ static void log_margin_checkpoint_age(ulint len)
const ulint margin= len + extra_len;
ut_ad(log_mutex_own());
mysql_mutex_assert_owner(&log_sys.mutex);
const lsn_t lsn= log_sys.get_lsn();
......@@ -676,7 +676,7 @@ static lsn_t log_reserve_and_open(size_t len)
{
for (ut_d(ulint count= 0);;)
{
ut_ad(log_mutex_own());
mysql_mutex_assert_owner(&log_sys.mutex);
/* Calculate an upper limit for the space the string may take in
the log buffer */
......@@ -687,7 +687,7 @@ static lsn_t log_reserve_and_open(size_t len)
if (log_sys.buf_free + len_upper_limit <= srv_log_buffer_size)
break;
log_mutex_exit();
mysql_mutex_unlock(&log_sys.mutex);
DEBUG_SYNC_C("log_buf_size_exceeded");
/* Not enough free space, do a write of the log buffer */
......@@ -697,7 +697,7 @@ static lsn_t log_reserve_and_open(size_t len)
ut_ad(++count < 50);
log_mutex_enter();
mysql_mutex_lock(&log_sys.mutex);
}
return log_sys.get_lsn();
......@@ -706,7 +706,7 @@ static lsn_t log_reserve_and_open(size_t len)
/** Append data to the log buffer. */
static void log_write_low(const void *str, size_t size)
{
ut_ad(log_mutex_own());
mysql_mutex_assert_owner(&log_sys.mutex);
const ulint trailer_offset= log_sys.trailer_offset();
do
......@@ -758,7 +758,7 @@ static void log_write_low(const void *str, size_t size)
@return whether buffer pool flushing is needed */
static bool log_close(lsn_t lsn)
{
ut_ad(log_mutex_own());
mysql_mutex_assert_owner(&log_sys.mutex);
ut_ad(lsn == log_sys.get_lsn());
byte *log_block= static_cast<byte*>(ut_align_down(log_sys.buf +
......@@ -820,7 +820,7 @@ inline ulint mtr_t::prepare_write()
if (UNIV_UNLIKELY(m_log_mode != MTR_LOG_ALL)) {
ut_ad(m_log_mode == MTR_LOG_NO_REDO);
ut_ad(m_log.size() == 0);
log_mutex_enter();
mysql_mutex_lock(&log_sys.mutex);
m_commit_lsn = log_sys.get_lsn();
return 0;
}
......@@ -839,7 +839,7 @@ inline ulint mtr_t::prepare_write()
space = NULL;
}
log_mutex_enter();
mysql_mutex_lock(&log_sys.mutex);
if (fil_names_write_if_was_clean(space)) {
len = m_log.size();
......@@ -864,7 +864,7 @@ inline ulint mtr_t::prepare_write()
inline std::pair<lsn_t,bool> mtr_t::finish_write(ulint len)
{
ut_ad(m_log_mode == MTR_LOG_ALL);
ut_ad(log_mutex_own());
mysql_mutex_assert_owner(&log_sys.mutex);
ut_ad(m_log.size() == len);
ut_ad(len > 0);
......
......@@ -1905,23 +1905,23 @@ srv_mon_process_existing_counter(
break;
case MONITOR_PENDING_CHECKPOINT_WRITE:
mutex_enter(&log_sys.mutex);
mysql_mutex_lock(&log_sys.mutex);
value = static_cast<mon_type_t>(
log_sys.n_pending_checkpoint_writes);
mutex_exit(&log_sys.mutex);
mysql_mutex_unlock(&log_sys.mutex);
break;
case MONITOR_LOG_IO:
mutex_enter(&log_sys.mutex);
mysql_mutex_lock(&log_sys.mutex);
value = static_cast<mon_type_t>(log_sys.n_log_ios);
mutex_exit(&log_sys.mutex);
mysql_mutex_unlock(&log_sys.mutex);
break;
case MONITOR_LSN_CHECKPOINT_AGE:
mutex_enter(&log_sys.mutex);
mysql_mutex_lock(&log_sys.mutex);
value = static_cast<mon_type_t>(log_sys.get_lsn()
- log_sys.last_checkpoint_lsn);
mutex_exit(&log_sys.mutex);
mysql_mutex_unlock(&log_sys.mutex);
break;
case MONITOR_OVLD_BUF_OLDEST_LSN:
......
......@@ -1281,13 +1281,13 @@ srv_export_innodb_status(void)
mutex_exit(&srv_innodb_monitor_mutex);
log_mutex_enter();
mysql_mutex_lock(&log_sys.mutex);
export_vars.innodb_lsn_current = log_sys.get_lsn();
export_vars.innodb_lsn_flushed = log_sys.get_flushed_lsn();
export_vars.innodb_lsn_last_checkpoint = log_sys.last_checkpoint_lsn;
export_vars.innodb_checkpoint_max_age = static_cast<ulint>(
log_sys.max_checkpoint_age);
log_mutex_exit();
mysql_mutex_unlock(&log_sys.mutex);
export_vars.innodb_checkpoint_age = static_cast<ulint>(
export_vars.innodb_lsn_current
......
......@@ -303,7 +303,7 @@ static dberr_t create_log_file(bool create_new_db, lsn_t lsn,
}
/* Create a log checkpoint. */
log_mutex_enter();
mysql_mutex_lock(&log_sys.mutex);
if (log_sys.is_encrypted() && !log_crypt_init()) {
return DB_ERROR;
}
......@@ -328,7 +328,7 @@ static dberr_t create_log_file(bool create_new_db, lsn_t lsn,
log_sys.log.write_header_durable(lsn);
log_mutex_exit();
mysql_mutex_unlock(&log_sys.mutex);
log_make_checkpoint();
log_write_up_to(LSN_MAX, true);
......@@ -355,12 +355,12 @@ static dberr_t create_log_file_rename(lsn_t lsn, std::string &logfile0)
ib::info() << "Renaming log file " << logfile0 << " to " << new_name;
log_mutex_enter();
mysql_mutex_lock(&log_sys.mutex);
ut_ad(logfile0.size() == 2 + new_name.size());
logfile0= new_name;
dberr_t err= log_sys.log.rename(std::move(new_name));
log_mutex_exit();
mysql_mutex_unlock(&log_sys.mutex);
DBUG_EXECUTE_IF("innodb_log_abort_10", err= DB_ERROR;);
......@@ -910,7 +910,7 @@ static lsn_t srv_prepare_to_delete_redo_log_file(bool old_exists)
DBUG_EXECUTE_IF("innodb_log_abort_1", DBUG_RETURN(0););
DBUG_PRINT("ib_log", ("After innodb_log_abort_1"));
log_mutex_enter();
mysql_mutex_lock(&log_sys.mutex);
fil_names_clear(log_sys.get_lsn(), false);
......@@ -949,7 +949,7 @@ static lsn_t srv_prepare_to_delete_redo_log_file(bool old_exists)
<< " bytes; LSN=" << flushed_lsn;
}
log_mutex_exit();
mysql_mutex_unlock(&log_sys.mutex);
if (flushed_lsn != log_sys.get_flushed_lsn()) {
log_write_up_to(flushed_lsn, false);
......
......@@ -461,8 +461,6 @@ LatchDebug::LatchDebug()
LEVEL_MAP_INSERT(SYNC_FTS_OPTIMIZE);
LEVEL_MAP_INSERT(SYNC_FTS_CACHE_INIT);
LEVEL_MAP_INSERT(SYNC_RECV);
LEVEL_MAP_INSERT(SYNC_LOG_FLUSH_ORDER);
LEVEL_MAP_INSERT(SYNC_LOG);
LEVEL_MAP_INSERT(SYNC_PURGE_QUEUE);
LEVEL_MAP_INSERT(SYNC_TRX_SYS_HEADER);
LEVEL_MAP_INSERT(SYNC_TRX);
......@@ -734,8 +732,6 @@ LatchDebug::check_order(
case SYNC_FTS_OPTIMIZE:
case SYNC_FTS_CACHE:
case SYNC_FTS_CACHE_INIT:
case SYNC_LOG:
case SYNC_LOG_FLUSH_ORDER:
case SYNC_SEARCH_SYS:
case SYNC_LOCK_SYS:
case SYNC_LOCK_WAIT_SYS:
......@@ -1237,11 +1233,6 @@ sync_latch_meta_init()
LATCH_ADD_MUTEX(IBUF_PESSIMISTIC_INSERT, SYNC_IBUF_PESS_INSERT_MUTEX,
ibuf_pessimistic_insert_mutex_key);
LATCH_ADD_MUTEX(LOG_SYS, SYNC_LOG, log_sys_mutex_key);
LATCH_ADD_MUTEX(LOG_FLUSH_ORDER, SYNC_LOG_FLUSH_ORDER,
log_flush_order_mutex_key);
LATCH_ADD_MUTEX(PURGE_SYS_PQ, SYNC_PURGE_QUEUE,
purge_sys_pq_mutex_key);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment