Commit 5567a8c9 authored by Marko Mäkelä's avatar Marko Mäkelä

MDEV-17138 Reduce redo log volume for undo tablespace initialization

Implement a 10.4 redo log format, which extends the 10.3 format
by introducing the MLOG_MEMSET record.

MLOG_MEMSET: A new redo log record type for filling an area with a byte.

mlog_memset(): Write the MLOG_MEMSET record.

mlog_parse_nbytes(): Handle MLOG_MEMSET as well.

trx_rseg_header_create(): Reduce the redo log volume by making use of
mlog_memset() and the zero-initialization that happens inside page
allocation.

fil_addr_null: Remove.

flst_init(): Create a variant that takes a zero-initialized
buf_block_t* as a parameter, and only writes the FIL_NULL using
mlog_memset().

flst_zero_addr(): A variant of flst_write_addr() that writes
a null address using mlog_memset() for the FIL_NULL.

The following fixes are replacing some use of MLOG_WRITE_STRING
with the more compact MLOG_MEMSET record, or eliminating
redundant redo log writes:

btr_store_big_rec_extern_fields(): Invoke mlog_memset() for
zero-initializing the tail of the ROW_FORMAT=COMPRESSED BLOB page.

trx_sysf_create(), trx_rseg_format_upgrade(): Invoke mlog_memset()
for zero-initializing the page trailer.

fsp_header_init(), trx_rseg_header_create():
Remove redundant zero-initializations.
parent 09af00cb
Branches unavailable
Tags unavailable
No related merge requests found
--innodb-log-buffer-size=2m
--source include/have_innodb.inc
# With 32k, truncation could happen on shutdown after the test,
# and the mtr.add_suppression() would not filter out the warning.
# With 64k, no truncation seems to happen.
# --source include/innodb_page_size.inc
--source include/innodb_page_size_small.inc
--source include/innodb_page_size.inc
--source include/have_undo_tablespaces.inc
SET @save_undo_logs = @@GLOBAL.innodb_undo_logs;
......
......@@ -1237,8 +1237,7 @@ btr_create(
buf_block_dbg_add_level(block, SYNC_IBUF_TREE_NODE_NEW);
flst_init(block->frame + PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST,
mtr);
flst_init(block, PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST, mtr);
} else {
block = fseg_create(space, 0,
PAGE_HEADER + PAGE_BTR_SEG_TOP, mtr);
......
......@@ -7499,16 +7499,20 @@ btr_store_big_rec_extern_fields(
+ FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION + 4,
rec_page_no,
MLOG_4BYTES, &mtr);
/* Zero out the unused part of the page. */
memset(page + page_zip_get_size(page_zip)
- c_stream.avail_out,
0, c_stream.avail_out);
mlog_log_string(page
+ FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION,
page_zip_get_size(page_zip)
- FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION,
- FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION
- c_stream.avail_out,
&mtr);
/* Zero out the unused part of the page. */
if (c_stream.avail_out) {
mlog_memset(block,
page_zip_get_size(page_zip)
- c_stream.avail_out,
c_stream.avail_out,
0, &mtr);
}
/* Copy the page to compressed storage,
because it will be flushed to disk
from there. */
......
......@@ -172,9 +172,6 @@ ulint fil_n_pending_tablespace_flushes = 0;
/** Number of files currently open */
ulint fil_n_file_opened = 0;
/** The null file address */
const fil_addr_t fil_addr_null = {FIL_NULL, 0};
/** The tablespace memory cache. This variable is NULL before the module is
initialized. */
fil_system_t fil_system;
......
......@@ -730,23 +730,23 @@ void fsp_header_init(fil_space_t* space, ulint size, mtr_t* mtr)
mlog_write_ulint(FSP_HEADER_OFFSET + FSP_SPACE_ID + block->frame,
space->id, MLOG_4BYTES, mtr);
mlog_write_ulint(FSP_HEADER_OFFSET + FSP_NOT_USED + block->frame, 0,
MLOG_4BYTES, mtr);
ut_ad(0 == mach_read_from_4(FSP_HEADER_OFFSET + FSP_NOT_USED
+ block->frame));
mlog_write_ulint(FSP_HEADER_OFFSET + FSP_SIZE + block->frame, size,
MLOG_4BYTES, mtr);
mlog_write_ulint(FSP_HEADER_OFFSET + FSP_FREE_LIMIT + block->frame, 0,
MLOG_4BYTES, mtr);
ut_ad(0 == mach_read_from_4(FSP_HEADER_OFFSET + FSP_FREE_LIMIT
+ block->frame));
mlog_write_ulint(FSP_HEADER_OFFSET + FSP_SPACE_FLAGS + block->frame,
space->flags & ~FSP_FLAGS_MEM_MASK,
MLOG_4BYTES, mtr);
mlog_write_ulint(FSP_HEADER_OFFSET + FSP_FRAG_N_USED + block->frame, 0,
MLOG_4BYTES, mtr);
flst_init(FSP_HEADER_OFFSET + FSP_FREE + block->frame, mtr);
flst_init(FSP_HEADER_OFFSET + FSP_FREE_FRAG + block->frame, mtr);
flst_init(FSP_HEADER_OFFSET + FSP_FULL_FRAG + block->frame, mtr);
flst_init(FSP_HEADER_OFFSET + FSP_SEG_INODES_FULL + block->frame, mtr);
flst_init(FSP_HEADER_OFFSET + FSP_SEG_INODES_FREE + block->frame, mtr);
ut_ad(0 == mach_read_from_4(FSP_HEADER_OFFSET + FSP_FRAG_N_USED
+ block->frame));
flst_init(block, FSP_HEADER_OFFSET + FSP_FREE, mtr);
flst_init(block, FSP_HEADER_OFFSET + FSP_FREE_FRAG, mtr);
flst_init(block, FSP_HEADER_OFFSET + FSP_FULL_FRAG, mtr);
flst_init(block, FSP_HEADER_OFFSET + FSP_SEG_INODES_FULL, mtr);
flst_init(block, FSP_HEADER_OFFSET + FSP_SEG_INODES_FREE, mtr);
mlog_write_ull(FSP_HEADER_OFFSET + FSP_SEG_ID + block->frame, 1, mtr);
......
......@@ -58,8 +58,8 @@ flst_add_to_empty(
flst_write_addr(base + FLST_LAST, node_addr, mtr);
/* Set prev and next fields of node to add */
flst_write_addr(node + FLST_PREV, fil_addr_null, mtr);
flst_write_addr(node + FLST_NEXT, fil_addr_null, mtr);
flst_zero_addr(node + FLST_PREV, mtr);
flst_zero_addr(node + FLST_NEXT, mtr);
/* Update len of base node */
mlog_write_ulint(base + FLST_LEN, 1, MLOG_4BYTES, mtr);
......
......@@ -366,19 +366,12 @@ typedef byte fil_faddr_t; /*!< 'type' definition in C: an address
#define FIL_ADDR_BYTE 4U /* then comes 2-byte byte offset within page*/
#define FIL_ADDR_SIZE 6U /* address size is 6 bytes */
#ifndef UNIV_INNOCHECKSUM
/** File space address */
struct fil_addr_t {
ulint page; /*!< page number within a space */
ulint boffset; /*!< byte offset within the page */
};
/** The null file address */
extern const fil_addr_t fil_addr_null;
#endif /* !UNIV_INNOCHECKSUM */
/** The byte offsets on a file page for various variables @{ */
#define FIL_PAGE_SPACE_OR_CHKSUM 0 /*!< in < MySQL-4.0.14 space id the
page belongs to (== 0) but in later
......
/*****************************************************************************
Copyright (c) 1995, 2014, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 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
......@@ -28,11 +29,8 @@ Created 11/28/1995 Heikki Tuuri
#ifndef UNIV_INNOCHECKSUM
#include "univ.i"
#include "fil0fil.h"
#include "mtr0mtr.h"
#include "fut0fut.h"
#include "mtr0log.h"
/* The C 'types' of base node and list node: these should be used to
write self-documenting code. Of course, the sizeof macro cannot be
......@@ -49,6 +47,47 @@ typedef byte flst_node_t;
#define FLST_NODE_SIZE (2 * FIL_ADDR_SIZE)
#ifndef UNIV_INNOCHECKSUM
/* We define the field offsets of a node for the list */
#define FLST_PREV 0 /* 6-byte address of the previous list element;
the page part of address is FIL_NULL, if no
previous element */
#define FLST_NEXT FIL_ADDR_SIZE /* 6-byte address of the next
list element; the page part of address
is FIL_NULL, if no next element */
/* We define the field offsets of a base node for the list */
#define FLST_LEN 0 /* 32-bit list length field */
#define FLST_FIRST 4 /* 6-byte address of the first element
of the list; undefined if empty list */
#define FLST_LAST (4 + FIL_ADDR_SIZE) /* 6-byte address of the
last element of the list; undefined
if empty list */
/** Initialize a zero-initialized list base node.
@param[in,out] block file page
@param[in] ofs byte offset of the list base node
@param[in,out] mtr mini-transaction */
inline void flst_init(buf_block_t* block, uint16_t ofs, mtr_t* mtr)
{
ut_ad(0 == mach_read_from_2(FLST_LEN + ofs + block->frame));
ut_ad(0 == mach_read_from_2(FLST_FIRST + FIL_ADDR_BYTE + ofs
+ block->frame));
ut_ad(0 == mach_read_from_2(FLST_LAST + FIL_ADDR_BYTE + ofs
+ block->frame));
compile_time_assert(FIL_NULL == 0xffU * 0x1010101U);
mlog_memset(block, FLST_FIRST + FIL_ADDR_PAGE + ofs, 4, 0xff, mtr);
mlog_memset(block, FLST_LAST + FIL_ADDR_PAGE + ofs, 4, 0xff, mtr);
}
/** Write a null file address.
@param[in,out] faddr file address to be zeroed otu
@param[in,out] mtr mini-transaction */
inline void flst_zero_addr(fil_faddr_t* faddr, mtr_t* mtr)
{
mlog_memset(faddr + FIL_ADDR_PAGE, 4, 0xff, mtr);
mlog_write_ulint(faddr + FIL_ADDR_BYTE, 0, MLOG_2BYTES, mtr);
}
/********************************************************************//**
Initializes a list base node. */
UNIV_INLINE
......
......@@ -23,26 +23,8 @@ File-based list utilities
Created 11/28/1995 Heikki Tuuri
***********************************************************************/
#include "fut0fut.h"
#include "mtr0log.h"
#include "buf0buf.h"
/* We define the field offsets of a node for the list */
#define FLST_PREV 0 /* 6-byte address of the previous list element;
the page part of address is FIL_NULL, if no
previous element */
#define FLST_NEXT FIL_ADDR_SIZE /* 6-byte address of the next
list element; the page part of address
is FIL_NULL, if no next element */
/* We define the field offsets of a base node for the list */
#define FLST_LEN 0 /* 32-bit list length field */
#define FLST_FIRST 4 /* 6-byte address of the first element
of the list; undefined if empty list */
#define FLST_LAST (4 + FIL_ADDR_SIZE) /* 6-byte address of the
last element of the list; undefined
if empty list */
/********************************************************************//**
Writes a file address. */
UNIV_INLINE
......@@ -101,8 +83,8 @@ flst_init(
| MTR_MEMO_PAGE_SX_FIX));
mlog_write_ulint(base + FLST_LEN, 0, MLOG_4BYTES, mtr);
flst_write_addr(base + FLST_FIRST, fil_addr_null, mtr);
flst_write_addr(base + FLST_LAST, fil_addr_null, mtr);
flst_zero_addr(base + FLST_FIRST, mtr);
flst_zero_addr(base + FLST_LAST, mtr);
}
/** Get the length of a list.
......
......@@ -481,6 +481,7 @@ MariaDB 10.2.18 and later will use the 10.3 format, but LOG_HEADER_SUBFORMAT
1 instead of 0. MariaDB 10.3 will use subformat 0 (5.7-style TRUNCATE) or 2
(MDEV-13564 backup-friendly TRUNCATE). */
#define LOG_HEADER_FORMAT_10_3 103
#define LOG_HEADER_FORMAT_10_4 104
/** The MariaDB 10.4.0 log format (only with innodb_encrypt_log=ON) */
#define LOG_HEADER_FORMAT_ENC_10_4 (104U | 1U << 31)
/** Encrypted MariaDB redo log */
......@@ -552,7 +553,7 @@ struct log_t{
struct files {
/** number of files */
ulint n_files;
/** format of the redo log: e.g., LOG_HEADER_FORMAT_10_3 */
/** format of the redo log: e.g., LOG_HEADER_FORMAT_10_4 */
uint32_t format;
/** redo log subformat: 0 with separately logged TRUNCATE,
2 with fully redo-logged TRUNCATE (1 in MariaDB 10.2) */
......
/*****************************************************************************
Copyright (c) 1995, 2014, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 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
......@@ -72,6 +73,23 @@ mlog_log_string(
byte* ptr, /*!< in: pointer written to */
ulint len, /*!< in: string length */
mtr_t* mtr); /*!< in: mini-transaction handle */
/** Initialize a string of bytes.
@param[in,out] b buffer page
@param[in] ofs byte offset from block->frame
@param[in] len length of the data to write
@param[in] val the data byte to write
@param[in,out] mtr mini-transaction */
void
mlog_memset(buf_block_t* b, ulint ofs, ulint len, byte val, mtr_t* mtr);
/** Initialize a string of bytes.
@param[in,out] byte byte address
@param[in] len length of the data to write
@param[in] val the data byte to write
@param[in,out] mtr mini-transaction */
void mlog_memset(byte* b, ulint len, byte val, mtr_t* mtr);
/********************************************************//**
Writes initial part of a log record consisting of one-byte item
type and four-byte space and page numbers. */
......@@ -189,7 +207,7 @@ mlog_parse_initial_log_record(
ulint* space, /*!< out: space id */
ulint* page_no);/*!< out: page number */
/********************************************************//**
Parses a log record written by mlog_write_ulint or mlog_write_ull.
Parses a log record written by mlog_write_ulint, mlog_write_ull, mlog_memset.
@return parsed record end, NULL if not a complete record */
byte*
mlog_parse_nbytes(
......
......@@ -228,8 +228,11 @@ enum mlog_id_t {
of a ROW_FORMAT=COMPRESSED table */
MLOG_ZIP_WRITE_TRX_ID = 62,
/** initialize a page with a string of identical bytes */
MLOG_MEMSET = 63,
/** biggest value (used in assertions) */
MLOG_BIGGEST_TYPE = MLOG_ZIP_WRITE_TRX_ID,
MLOG_BIGGEST_TYPE = MLOG_MEMSET,
/** log record for writing/updating crypt data of
a tablespace */
......
......@@ -665,7 +665,7 @@ void log_t::files::create(ulint n_files)
this->n_files= n_files;
format= srv_encrypt_log
? LOG_HEADER_FORMAT_ENC_10_4 : LOG_HEADER_FORMAT_10_3;
? LOG_HEADER_FORMAT_ENC_10_4 : LOG_HEADER_FORMAT_10_4;
subformat= 2;
file_size= srv_log_file_size;
lsn= LOG_START_LSN;
......@@ -698,7 +698,7 @@ log_file_header_flush(
ut_ad(log_write_mutex_own());
ut_ad(!recv_no_log_write);
ut_a(nth_file < log_sys.log.n_files);
ut_ad(log_sys.log.format == LOG_HEADER_FORMAT_10_3
ut_ad(log_sys.log.format == LOG_HEADER_FORMAT_10_4
|| log_sys.log.format == LOG_HEADER_FORMAT_ENC_10_4);
buf = log_sys.log.file_header_bufs[nth_file];
......
......@@ -1087,7 +1087,8 @@ recv_find_max_checkpoint(ulint* max_field)
case LOG_HEADER_FORMAT_10_2 | LOG_HEADER_FORMAT_ENCRYPTED:
case LOG_HEADER_FORMAT_10_3:
case LOG_HEADER_FORMAT_10_3 | LOG_HEADER_FORMAT_ENCRYPTED:
case LOG_HEADER_FORMAT_ENC_10_4:
case LOG_HEADER_FORMAT_10_4:
case LOG_HEADER_FORMAT_10_4 | LOG_HEADER_FORMAT_ENCRYPTED:
break;
default:
ib::error() << "Unsupported redo log format."
......@@ -1257,6 +1258,7 @@ recv_parse_or_apply_log_rec_body(
break;
#endif /* UNIV_LOG_LSN_DEBUG */
case MLOG_1BYTE: case MLOG_2BYTES: case MLOG_4BYTES: case MLOG_8BYTES:
case MLOG_MEMSET:
#ifdef UNIV_DEBUG
if (page && page_type == FIL_PAGE_TYPE_ALLOCATED
&& end_ptr >= ptr + 2) {
......@@ -3848,6 +3850,9 @@ static const char* get_mlog_string(mlog_id_t type)
case MLOG_TRUNCATE:
return("MLOG_TRUNCATE");
case MLOG_MEMSET:
return("MLOG_MEMSET");
case MLOG_FILE_WRITE_CRYPT_DATA:
return("MLOG_FILE_WRITE_CRYPT_DATA");
}
......
/*****************************************************************************
Copyright (c) 1995, 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
......@@ -121,7 +121,7 @@ mlog_parse_initial_log_record(
}
/********************************************************//**
Parses a log record written by mlog_write_ulint or mlog_write_ull.
Parses a log record written by mlog_write_ulint, mlog_write_ull, mlog_memset.
@return parsed record end, NULL if not a complete record or a corrupt record */
byte*
mlog_parse_nbytes(
......@@ -137,29 +137,43 @@ mlog_parse_nbytes(
ulint val;
ib_uint64_t dval;
ut_a(type <= MLOG_8BYTES);
ut_ad(type <= MLOG_8BYTES || type == MLOG_MEMSET);
ut_a(!page || !page_zip
|| !fil_page_index_page_check(page));
if (end_ptr < ptr + 2) {
return(NULL);
return NULL;
}
offset = mach_read_from_2(ptr);
ptr += 2;
if (offset >= srv_page_size) {
recv_sys->found_corrupt_log = TRUE;
return(NULL);
if (UNIV_UNLIKELY(offset >= srv_page_size)) {
goto corrupt;
}
if (type == MLOG_8BYTES) {
switch (type) {
case MLOG_MEMSET:
if (end_ptr < ptr + 3) {
return NULL;
}
val = mach_read_from_2(ptr);
ptr += 2;
if (UNIV_UNLIKELY(offset + val > srv_page_size)) {
goto corrupt;
}
if (page) {
memset(page + offset, *ptr, val);
if (page_zip) {
memset(static_cast<page_zip_des_t*>(page_zip)
->data + offset, *ptr, val);
}
}
return const_cast<byte*>(++ptr);
case MLOG_8BYTES:
dval = mach_u64_parse_compressed(&ptr, end_ptr);
if (ptr == NULL) {
return(NULL);
return NULL;
}
if (page) {
......@@ -171,14 +185,13 @@ mlog_parse_nbytes(
mach_write_to_8(page + offset, dval);
}
return(const_cast<byte*>(ptr));
return const_cast<byte*>(ptr);
default:
val = mach_parse_compressed(&ptr, end_ptr);
}
val = mach_parse_compressed(&ptr, end_ptr);
if (ptr == NULL) {
return(NULL);
return NULL;
}
switch (type) {
......@@ -221,11 +234,11 @@ mlog_parse_nbytes(
break;
default:
corrupt:
recv_sys->found_corrupt_log = TRUE;
recv_sys->found_corrupt_log = true;
ptr = NULL;
}
return(const_cast<byte*>(ptr));
return const_cast<byte*>(ptr);
}
/********************************************************//**
......@@ -409,6 +422,72 @@ mlog_parse_string(
return(ptr + len);
}
/** Initialize a string of bytes.
@param[in,out] b buffer page
@param[in] ofs byte offset from block->frame
@param[in] len length of the data to write
@param[in] val the data byte to write
@param[in,out] mtr mini-transaction */
void
mlog_memset(buf_block_t* b, ulint ofs, ulint len, byte val, mtr_t* mtr)
{
ut_ad(len);
ut_ad(ofs <= ulint(srv_page_size));
ut_ad(ofs + len <= ulint(srv_page_size));
memset(ofs + b->frame, val, len);
mtr->set_modified();
switch (mtr->get_log_mode()) {
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;
}
byte* l = mtr->get_log()->open(11 + 2 + 2 + 1);
l = mlog_write_initial_log_record_low(
MLOG_MEMSET, b->page.id.space(), b->page.id.page_no(), l, mtr);
mach_write_to_2(l, ofs);
mach_write_to_2(l + 2, len);
l[4] = val;
mlog_close(mtr, l + 5);
}
/** Initialize a string of bytes.
@param[in,out] byte byte address
@param[in] len length of the data to write
@param[in] val the data byte to write
@param[in,out] mtr mini-transaction */
void mlog_memset(byte* b, ulint len, byte val, mtr_t* mtr)
{
ut_ad(len);
ut_ad(page_offset(b) + len <= ulint(srv_page_size));
memset(b, val, len);
mtr->set_modified();
switch (mtr->get_log_mode()) {
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;
}
byte* l = mtr->get_log()->open(11 + 2 + 2 + 1);
l = mlog_write_initial_log_record_fast(b, MLOG_MEMSET, l, mtr);
mach_write_to_2(l, page_offset(b));
mach_write_to_2(l + 2, len);
l[4] = val;
mlog_close(mtr, l + 5);
}
/********************************************************//**
Opens a buffer for mlog, writes the initial log record and,
if needed, the field lengths of an index.
......
......@@ -1249,9 +1249,8 @@ srv_prepare_to_delete_redo_log_files(
{
ib::info info;
if (srv_log_file_size == 0
|| (log_sys.log.format != LOG_HEADER_FORMAT_10_3
&& log_sys.log.format
!= LOG_HEADER_FORMAT_ENC_10_4)) {
|| (log_sys.log.format & ~LOG_HEADER_FORMAT_ENCRYPTED)
!= LOG_HEADER_FORMAT_10_4) {
info << "Upgrading redo log: ";
} else if (n_files != srv_n_log_files
|| srv_log_file_size
......@@ -2062,7 +2061,7 @@ dberr_t srv_start(bool create_new_db)
&& log_sys.log.format
== (srv_encrypt_log
? LOG_HEADER_FORMAT_ENC_10_4
: LOG_HEADER_FORMAT_10_3)
: LOG_HEADER_FORMAT_10_4)
&& log_sys.log.subformat == 2) {
/* No need to add or remove encryption,
upgrade, downgrade, or resize. */
......
......@@ -253,12 +253,10 @@ void trx_rseg_format_upgrade(trx_rsegf_t* rseg_header, mtr_t* mtr)
mlog_write_ulint(rseg_format, 0, MLOG_4BYTES, mtr);
/* Clear also possible garbage at the end of the page. Old
InnoDB versions did not initialize unused parts of pages. */
byte* b = rseg_header + TRX_RSEG_MAX_TRX_ID + 8;
ulint len = srv_page_size
- (FIL_PAGE_DATA_END
+ TRX_RSEG + TRX_RSEG_MAX_TRX_ID + 8);
memset(b, 0, len);
mlog_log_string(b, len, mtr);
mlog_memset(TRX_RSEG_MAX_TRX_ID + 8 + rseg_header,
srv_page_size
- (FIL_PAGE_DATA_END
+ TRX_RSEG + TRX_RSEG_MAX_TRX_ID + 8), 0, mtr);
}
/** Create a rollback segment header.
......@@ -274,8 +272,6 @@ trx_rseg_header_create(
buf_block_t* sys_header,
mtr_t* mtr)
{
ulint page_no;
trx_rsegf_t* rsegf;
buf_block_t* block;
ut_ad(mtr_memo_contains(mtr, &space->latch, MTR_MEMO_X_LOCK));
......@@ -292,25 +288,17 @@ trx_rseg_header_create(
buf_block_dbg_add_level(block, SYNC_RSEG_HEADER_NEW);
page_no = block->page.id.page_no();
/* Get the rollback segment file page */
rsegf = trx_rsegf_get_new(space->id, page_no, mtr);
mlog_write_ulint(rsegf + TRX_RSEG_FORMAT, 0, MLOG_4BYTES, mtr);
ut_ad(0 == mach_read_from_4(TRX_RSEG_FORMAT + TRX_RSEG
+ block->frame));
ut_ad(0 == mach_read_from_4(TRX_RSEG_HISTORY_SIZE + TRX_RSEG
+ block->frame));
/* Initialize the history list */
mlog_write_ulint(rsegf + TRX_RSEG_HISTORY_SIZE, 0, MLOG_4BYTES, mtr);
flst_init(rsegf + TRX_RSEG_HISTORY, mtr);
flst_init(block, TRX_RSEG_HISTORY + TRX_RSEG, mtr);
/* Reset the undo log slots */
for (ulint i = 0; i < TRX_RSEG_N_SLOTS; i++) {
/* FIXME: This is generating a lot of redo log.
Why not just let it remain zero-initialized,
and adjust trx_rsegf_undo_find_free() and friends? */
trx_rsegf_set_nth_undo(rsegf, i, FIL_NULL, mtr);
}
mlog_memset(block, TRX_RSEG_UNDO_SLOTS + TRX_RSEG,
TRX_RSEG_N_SLOTS * 4, 0xff, mtr);
if (sys_header) {
/* Add the rollback segment info to the free slot in
......@@ -325,10 +313,10 @@ trx_rseg_header_create(
+ TRX_SYS_RSEG_PAGE_NO
+ rseg_id * TRX_SYS_RSEG_SLOT_SIZE
+ sys_header->frame,
page_no, MLOG_4BYTES, mtr);
block->page.id.page_no(), MLOG_4BYTES, mtr);
}
return(page_no);
return block->page.id.page_no();
}
/** Free a rollback segment in memory. */
......
......@@ -195,10 +195,9 @@ trx_sysf_create(
ut_a(ptr <= page + (srv_page_size - FIL_PAGE_DATA_END));
/* Initialize all of the page. This part used to be uninitialized. */
memset(ptr, 0, srv_page_size - FIL_PAGE_DATA_END + size_t(page - ptr));
mlog_log_string(TRX_SYS + page, srv_page_size - FIL_PAGE_DATA_END
- TRX_SYS, mtr);
mlog_memset(block, ptr - page,
srv_page_size - FIL_PAGE_DATA_END + size_t(page - ptr),
0, mtr);
/* Create the first rollback segment in the SYSTEM tablespace */
slot_no = trx_sys_rseg_find_free(block);
......
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