MySQL 9.0.0
Source Code Documentation
log0write.cc File Reference

Redo log writing and flushing, including functions for: More...

#include <atomic>
#include <mysql/service_thd_wait.h>
#include <cstring>
#include "arch0arch.h"
#include "buf0types.h"
#include "log0buf.h"
#include "log0chkp.h"
#include "log0files_capacity.h"
#include "log0files_governor.h"
#include "log0log.h"
#include "log0meb.h"
#include "log0recv.h"
#include "log0sys.h"
#include "log0test.h"
#include "log0types.h"
#include "log0write.h"
#include "sql/sql_thd_internal_api.h"
#include "srv0mon.h"
#include "srv0srv.h"
#include "ut0byte.h"

Classes

struct  Log_thread_waiting
 Small utility which is used inside log threads when they have to wait for next interesting event to happen. More...
 
struct  Log_write_to_file_requests_monitor
 

Namespaces

namespace  Log_files_write_impl
 

Functions

static void Log_files_write_impl::validate_buffer (const log_t &log, const byte *buffer, size_t buffer_size)
 
static void Log_files_write_impl::validate_start_lsn (const log_t &log, lsn_t start_lsn, size_t buffer_size)
 
static bool Log_files_write_impl::current_file_has_space (const log_t &log, os_offset_t offset, size_t size)
 
static dberr_t Log_files_write_impl::start_next_file (log_t &log, lsn_t start_lsn)
 
static bool Log_files_write_impl::write_ahead_enough (os_offset_t write_ahead_end, os_offset_t offset, size_t size)
 
static bool Log_files_write_impl::current_write_ahead_enough (const log_t &log, os_offset_t offset, size_t size)
 
static os_offset_t Log_files_write_impl::compute_next_write_ahead_end (os_offset_t real_offset)
 
static size_t Log_files_write_impl::compute_how_much_to_write (const log_t &log, os_offset_t real_offset, size_t buffer_size, bool &write_from_log_buffer)
 
static void Log_files_write_impl::prepare_full_blocks (const log_t &log, byte *buffer, size_t size, lsn_t start_lsn)
 
static dberr_t Log_files_write_impl::write_blocks (log_t &log, byte *write_buf, size_t write_size, os_offset_t real_offset)
 
static void Log_files_write_impl::notify_about_advanced_write_lsn (log_t &log, lsn_t old_write_lsn, lsn_t new_write_lsn)
 
static void Log_files_write_impl::copy_to_write_ahead_buffer (log_t &log, const byte *buffer, size_t &size, lsn_t start_lsn)
 
static size_t Log_files_write_impl::prepare_for_write_ahead (log_t &log, os_offset_t real_offset, size_t &write_size)
 
static void Log_files_write_impl::update_current_write_ahead (log_t &log, os_offset_t real_offset, size_t write_size)
 
