Commit 4683c2fe authored by Marko Mäkelä's avatar Marko Mäkelä

MDEV-34850: Busy work while parsing FILE_ records

In mariadb-backup --backup, we only have to invoke the undo_space_trunc
and log_file_op callbacks as well as validate the mini-transaction
checksums. There is absolutely no need to access recv_sys.pages or
recv_spaces. This is what the new mode recv_sys_t::store::BACKUP will do.

In the skip_the_rest: loop, the minimum that needs to be done is to
process all FILE_ records until the end of the log is reached.
Additionally, in case we invoked file_name_t::add_freed_page() for a
FREE_PAGE record before switching to the skip_the_rest: loop, we must
invoke file_name_t::remove_freed_page() for any INIT_PAGE record.
Any other records that we encounter during this parsing can be ignored;
they will eventually be processed on a subsequent call to recv_scan_log()
with store=true.

This was measured to reduce the CPU time between the messages
"InnoDB: Multi-batch recovery needed at LSN" and
"InnoDB: End of log at LSN"
by some 20%.

recv_sys_t::store: A ternary enumeration that specifies how records
should be stored: NO, BACKUP, or YES.

recv_sys_t::parse(), recv_sys_t::parse_mtr(), recv_sys_t::parse_pmem():
Replace template<bool store> with template<store storing>.

store_freed_or_init_rec(): Simplify some logic. We can look up also
the system tablespace.
parent 2d3ddaef
......@@ -3405,7 +3405,8 @@ static bool xtrabackup_copy_mmap_logfile()
recv_sys_t::parse_mtr_result r;
const byte *start= &log_sys.buf[recv_sys.offset];
if (recv_sys.parse_mmap<false>(false) == recv_sys_t::OK)
if (recv_sys.parse_mmap<recv_sys_t::store::BACKUP>(false) ==
recv_sys_t::OK)
{
const byte *end;
......@@ -3425,7 +3426,8 @@ static bool xtrabackup_copy_mmap_logfile()
start = seq + 1;
}
}
while ((r= recv_sys.parse_mmap<false>(false)) == recv_sys_t::OK);
while ((r= recv_sys.parse_mmap<recv_sys_t::store::BACKUP>(false)) ==
recv_sys_t::OK);
end= &log_sys.buf[recv_sys.offset];
......@@ -3530,7 +3532,8 @@ static bool xtrabackup_copy_logfile()
if (log_sys.buf[recv_sys.offset] <= 1)
break;
if (recv_sys.parse_mtr<false>(false) == recv_sys_t::OK)
if (recv_sys.parse_mtr<recv_sys_t::store::BACKUP>(false) ==
recv_sys_t::OK)
{
do
{
......@@ -3540,7 +3543,8 @@ static bool xtrabackup_copy_logfile()
sequence_offset));
*seq= 1;
}
while ((r= recv_sys.parse_mtr<false>(false)) == recv_sys_t::OK);
while ((r= recv_sys.parse_mtr<recv_sys_t::store::BACKUP>(false)) ==
recv_sys_t::OK);
if (ds_write(dst_log_file, log_sys.buf + start_offset,
recv_sys.offset - start_offset))
......
......@@ -390,12 +390,15 @@ struct recv_sys_t
GOT_OOM
};
/** Whether to store parsed log records */
enum store{NO,BACKUP,YES};
private:
/** Parse and register one log_t::FORMAT_10_8 mini-transaction.
@tparam store whether to store the records
@tparam storing whether to store the records
@param l log data source
@param if_exists if store: whether to check if the tablespace exists */
template<typename source,bool store>
template<typename source,store storing>
inline parse_mtr_result parse(source &l, bool if_exists) noexcept;
/** Rewind a mini-transaction when parse() runs out of memory.
......@@ -409,20 +412,20 @@ struct recv_sys_t
public:
/** Parse and register one log_t::FORMAT_10_8 mini-transaction,
without handling any log_sys.is_mmap() buffer wrap-around.
@tparam store whether to store the records
@param if_exists if store: whether to check if the tablespace exists */
template<bool store>
@tparam storing whether to store the records
@param if_exists storing=YES: whether to check if the tablespace exists */
template<store storing>
static parse_mtr_result parse_mtr(bool if_exists) noexcept;
/** Parse and register one log_t::FORMAT_10_8 mini-transaction,
handling log_sys.is_mmap() buffer wrap-around.
@tparam store whether to store the records
@param if_exists if store: whether to check if the tablespace exists */
template<bool store>
@tparam storing whether to store the records
@param if_exists storing=YES: whether to check if the tablespace exists */
template<store storing>
static parse_mtr_result parse_mmap(bool if_exists) noexcept
#ifdef HAVE_INNODB_MMAP
;
#else
{ return parse_mtr<store>(if_exists); }
{ return parse_mtr<storing>(if_exists); }
#endif
/** Erase log records for a page. */
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment