mirror of
https://github.com/MariaDB/server.git
synced 2026-05-15 03:17:20 +02:00
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.
This commit is contained in:
parent
09af00cbde
commit
5567a8c936
19 changed files with 222 additions and 121 deletions
|
|
@ -1 +0,0 @@
|
|||
--innodb-log-buffer-size=2m
|
||||
|
|
@ -1,9 +1,5 @@
|
|||
--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);
|
||||
ut_ad(0 == mach_read_from_4(FSP_HEADER_OFFSET + FSP_FRAG_N_USED
|
||||
+ block->frame));
|
||||
|
||||
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);
|
||||
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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/*****************************************************************************
|
||||
|
||||
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) */
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/*****************************************************************************
|
||||
|
||||
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 @@ parse_log:
|
|||
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");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/*****************************************************************************
|
||||
|
||||
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 @@ files_checked:
|
|||
&& 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);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue