Skip to content

Commit

Permalink
MDEV-16045: Replace log_group_t with log_t::files
Browse files Browse the repository at this point in the history
There is only one log_sys and only one log_sys.log.

log_t::files::create(): Replaces log_init().

log_t::files::close(): Replaces log_group_close(), log_group_close_all().

fil_close_log_files(): if (free) log_sys.log_close();
The callers that passed free=true used to call log_group_close_all().

log_header_read(): Replaces log_group_header_read().

log_t::files::file_header_bufs_ptr: Use a single allocation.

log_t::files::file_header_bufs[]: Statically allocate the pointers.

log_t::files::set_fields(): Replaces log_group_set_fields().

log_t::files::calc_lsn_offset(): Replaces log_group_calc_lsn_offset().
Simplify the computation by using fewer variables.

log_t::files::read_log_seg(): Replaces log_group_read_log_seg().

log_sys_t::complete_checkpoint(): Replaces log_io_complete_checkpoint().

fil_aio_wait(): Move the logic from log_io_complete().
  • Loading branch information
dr-m committed Apr 29, 2018
1 parent d73a898 commit baa5a43
Show file tree
Hide file tree
Showing 8 changed files with 234 additions and 481 deletions.
7 changes: 3 additions & 4 deletions extra/mariabackup/xtrabackup.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2544,8 +2544,7 @@ xtrabackup_copy_logfile(copy_logfile copy)

lsn_t lsn= start_lsn;
for(int retries= 0; retries < 100; retries++) {
if (log_group_read_log_seg(log_sys.buf, &log_sys.log,
&lsn, end_lsn)){
if (log_sys.log.read_log_seg(&lsn, end_lsn)) {
break;
}
msg("Retrying read of a redo log block");
Expand Down Expand Up @@ -3819,7 +3818,7 @@ xtrabackup_backup_func()
SRV_MAX_N_PENDING_SYNC_IOS);

log_sys.create();
log_init(srv_n_log_files);
log_sys.log.create(srv_n_log_files);
fil_space_t* space = fil_space_create(
"innodb_redo_log", SRV_LOG_SPACE_FIRST_ID, 0,
FIL_TYPE_LOG, NULL);
Expand Down Expand Up @@ -3924,7 +3923,7 @@ xtrabackup_backup_func()
ut_ad(!((log_sys.log.format ^ LOG_HEADER_FORMAT_CURRENT)
& ~LOG_HEADER_FORMAT_ENCRYPTED));

log_group_header_read(&log_sys.log, max_cp_field);
log_header_read(max_cp_field);

if (checkpoint_no_start != mach_read_from_8(buf + LOG_CHECKPOINT_NO)) {
goto reread_log_header;
Expand Down
25 changes: 24 additions & 1 deletion storage/innobase/fil/fil0fil.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2007,6 +2007,10 @@ fil_close_log_files(
}

mutex_exit(&fil_system.mutex);

if (free) {
log_sys.log.close();
}
}

/*******************************************************************//**
Expand Down Expand Up @@ -4685,7 +4689,26 @@ fil_aio_wait(
switch (purpose) {
case FIL_TYPE_LOG:
srv_set_io_thread_op_info(segment, "complete io for log");
log_io_complete(static_cast<log_group_t*>(message));
/* We use synchronous writing of the logs
and can only end up here when writing a log checkpoint! */
ut_a(ptrdiff_t(message) == 1);
/* It was a checkpoint write */
switch (srv_file_flush_method) {
case SRV_O_DSYNC:
case SRV_NOSYNC:
break;
case SRV_FSYNC:
case SRV_LITTLESYNC:
case SRV_O_DIRECT:
case SRV_O_DIRECT_NO_FSYNC:
#ifdef _WIN32
case SRV_ALL_O_DIRECT_FSYNC:
#endif
fil_flush(SRV_LOG_SPACE_FIRST_ID);
}

DBUG_PRINT("ib_log", ("checkpoint info written"));
log_sys.complete_checkpoint();
return;
case FIL_TYPE_TABLESPACE:
case FIL_TYPE_TEMPORARY:
Expand Down
180 changes: 90 additions & 90 deletions storage/innobase/include/log0log.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ Created 12/9/1995 Heikki Tuuri
#include "os0event.h"
#include "os0file.h"

/** Redo log group */
struct log_group_t;
/** Maximum number of srv_n_log_files, or innodb_log_files_in_group */
#define SRV_N_LOG_FILES_MAX 100

/** Magic value to use instead of log checksums when they are disabled */
#define LOG_NO_CHECKSUM_MAGIC 0xDEADBEEFUL
Expand Down Expand Up @@ -151,10 +151,6 @@ lsn_t
log_get_max_modified_age_async(void);
/*================================*/

/** Initialize the redo log.
@param[in] n_files number of files */
void
log_init(ulint n_files);
/** Calculate the recommended highest values for lsn - last_checkpoint_lsn
and lsn - buf_get_oldest_modification().
@param[in] file_size requested innodb_log_file_size
Expand All @@ -166,12 +162,6 @@ log_set_capacity(ulonglong file_size)
MY_ATTRIBUTE((warn_unused_result));

/******************************************************//**
Completes an i/o to a log file. */
void
log_io_complete(
/*============*/
log_group_t* group); /*!< in: log group */
/******************************************************//**
This function is called, e.g., when a transaction wants to commit. It checks
that the log has been written to the log file up to the last log entry written
by the transaction. If there is a flush running, it waits and checks if the
Expand Down Expand Up @@ -231,12 +221,8 @@ void
logs_empty_and_mark_files_at_shutdown(void);
/*=======================================*/
/** Read a log group header page to log_sys.checkpoint_buf.
@param[in] group log group
@param[in] header 0 or LOG_CHEKCPOINT_1 or LOG_CHECKPOINT2 */
void
log_group_header_read(
const log_group_t* group,
ulint header);
@param[in] header 0 or LOG_CHECKPOINT_1 or LOG_CHECKPOINT2 */
void log_header_read(ulint header);
/** Write checkpoint info to the log header and invoke log_mutex_exit().
@param[in] sync whether to wait for the write to complete
@param[in] end_lsn start LSN of the MLOG_CHECKPOINT mini-transaction */
Expand All @@ -257,16 +243,6 @@ objects! */
void
log_check_margins(void);

/********************************************************//**
Sets the field values in group to correspond to a given lsn. For this function
to work, the values must already be correctly initialized to correspond to
some lsn, for instance, a checkpoint lsn. */
void
log_group_set_fields(
/*=================*/
log_group_t* group, /*!< in/out: group */
lsn_t lsn); /*!< in: lsn for which the values should be
set */
/************************************************************//**
Gets a log block flush bit.
@return TRUE if this block was the first to be written in a log flush */
Expand Down Expand Up @@ -398,11 +374,6 @@ Refreshes the statistics used to print per-second averages. */
void
log_refresh_stats(void);
/*===================*/
/********************************************************//**
Closes all log groups. */
void
log_group_close_all(void);
/*=====================*/

/** Whether to generate and require checksums on the redo log pages */
extern my_bool innodb_log_checksums;
Expand Down Expand Up @@ -536,50 +507,6 @@ enum log_group_state_t {
typedef ib_mutex_t LogSysMutex;
typedef ib_mutex_t FlushOrderMutex;

/** Log group consists of a number of log files, each of the same size; a log
group is implemented as a space in the sense of the module fil0fil.
Currently, this is only protected by log_sys.mutex. However, in the case
of log_write_up_to(), we will access some members only with the protection
of log_sys.write_mutex, which should affect nothing for now. */
struct log_group_t{
/** number of files in the group */
ulint n_files;
/** format of the redo log: e.g., LOG_HEADER_FORMAT_CURRENT */
ulint format;
/** individual log file size in bytes, including the header */
lsn_t file_size;
/** corruption status */
log_group_state_t state;
/** lsn used to fix coordinates within the log group */
lsn_t lsn;
/** the byte offset of the above lsn */
lsn_t lsn_offset;
/** unaligned buffers */
byte** file_header_bufs_ptr;
/** buffers for each file header in the group */
byte** file_header_bufs;

/** used only in recovery: recovery scan succeeded up to this
lsn in this log group */
lsn_t scanned_lsn;
/** unaligned checkpoint header */
byte* checkpoint_buf_ptr;
/** buffer for writing a checkpoint header */
byte* checkpoint_buf;

/** @return whether the redo log is encrypted */
bool is_encrypted() const
{
return((format & LOG_HEADER_FORMAT_ENCRYPTED) != 0);
}

/** @return capacity in bytes */
inline lsn_t capacity() const
{
return((file_size - LOG_FILE_HDR_SIZE) * n_files);
}
};

/** Redo log buffer */
struct log_t{
MY_ALIGNED(CACHE_LINE_SIZE)
Expand All @@ -590,8 +517,7 @@ struct log_t{
MY_ALIGNED(CACHE_LINE_SIZE)
LogSysMutex mutex; /*!< mutex protecting the log */
MY_ALIGNED(CACHE_LINE_SIZE)
LogSysMutex write_mutex; /*!< mutex protecting writing to log
file and accessing to log_group_t */
LogSysMutex write_mutex; /*!< mutex protecting writing to log */
MY_ALIGNED(CACHE_LINE_SIZE)
FlushOrderMutex log_flush_order_mutex;/*!< mutex to serialize access to
the flush list when we are putting
Expand Down Expand Up @@ -626,8 +552,67 @@ struct log_t{
max_checkpoint_age; this flag is
peeked at by log_free_check(), which
does not reserve the log mutex */
/** the redo log */
log_group_t log;

/** Log files. Protected by mutex or write_mutex. */
struct files {
/** number of files */
ulint n_files;
/** format of the redo log: e.g., LOG_HEADER_FORMAT_CURRENT */
ulint format;
/** individual log file size in bytes, including the header */
lsn_t file_size;
/** corruption status */
log_group_state_t state;
/** lsn used to fix coordinates within the log group */
lsn_t lsn;
/** the byte offset of the above lsn */
lsn_t lsn_offset;

/** unaligned buffers */
byte* file_header_bufs_ptr;
/** buffers for each file header in the group */
byte* file_header_bufs[SRV_N_LOG_FILES_MAX];

/** used only in recovery: recovery scan succeeded up to this
lsn in this log group */
lsn_t scanned_lsn;

/** @return whether the redo log is encrypted */
bool is_encrypted() const { return format & LOG_HEADER_FORMAT_ENCRYPTED; }
/** @return capacity in bytes */
lsn_t capacity() const{ return (file_size - LOG_FILE_HDR_SIZE) * n_files; }
/** Calculate the offset of a log sequence number.
@param[in] lsn log sequence number
@return offset within the log */
inline lsn_t calc_lsn_offset(lsn_t lsn) const;

/** Set the field values to correspond to a given lsn. */
void set_fields(lsn_t lsn)
{
lsn_offset = calc_lsn_offset(lsn);
this->lsn = lsn;
}

/** Read a log segment to log_sys.buf.
@param[in,out] start_lsn in: read area start,
out: the last read valid lsn
@param[in] end_lsn read area end
@return whether no invalid blocks (e.g checksum mismatch) were found */
bool read_log_seg(lsn_t* start_lsn, lsn_t end_lsn);

/** Initialize the redo log buffer.
@param[in] n_files number of files */
void create(ulint n_files);

/** Close the redo log buffer. */
void close()
{
ut_free(file_header_bufs_ptr);
n_files = 0;
file_header_bufs_ptr = NULL;
memset(file_header_bufs, 0, sizeof file_header_bufs);
}
} log;

/** The fields involved in the log buffer flush @{ */

Expand Down Expand Up @@ -730,6 +715,9 @@ struct log_t{

bool is_initialised() { return m_initialised; }

/** Complete an asynchronous checkpoint write. */
void complete_checkpoint();

/** Initialise the redo log subsystem. */
void create();

Expand All @@ -740,6 +728,27 @@ struct log_t{
/** Redo log system */
extern log_t log_sys;

/** Calculate the offset of a log sequence number.
@param[in] lsn log sequence number
@return offset within the log */
inline lsn_t log_t::files::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_sys.write_mutex.is_owned());
const lsn_t group_size= capacity();
lsn_t l= lsn - this->lsn;
if (longlong(l) < 0) {
l= lsn_t(-longlong(l)) % group_size;
l= group_size - l;
}

l+= lsn_offset - LOG_FILE_HDR_SIZE * (1 + lsn_offset / file_size);
l%= group_size;
return l + LOG_FILE_HDR_SIZE * (1 + l / (file_size - LOG_FILE_HDR_SIZE));
}

/** Test if flush order mutex is owned. */
#define log_flush_order_mutex_own() \
mutex_own(&log_sys.log_flush_order_mutex)
Expand Down Expand Up @@ -783,15 +792,6 @@ extern log_t log_sys;
mutex_exit(&log_sys.write_mutex); \
} while (0)

/** Calculate the offset of an lsn within a log group.
@param[in] lsn log sequence number
@param[in] group log group
@return offset within the log group */
lsn_t
log_group_calc_lsn_offset(
lsn_t lsn,
const log_group_t* group);

/* log scrubbing speed, in bytes/sec */
extern ulonglong innodb_scrub_log_speed;

Expand Down
16 changes: 1 addition & 15 deletions storage/innobase/include/log0recv.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2017, MariaDB Corporation.
Copyright (c) 2017, 2018, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Expand Down Expand Up @@ -96,20 +96,6 @@ void
recv_sys_debug_free(void);
/*=====================*/

/** Read a log segment to a buffer.
@param[out] buf buffer
@param[in] group redo log files
@param[in, out] start_lsn in : read area start, out: the last read valid lsn
@param[in] end_lsn read area end
@param[out] invalid_block - invalid, (maybe incompletely written) block encountered
@return false, if invalid block encountered (e.g checksum mismatch), true otherwise */
bool
log_group_read_log_seg(
byte* buf,
const log_group_t* group,
lsn_t* start_lsn,
lsn_t end_lsn);

/********************************************************//**
Reset the state of the recovery system variables. */
void
Expand Down
2 changes: 0 additions & 2 deletions storage/innobase/include/srv0srv.h
Original file line number Diff line number Diff line change
Expand Up @@ -339,8 +339,6 @@ extern const ulint SRV_UNDO_TABLESPACE_SIZE_IN_PAGES;

extern char* srv_log_group_home_dir;

/** Maximum number of srv_n_log_files, or innodb_log_files_in_group */
#define SRV_N_LOG_FILES_MAX 100
extern ulong srv_n_log_files;
/** The InnoDB redo log file size, or 0 when changing the redo log format
at startup (while disallowing writes to the redo log). */
Expand Down
Loading

0 comments on commit baa5a43

Please sign in to comment.