Commit 76c62bc6 authored by Marko Mäkelä's avatar Marko Mäkelä

MDEV-15914: Restore MLOG_UNDO_INSERT

trx_undof_page_add_undo_rec_log(): Write the MLOG_UNDO_INSERT
record instead of the equivalent MLOG_2BYTES and MLOG_WRITE_STRING.
This essentially reverts commit 9ee8917d.

In MariaDB 10.3, I attempted to simplify the crash recovery code
by making use of lower-level redo log records. It turns out that
we must keep the redo log parsing code in order to allow crash-upgrade
from older MariaDB versions (MDEV-14848).

Now, it further turns out that the InnoDB redo log record format is
suboptimal for logging multiple changes to a single page. This simple
change to the redo logging of undo log significantly affects the
INSERT and UPDATE performance.

Essentially, we wrote
	(space_id,page_number,MLOG_2BYTES,2 bytes)
	(space_id,page_number,MLOG_WRITE_STRING,N+4 bytes)
instead of the previously written
	(space_id,page_number,MLOG_UNDO_INSERT,N+2 bytes)

The added redo log volume caused a single-threaded INSERT
(without innodb_adaptive_hash_index) of
1,000,000 rows to consume 11 seconds instead of 9 seconds,
and a subsequent UPDATE of 30,000,000 rows to consume 64 seconds
instead of 58 seconds. If we omitted all redo logging for the
undo log, the INSERT would consume only 4 seconds.
parent 83bd4dd1
...@@ -100,7 +100,7 @@ enum mlog_id_t { ...@@ -100,7 +100,7 @@ enum mlog_id_t {
/** Create an index page */ /** Create an index page */
MLOG_PAGE_CREATE = 19, MLOG_PAGE_CREATE = 19,
/** insert an undo log record (used in MariaDB 10.2) */ /** insert an undo log record */
MLOG_UNDO_INSERT = 20, MLOG_UNDO_INSERT = 20,
/** erase an undo log page end (used in MariaDB 10.2) */ /** erase an undo log page end (used in MariaDB 10.2) */
......
...@@ -244,7 +244,7 @@ trx_undo_prev_version_build( ...@@ -244,7 +244,7 @@ trx_undo_prev_version_build(
into this function by purge thread or not. into this function by purge thread or not.
And if we read "after image" of undo log */ And if we read "after image" of undo log */
/** Parse MLOG_UNDO_INSERT for crash-upgrade from MariaDB 10.2. /** Parse MLOG_UNDO_INSERT.
@param[in] ptr log record @param[in] ptr log record
@param[in] end_ptr end of log record buffer @param[in] end_ptr end of log record buffer
@param[in,out] page page or NULL @param[in,out] page page or NULL
......
...@@ -70,12 +70,37 @@ trx_undof_page_add_undo_rec_log( ...@@ -70,12 +70,37 @@ trx_undof_page_add_undo_rec_log(
ut_ad(mach_read_from_2(undo_page ut_ad(mach_read_from_2(undo_page
+ TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_FREE) + TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_FREE)
== new_free); == new_free);
mlog_write_ulint(undo_page + TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_FREE, mtr->set_modified();
new_free, MLOG_2BYTES, mtr); switch (mtr->get_log_mode()) {
mlog_log_string(undo_page + old_free, new_free - old_free, mtr); case MTR_LOG_NONE:
case MTR_LOG_NO_REDO:
return;
case MTR_LOG_SHORT_INSERTS:
ut_ad(0);
/* fall through */
case MTR_LOG_ALL:
break;
}
const uint32_t
len = uint32_t(new_free - old_free - 4),
reserved = std::min<uint32_t>(11 + 13 + len,
mtr->get_log()->MAX_DATA_SIZE);
byte* log_ptr = mtr->get_log()->open(reserved);
const byte* log_end = log_ptr + reserved;
log_ptr = mlog_write_initial_log_record_fast(
undo_page, MLOG_UNDO_INSERT, log_ptr, mtr);
mach_write_to_2(log_ptr, len);
if (log_ptr + 2 + len <= log_end) {
memcpy(log_ptr + 2, undo_page + old_free + 2, len);
mlog_close(mtr, log_ptr + 2 + len);
} else {
mlog_close(mtr, log_ptr + 2);
mtr->get_log()->push(undo_page + old_free + 2, len);
}
} }
/** Parse MLOG_UNDO_INSERT for crash-upgrade from MariaDB 10.2. /** Parse MLOG_UNDO_INSERT.
@param[in] ptr log record @param[in] ptr log record
@param[in] end_ptr end of log record buffer @param[in] end_ptr end of log record buffer
@param[in,out] page page or NULL @param[in,out] page page or NULL
......
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