/** Ensure that the log has been written to the log file up to a given logentry(suchasthatofatransactioncommit).Startanewwrite,or waitandcheckifanalreadyrunningwriteiscoveringtherequest. @paramlsnlogsequencenumberthatshouldbeincludedinthefilewrite @paramdurablewhetherthewriteneedstobedurable
@param callback log write completion callback */ void log_write_up_to(lsn_t lsn, bool durable, const completion_callback *callback= nullptr) noexcept;
/** Write to the log file up to the last log entry.
@param durable whether to wait for a durable write to complete */ void log_buffer_flush_to_disk(bool durable= true) noexcept;
/** Prepare to invoke log_write_and_flush(), before acquiring log_sys.latch. */
ATTRIBUTE_COLD void log_write_and_flush_prepare() noexcept;
/** Durably write the log up to log_sys.get_lsn(). */
ATTRIBUTE_COLD void log_write_and_flush() noexcept;
/** Make a checkpoint */
ATTRIBUTE_COLD void log_make_checkpoint() noexcept;
/** Make a checkpoint at the latest lsn on shutdown.
@return the shutdown LSN */
ATTRIBUTE_COLD lsn_t logs_empty_and_mark_files_at_shutdown() noexcept;
/******************************************************//**
Prints info of the log. */ void
log_print( /*======*/
FILE* file); /*!< in: file where to print */
/** Offsets of a log file header */ /* @{ */ /** Log file header format identifier (32-bit unsigned big-endian integer). ThisusedtobecalledLOG_GROUP_IDandalwayswrittenas0,
because InnoDB never supported more than one copy of the redo log. */ #define LOG_HEADER_FORMAT 0 /** LSN of the start of data in this log file (with format version 1;
in format version 0, it was called LOG_FILE_START_LSN and at offset 4). */ #define LOG_HEADER_START_LSN 8 /** A null-terminated string which will contain either the string 'ibbackup' andthecreationtimeifthelogfilewascreatedbymysqlbackup--restore,
or the MySQL version that created the redo log file. */ #define LOG_HEADER_CREATOR 16 /** End of the log file creator field. */ #define LOG_HEADER_CREATOR_END 48 /* @} */
/** Redo log buffer */ struct log_t
{ friend recv_warp; /** The maximum buf_size */ static constexpr unsigned buf_size_max= os_file_request_size_max;
/** The original (not version-tagged) InnoDB redo log format */ static constexpr uint32_t FORMAT_3_23= 0; /** The MySQL 5.7.9/MariaDB 10.2.2 log format */ static constexpr uint32_t FORMAT_10_2= 1; /** The MariaDB 10.3.2 log format. */ static constexpr uint32_t FORMAT_10_3= 103; /** The MariaDB 10.4.0 log format. */ static constexpr uint32_t FORMAT_10_4= 104; /** Encrypted MariaDB redo log */ static constexpr uint32_t FORMAT_ENCRYPTED= 1U << 31; /** The MariaDB 10.4.0 log format (only with innodb_encrypt_log=ON) */ static constexpr uint32_t FORMAT_ENC_10_4= FORMAT_10_4 | FORMAT_ENCRYPTED; /** The MariaDB 10.5.1 physical redo log format */ static constexpr uint32_t FORMAT_10_5= 0x50485953; /** The MariaDB 10.5.1 physical format (only with innodb_encrypt_log=ON) */ static constexpr uint32_t FORMAT_ENC_10_5= FORMAT_10_5 | FORMAT_ENCRYPTED; /** The MariaDB 10.8.0 variable-block-size redo log format */ static constexpr uint32_t FORMAT_10_8= 0x50687973; /** The MariaDB 10.8.0 format with innodb_encrypt_log=ON */ static constexpr uint32_t FORMAT_ENC_10_8= FORMAT_10_8 | FORMAT_ENCRYPTED; /** The MariaDB 10.11 format with innodb_encrypt_log=ON */ static constexpr uint32_t FORMAT_ENC_11= 0xf09f979d;
/** Location of the first checkpoint block */ static constexpr size_t CHECKPOINT_1= 4096; /** Location of the second checkpoint block */ static constexpr size_t CHECKPOINT_2= 8192; /** Start of record payload */ static constexpr lsn_t START_OFFSET= 12288;
/** smallest possible log sequence number in the current format
(used to be 2048 before FORMAT_10_8). */ static constexpr lsn_t FIRST_LSN= START_OFFSET;
private: /** the least significant bit of the write_to_buf buffer */ static constexpr size_t WRITE_TO_BUF_SHIFT{34}; /** write_lsn_offset component for incrementing write_to_buf */ static constexpr uint64_t WRITE_TO_BUF{1ULL << WRITE_TO_BUF_SHIFT}; /** write_lsn_offset flag to indicate that append_prepare_wait() is active */ static constexpr uint64_t WRITE_BACKOFF{1ULL << 33};
/** The current log sequence number, relative to base_lsn, and flags;
may be modified while latch_have_any() */
alignas(CPU_LEVEL1_DCACHE_LINESIZE)
Atomic_relaxed<uint64_t> write_lsn_offset; /** the LSN of the last write_buf() or persist(); protected by latch */
std::atomic<lsn_t> base_lsn; /** the first guaranteed-durable log sequence number */
std::atomic<lsn_t> flushed_to_disk_lsn; public: /** innodb_log_buffer_size (usable append_prepare() size in bytes) */ unsigned buf_size; /** current innodb_log_write_ahead_size */
uint write_size; /** maximum write_size */ static constexpr uint WRITE_SIZE_MAX{4096}; /** log file size in bytes, including the header */
lsn_t file_size;
#ifdefined LOG_LATCH_DEBUG && defined UNIV_DEBUG typedef srw_lock_debug_simple log_rwlock;
/** format of the redo log: e.g., FORMAT_10_8 */
uint32_t format; /** the minimum log file size */ static constexpr lsn_t FILE_SIZE_MIN{4 << 20}; private: #ifdef HAVE_PMEM /** whether the memory-mapped interface is enabled for writing */ bool is_pmem:1; #endif /** whether !archive log records may have been written with
get_sequence_bit()==0 */ bool circular_recovery_from_sequence_bit_0:1; public: /** the default value of log_mmap */ static constexpr bool log_mmap_default= # ifdefined __linux__ /* MAP_POPULATE would enable read-ahead */ true || # elif defined __FreeBSD__ /* MAP_PREFAULT_READ would enable read-ahead */ true || # else/* an unnecessary read-ahead of a large ib_logfile0 is a risk */ # endif false; #ifdefined __linux__ || defined _WIN32 # ifdef _WIN32 static constexpr bool log_maybe_unbuffered= true; # else /** whether file system caching may be disabled */ bool log_maybe_unbuffered:1; # endif /** whether file system caching is enabled for the log */
my_bool log_buffered; #endif /** whether each write to ib_logfile0 is durable (O_DSYNC) */
my_bool log_write_through; /** the current value of innodb_log_archive; protected by latch.wr_lock() */
my_bool archive; /** whether the memory-mapped interface is enabled for the log */
my_bool log_mmap; /** Set when there may be need for write_checkpoint().
This must hold if get_lsn() - last_checkpoint_lsn > checkpoint_age_max(). */
std::atomic<bool> need_checkpoint; /** next available checkpoint number, orUINT16_MAXinrecv_sys_t::find_checkpoint_archived();
protected by latch.wr_lock() */
uint16_t next_checkpoint_no; private: #ifdef HAVE_PMEM /** mutex protecting wrap-around in resize_write() */
srw_mutex resize_wrap_mutex; #endif public:
/** log record buffer, written to by mtr_t::commit() */
alignas(CPU_LEVEL1_DCACHE_LINESIZE) byte *buf;
/** number of write requests to buf, excluding(write_lsn_offset&WRITE_TO_BUF);
protected by latch.wr_lock() */
size_t write_to_buf;
/** number of writes from buf or flush_buf to log;
protected by latch.wr_lock() */
size_t write_to_log;
/** Last written LSN; protected by latch */
lsn_t write_lsn;
/** Buffer for writing data to ib_logfile0, or nullptr if is_mmap().
In write_buf(), buf and flush_buf may be swapped */
byte *flush_buf;
/** Log sequence number when a log file overwrite (broken crash recovery)
was noticed. Protected by latch.wr_lock(). */
lsn_t overwrite_warned;
/** latest completed checkpoint (protected by latch.wr_lock()) */
Atomic_relaxed<lsn_t> last_checkpoint_lsn; /** The log writer (protected by latch.wr_lock()) */
lsn_t (*writer)() noexcept; /** end_lsn of the first available checkpoint, or 0;
protected by latch.wr_lock() */
lsn_t archived_lsn;
/** Log file */
log_file_t log; private: /** Log file being constructed during resizing,
or the previous archived log file; protected by latch */
log_file_t resize_log; /** size of resize_log, or the requested innodb_log_file_size
of the next file created if archive==TRUE; protected by latch */
lsn_t resize_target; /** Buffer for writing to resize_log; @see buf Alsoasparebufferbetweenarchived_mmap_switch_prepare() andarchived_mmap_switch_complete(), orarchived_mmap_switch_recovery_prepare()
and archived_mmap_switch_recovery_complete(). */
byte *resize_buf; /** Buffer for writing to resize_log; @see flush_buf */
byte *resize_flush_buf;
/** log sequence number when log resizing was initiated;
0 if the log is not being resized, 1 if resize_start() is in progress */
std::atomic<lsn_t> resize_lsn; /** the log sequence number at the start of the current log file */
lsn_t first_lsn; /** the log sequence number when the latest checkpoint was initiated */
lsn_t end_lsn; public: /** Fields involved in checkpoints @{ */
lsn_t log_capacity; /*!< capacity of the log; if thecheckpointageexceedsthis,itis aseriouserrorbecauseitispossible wewillthenoverwritelogandspoil
crash recovery */
lsn_t max_modified_age_async; /*!< when this recommended valueforlsn- buf_pool.get_oldest_modification() isexceeded,westartan
asynchronous preflush of pool pages */
lsn_t max_checkpoint_age; /*!< this is the maximum allowed value forlsn-last_checkpoint_lsnwhena
new query step is started */
/** buffer for checkpoint header; protected by latch; nullptrifis_mmap()andatmostonelogfileisopen;
a pointer to the oldest open archive log file if is_mmap() */
byte *checkpoint_buf; /* @} */
private: /** the thread that initiated resize_start() */
Atomic_relaxed<void*> resize_initiator; public: /** number of long append_prepare_wait(); protected by latch_have_wr() */
size_t waits;
/** @return whether a handle to the log is open;
is_mmap() && (is_opened() == archive) holds for PMEM */ bool is_opened() const noexcept { return log.is_opened(); }
/** @return LSN at which log resizing was started and is still in progress @retval0ifnologresizingisinprogress
@retval 1 if resize_start() is in progress */
lsn_t resize_in_progress() const noexcept
{ return resize_lsn.load(std::memory_order_relaxed); }
/** Status of resize_start() */ enum resize_start_status {
RESIZE_NO_CHANGE, RESIZE_IN_PROGRESS, RESIZE_STARTED, RESIZE_FAILED
};
/** Start resizing the log and release the exclusive latch. @paramsizerequestednewfile_size @paramthdthecurrentthreadidentifier
@return whether the resizing was started successfully */
resize_start_status resize_start(os_offset_t size, void *thd) noexcept;
/** Abort a resize_start() that we started.
@param thd thread identifier that had been passed to resize_start() */ void resize_abort(void *thd) noexcept;
/** @return whether a particular resize_start() is in progress */ bool resize_running(void *thd) const noexcept
{ return thd == resize_initiator; }
/** Replicate a write to the log. @tparammmapwhetherthememory-mappedinterfaceisenabled @paramlsnstartLSN @paramendendofthemini-transaction @paramlenlengthofthemini-transaction
@param seq offset of the sequence bit from the end */ template<bool mmap> inlinevoid resize_write(lsn_t lsn, const byte *end,
size_t len, size_t seq) noexcept
{ if (UNIV_LIKELY_NULL(resize_buf))
resize_write_low<mmap>(lsn, end, len, seq);
}
/** SET GLOBAL innodb_log_archive @paramarchivethenewvalueofinnodb_log_archive
@param thd SQL connection */ void set_archive(my_bool archive, THD *thd) noexcept;
private: /** Replicate a write to the log. @tparammmapwhetherthememory-mappedinterfaceisenabled @paramlsnstartLSN @paramendendofthemini-transaction @paramlenlengthofthemini-transaction
@param seq offset of the sequence bit from the end */ template<bool mmap>
ATTRIBUTE_COLD void resize_write_low(lsn_t lsn, const byte *end,
size_t len, size_t seq) noexcept; /** Write resize_buf to resize_log. @parambresize_buforresize_flush_buf
@param length the used length of b */ void resize_write_buf(const byte *b, size_t length) noexcept;
/** Rename a log file. @paramold_nametheoldlogfilename
@return whether an error occurred */
ATTRIBUTE_COLD staticbool rename(const std::string &old_name) noexcept; public:
/** Rename a log file after resizing.
@return whether an error occurred */
ATTRIBUTE_COLD staticbool resize_rename() noexcept;
/** During recovery, rename an archived log file to ib_logfile0.
@return whether an error occurred. */
ATTRIBUTE_COLD bool archive_rename() noexcept;
/** Initialise the redo log subsystem. */ void create() noexcept;
/** Access mode of a log file */ enum log_access { #ifdef HAVE_PMEM /** read/write memory-mapping */
PMEM= -1, #endif /** write via pwrite(); memory-mapped reads if log_sys.log_mmap */
READ_WRITE= 0, /** read via pread() or memory-mapping according to log_sys.log_mmap */
READ_ONLY
};
/** Attach a log file.
@return whether the memory allocation succeeded */ bool attach(log_file_t file, os_offset_t size, log_access access) noexcept;
/** Disable memory-mapped access (update log_mmap) */ void clear_mmap() noexcept; void close_file(bool really_close= true) noexcept; /** Stash a log archive file in multi-file recovery,
to allow quick switching between the last two files. */ inlinevoid stash_archive_file() noexcept; /** Unstash a log archive file. */
ATTRIBUTE_COLD void unstash_archive_file() noexcept;
#ifdefined __linux__ || defined _WIN32 /** Try to enable or disable file system caching (update log_buffered) */ void set_buffered(bool buffered) noexcept; #endif /** Try to enable or disable durable writes (update log_write_through) */ void set_write_through(bool write_through);
/** Calculate the checkpoint safety margins. */ staticvoid set_capacity() noexcept;
/** Write a log file header. @parambuflogheaderbuffer @paramlsnlogsequencenumbercorrespondingtolog_sys.START_OFFSET
@param encrypted whether the log is encrypted */ staticvoid header_write(byte *buf, lsn_t lsn, bool encrypted) noexcept;
/** Rewrite the log file header in set_archive()
@param archive the new value of innodb_log_archive */ void header_rewrite(my_bool archive) noexcept;
/** @return an estimate of get_lsn(), usingacquire-releaseorderingwithwrite_buf()orpersist(); anupperboundifsaidfunctionshaveupdatedonlyoneofthefields,
a lower bound if append_prepare_wait() is pending, otherwise exact */
lsn_t get_lsn_approx() const noexcept
{ /* acquire-release ordering with write_buf() and persist() */
lsn_t lsn= base_lsn.load(std::memory_order_acquire);
lsn += write_lsn_offset.load(std::memory_order_relaxed) &
(WRITE_BACKOFF - 1); return lsn;
}
/** @return the current log sequence number (logical time stamp) */
lsn_t get_lsn() const noexcept
{
ut_ad(latch_have_wr()); return base_lsn.load(std::memory_order_relaxed) +
(write_lsn_offset & (WRITE_BACKOFF - 1));
}
/** @return whether a back-off in a log write is in progress */ bool is_backoff() const noexcept
{
ut_ad(latch_have_wr()); return write_lsn_offset & WRITE_BACKOFF;
}
/** Initialize the LSN on initial log file creation. */ inline lsn_t init_lsn() noexcept;
/** Set the LSN up to which everything has been recovered from the log. */
ATTRIBUTE_COLD void set_recovered_lsn(lsn_t lsn) noexcept;
#ifdef HAVE_PMEM /** @return whether the log is memory-mapped read-write */ bool is_mmap_writeable() const noexcept { return is_pmem; } /** Persist the log.
@param lsn desired new value of flushed_to_disk_lsn */ void persist(lsn_t lsn) noexcept; /** @return the overflow buffer when ARCHIVED_MMAP is wrapping around */
byte *get_archived_mmap_switch() const noexcept
{
ut_ad(archived_mmap_switch()); return resize_buf + START_OFFSET;
} #else static constexpr bool is_mmap_writeable() { returnfalse; } #endif /** @return whether archived_mmap_switch_complete() needs to be called */ bool archived_mmap_switch() const noexcept
{
ut_ad(latch_have_any()); return UNIV_UNLIKELY(archive && resize_buf);
}
/** Try to create an archive log file. @paramlsnfirst_lsnofthelogfile
@param ex whether we are holding exclusive latch (and must succeed) */
ATTRIBUTE_COLD void archive_create(lsn_t lsn, bool ex) noexcept;
/** Create a new log file when the current one will fill up. @parambuflogrecordstoappend @paramlengthsizeofthelogrecords,inbytes
@param offset log file offset */
ATTRIBUTE_COLD void archive_new_write(const byte *buf, size_t length,
lsn_t offset) noexcept;
/** Ensure that innodb_log_archive=ON will default to the current
innodb_log_file_size if no size has been specified. */ void archive_set_size() noexcept
{
ut_ad(!resize_in_progress()); if (!resize_target)
resize_target= file_size;
}
/** @return whether !archive log records may have been written with
get_sequence_bit()==0 */ bool circular_recovery_from_0() const noexcept
{ ut_ad(latch_have_wr()); return circular_recovery_from_sequence_bit_0; }
/** Make previous write_buf() durable and update flushed_to_disk_lsn. */ bool flush(lsn_t lsn) noexcept;
/** Shut down the redo log subsystem. */ void close();
#ifdefined __linux__ || defined _WIN32 /** Set the log block size for file I/O. */ void set_block_size(uint32 size) noexcept
{ if (write_size < size)
write_size= size;
} #endif
/** Wait in append_prepare() for buffer to become available @paramlatewhethertheWRITE_BACKOFFflaghadalreadybeenset
@param ex whether log_sys.latch is exclusively locked */
ATTRIBUTE_COLD void append_prepare_wait(bool late, bool ex) noexcept; #ifdef HAVE_PMEM /** Wait in append_prepare<ARCHIVED_MMAP>() for buffer to become available @paramlatewhethertheWRITE_BACKOFFflaghadalreadybeenset
@param ex whether log_sys.latch is exclusively locked */
ATTRIBUTE_COLD void archived_mmap_switch_prepare(bool late, bool ex)
noexcept; #endif public: /** Attempt to finish archived_mmap_switch_prepare(). @returnthecurrentLSNinthenewfile
@retval 0 if no switch took place */
ATTRIBUTE_COLD lsn_t archived_mmap_switch_complete() noexcept;
/** Prepare for multi-file memory-mapped log recovery. */
ATTRIBUTE_COLD void archived_mmap_switch_recovery_prepare() noexcept; /** Finish archived_mmap_switch_recovery_prepare(). */
ATTRIBUTE_COLD void archived_mmap_switch_recovery_complete() noexcept; /** Prepare to switch archive log files on recovery. @paramlsnfirstsequencenumberofthefile
@return whether a spare log file was opened */ bool archived_switch_recovery_prepare(lsn_t lsn) noexcept; /** Try to switch archive log files on recovery.
@return whether the log file was switched */ bool archived_switch_recovery() noexcept; /** Undo archived_switch_recovery()
in recv_sys_t::find_checkpoint_archived() */ inlinevoid archived_switch_recovery_rewind_checkpoint() noexcept; /** Rewind the log during recovery.
@param lsn log sequence number to rewind to */
ATTRIBUTE_COLD void recovery_rewind(lsn_t lsn) noexcept;
/** How to write log */ enum write { /** normal writing !log_sys.is_mmap() */
WRITE_NORMAL, /** circular memory-mapped writing when log_sys.is_mmap() */
CIRCULAR_MMAP, /** memory-mapped log for log_sys.archive */
ARCHIVED_MMAP
};
/** Get a name of a circular log file. @paramilogfilenumber(0to101)
@return the path name of the log file */
ATTRIBUTE_COLD static std::string get_circular_path(size_t i= 0);
/** @return the name of the current log file */
ATTRIBUTE_COLD std::string get_path() const;
/** Append the archive log file base name to a string. @parampathdirectorynameandseparator @paramlsnfirstLSNstoredinthefile
@return path with the base file name appended */ static ATTRIBUTE_COLD std::string &append_archive_name(std::string &path,
lsn_t lsn);
/** Generate an archive log file name. @paramlsnfirstLSNstoredinthefile
@return archive log file name */
ATTRIBUTE_COLD std::string get_archive_path(lsn_t lsn) const; /** @return the current archive log file name */
std::string get_archive_path() const { return get_archive_path(first_lsn); }
/** Reserve space in the log buffer for appending data. @tparammodehowtowritelog @paramsizetotallengthofthedatatoappend(),inbytes @paramexwhetherlog_sys.latchisexclusivelylocked
@return the start LSN and the buffer position for append() */ template<write mode>
std::pair<lsn_t,byte*> append_prepare(size_t size, bool ex) noexcept;
/** Append a string of bytes to the redo log. @paramddestination @paramsstringofbytes
@param size length of str, in bytes */ staticinlinevoid append(byte *&d, constvoid *s, size_t size) noexcept;
/** Set the log file format. */ void set_latest_format(bool encrypted) noexcept
{ format= encrypted ? FORMAT_ENC_11 : FORMAT_10_8; } /** @return whether the redo log is encrypted */ bool is_encrypted() const noexcept { return format & FORMAT_ENCRYPTED; } /** @return whether the redo log is in the latest format */ bool is_latest() const noexcept
{ return format == FORMAT_10_8 || format == FORMAT_ENC_11; } /** @return whether the redo log is in a format that can be recovered */ bool is_recoverable() const noexcept
{ return (format | FORMAT_ENCRYPTED) == FORMAT_ENC_10_8 ||
format == FORMAT_ENC_11;
}
/** Set the LSN of the log file at file creation. */ void set_first_lsn(lsn_t lsn) noexcept { write_lsn= first_lsn= lsn; } /** @return the first LSN of the log file */
lsn_t get_first_lsn() const noexcept { return first_lsn; }
/** Set the recovered checkpoint. @paramlsnlogsequencenumberofthecheckpoint @paramend_lsnLSNpassedtowrite_checkpoint()
@param number checkpoint number */ void set_recovered_checkpoint(lsn_t lsn, lsn_t end_lsn, uint16_t number)
noexcept
{
last_checkpoint_lsn= lsn; this->end_lsn= end_lsn;
next_checkpoint_no= number;
}
/** Determine the sequence bit at a log sequence number */
byte get_sequence_bit(lsn_t lsn) const noexcept
{
ut_ad(lsn >= first_lsn); return !(((lsn - first_lsn) / capacity()) & 1);
}
/** Calculate the offset of a log sequence number. @paramlsnlogsequencenumber
@return byte offset within ib_logfile0 */
lsn_t calc_lsn_offset(lsn_t lsn) const noexcept
{
ut_ad(lsn >= first_lsn); return START_OFFSET + (lsn - first_lsn) % capacity();
}
/** Write checkpoint information and invoke latch.wr_unlock(). @paramcheckpointthenewcheckpointLSN @paramend_lsnstartLSNoftheFILE_CHECKPOINTmini-transaction @returnthelsntoinvokearchive_create(lsn,false)on
@retval 0 if archive_create() should not be called */ inline lsn_t write_checkpoint(lsn_t checkpoint, lsn_t end_lsn) noexcept;
/** Wait for write_checkpoint() if necessary. */
ATTRIBUTE_COLD void checkpoint_margin() noexcept;
/** Variations of write_buf() */ enum resizing_and_latch { /** skip latch.wr_unlock(); log resizing may or may not be in progress */
RETAIN_LATCH, /** invoke latch.wr_unlock(); !(resize_in_progress() > 1) */
NOT_RESIZING, /** invoke latch.wr_unlock(); resize_in_progress() > 1 */
RESIZING
};
/** Write buf to ib_logfile0 and possibly ib_logfile101. @tparamresizingwhethertoreleaselatchandwhetherresize_in_progress()>1
@return the current log sequence number */ template<resizing_and_latch resizing> inline lsn_t write_buf() noexcept;
/** Create the log. */ void create(lsn_t lsn) noexcept;
};
/** Redo log system */ extern log_t log_sys;
/** Wait for a log checkpoint if needed. NOTEthatthisfunctionmayonlybecalledwhilenotholding
any synchronization objects except dict_sys.latch. */ void log_free_check() noexcept;
/** @return the current log sequence number (may be stale) */
lsn_t log_get_lsn() noexcept;
/** Release the latches that protect log resizing. */ void log_resize_release() noexcept;
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.14 Sekunden
(vorverarbeitet am 2026-10-08)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.