polardbxengine/storage/innobase/include/log0log.h

1217 lines
50 KiB
C++

/*****************************************************************************
Copyright (c) 1995, 2019, Oracle and/or its affiliates. All rights reserved.
Copyright (c) 2009, Google Inc.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
briefly in the InnoDB documentation. The contributions by Google are
incorporated with their permission, and subject to the conditions contained in
the file COPYING.Google.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License, version 2.0, as published by the
Free Software Foundation.
This program is also distributed with certain software (including but not
limited to OpenSSL) that is licensed under separate terms, as designated in a
particular file or component or in included license documentation. The authors
of MySQL hereby grant you an additional permission to link the program and
your derivative works with the separately licensed software that they have
included with MySQL.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License, version 2.0,
for more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*****************************************************************************/
/**************************************************/ /**
@file include/log0log.h
Redo log constants and functions.
Types are defined inside log0types.h.
Created 12/9/1995 Heikki Tuuri
*******************************************************/
#ifndef log0log_h
#define log0log_h
#include "dyn0buf.h"
#include "univ.i"
#ifndef UNIV_HOTBACKUP
#include "sync0rw.h"
#endif /* !UNIV_HOTBACKUP */
#include "log0test.h"
#include "log0types.h"
/** Prefix for name of log file, e.g. "ib_logfile" */
constexpr const char *const ib_logfile_basename = "ib_logfile";
/* base name length(10) + length for decimal digits(22) */
constexpr uint32_t MAX_LOG_FILE_NAME = 32;
/** Magic value to use instead of log checksums when they are disabled. */
constexpr uint32_t LOG_NO_CHECKSUM_MAGIC = 0xDEADBEEFUL;
/** Absolute margin for the free space in the log, before a new query step
which modifies the database, is started. Expressed in number of pages. */
constexpr uint32_t LOG_CHECKPOINT_EXTRA_FREE = 8;
/** Per thread margin for the free space in the log, before a new query step
which modifies the database, is started. It's multiplied by maximum number
of threads, that can concurrently enter mini transactions. Expressed in
number of pages. */
constexpr uint32_t LOG_CHECKPOINT_FREE_PER_THREAD = 4;
/** Controls asynchronous making of a new checkpoint.
Should be bigger than LOG_POOL_PREFLUSH_RATIO_SYNC. */
constexpr uint32_t LOG_POOL_CHECKPOINT_RATIO_ASYNC = 32;
/** Controls synchronous preflushing of modified buffer pages. */
constexpr uint32_t LOG_POOL_PREFLUSH_RATIO_SYNC = 16;
/** Controls asynchronous preflushing of modified buffer pages.
Should be less than the LOG_POOL_PREFLUSH_RATIO_SYNC. */
constexpr uint32_t LOG_POOL_PREFLUSH_RATIO_ASYNC = 8;
/** The counting of lsn's starts from this value: this must be non-zero. */
constexpr lsn_t LOG_START_LSN = 16 * OS_FILE_LOG_BLOCK_SIZE;
/* Offsets used in a log block header. */
/** Block number which must be > 0 and is allowed to wrap around at 1G.
The highest bit is set to 1, if this is the first block in a call to
fil_io (for possibly many consecutive blocks). */
constexpr uint32_t LOG_BLOCK_HDR_NO = 0;
/** Mask used to get the highest bit in the hdr_no field. */
constexpr uint32_t LOG_BLOCK_FLUSH_BIT_MASK = 0x80000000UL;
/** Maximum allowed block's number (stored in hdr_no). */
constexpr uint32_t LOG_BLOCK_MAX_NO = 0x3FFFFFFFUL + 1;
/** Number of bytes written to this block (also header bytes). */
constexpr uint32_t LOG_BLOCK_HDR_DATA_LEN = 4;
/** Mask used to get the highest bit in the data len field,
this bit is to indicate if this block is encrypted or not. */
constexpr uint32_t LOG_BLOCK_ENCRYPT_BIT_MASK = 0x8000UL;
/** Offset of the first start of mtr log record group in this log block.
0 if none. If the value is the same as LOG_BLOCK_HDR_DATA_LEN, it means
that the first rec group has not yet been concatenated to this log block,
but if it will, it will start at this offset.
An archive recovery can start parsing the log records starting from this
offset in this log block, if value is not 0. */
constexpr uint32_t LOG_BLOCK_FIRST_REC_GROUP = 6;
/** 4 lower bytes of the value of log_sys->next_checkpoint_no when the log
block was last written to: if the block has not yet been written full,
this value is only updated before a log buffer flush. */
constexpr uint32_t LOG_BLOCK_CHECKPOINT_NO = 8;
/** Size of the log block's header in bytes. */
constexpr uint32_t LOG_BLOCK_HDR_SIZE = 12;
/* Offsets used in a log block's footer (refer to the end of the block). */
/** 4 byte checksum of the log block contents. In InnoDB versions < 3.23.52
this did not contain the checksum, but the same value as .._HDR_NO. */
constexpr uint32_t LOG_BLOCK_CHECKSUM = 4;
/** Size of the log block footer (trailer) in bytes. */
constexpr uint32_t LOG_BLOCK_TRL_SIZE = 4;
static_assert(LOG_BLOCK_HDR_SIZE + LOG_BLOCK_TRL_SIZE < OS_FILE_LOG_BLOCK_SIZE,
"Header + footer cannot be larger than the whole log block.");
/** Size of log block's data fragment (where actual data is stored). */
constexpr uint32_t LOG_BLOCK_DATA_SIZE =
OS_FILE_LOG_BLOCK_SIZE - LOG_BLOCK_HDR_SIZE - LOG_BLOCK_TRL_SIZE;
/** Ensure, that 64 bits are enough to represent lsn values, when 63 bits
are used to represent sn values. It is enough to ensure that lsn < 2*sn,
and that is guaranteed if the overhead enumerated in lsn sequence is not
bigger than number of actual data bytes. */
static_assert(LOG_BLOCK_HDR_SIZE + LOG_BLOCK_TRL_SIZE < LOG_BLOCK_DATA_SIZE,
"Overhead in LSN sequence cannot be bigger than actual data.");
/** Maximum possible sn value. */
constexpr sn_t SN_MAX = (1ULL << 62) - 1;
/** Maximum possible lsn value is slightly higher than the maximum sn value,
because lsn sequence enumerates also bytes used for headers and footers of
all log blocks. However, still 64-bits are enough to represent the maximum
lsn value, because only 63 bits are used to represent sn value. */
constexpr lsn_t LSN_MAX = (1ULL << 63) - 1;
/* Offsets inside the checkpoint pages (redo log format version 1). */
/** Checkpoint number. It's incremented by one for each consecutive checkpoint.
During recovery, all headers are scanned, and one with the maximum checkpoint
number is used for the recovery (checkpoint_lsn from the header is used). */
constexpr uint32_t LOG_CHECKPOINT_NO = 0;
/** Checkpoint lsn. Recovery starts from this lsn and searches for the first
log record group that starts since then. In InnoDB < 8.0, it was exact value
at which the first log record group started. Because of the relaxed order in
flush lists, checkpoint lsn values are not precise anymore (the maximum delay
related to the relaxed order in flush lists, is subtracted from oldest_lsn,
when writing a checkpoint). */
constexpr uint32_t LOG_CHECKPOINT_LSN = 8;
/** Offset within the log files, which corresponds to checkpoint lsn.
Used for calibration of lsn and offset calculations. */
constexpr uint32_t LOG_CHECKPOINT_OFFSET = 16;
/** Size of the log buffer, when the checkpoint write was started.
It seems to be write-only field in InnoDB. Not used by recovery.
@note
Note that when the log buffer is being resized, all the log background threads
are stopped, so there no is concurrent checkpoint write (the log_checkpointer
thread is stopped). */
constexpr uint32_t LOG_CHECKPOINT_LOG_BUF_SIZE = 24;
/** Offsets used in a log file header */
/** Log file header format identifier (32-bit unsigned big-endian integer).
This used to be called LOG_GROUP_ID and always written as 0,
because InnoDB never supported more than one copy of the redo log. */
constexpr uint32_t LOG_HEADER_FORMAT = 0;
/** 4 unused (zero-initialized) bytes. */
constexpr uint32_t LOG_HEADER_PAD1 = 4;
/** LSN of the start of data in this log file (with format version 1 and 2). */
constexpr uint32_t LOG_HEADER_START_LSN = 8;
/** A null-terminated string which will contain either the string 'MEB'
and the MySQL version if the log file was created by mysqlbackup,
or 'MySQL' and the MySQL version that created the redo log file. */
constexpr uint32_t LOG_HEADER_CREATOR = 16;
/** End of the log file creator field. */
constexpr uint32_t LOG_HEADER_CREATOR_END = LOG_HEADER_CREATOR + 32;
/** Contents of the LOG_HEADER_CREATOR field */
#define LOG_HEADER_CREATOR_CURRENT "MySQL " INNODB_VERSION_STR
/** Header is created during DB clone */
#define LOG_HEADER_CREATOR_CLONE "MySQL Clone"
/** First checkpoint field in the log header. We write alternately to
the checkpoint fields when we make new checkpoints. This field is only
defined in the first log file. */
constexpr uint32_t LOG_CHECKPOINT_1 = OS_FILE_LOG_BLOCK_SIZE;
/** Log Encryption information in redo log header. */
constexpr uint32_t LOG_ENCRYPTION = 2 * OS_FILE_LOG_BLOCK_SIZE;
/** Second checkpoint field in the header of the first log file. */
constexpr uint32_t LOG_CHECKPOINT_2 = 3 * OS_FILE_LOG_BLOCK_SIZE;
/** Size of log file's header. */
constexpr uint32_t LOG_FILE_HDR_SIZE = 4 * OS_FILE_LOG_BLOCK_SIZE;
/** Constants related to server variables (default, min and max values). */
/** Default value of innodb_log_write_max_size (in bytes). */
constexpr ulint INNODB_LOG_WRITE_MAX_SIZE_DEFAULT = 4096;
/** Default value of innodb_log_checkpointer_every (in milliseconds). */
constexpr ulong INNODB_LOG_CHECKPOINT_EVERY_DEFAULT = 1000; // 1000ms = 1s
/** Default value of innodb_log_writer_spin_delay (in spin rounds).
We measured that 1000 spin round takes 4us. We decided to select 1ms
as the maximum time for busy waiting. Therefore it corresponds to 250k
spin rounds. Note that first wait on event takes 50us-100us (even if 10us
is passed), so it is 5%-10% of the total time that we have already spent
on busy waiting, when we fall back to wait on event. */
constexpr ulong INNODB_LOG_WRITER_SPIN_DELAY_DEFAULT = 250000;
/** Default value of innodb_log_writer_timeout (in microseconds).
Note that it will anyway take at least 50us. */
constexpr ulong INNODB_LOG_WRITER_TIMEOUT_DEFAULT = 10;
/** Default value of innodb_log_spin_cpu_abs_lwm.
Expressed in percent (80 stands for 80%) of a single CPU core. */
constexpr ulong INNODB_LOG_SPIN_CPU_ABS_LWM_DEFAULT = 80;
/** Default value of innodb_log_spin_cpu_pct_hwm.
Expressed in percent (50 stands for 50%) of all CPU cores. */
constexpr uint INNODB_LOG_SPIN_CPU_PCT_HWM_DEFAULT = 50;
/** Default value of innodb_log_wait_for_write_spin_delay (in spin rounds).
Read about INNODB_LOG_WRITER_SPIN_DELAY_DEFAULT.
Number of spin rounds is calculated according to current usage of CPU cores.
If the usage is smaller than lwm percents of single core, then max rounds = 0.
If the usage is smaller than 50% of hwm percents of all cores, then max rounds
is decreasing linearly from 10x innodb_log_writer_spin_delay to 1x (for 50%).
Then in range from 50% of hwm to 100% of hwm, the max rounds stays equal to
the innodb_log_writer_spin_delay, because it doesn't make sense to use too
short waits. Hence this is minimum value for the max rounds when non-zero
value is being used. */
constexpr ulong INNODB_LOG_WAIT_FOR_WRITE_SPIN_DELAY_DEFAULT = 25000;
/** Default value of innodb_log_wait_for_write_timeout (in microseconds). */
constexpr ulong INNODB_LOG_WAIT_FOR_WRITE_TIMEOUT_DEFAULT = 1000;
/** Default value of innodb_log_wait_for_flush_spin_delay (in spin rounds).
Read about INNODB_LOG_WAIT_FOR_WRITE_SPIN_DELAY_DEFAULT. The same mechanism
applies here (to compute max rounds). */
constexpr ulong INNODB_LOG_WAIT_FOR_FLUSH_SPIN_DELAY_DEFAULT = 25000;
/** Default value of innodb_log_wait_for_flush_spin_hwm (in microseconds). */
constexpr ulong INNODB_LOG_WAIT_FOR_FLUSH_SPIN_HWM_DEFAULT = 400;
/** Default value of innodb_log_wait_for_flush_timeout (in microseconds). */
constexpr ulong INNODB_LOG_WAIT_FOR_FLUSH_TIMEOUT_DEFAULT = 1000;
/** Default value of innodb_log_flusher_spin_delay (in spin rounds).
Read about INNODB_LOG_WRITER_SPIN_DELAY_DEFAULT. */
constexpr ulong INNODB_LOG_FLUSHER_SPIN_DELAY_DEFAULT = 250000;
/** Default value of innodb_log_flusher_timeout (in microseconds).
Note that it will anyway take at least 50us. */
constexpr ulong INNODB_LOG_FLUSHER_TIMEOUT_DEFAULT = 10;
/** Default value of innodb_log_write_notifier_spin_delay (in spin rounds). */
constexpr ulong INNODB_LOG_WRITE_NOTIFIER_SPIN_DELAY_DEFAULT = 0;
/** Default value of innodb_log_write_notifier_timeout (in microseconds). */
constexpr ulong INNODB_LOG_WRITE_NOTIFIER_TIMEOUT_DEFAULT = 10;
/** Default value of innodb_log_flush_notifier_spin_delay (in spin rounds). */
constexpr ulong INNODB_LOG_FLUSH_NOTIFIER_SPIN_DELAY_DEFAULT = 0;
/** Default value of innodb_log_flush_notifier_timeout (in microseconds). */
constexpr ulong INNODB_LOG_FLUSH_NOTIFIER_TIMEOUT_DEFAULT = 10;
/** Default value of innodb_log_closer_spin_delay (in spin rounds). */
constexpr ulong INNODB_LOG_CLOSER_SPIN_DELAY_DEFAULT = 0;
/** Default value of innodb_log_closer_timeout (in microseconds). */
constexpr ulong INNODB_LOG_CLOSER_TIMEOUT_DEFAULT = 1000;
/** Default value of innodb_log_buffer_size (in bytes). */
constexpr ulong INNODB_LOG_BUFFER_SIZE_DEFAULT = 16 * 1024 * 1024UL;
/** Minimum allowed value of innodb_log_buffer_size. */
constexpr ulong INNODB_LOG_BUFFER_SIZE_MIN = 256 * 1024UL;
/** Maximum allowed value of innodb_log_buffer_size. */
constexpr ulong INNODB_LOG_BUFFER_SIZE_MAX = ULONG_MAX;
/** Default value of innodb_log_recent_written_size (in bytes). */
constexpr ulong INNODB_LOG_RECENT_WRITTEN_SIZE_DEFAULT = 1024 * 1024;
/** Minimum allowed value of innodb_log_recent_written_size. */
constexpr ulong INNODB_LOG_RECENT_WRITTEN_SIZE_MIN = OS_FILE_LOG_BLOCK_SIZE;
/** Maximum allowed value of innodb_log_recent_written_size. */
constexpr ulong INNODB_LOG_RECENT_WRITTEN_SIZE_MAX = 1024 * 1024 * 1024UL;
/** Default value of innodb_log_recent_closed_size (in bytes). */
constexpr ulong INNODB_LOG_RECENT_CLOSED_SIZE_DEFAULT = 2 * 1024 * 1024;
/** Minimum allowed value of innodb_log_recent_closed_size. */
constexpr ulong INNODB_LOG_RECENT_CLOSED_SIZE_MIN = OS_FILE_LOG_BLOCK_SIZE;
/** Maximum allowed value of innodb_log_recent_closed_size. */
constexpr ulong INNODB_LOG_RECENT_CLOSED_SIZE_MAX = 1024 * 1024 * 1024UL;
/** Default value of innodb_log_events (number of events). */
constexpr ulong INNODB_LOG_EVENTS_DEFAULT = 2048;
/** Minimum allowed value of innodb_log_events. */
constexpr ulong INNODB_LOG_EVENTS_MIN = 1;
/** Maximum allowed value of innodb_log_events. */
constexpr ulong INNODB_LOG_EVENTS_MAX = 1024 * 1024 * 1024UL;
/** Default value of innodb_log_write_ahead_size (in bytes). */
constexpr ulong INNODB_LOG_WRITE_AHEAD_SIZE_DEFAULT = 8192;
/** Minimum allowed value of innodb_log_write_ahead_size. */
constexpr ulong INNODB_LOG_WRITE_AHEAD_SIZE_MIN = OS_FILE_LOG_BLOCK_SIZE;
/** Maximum allowed value of innodb_log_write_ahead_size. */
constexpr ulint INNODB_LOG_WRITE_AHEAD_SIZE_MAX =
UNIV_PAGE_SIZE_DEF; // 16kB...
/** Value to which MLOG_TEST records should sum up within a group. */
constexpr int64_t MLOG_TEST_VALUE = 10000;
/** Maximum size of single MLOG_TEST record (in bytes). */
constexpr uint32_t MLOG_TEST_MAX_REC_LEN = 100;
/** Maximum number of MLOG_TEST records in single group of log records. */
constexpr uint32_t MLOG_TEST_GROUP_MAX_REC_N = 100;
/** Bytes consumed by MLOG_TEST record with an empty payload. */
constexpr uint32_t MLOG_TEST_REC_OVERHEAD = 37;
/** Redo log system (singleton). */
extern log_t *log_sys;
/** Pointer to the log checksum calculation function. Changes are protected
by log_mutex_enter_all, which also stops the log background threads. */
extern log_checksum_func_t log_checksum_algorithm_ptr;
#ifndef UNIV_HOTBACKUP
/** Represents currently running test of redo log, nullptr otherwise. */
extern std::unique_ptr<Log_test> log_test;
#endif /* !UNIV_HOTBACKUP */
/* Declaration of inline functions (definition is available in log0log.ic). */
/** Gets a log block flush bit. The flush bit is set, if and only if,
the block was the first block written in a call to fil_io().
During recovery, when encountered the flush bit, recovery code can be
pretty sure, that all previous blocks belong to a completed fil_io(),
because the block with flush bit belongs to the next call to fil_io(),
which could only be started after the previous one has been finished.
@param[in] log_block log block
@return true if this block was the first to be written in fil_io(). */
inline bool log_block_get_flush_bit(const byte *log_block);
/** Sets the log block flush bit.
@param[in,out] log_block log block (must have hdr_no != 0)
@param[in] value value to set */
inline void log_block_set_flush_bit(byte *log_block, bool value);
/** Gets a log block number stored in the header. The number corresponds
to lsn range for data stored in the block.
During recovery, when a next block is being parsed, a next range of lsn
values is expected to be read. This corresponds to a log block number
increased by one. However, if a smaller number is read from the header,
it is then considered the end of the redo log and recovery is finished.
In such case, the next block is most likely an empty block or a block
from the past, because the redo log is written in circular manner.
@param[in] log_block log block (may be invalid or empty block)
@return log block number stored in the block header */
inline uint32_t log_block_get_hdr_no(const byte *log_block);
/** Sets the log block number stored in the header.
NOTE that this must be set before the flush bit!
@param[in,out] log_block log block
@param[in] n log block number: must be in (0, 1G] */
inline void log_block_set_hdr_no(byte *log_block, uint32_t n);
/** Gets a log block data length.
@param[in] log_block log block
@return log block data length measured as a byte offset from the block start */
inline uint32_t log_block_get_data_len(const byte *log_block);
/** Sets the log block data length.
@param[in,out] log_block log block
@param[in] len data length (@see log_block_get_data_len) */
inline void log_block_set_data_len(byte *log_block, ulint len);
/** Gets an offset to the beginning of the first group of log records
in a given log block.
@param[in] log_block log block
@return first mtr log record group byte offset from the block start,
0 if none. */
inline uint32_t log_block_get_first_rec_group(const byte *log_block);
/** Sets an offset to the beginning of the first group of log records
in a given log block.
@param[in,out] log_block log block
@param[in] offset offset, 0 if none */
inline void log_block_set_first_rec_group(byte *log_block, uint32_t offset);
/** Gets a log block checkpoint number field (4 lowest bytes).
@param[in] log_block log block
@return checkpoint no (4 lowest bytes) */
inline uint32_t log_block_get_checkpoint_no(const byte *log_block);
/** Sets a log block checkpoint number field (4 lowest bytes).
@param[in,out] log_block log block
@param[in] no checkpoint no */
inline void log_block_set_checkpoint_no(byte *log_block, uint64_t no);
/** Converts a lsn to a log block number. Consecutive log blocks have
consecutive numbers (unless the sequence wraps). It is guaranteed that
the calculated number is greater than zero.
@param[in] lsn lsn of a byte within the block
@return log block number, it is > 0 and <= 1G */
inline uint32_t log_block_convert_lsn_to_no(lsn_t lsn);
/** Calculates the checksum for a log block.
@param[in] log_block log block
@return checksum */
inline uint32_t log_block_calc_checksum(const byte *log_block);
/** Calculates the checksum for a log block using the MySQL 5.7 algorithm.
@param[in] log_block log block
@return checksum */
inline uint32_t log_block_calc_checksum_crc32(const byte *log_block);
/** Calculates the checksum for a log block using the "no-op" algorithm.
@param[in] log_block log block
@return checksum */
inline uint32_t log_block_calc_checksum_none(const byte *log_block);
/** Gets value of a log block checksum field.
@param[in] log_block log block
@return checksum */
inline uint32_t log_block_get_checksum(const byte *log_block);
/** Sets value of a log block checksum field.
@param[in,out] log_block log block
@param[in] checksum checksum */
inline void log_block_set_checksum(byte *log_block, uint32_t checksum);
/** Stores a 4-byte checksum to the trailer checksum field of a log block.
This is used before writing the log block to disk. The checksum in a log
block is used in recovery to check the consistency of the log block.
@param[in] log_block log block (completely filled in!) */
inline void log_block_store_checksum(byte *log_block);
/** Gets the current lsn value. This value points to the first non
reserved data byte in the redo log. When next user thread reserves
space in the redo log, it starts at this lsn.
If the last reservation finished exactly before footer of log block,
this value points to the first byte after header of the next block.
NOTE that it is possible that the current lsn value does not fit
free space in the log files or in the log buffer. In such case,
user threads need to wait until the space becomes available.
@return current lsn */
inline lsn_t log_get_lsn(const log_t &log);
/** Gets the last checkpoint lsn stored and flushed to disk.
@return last checkpoint lsn */
inline lsn_t log_get_checkpoint_lsn(const log_t &log);
#ifndef UNIV_HOTBACKUP
/** @return true iff log_free_check should be executed. */
inline bool log_needs_free_check();
/** Any database operation should call this when it has modified more than
about 4 pages. NOTE that this function may only be called when the thread
owns no synchronization objects except the dictionary mutex.
Checks if current log.sn exceeds log.free_check_limit_sn, in which case waits.
This is supposed to guarantee that we would not run out of space in the log
files when holding latches of some dirty pages (which could end up in
a deadlock, because flush of the latched dirty pages could be required
to reclaim the space and it is impossible to flush latched pages). */
inline void log_free_check();
/** Calculates lsn value for given sn value. Sequence of sn values
enumerate all data bytes in the redo log. Sequence of lsn values
enumerate all data bytes and bytes used for headers and footers
of all log blocks in the redo log. For every LOG_BLOCK_DATA_SIZE
bytes of data we have OS_FILE_LOG_BLOCK_SIZE bytes in the redo log.
NOTE that LOG_BLOCK_DATA_SIZE + LOG_BLOCK_HDR_SIZE + LOG_BLOCK_TRL_SIZE
== OS_FILE_LOG_BLOCK_SIZE. The calculated lsn value will always point
to some data byte (will be % OS_FILE_LOG_BLOCK_SIZE >= LOG_BLOCK_HDR_SIZE,
and < OS_FILE_LOG_BLOCK_SIZE - LOG_BLOCK_TRL_SIZE).
@param[in] sn sn value
@return lsn value for the provided sn value */
constexpr inline lsn_t log_translate_sn_to_lsn(lsn_t sn);
/** Calculates sn value for given lsn value.
@see log_translate_sn_to_lsn
@param[in] lsn lsn value
@return sn value for the provided lsn value */
inline lsn_t log_translate_lsn_to_sn(lsn_t lsn);
#endif /* !UNIV_HOTBACKUP */
/** Validates a given lsn value. Checks if the lsn value points to data
bytes inside log block (not to some bytes in header/footer). It is used
by assertions.
@return true if lsn points to data bytes within log block */
inline bool log_lsn_validate(lsn_t lsn);
#ifndef UNIV_HOTBACKUP
/** Calculates age of current checkpoint as number of bytes since
last checkpoint. This includes bytes for headers and footers of
all log blocks. The calculation is based on the latest written
checkpoint lsn, and the current lsn, which points to the first
non reserved data byte. Note that the current lsn could not fit
the free space in the log files. This means that the checkpoint
age could potentially be larger than capacity of the log files.
However we do the best effort to avoid such situations, and if
they happen, user threads wait until the space is reclaimed.
@param[in] log redo log
@return checkpoint age as number of bytes */
inline lsn_t log_get_checkpoint_age(const log_t &log);
/* Declaration of log_buffer functions (definition in log0buf.cc). */
/** Reserves space in the redo log for following write operations.
Space is reserved for a given number of data bytes. Additionally
bytes for required headers and footers of log blocks are reserved.
After the space is reserved, range of lsn values from a start_lsn
to an end_lsn is assigned. The log writer thread cannot proceed
further than to the start_lsn, until a link start_lsn -> end_lsn
has been added to the log recent written buffer.
NOTE that the link is added after data is written to the reserved
space in the log buffer. It is very critical to do all these steps
as fast as possible, because very likely the log writer thread is
waiting for the link.
@see @ref sect_redo_log_buf_reserve
@param[in,out] log redo log
@param[in] len number of data bytes to reserve for write
@return handle that represents the reservation */
Log_handle log_buffer_reserve(log_t &log, size_t len);
/** Writes data to the log buffer. The space in the redo log has to be
reserved before calling to this function and lsn pointing to inside the
reserved range of lsn values has to be provided.
The write does not have to cover the whole reserved space, but may not
overflow it. If it does not cover, then returned value should be used
to start the next write operation. Note that finally we must use exactly
all the reserved space.
@see @ref sect_redo_log_buf_write
@param[in,out] log redo log
@param[in] handle handle for the reservation of space
@param[in] str memory to write data from
@param[in] str_len number of bytes to write
@param[in] start_lsn lsn to start writing at (the reserved space)
@return end_lsn after writing the data (in the reserved space), could be
used to start the next write operation if there is still free space in
the reserved space */
lsn_t log_buffer_write(log_t &log, const Log_handle &handle, const byte *str,
size_t str_len, lsn_t start_lsn);
/** Adds a link start_lsn -> end_lsn to the log recent written buffer.
This function must be called after the data has been written to the
fragment of log buffer represented by range [start_lsn, end_lsn).
After the link is added, the log writer may write the data to disk.
NOTE that still dirty pages for the [start_lsn, end_lsn) are not added
to flush lists when this function is called.
@see @ref sect_redo_log_buf_add_links_to_recent_written
@param[in,out] log redo log
@param[in] handle handle for the reservation of space
@param[in] start_lsn start_lsn of the link to add
@param[in] end_lsn end_lsn of the link to add */
void log_buffer_write_completed(log_t &log, const Log_handle &handle,
lsn_t start_lsn, lsn_t end_lsn);
/** Modifies header of log block in the log buffer, which contains
a given lsn value, and sets offset to the first group of log records
within the block.
This is used by mtr after writing a log record group which ends at
lsn belonging to different log block than lsn at which the group was
started. When write was finished at the last data byte of log block,
it is considered ended in the next log block, because the next data
byte belongs to that block.
During recovery, when recovery is started in the middle of some group
of log records, it first looks for the beginning of the next group.
@param[in,out] log redo log
@param[in] handle handle for the reservation of space
@param[in] rec_group_end_lsn lsn at which the first log record
group starts within the block containing this lsn value */
void log_buffer_set_first_record_group(log_t &log, const Log_handle &handle,
lsn_t rec_group_end_lsn);
/** Adds a link start_lsn -> end_lsn to the log recent closed buffer.
This is called after all dirty pages related to [start_lsn, end_lsn)
have been added to corresponding flush lists.
For detailed explanation - @see log0write.cc.
@see @ref sect_redo_log_add_link_to_recent_closed
@param[in,out] log redo log
@param[in] handle handle for the reservation of space */
void log_buffer_close(log_t &log, const Log_handle &handle);
/** Write to the log file up to the last log entry.
@param[in,out] log redo log
@param[in] sync whether we want the written log
also to be flushed to disk. */
void log_buffer_flush_to_disk(log_t &log, bool sync = true);
/** Requests flush of the log buffer.
@param[in] sync true: wait until the flush is done */
inline void log_buffer_flush_to_disk(bool sync = true);
/** @return lsn up to which all writes to log buffer have been finished */
inline lsn_t log_buffer_ready_for_write_lsn(const log_t &log);
/** @return lsn up to which all dirty pages have been added to flush list */
inline lsn_t log_buffer_dirty_pages_added_up_to_lsn(const log_t &log);
/** @return capacity of the recent_closed, or 0 if !log_use_threads() */
inline lsn_t log_buffer_flush_order_lag(const log_t &log);
/** Get last redo block from redo buffer and end LSN. Note that it takes
x-lock on the log buffer for a short period. Out values are always set,
even when provided last_block is nullptr.
@param[in,out] log redo log
@param[out] last_lsn end lsn of last mtr
@param[out] last_block last redo block
@param[in,out] block_len length in bytes */
void log_buffer_get_last_block(log_t &log, lsn_t &last_lsn, byte *last_block,
uint32_t &block_len);
/** Advances log.buf_ready_for_write_lsn using links in the recent written
buffer. It's used by the log writer thread only.
@param[in] log redo log
@return true if and only if the lsn has been advanced */
bool log_advance_ready_for_write_lsn(log_t &log);
/** Advances log.buf_dirty_pages_added_up_to_lsn using links in the recent
closed buffer. It's used by the log closer thread only.
@param[in] log redo log
@return true if and only if the lsn has been advanced */
bool log_advance_dirty_pages_added_up_to_lsn(log_t &log);
/** Validates that all slots in log recent written buffer for lsn values
in range between begin and end, are empty. Used during tests, crashes the
program if validation does not pass.
@param[in] log redo log which buffer is validated
@param[in] begin validation start (inclusive)
@param[in] end validation end (exclusive) */
void log_recent_written_empty_validate(const log_t &log, lsn_t begin,
lsn_t end);
/** Validates that all slots in log recent closed buffer for lsn values
in range between begin and end, are empty. Used during tests, crashes the
program if validation does not pass.
@param[in] log redo log which buffer is validated
@param[in] begin validation start (inclusive)
@param[in] end validation end (exclusive) */
void log_recent_closed_empty_validate(const log_t &log, lsn_t begin, lsn_t end);
/* Declaration of remaining functions. */
/** Waits until there is free space in the log recent closed buffer
for any links start_lsn -> end_lsn, which start at provided start_lsn.
It does not add any link.
This is called just before dirty pages for [start_lsn, end_lsn)
are added to flush lists. That's because we need to guarantee,
that the delay until dirty page is added to flush list is limited.
For detailed explanation - @see log0write.cc.
@see @ref sect_redo_log_add_dirty_pages
@param[in,out] log redo log
@param[in] lsn lsn on which we wait (for any link: lsn -> x) */
void log_wait_for_space_in_log_recent_closed(log_t &log, lsn_t lsn);
/** Waits until there is free space in the log buffer. The free space has to be
available for range of sn values ending at the provided sn.
@see @ref sect_redo_log_waiting_for_writer
@param[in] log redo log
@param[in] end_sn end of the range of sn values */
void log_wait_for_space_in_log_buf(log_t &log, sn_t end_sn);
/** Waits until there is free space for range of sn values ending
at the provided sn, in both the log buffer and in the log files.
@param[in] log redo log
@param[in] end_sn end of the range of sn values */
void log_wait_for_space(log_t &log, sn_t end_sn);
/** Computes capacity of redo log available until log_free_check()
reaches point where it needs to wait.
@param[in] log redo log
@return lsn capacity up to free_check_wait happens */
lsn_t log_get_free_check_capacity(const log_t &log);
/** When the oldest dirty page age exceeds this value, we start
an asynchronous preflush of dirty pages.
@param[in] log redo log
@return age of dirty page at which async preflush is started */
lsn_t log_get_max_modified_age_async(const log_t &log);
/** Waits until there is free space in log files which includes
concurrency margin required for all threads. You should rather
use log_free_check().
@see @ref sect_redo_log_reclaim_space
@param[in] log redo log */
void log_free_check_wait(log_t &log);
/** Updates limits related to free space in redo log files:
log.available_for_checkpoint_lsn and log.free_check_limit_sn.
@param[in,out] log redo log */
void log_update_limits(log_t &log);
/** Updates limit used when writing to log buffer. Note that the
log buffer may have space for log records for which we still do
not have space in log files (for larger lsn values).
@param[in,out] log redo log */
void log_update_buf_limit(log_t &log);
/** Updates limit used when writing to log buffer, according to provided
write_lsn. It must be <= log.write_lsn.load() to protect from log buffer
overwrites.
@param[in,out] log redo log
@param[in] write_lsn value <= log.write_lsn.load() */
void log_update_buf_limit(log_t &log, lsn_t write_lsn);
/** Waits until the redo log is written up to a provided lsn.
@param[in] log redo log
@param[in] lsn lsn to wait for
@param[in] flush_to_disk true: wait until it is flushed
@return statistics about waiting inside */
Wait_stats log_write_up_to(log_t &log, lsn_t lsn, bool flush_to_disk);
/* Read the first log file header to get the encryption
information if it exist.
@return true if success */
bool log_read_encryption();
/** Write the encryption info into the log file header(the 3rd block).
It just need to flush the file header block with current master key.
@param[in] key encryption key
@param[in] iv encryption iv
@param[in] is_boot if it is for bootstrap
@return true if success. */
bool log_write_encryption(byte *key, byte *iv, bool is_boot);
/** Rotate the redo log encryption
It will re-encrypt the redo log encryption metadata and write it to
redo log file header.
@return true if success. */
bool log_rotate_encryption();
/** Rotate default master key for redo log encryption. */
void redo_rotate_default_master_key();
/** Requests a sharp checkpoint write for provided or greater lsn.
@param[in,out] log redo log
@param[in] sync true -> wait until it is finished
@param[in] lsn lsn for which we need checkpoint (or greater chkp) */
void log_request_checkpoint(log_t &log, bool sync, lsn_t lsn);
/** Requests a fuzzy checkpoint write (for lsn currently available
for checkpointing).
@param[in,out] log redo log
@param[in] sync true -> wait until it is finished */
void log_request_checkpoint(log_t &log, bool sync);
/** Make a checkpoint at the current lsn. Reads current lsn and waits
until all dirty pages have been flushed up to that lsn. Afterwards
requests a checkpoint write and waits until it is finished.
@param[in,out] log redo log
@return true iff current lsn was greater than last checkpoint lsn */
bool log_make_latest_checkpoint(log_t &log);
/** Make a checkpoint at the current lsn. Reads current lsn and waits
until all dirty pages have been flushed up to that lsn. Afterwards
requests a checkpoint write and waits until it is finished.
@return true iff current lsn was greater than last checkpoint lsn */
bool log_make_latest_checkpoint();
/** Reads a log file header page to log.checkpoint_buf.
@param[in,out] log redo log
@param[in] header 0 or LOG_CHECKPOINT_1 or LOG_CHECKPOINT2 */
void log_files_header_read(log_t &log, uint32_t header);
/** Fill redo log header.
@param[out] buf filled buffer
@param[in] start_lsn log start LSN
@param[in] creator creator of the header */
void log_files_header_fill(byte *buf, lsn_t start_lsn, const char *creator);
/** Writes a log file header to the log file space.
@param[in] log redo log
@param[in] nth_file header for the nth file in the log files
@param[in] start_lsn log file data starts at this lsn */
void log_files_header_flush(log_t &log, uint32_t nth_file, lsn_t start_lsn);
/** Changes format of redo files to previous format version.
@note Note this will work between the two formats 5_7_9 & current because
the only change is the version number */
void log_files_downgrade(log_t &log);
/** Writes the next checkpoint info to header of the first log file.
Note that two pages of the header are used alternately for consecutive
checkpoints. If we crashed during the write, we would still have the
previous checkpoint info and recovery would work.
@param[in,out] log redo log
@param[in] next_checkpoint_lsn writes checkpoint at this lsn */
void log_files_write_checkpoint(log_t &log, lsn_t next_checkpoint_lsn);
/** Updates current_file_lsn and current_file_real_offset to correspond
to a given lsn. For this function to work, the values must already be
initialized to correspond to some lsn, for instance, a checkpoint lsn.
@param[in,out] log redo log
@param[in] lsn log sequence number to set files_start_lsn at */
void log_files_update_offsets(log_t &log, lsn_t lsn);
/** Acquires the log buffer s-lock.
@param[in,out] log redo log
@return lock no, must be passed to s_lock_exit() */
size_t log_buffer_s_lock_enter(log_t &log);
/** Releases the log buffer s-lock.
@param[in,out] log redo log
@param[in] lock_no lock no received from s_lock_enter() */
void log_buffer_s_lock_exit(log_t &log, size_t lock_no);
/** Acquires the log buffer x-lock.
@param[in,out] log redo log */
void log_buffer_x_lock_enter(log_t &log);
/** Releases the log buffer x-lock.
@param[in,out] log redo log */
void log_buffer_x_lock_exit(log_t &log);
#endif /* !UNIV_HOTBACKUP */
/** Calculates offset within log files, excluding headers of log files.
@param[in] log redo log
@param[in] offset real offset (including log file headers)
@return size offset excluding log file headers (<= offset) */
uint64_t log_files_size_offset(const log_t &log, uint64_t offset);
/** Calculates offset within log files, including headers of log files.
@param[in] log redo log
@param[in] offset size offset (excluding log file headers)
@return real offset including log file headers (>= offset) */
uint64_t log_files_real_offset(const log_t &log, uint64_t offset);
/** Calculates offset within log files, including headers of log files,
for the provided lsn value.
@param[in] log redo log
@param[in] lsn log sequence number
@return real offset within the log files */
uint64_t log_files_real_offset_for_lsn(const log_t &log, lsn_t lsn);
#ifndef UNIV_HOTBACKUP
/** Changes size of the log buffer. This is a thread-safe version.
It is used by SET GLOBAL innodb_log_buffer_size = X.
@param[in,out] log redo log
@param[in] new_size requested new size
@return true iff succeeded in resize */
bool log_buffer_resize(log_t &log, size_t new_size);
/** Changes size of the log buffer. This is a non-thread-safe version
which might be invoked only when there are no concurrent possible writes
to the log buffer. It is used in log_buffer_reserve() when a requested
size to reserve is larger than size of the log buffer.
@param[in,out] log redo log
@param[in] new_size requested new size
@param[in] end_lsn maximum lsn written to log buffer
@return true iff succeeded in resize */
bool log_buffer_resize_low(log_t &log, size_t new_size, lsn_t end_lsn);
/** Resizes the write ahead buffer in the redo log.
@param[in,out] log redo log
@param[in] new_size new size (in bytes) */
void log_write_ahead_resize(log_t &log, size_t new_size);
/** Updates the field log.dict_max_allowed_checkpoint_lsn.
@param[in,out] log redo log
@param[in] max_lsn new value for the field */
void log_set_dict_max_allowed_checkpoint_lsn(log_t &log, lsn_t max_lsn);
/** Updates log.dict_persist_margin and recompute free check limit.
@param[in,out] log redo log
@param[in] margin new value for log.dict_persist_margin */
void log_set_dict_persist_margin(log_t &log, sn_t margin);
/** Increase concurrency_margin used inside log_free_check() calls. */
void log_increase_concurrency_margin(log_t &log);
/** Prints information about important lsn values used in the redo log,
and some statistics about speed of writing and flushing of data.
@param[in] log redo log for which print information
@param[out] file file where to print */
void log_print(const log_t &log, FILE *file);
/** Refreshes the statistics used to print per-second averages in log_print().
@param[in,out] log redo log */
void log_refresh_stats(log_t &log);
/** Creates the first checkpoint ever in the log files. Used during
initialization of new log files. Flushes:
- header of the first log file (including checkpoint headers),
- log block with data addressed by the checkpoint lsn.
@param[in,out] log redo log
@param[in] lsn the first checkpoint lsn */
void log_create_first_checkpoint(log_t &log, lsn_t lsn);
/** Calculates limits for maximum age of checkpoint and maximum age of
the oldest page.
@param[in,out] log redo log */
void log_calc_max_ages(log_t &log);
/** Updates concurrency margin. Uses current value of srv_thread_concurrency.
@param[in,out] log redo log
@retval true if success
@retval false if the redo log is too small to accommodate the number of
OS threads in the database server */
bool log_calc_concurrency_margin(log_t &log);
/** Initializes the log system. Note that the log system is not ready
for user writes after this call is finished. It should be followed by
a call to log_start. Also, log background threads need to be started
manually using log_start_background_threads afterwards.
Hence the proper order of calls looks like this:
- log_sys_init(),
- log_start(),
- log_start_background_threads().
@param[in] n_files number of log files
@param[in] file_size size of each log file in bytes
@param[in] space_id space id of the file space with log files */
bool log_sys_init(uint32_t n_files, uint64_t file_size, space_id_t space_id);
/** Starts the initialized redo log system using a provided
checkpoint_lsn and current lsn. Block for current_lsn must
be properly initialized in the log buffer prior to calling
this function. Therefore a proper value of first_rec_group
must be set for that block before log_start is called.
@param[in,out] log redo log
@param[in] checkpoint_no checkpoint no (sequential number)
@param[in] checkpoint_lsn checkpoint lsn
@param[in] start_lsn current lsn to start at */
void log_start(log_t &log, checkpoint_no_t checkpoint_no, lsn_t checkpoint_lsn,
lsn_t start_lsn);
/** Validates that the log writer thread is active.
Used only to assert, that the state is correct.
@param[in] log redo log */
void log_writer_thread_active_validate(const log_t &log);
/** Validates that the log closer thread is active.
Used only to assert, that the state is correct.
@param[in] log redo log */
void log_closer_thread_active_validate(const log_t &log);
/** Validates that the log writer, flusher threads are active.
Used only to assert, that the state is correct.
@param[in] log redo log */
void log_background_write_threads_active_validate(const log_t &log);
/** Validates that all the log background threads are active.
Used only to assert, that the state is correct.
@param[in] log redo log */
void log_background_threads_active_validate(const log_t &log);
/** Validates that all the log background threads are inactive.
Used only to assert, that the state is correct.
@param[in] log redo log */
void log_background_threads_inactive_validate(const log_t &log);
/** Starts all the log background threads. This can be called only,
when the threads are inactive. This should never be called concurrently.
This may not be called during read-only mode.
@param[in,out] log redo log */
void log_start_background_threads(log_t &log);
/** Stops all the log background threads. This can be called only,
when the threads are active. This should never be called concurrently.
This may not be called in read-only mode. Note that is is impossible
to start log background threads in such case.
@param[in,out] log redo log */
void log_stop_background_threads(log_t &log);
/** Marks the flag which tells log threads to stop and wakes them.
Does not wait until they are stopped. */
void log_stop_background_threads_nowait(log_t &log);
/** Wakes up all log threads which are alive. */
void log_wake_threads(log_t &log);
/** Free the log system data structures. Deallocate all the related memory. */
void log_sys_close();
/** The log writer thread co-routine.
@see @ref sect_redo_log_writer
@param[in,out] log_ptr pointer to redo log */
void log_writer(log_t *log_ptr);
/** The log flusher thread co-routine.
@see @ref sect_redo_log_flusher
@param[in,out] log_ptr pointer to redo log */
void log_flusher(log_t *log_ptr);
/** The log flush notifier thread co-routine.
@see @ref sect_redo_log_flush_notifier
@param[in,out] log_ptr pointer to redo log */
void log_flush_notifier(log_t *log_ptr);
/** The log write notifier thread co-routine.
@see @ref sect_redo_log_write_notifier
@param[in,out] log_ptr pointer to redo log */
void log_write_notifier(log_t *log_ptr);
/** The log closer thread co-routine.
@see @ref sect_redo_log_closer
@param[in,out] log_ptr pointer to redo log */
void log_closer(log_t *log_ptr);
/** The log checkpointer thread co-routine.
@see @ref sect_redo_log_checkpointer
@param[in,out] log_ptr pointer to redo log */
void log_checkpointer(log_t *log_ptr);
#define log_buffer_x_lock_own(log) log.sn_lock.x_own()
#define log_checkpointer_mutex_enter(log) \
mutex_enter(&((log).checkpointer_mutex))
#define log_checkpointer_mutex_exit(log) mutex_exit(&((log).checkpointer_mutex))
#define log_checkpointer_mutex_own(log) \
(mutex_own(&((log).checkpointer_mutex)) || !log_checkpointer_is_active())
#define log_closer_mutex_enter(log) mutex_enter(&((log).closer_mutex))
#define log_closer_mutex_exit(log) mutex_exit(&((log).closer_mutex))
#define log_closer_mutex_own(log) \
(mutex_own(&((log).closer_mutex)) || !log_closer_is_active())
#define log_flusher_mutex_enter(log) mutex_enter(&((log).flusher_mutex))
#define log_flusher_mutex_enter_nowait(log) \
mutex_enter_nowait(&((log).flusher_mutex))
#define log_flusher_mutex_exit(log) mutex_exit(&((log).flusher_mutex))
#define log_flusher_mutex_own(log) \
(mutex_own(&((log).flusher_mutex)) || !log_flusher_is_active())
#define log_flush_notifier_mutex_enter(log) \
mutex_enter(&((log).flush_notifier_mutex))
#define log_flush_notifier_mutex_exit(log) \
mutex_exit(&((log).flush_notifier_mutex))
#define log_flush_notifier_mutex_own(log) \
(mutex_own(&((log).flush_notifier_mutex)) || !log_flush_notifier_is_active())
#define log_writer_mutex_enter(log) mutex_enter(&((log).writer_mutex))
#define log_writer_mutex_enter_nowait(log) \
mutex_enter_nowait(&((log).writer_mutex))
#define log_writer_mutex_exit(log) mutex_exit(&((log).writer_mutex))
#define log_writer_mutex_own(log) \
(mutex_own(&((log).writer_mutex)) || !log_writer_is_active())
#define log_write_notifier_mutex_enter(log) \
mutex_enter(&((log).write_notifier_mutex))
#define log_write_notifier_mutex_exit(log) \
mutex_exit(&((log).write_notifier_mutex))
#define log_write_notifier_mutex_own(log) \
(mutex_own(&((log).write_notifier_mutex)) || !log_write_notifier_is_active())
#define log_limits_mutex_enter(log) mutex_enter(&((log).limits_mutex))
#define log_limits_mutex_exit(log) mutex_exit(&((log).limits_mutex))
#define log_limits_mutex_own(log) mutex_own(&(log).limits_mutex)
#define LOG_SYNC_POINT(a) \
do { \
DEBUG_SYNC_C(a); \
DBUG_EXECUTE_IF(a, DBUG_SUICIDE();); \
if (log_test != nullptr) { \
log_test->sync_point(a); \
} \
} while (0)
/** Lock redo log. Both current lsn and checkpoint lsn will not change
until the redo log is unlocked.
@param[in,out] log redo log to lock */
void log_position_lock(log_t &log);
/** Unlock the locked redo log.
@param[in,out] log redo log to unlock */
void log_position_unlock(log_t &log);
/** Collect coordinates in the locked redo log.
@param[in] log locked redo log
@param[out] current_lsn stores current lsn there
@param[out] checkpoint_lsn stores checkpoint lsn there */
void log_position_collect_lsn_info(const log_t &log, lsn_t *current_lsn,
lsn_t *checkpoint_lsn);
/** Checks if log writer thread is active.
@return true if and only if the log writer thread is active */
inline bool log_writer_is_active();
/** Checks if log write notifier thread is active.
@return true if and only if the log write notifier thread is active */
inline bool log_write_notifier_is_active();
/** Checks if log flusher thread is active.
@return true if and only if the log flusher thread is active */
inline bool log_flusher_is_active();
/** Checks if log flush notifier thread is active.
@return true if and only if the log flush notifier thread is active */
inline bool log_flush_notifier_is_active();
/** Checks if log closer thread is active.
@return true if and only if the log closer thread is active */
inline bool log_closer_is_active();
/** Checks if log checkpointer thread is active.
@return true if and only if the log checkpointer thread is active */
inline bool log_checkpointer_is_active();
/** Writes encryption information to log header.
@param[in,out] buf log file header
@param[in] key encryption key
@param[in] iv encryption iv
@param[in] is_boot if it's for bootstrap
@param[in] encrypt_key encrypt with master key */
bool log_file_header_fill_encryption(byte *buf, byte *key, byte *iv,
bool is_boot, bool encrypt_key);
#else /* !UNIV_HOTBACKUP */
#ifdef UNIV_DEBUG
/** Print a log file header.
@param[in] block pointer to the log buffer */
void meb_log_print_file_hdr(byte *block);
#endif /* UNIV_DEBUG */
#endif /* !UNIV_HOTBACKUP */
#include "log0log.ic"
#endif /* !log0log_h */