Log writer thread
static dberr_t log_write_buffer (log_t &log, byte *buffer, size_t buffer_size, lsn_t start_lsn)
 Writes a given fragment of the log buffer to the current redo log file, unless the file is full, in which case a new file is produced and function exits (note, that the new log file's header is flushed in such case). More...
 
static void log_writer_enter_extra_margin (log_t &log)
 Called when the redo log writer enters the extra_margin. More...
 
static void log_writer_exit_extra_margin (log_t &log)
 Called when the redo log writer exits the extra_margin. More...
 
static lsn_t log_writer_wait_on_checkpoint (log_t &log, lsn_t last_write_lsn, lsn_t next_write_lsn)
 
static void log_writer_wait_on_archiver (log_t &log, lsn_t next_write_lsn)
 
static void log_writer_write_failed (log_t &log, dberr_t err)
 Called after a write to the redo log file failed. More...
 
static void log_writer_write_buffer (log_t &log, lsn_t next_write_lsn)
 Writes fragment of the log buffer, not further than up to provided lsn. More...
 
static bool log_writer_extra_margin_check (log_t &log, lsn_t checkpoint_lsn, lsn_t next_write_lsn)
 
void log_writer_check_if_exited_extra_margin (log_t &log)
 Checks if the redo log writer exited extra margin. More...
 
static std::pair< lsn_t, bool > log_writer_wait_on_checkpoint_optimistic (log_t &log, lsn_t last_write_lsn, lsn_t next_write_lsn)
 
static lsn_t log_writer_wait_on_checkpoint_pessimistic (log_t &log, lsn_t last_write_lsn, lsn_t next_write_lsn)
 
static void log_writer_wait_on_consumers (log_t &log, lsn_t next_write_lsn)
 
static bool log_writer_is_allowed_to_stop (log_t &log)
 
void log_writer (log_t *log_ptr)
 The log writer thread routine. More...
 
Log flusher thread
static void log_flush_low (log_t &log)
 Executes a synchronous flush of the log files (doing fsyncs). More...
 
static void log_flush_update_stats (log_t &log)
 
uint64_t log_total_flushes ()
 Total number of redo log flushes (fsyncs) that have been started since the redo log system (log_sys) became initialized (. More...
 
uint64_t log_pending_flushes ()
 Number of currently pending redo log flushes (fsyncs in-progress). More...
 
void log_flusher (log_t *log_ptr)
 The log flusher thread routine. More...
 
Waiting for redo log written or flushed up to lsn
static size_t log_compute_wait_event_slot (lsn_t lsn, size_t events_n)
 Computes index of a slot (in array of "wait events"), which should be used when waiting until redo reached provided lsn. More...
 
static size_t log_compute_write_event_slot (const log_t &log, lsn_t lsn)
 Computes index of a slot (in array of "wait events"), which should be used when waiting in log.write_events (for redo written up to lsn). More...
 
static size_t log_compute_flush_event_slot (const log_t &log, lsn_t lsn)
 Computes index of a slot (in array of "wait events"), which should be used when waiting in log.flush_events (for redo flushed up to lsn). More...
 
static uint64_t log_max_spins_when_waiting_in_user_thread (uint64_t min_non_zero_value)
 Computes maximum number of spin rounds which should be used when waiting in user thread (for written or flushed redo) or 0 if busy waiting should not be used at all. More...
 
static Wait_stats log_wait_for_write (const log_t &log, lsn_t lsn, bool *interrupted)
 Waits until redo log is written up to provided lsn (or greater). More...
 
static Wait_stats log_wait_for_flush (const log_t &log, lsn_t lsn, bool *interrupted)
 Waits until redo log is flushed up to provided lsn (or greater). More...
 
static Wait_stats log_self_write_up_to (log_t &log, lsn_t end_lsn, bool flush_to_disk, bool *interrupted)
 Write the redo log up to a provided lsn by itself, if necessary. More...
 
Wait_stats log_write_up_to (log_t &log, lsn_t end_lsn, bool flush_to_disk)
 Waits until the redo log is written up to a provided lsn. More...
 
Log write_notifier thread
void log_write_notifier (log_t *log_ptr)
 The log write notifier thread routine. More...
 
Log flush_notifier thread
void log_flush_notifier (log_t *log_ptr)
 The log flush notifier thread routine. More...
 

Detailed Description

Redo log writing and flushing, including functions for:

  1. Waiting for the log written / flushed up to provided lsn.
  2. Redo log write threads: log_writer, log_flusher, log_write_notifier, log_flush_notifier.
Author
Paweł Olchawa

Function Documentation

◆ log_compute_flush_event_slot()

static size_t log_compute_flush_event_slot ( const log_t log,
lsn_t  lsn 
)
inlinestatic

Computes index of a slot (in array of "wait events"), which should be used when waiting in log.flush_events (for redo flushed up to lsn).

Parameters
[in]logredo log
[in]lsnlsn up to which waiting (for log.flushed_to_disk_lsn)
Returns
index of the slot (integer in range 0 .. log.flush_events_size-1)

◆ log_compute_wait_event_slot()

static size_t log_compute_wait_event_slot ( lsn_t  lsn,
size_t  events_n 
)
inlinestatic

Computes index of a slot (in array of "wait events"), which should be used when waiting until redo reached provided lsn.

Parameters
[in]lsnlsn up to which waiting takes place
[in]events_nsize of the array (number of slots)
Returns
index of the slot (integer in range 0 .. events_n-1)

◆ log_compute_write_event_slot()

static size_t log_compute_write_event_slot ( const log_t log,
lsn_t  lsn 
)
inlinestatic

Computes index of a slot (in array of "wait events"), which should be used when waiting in log.write_events (for redo written up to lsn).

Parameters
[in]logredo log
[in]lsnlsn up to which waiting (for log.write_lsn)
Returns
index of the slot (integer in range 0 .. log.write_events_size-1)

◆ log_flush_low()

static void log_flush_low ( log_t log)
static

Executes a synchronous flush of the log files (doing fsyncs).

Advances log.flushed_to_disk_lsn and notifies log flush_notifier thread. Note: if only a single log block was flushed to disk, user threads waiting for lsns within the block are notified directly from here, and log flush_notifier thread is not notified! (optimization)

Parameters
[in,out]logredo log

◆ log_flush_notifier()

void log_flush_notifier ( log_t log_ptr)

The log flush notifier thread routine.

Parameters
[in,out]log_ptrpointer to redo log

◆ log_flush_update_stats()

static void log_flush_update_stats ( log_t log)
static

◆ log_flusher()

void log_flusher ( log_t log_ptr)

The log flusher thread routine.

Parameters
[in,out]log_ptrpointer to redo log

◆ log_max_spins_when_waiting_in_user_thread()

static uint64_t log_max_spins_when_waiting_in_user_thread ( uint64_t  min_non_zero_value)
inlinestatic

Computes maximum number of spin rounds which should be used when waiting in user thread (for written or flushed redo) or 0 if busy waiting should not be used at all.

Parameters
[in]min_non_zero_valueminimum allowed value (unless 0 is returned)
Returns
maximum number of spin rounds or 0

◆ log_pending_flushes()

uint64_t log_pending_flushes ( )

Number of currently pending redo log flushes (fsyncs in-progress).

Returns
number of pending fsyncs or 0 if the redo log system is uninitialized

◆ log_self_write_up_to()

static Wait_stats log_self_write_up_to ( log_t log,
lsn_t  end_lsn,
bool  flush_to_disk,
bool *  interrupted 
)
static

Write the redo log up to a provided lsn by itself, if necessary.

Parameters
[in]logredo log
[in]end_lsnlsn to write for
[in]flush_to_diskwhether the written log should also be flushed
[in,out]interruptedif true, was interrupted, needs retry
Returns
statistics about waiting inside

◆ log_total_flushes()

uint64_t log_total_flushes ( )

Total number of redo log flushes (fsyncs) that have been started since the redo log system (log_sys) became initialized (.

See also
log_sys_init).
Returns
total number of fsyncs or 0 if the redo log system is uninitialized

◆ log_wait_for_flush()

static Wait_stats log_wait_for_flush ( const log_t log,
lsn_t  lsn,
bool *  interrupted 
)
static

Waits until redo log is flushed up to provided lsn (or greater).

Parameters
[in]logredo log
[in]lsnwait until log.flushed_to_disk_lsn >= lsn
[in,out]interruptedif true, was interrupted, needs retry.
Returns
statistics related to waiting inside

◆ log_wait_for_write()

static Wait_stats log_wait_for_write ( const log_t log,
lsn_t  lsn,
bool *  interrupted 
)
static

Waits until redo log is written up to provided lsn (or greater).

We do not care if it's flushed or not.

Parameters
[in]logredo log
[in]lsnwait until log.write_lsn >= lsn
[in,out]interruptedif true, was interrupted, needs retry.
Returns
statistics related to waiting inside

◆ log_write_buffer()

static dberr_t log_write_buffer ( log_t log,
byte buffer,
size_t  buffer_size,
lsn_t  start_lsn 
)
static

Writes a given fragment of the log buffer to the current redo log file, unless the file is full, in which case a new file is produced and function exits (note, that the new log file's header is flushed in such case).

After data to the current log file has been written (log_data_blocks_write()), the log.write_lsn is advanced accordingly to the number of written bytes, which might be smaller than the requested number of bytes to write. That's because this function exits after doing a single write operation. That's because it might make sense to advance the lsn up to which data is ready in the log buffer (for writing), before making decision about next write (e.g. then the next write could be done for full blocks only).

Parameters
[in]logredo log
[in]bufferthe beginning of first log block to write
[in]buffer_sizenumber of bytes to write since 'buffer'
[in]start_lsnlsn corresponding to first block start
Returns
DB_SUCCESS or error

◆ log_write_notifier()

void log_write_notifier ( log_t log_ptr)

The log write notifier thread routine.

Parameters
[in,out]log_ptrpointer to redo log

◆ log_write_up_to()

Wait_stats log_write_up_to ( log_t log,
lsn_t  lsn,
bool  flush_to_disk 
)

Waits until the redo log is written up to a provided lsn.

Parameters
[in]logredo log
[in]lsnlsn to wait for
[in]flush_to_disktrue: wait until it is flushed
Returns
statistics about waiting inside

◆ log_writer()

void log_writer ( log_t log_ptr)

The log writer thread routine.

Parameters
[in,out]log_ptrpointer to redo log

◆ log_writer_check_if_exited_extra_margin()

void log_writer_check_if_exited_extra_margin ( log_t log)

Checks if the redo log writer exited extra margin.

To minimize flipping of log.m_writer_inside_extra_margin, the check assumes the very pessimistic scenario in which a next write of the log_writer thread, would be executed up to the current lsn.

Requirement: log.writer_mutex acquired and log.m_writer_inside_extra_margin is true, before calling this function.

Remarks
This method is supposed to be used by the log_checkpointer thread to detect situation in which the redo log writer has actually exited the extra_margin, because of advanced log.last_checkpoint_lsn, but the log_writer thread didn't notice it because it has not been active since then (e.g. because there is nothing more to write, ie. log.write_lsn == current lsn).
Parameters
[in,out]logredo log

◆ log_writer_enter_extra_margin()

static void log_writer_enter_extra_margin ( log_t log)
static

Called when the redo log writer enters the extra_margin.

Requirement: log.writer_mutex acquired and log.m_write_inside_extra_margin being false, before calling this function.

Parameters
[in,out]logredo log

◆ log_writer_exit_extra_margin()

static void log_writer_exit_extra_margin ( log_t log)
static

Called when the redo log writer exits the extra_margin.

Requirement: log.writer_mutex acquired and log.m_write_inside_extra_margin being true, before calling this function.

Parameters
[in,out]logredo log

◆ log_writer_extra_margin_check()

static bool log_writer_extra_margin_check ( log_t log,
lsn_t  checkpoint_lsn,
lsn_t  next_write_lsn 
)
inlinestatic

◆ log_writer_is_allowed_to_stop()

static bool log_writer_is_allowed_to_stop ( log_t log)
static

◆ log_writer_wait_on_archiver()

static void log_writer_wait_on_archiver ( log_t log,
lsn_t  next_write_lsn 
)
static

◆ log_writer_wait_on_checkpoint()

static lsn_t log_writer_wait_on_checkpoint ( log_t log,
lsn_t  last_write_lsn,
lsn_t  next_write_lsn 
)
static

◆ log_writer_wait_on_checkpoint_optimistic()

static std::pair< lsn_t, bool > log_writer_wait_on_checkpoint_optimistic ( log_t log,
lsn_t  last_write_lsn,
lsn_t  next_write_lsn 
)
inlinestatic

◆ log_writer_wait_on_checkpoint_pessimistic()

static lsn_t log_writer_wait_on_checkpoint_pessimistic ( log_t log,
lsn_t  last_write_lsn,
lsn_t  next_write_lsn 
)
static

◆ log_writer_wait_on_consumers()

static void log_writer_wait_on_consumers ( log_t log,
lsn_t  next_write_lsn 
)
static

◆ log_writer_write_buffer()

static void log_writer_write_buffer ( log_t log,
lsn_t  next_write_lsn 
)
static

Writes fragment of the log buffer, not further than up to provided lsn.

Stops after the first call to log_data_blocks_write() or after producing a new log file or if it notices that some other thread has written to the redo log meanwhile. If some data was written, the log.write_lsn is advanced. For more details see

See also
log_write_buffer().
Parameters
[in]logredo log
[in]next_write_lsnwrite up to this lsn value

◆ log_writer_write_failed()

static void log_writer_write_failed ( log_t log,
dberr_t  err 
)
static

Called after a write to the redo log file failed.

If the reason was not related to missing free space or busy file-lock, emits fatal error.

Parameters
[in,out]logredo log
[in]errerror code (non-zero)