Commit 8d1d38f9 authored by Marko Mäkelä's avatar Marko Mäkelä

Simplify access to the TRX_SYS page

trx_sysf_t: Remove.

trx_sysf_get(): Return the TRX_SYS page, not a pointer within it.

trx_sysf_rseg_get_space(), trx_sysf_rseg_get_page_no():
Remove a parameter, and merge the declaration and definition.
Take the TRX_SYS page as a parameter.

TRX_SYS_N_RSEGS: Correct the comment.

trx_sysf_rseg_find_free(), trx_sys_update_mysql_binlog_offset(),
trx_sys_update_wsrep_checkpoint(): Take the TRX_SYS page as a parameter.

trx_rseg_header_create(): Add a parameter for the TRX_SYS page.

trx_sysf_rseg_set_space(), trx_sysf_rseg_set_page_no(): Remove;
merge to the only caller, trx_rseg_header_create().
parent 54c715ac
...@@ -4849,19 +4849,19 @@ xtrabackup_prepare_func(char** argv) ...@@ -4849,19 +4849,19 @@ xtrabackup_prepare_func(char** argv)
if (ok) { if (ok) {
mtr_t mtr; mtr_t mtr;
mtr.start(); mtr.start();
const trx_sysf_t* sys_header = trx_sysf_get(&mtr); const buf_block_t* sys_header = trx_sysf_get(&mtr, false);
if (mach_read_from_4(TRX_SYS_MYSQL_LOG_INFO if (mach_read_from_4(TRX_SYS_MYSQL_LOG_INFO
+ TRX_SYS_MYSQL_LOG_MAGIC_N_FLD + TRX_SYS_MYSQL_LOG_MAGIC_N_FLD
+ sys_header) + TRX_SYS + sys_header->frame)
== TRX_SYS_MYSQL_LOG_MAGIC_N) { == TRX_SYS_MYSQL_LOG_MAGIC_N) {
ulonglong pos = mach_read_from_8( ulonglong pos = mach_read_from_8(
TRX_SYS_MYSQL_LOG_INFO TRX_SYS_MYSQL_LOG_INFO
+ TRX_SYS_MYSQL_LOG_OFFSET + TRX_SYS_MYSQL_LOG_OFFSET
+ sys_header); + TRX_SYS + sys_header->frame);
const char* name = reinterpret_cast<const char*>( const char* name = reinterpret_cast<const char*>(
TRX_SYS_MYSQL_LOG_INFO + TRX_SYS_MYSQL_LOG_NAME TRX_SYS_MYSQL_LOG_INFO + TRX_SYS_MYSQL_LOG_NAME
+ sys_header); + TRX_SYS + sys_header->frame);
msg("Last binlog file %s, position %llu\n", name, pos); msg("Last binlog file %s, position %llu\n", name, pos);
/* output to xtrabackup_binlog_pos_innodb and /* output to xtrabackup_binlog_pos_innodb and
......
...@@ -19718,8 +19718,9 @@ innobase_wsrep_set_checkpoint( ...@@ -19718,8 +19718,9 @@ innobase_wsrep_set_checkpoint(
if (wsrep_is_wsrep_xid(xid)) { if (wsrep_is_wsrep_xid(xid)) {
mtr_t mtr; mtr_t mtr;
mtr_start(&mtr); mtr_start(&mtr);
trx_sysf_t* sys_header = trx_sysf_get(&mtr); if (buf_block_t* sys_header = trx_sysf_get(&mtr)) {
trx_sys_update_wsrep_checkpoint(xid, sys_header, &mtr); trx_sys_update_wsrep_checkpoint(xid, sys_header, &mtr);
}
mtr_commit(&mtr); mtr_commit(&mtr);
innobase_flush_logs(hton, false); innobase_flush_logs(hton, false);
return 0; return 0;
......
/***************************************************************************** /*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 1996, 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 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 the terms of the GNU General Public License as published by the Free Software
...@@ -91,14 +91,16 @@ This function is called only when a new rollback segment is created in ...@@ -91,14 +91,16 @@ This function is called only when a new rollback segment is created in
the database. the database.
@param[in] space space id @param[in] space space id
@param[in] max_size max size in pages @param[in] max_size max size in pages
@param[in] rseg_slot_no rseg id == slot number in trx sys @param[in] rseg_id rollback segment identifier
@param[in,out] sys_header the TRX_SYS page (NULL for temporary rseg)
@param[in,out] mtr mini-transaction @param[in,out] mtr mini-transaction
@return page number of the created segment, FIL_NULL if fail */ @return page number of the created segment, FIL_NULL if fail */
ulint ulint
trx_rseg_header_create( trx_rseg_header_create(
ulint space, ulint space,
ulint max_size, ulint max_size,
ulint rseg_slot_no, ulint rseg_id,
buf_block_t* sys_header,
mtr_t* mtr); mtr_t* mtr);
/** Initialize the rollback segments in memory at database startup. */ /** Initialize the rollback segments in memory at database startup. */
......
/***************************************************************************** /*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 1996, 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 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 the terms of the GNU General Public License as published by the Free Software
...@@ -50,10 +50,13 @@ typedef UT_LIST_BASE_NODE_T(trx_t) trx_ut_list_t; ...@@ -50,10 +50,13 @@ typedef UT_LIST_BASE_NODE_T(trx_t) trx_ut_list_t;
/** Checks if a page address is the trx sys header page. /** Checks if a page address is the trx sys header page.
@param[in] page_id page id @param[in] page_id page id
@return true if trx sys header page */ @return true if trx sys header page */
UNIV_INLINE inline
bool bool
trx_sys_hdr_page( trx_sys_hdr_page(const page_id_t& page_id)
const page_id_t& page_id); {
return(page_id.space() == TRX_SYS_SPACE
&& page_id.page_no() == TRX_SYS_PAGE_NO);
}
/** Initialize the transaction system main-memory data structures. */ /** Initialize the transaction system main-memory data structures. */
void trx_sys_init_at_db_start(); void trx_sys_init_at_db_start();
...@@ -63,79 +66,45 @@ Creates and initializes the transaction system at the database creation. */ ...@@ -63,79 +66,45 @@ Creates and initializes the transaction system at the database creation. */
void void
trx_sys_create_sys_pages(void); trx_sys_create_sys_pages(void);
/*==========================*/ /*==========================*/
/** @return an unallocated rollback segment slot in the TRX_SYS header /** Find an available rollback segment.
@param[in] sys_header
@return an unallocated rollback segment slot in the TRX_SYS header
@retval ULINT_UNDEFINED if not found */ @retval ULINT_UNDEFINED if not found */
ulint ulint
trx_sysf_rseg_find_free(mtr_t* mtr); trx_sys_rseg_find_free(const buf_block_t* sys_header);
/**********************************************************************//** /** Request the TRX_SYS page.
Gets a pointer to the transaction system file copy and x-locks its page. @param[in] rw whether to lock the page for writing
@return pointer to system file copy, page x-locked */ @return the TRX_SYS page
UNIV_INLINE @retval NULL if the page cannot be read */
trx_sysf_t* inline
trx_sysf_get( buf_block_t*
/*=========*/ trx_sysf_get(mtr_t* mtr, bool rw = true)
mtr_t* mtr); /*!< in: mtr */ {
/*****************************************************************//** buf_block_t* block = buf_page_get(
Gets the space of the nth rollback segment slot in the trx system page_id_t(TRX_SYS_SPACE, TRX_SYS_PAGE_NO),
file copy. univ_page_size, rw ? RW_X_LATCH : RW_S_LATCH, mtr);
@return space id */ if (block) {
UNIV_INLINE buf_block_dbg_add_level(block, SYNC_TRX_SYS_HEADER);
ulint }
trx_sysf_rseg_get_space( return block;
/*====================*/ }
trx_sysf_t* sys_header, /*!< in: trx sys file copy */
ulint i, /*!< in: slot index == rseg id */
mtr_t* mtr); /*!< in: mtr */
/*****************************************************************//**
Gets the page number of the nth rollback segment slot in the trx system
file copy.
@return page number, FIL_NULL if slot unused */
UNIV_INLINE
ulint
trx_sysf_rseg_get_page_no(
/*======================*/
trx_sysf_t* sys_header, /*!< in: trx sys file copy */
ulint i, /*!< in: slot index == rseg id */
mtr_t* mtr); /*!< in: mtr */
/*****************************************************************//**
Sets the space id of the nth rollback segment slot in the trx system
file copy. */
UNIV_INLINE
void
trx_sysf_rseg_set_space(
/*====================*/
trx_sysf_t* sys_header, /*!< in: trx sys file copy */
ulint i, /*!< in: slot index == rseg id */
ulint space, /*!< in: space id */
mtr_t* mtr); /*!< in: mtr */
/*****************************************************************//**
Sets the page number of the nth rollback segment slot in the trx system
file copy. */
UNIV_INLINE
void
trx_sysf_rseg_set_page_no(
/*======================*/
trx_sysf_t* sys_header, /*!< in: trx sys file copy */
ulint i, /*!< in: slot index == rseg id */
ulint page_no, /*!< in: page number, FIL_NULL if
the slot is reset to unused */
mtr_t* mtr); /*!< in: mtr */
#ifdef UNIV_DEBUG #ifdef UNIV_DEBUG
/* Flag to control TRX_RSEG_N_SLOTS behavior debugging. */ /* Flag to control TRX_RSEG_N_SLOTS behavior debugging. */
extern uint trx_rseg_n_slots_debug; extern uint trx_rseg_n_slots_debug;
#endif #endif
/*****************************************************************//** /** Write DB_TRX_ID.
Writes a trx id to an index page. In case that the id size changes in @param[out] db_trx_id the DB_TRX_ID field to be written to
some future version, this function should be used instead of @param[in] id transaction ID */
mach_write_... */
UNIV_INLINE UNIV_INLINE
void void
trx_write_trx_id( trx_write_trx_id(byte* db_trx_id, trx_id_t id)
/*=============*/ {
byte* ptr, /*!< in: pointer to memory where written */ compile_time_assert(DATA_TRX_ID_LEN == 6);
trx_id_t id); /*!< in: id */ ut_ad(id);
mach_write_to_6(db_trx_id, id);
}
/** Read a transaction identifier. /** Read a transaction identifier.
@return id */ @return id */
...@@ -143,9 +112,7 @@ inline ...@@ -143,9 +112,7 @@ inline
trx_id_t trx_id_t
trx_read_trx_id(const byte* ptr) trx_read_trx_id(const byte* ptr)
{ {
#if DATA_TRX_ID_LEN != 6 compile_time_assert(DATA_TRX_ID_LEN == 6);
# error "DATA_TRX_ID_LEN != 6"
#endif
return(mach_read_from_6(ptr)); return(mach_read_from_6(ptr));
} }
...@@ -171,23 +138,23 @@ trx_sys_update_mysql_binlog_offset( ...@@ -171,23 +138,23 @@ trx_sys_update_mysql_binlog_offset(
/*===============================*/ /*===============================*/
const char* file_name,/*!< in: MySQL log file name */ const char* file_name,/*!< in: MySQL log file name */
int64_t offset, /*!< in: position in that log file */ int64_t offset, /*!< in: position in that log file */
trx_sysf_t* sys_header, /*!< in: trx sys header */ buf_block_t* sys_header, /*!< in,out: trx sys header */
mtr_t* mtr); /*!< in: mtr */ mtr_t* mtr); /*!< in,out: mini-transaction */
/** Display the MySQL binlog offset info if it is present in the trx /** Display the MySQL binlog offset info if it is present in the trx
system header. */ system header. */
void void
trx_sys_print_mysql_binlog_offset(); trx_sys_print_mysql_binlog_offset();
#ifdef WITH_WSREP #ifdef WITH_WSREP
/** Update WSREP XID info in sys_header of TRX_SYS_PAGE_NO = 5. /** Update WSREP XID info in the TRX_SYS page.
@param[in] xid Transaction XID @param[in] xid Transaction XID
@param[in,out] sys_header sys_header @param[in,out] sys_header TRX_SYS page
@param[in] mtr minitransaction */ @param[in,out] mtr mini-transaction */
UNIV_INTERN UNIV_INTERN
void void
trx_sys_update_wsrep_checkpoint( trx_sys_update_wsrep_checkpoint(
const XID* xid, const XID* xid,
trx_sysf_t* sys_header, buf_block_t* sys_header,
mtr_t* mtr); mtr_t* mtr);
/** Read WSREP checkpoint XID from sys header. /** Read WSREP checkpoint XID from sys header.
...@@ -232,15 +199,50 @@ trx_sys_create_rsegs(); ...@@ -232,15 +199,50 @@ trx_sys_create_rsegs();
slots */ slots */
/*------------------------------------------------------------- @} */ /*------------------------------------------------------------- @} */
/* Max number of rollback segments: the number of segment specification slots /** The number of rollback segments; rollback segment id must fit in
in the transaction system array; rollback segment id must fit in one (signed) the 7 bits reserved for it in DB_ROLL_PTR. */
byte, therefore 128; each slot is currently 8 bytes in size. If you want
to raise the level to 256 then you will need to fix some assertions that
impose the 7 bit restriction. e.g., mach_write_to_3() */
#define TRX_SYS_N_RSEGS 128 #define TRX_SYS_N_RSEGS 128
/** Maximum number of undo tablespaces (not counting the system tablespace) */ /** Maximum number of undo tablespaces (not counting the system tablespace) */
#define TRX_SYS_MAX_UNDO_SPACES (TRX_SYS_N_RSEGS - 1) #define TRX_SYS_MAX_UNDO_SPACES (TRX_SYS_N_RSEGS - 1)
/* Rollback segment specification slot offsets */
/** the tablespace ID of an undo log header; starting with
MySQL/InnoDB 5.1.7, this is FIL_NULL if the slot is unused */
#define TRX_SYS_RSEG_SPACE 0
/** the page number of an undo log header, or FIL_NULL if unused */
#define TRX_SYS_RSEG_PAGE_NO 4
/** Size of a rollback segment specification slot */
#define TRX_SYS_RSEG_SLOT_SIZE 8
/** Read the tablespace ID of a rollback segment slot.
@param[in] sys_header TRX_SYS page
@param[in] rseg_id rollback segment identifier
@return undo tablespace id */
inline
uint32_t
trx_sysf_rseg_get_space(const buf_block_t* sys_header, ulint rseg_id)
{
ut_ad(rseg_id < TRX_SYS_N_RSEGS);
return mach_read_from_4(TRX_SYS + TRX_SYS_RSEGS + TRX_SYS_RSEG_SPACE
+ rseg_id * TRX_SYS_RSEG_SLOT_SIZE
+ sys_header->frame);
}
/** Read the page number of a rollback segment slot.
@param[in] sys_header TRX_SYS page
@param[in] rseg_id rollback segment identifier
@return undo page number */
inline
uint32_t
trx_sysf_rseg_get_page_no(const buf_block_t* sys_header, ulint rseg_id)
{
ut_ad(rseg_id < TRX_SYS_N_RSEGS);
return mach_read_from_4(TRX_SYS + TRX_SYS_RSEGS + TRX_SYS_RSEG_PAGE_NO
+ rseg_id * TRX_SYS_RSEG_SLOT_SIZE
+ sys_header->frame);
}
/** Maximum length of MySQL binlog file name, in bytes. */ /** Maximum length of MySQL binlog file name, in bytes. */
#define TRX_SYS_MYSQL_LOG_NAME_LEN 512 #define TRX_SYS_MYSQL_LOG_NAME_LEN 512
/** Contents of TRX_SYS_MYSQL_LOG_MAGIC_N_FLD */ /** Contents of TRX_SYS_MYSQL_LOG_MAGIC_N_FLD */
...@@ -1018,6 +1020,4 @@ struct trx_sys_t { ...@@ -1018,6 +1020,4 @@ struct trx_sys_t {
/** The transaction system */ /** The transaction system */
extern trx_sys_t trx_sys; extern trx_sys_t trx_sys;
#include "trx0sys.ic"
#endif #endif
/*****************************************************************************
Copyright (c) 1996, 2015, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2017, 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
Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
*****************************************************************************/
/**************************************************//**
@file include/trx0sys.ic
Transaction system
Created 3/26/1996 Heikki Tuuri
*******************************************************/
#include "trx0trx.h"
#include "data0type.h"
#include "srv0srv.h"
#include "mtr0log.h"
/* The typedef for rseg slot in the file copy */
typedef byte trx_sysf_rseg_t;
/* Rollback segment specification slot offsets */
/*-------------------------------------------------------------*/
#define TRX_SYS_RSEG_SPACE 0 /* space where the segment
header is placed; starting with
MySQL/InnoDB 5.1.7, this is
UNIV_UNDEFINED if the slot is unused */
#define TRX_SYS_RSEG_PAGE_NO 4 /* page number where the segment
header is placed; this is FIL_NULL
if the slot is unused */
/*-------------------------------------------------------------*/
/* Size of a rollback segment specification slot */
#define TRX_SYS_RSEG_SLOT_SIZE 8
/** Checks if a page address is the trx sys header page.
@param[in] page_id page id
@return true if trx sys header page */
UNIV_INLINE
bool
trx_sys_hdr_page(
const page_id_t& page_id)
{
return(page_id.space() == TRX_SYS_SPACE
&& page_id.page_no() == TRX_SYS_PAGE_NO);
}
/**********************************************************************//**
Gets a pointer to the transaction system header and x-latches its page.
@return pointer to system header, page x-latched. */
UNIV_INLINE
trx_sysf_t*
trx_sysf_get(
/*=========*/
mtr_t* mtr) /*!< in: mtr */
{
buf_block_t* block = NULL;
trx_sysf_t* header = NULL;
ut_ad(mtr);
block = buf_page_get(page_id_t(TRX_SYS_SPACE, TRX_SYS_PAGE_NO),
univ_page_size, RW_X_LATCH, mtr);
if (block) {
buf_block_dbg_add_level(block, SYNC_TRX_SYS_HEADER);
header = TRX_SYS + buf_block_get_frame(block);
}
return(header);
}
/*****************************************************************//**
Gets the space of the nth rollback segment slot in the trx system
file copy.
@return space id */
UNIV_INLINE
ulint
trx_sysf_rseg_get_space(
/*====================*/
trx_sysf_t* sys_header, /*!< in: trx sys header */
ulint i, /*!< in: slot index == rseg id */
mtr_t* mtr) /*!< in: mtr */
{
ut_ad(sys_header);
ut_ad(i < TRX_SYS_N_RSEGS);
return(mtr_read_ulint(sys_header + TRX_SYS_RSEGS
+ i * TRX_SYS_RSEG_SLOT_SIZE
+ TRX_SYS_RSEG_SPACE, MLOG_4BYTES, mtr));
}
/*****************************************************************//**
Gets the page number of the nth rollback segment slot in the trx system
header.
@return page number, FIL_NULL if slot unused */
UNIV_INLINE
ulint
trx_sysf_rseg_get_page_no(
/*======================*/
trx_sysf_t* sys_header, /*!< in: trx system header */
ulint i, /*!< in: slot index == rseg id */
mtr_t* mtr) /*!< in: mtr */
{
ut_ad(sys_header);
ut_ad(i < TRX_SYS_N_RSEGS);
return(mtr_read_ulint(sys_header + TRX_SYS_RSEGS
+ i * TRX_SYS_RSEG_SLOT_SIZE
+ TRX_SYS_RSEG_PAGE_NO, MLOG_4BYTES, mtr));
}
/*****************************************************************//**
Sets the space id of the nth rollback segment slot in the trx system
file copy. */
UNIV_INLINE
void
trx_sysf_rseg_set_space(
/*====================*/
trx_sysf_t* sys_header, /*!< in: trx sys file copy */
ulint i, /*!< in: slot index == rseg id */
ulint space, /*!< in: space id */
mtr_t* mtr) /*!< in: mtr */
{
ut_ad(sys_header);
ut_ad(i < TRX_SYS_N_RSEGS);
mlog_write_ulint(sys_header + TRX_SYS_RSEGS
+ i * TRX_SYS_RSEG_SLOT_SIZE
+ TRX_SYS_RSEG_SPACE,
space,
MLOG_4BYTES, mtr);
}
/*****************************************************************//**
Sets the page number of the nth rollback segment slot in the trx system
header. */
UNIV_INLINE
void
trx_sysf_rseg_set_page_no(
/*======================*/
trx_sysf_t* sys_header, /*!< in: trx sys header */
ulint i, /*!< in: slot index == rseg id */
ulint page_no, /*!< in: page number, FIL_NULL if the
slot is reset to unused */
mtr_t* mtr) /*!< in: mtr */
{
ut_ad(sys_header);
ut_ad(i < TRX_SYS_N_RSEGS);
mlog_write_ulint(sys_header + TRX_SYS_RSEGS
+ i * TRX_SYS_RSEG_SLOT_SIZE
+ TRX_SYS_RSEG_PAGE_NO,
page_no,
MLOG_4BYTES, mtr);
}
/*****************************************************************//**
Writes a trx id to an index page. In case that the id size changes in
some future version, this function should be used instead of
mach_write_... */
UNIV_INLINE
void
trx_write_trx_id(
/*=============*/
byte* ptr, /*!< in: pointer to memory where written */
trx_id_t id) /*!< in: id */
{
#if DATA_TRX_ID_LEN != 6
# error "DATA_TRX_ID_LEN != 6"
#endif
ut_ad(id > 0);
mach_write_to_6(ptr, id);
}
...@@ -144,8 +144,6 @@ struct trx_savept_t{ ...@@ -144,8 +144,6 @@ struct trx_savept_t{
/** File objects */ /** File objects */
/* @{ */ /* @{ */
/** Transaction system header */
typedef byte trx_sysf_t;
/** Rollback segment header */ /** Rollback segment header */
typedef byte trx_rsegf_t; typedef byte trx_rsegf_t;
/** Undo segment header */ /** Undo segment header */
......
...@@ -1058,7 +1058,6 @@ srv_undo_tablespaces_init(bool create_new_db) ...@@ -1058,7 +1058,6 @@ srv_undo_tablespaces_init(bool create_new_db)
/* Step-1: Initialize the tablespace header and rsegs header. */ /* Step-1: Initialize the tablespace header and rsegs header. */
mtr_t mtr; mtr_t mtr;
trx_sysf_t* sys_header;
mtr_start(&mtr); mtr_start(&mtr);
/* Turn off REDO logging. We are in server start mode and fixing /* Turn off REDO logging. We are in server start mode and fixing
...@@ -1067,7 +1066,11 @@ srv_undo_tablespaces_init(bool create_new_db) ...@@ -1067,7 +1066,11 @@ srv_undo_tablespaces_init(bool create_new_db)
as part of the current recovery process. We surely don't need as part of the current recovery process. We surely don't need
that as this is fix-up action parallel to REDO logging. */ that as this is fix-up action parallel to REDO logging. */
mtr_set_log_mode(&mtr, MTR_LOG_NO_REDO); mtr_set_log_mode(&mtr, MTR_LOG_NO_REDO);
sys_header = trx_sysf_get(&mtr); buf_block_t* sys_header = trx_sysf_get(&mtr);
if (!sys_header) {
mtr.commit();
return DB_CORRUPTION;
}
for (undo::undo_spaces_t::const_iterator it for (undo::undo_spaces_t::const_iterator it
= undo::Truncate::s_fix_up_spaces.begin(); = undo::Truncate::s_fix_up_spaces.begin();
...@@ -1082,13 +1085,11 @@ srv_undo_tablespaces_init(bool create_new_db) ...@@ -1082,13 +1085,11 @@ srv_undo_tablespaces_init(bool create_new_db)
mtr_x_lock(fil_space_get_latch(*it, NULL), &mtr); mtr_x_lock(fil_space_get_latch(*it, NULL), &mtr);
for (ulint i = 0; i < TRX_SYS_N_RSEGS; i++) { for (ulint i = 0; i < TRX_SYS_N_RSEGS; i++) {
if (trx_sysf_rseg_get_space(sys_header, i)
ulint space_id = trx_sysf_rseg_get_space( == *it) {
sys_header, i, &mtr);
if (space_id == *it) {
trx_rseg_header_create( trx_rseg_header_create(
*it, ULINT_MAX, i, &mtr); *it, ULINT_MAX, i,
sys_header, &mtr);
} }
} }
......
/***************************************************************************** /*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 1996, 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 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 the terms of the GNU General Public License as published by the Free Software
...@@ -39,25 +39,26 @@ This function is called only when a new rollback segment is created in ...@@ -39,25 +39,26 @@ This function is called only when a new rollback segment is created in
the database. the database.
@param[in] space space id @param[in] space space id
@param[in] max_size max size in pages @param[in] max_size max size in pages
@param[in] rseg_slot_no rseg id == slot number in trx sys @param[in] rseg_id rollback segment identifier
@param[in,out] sys_header the TRX_SYS page (NULL for temporary rseg)
@param[in,out] mtr mini-transaction @param[in,out] mtr mini-transaction
@return page number of the created segment, FIL_NULL if fail */ @return page number of the created segment, FIL_NULL if fail */
ulint ulint
trx_rseg_header_create( trx_rseg_header_create(
ulint space, ulint space,
ulint max_size, ulint max_size,
ulint rseg_slot_no, ulint rseg_id,
buf_block_t* sys_header,
mtr_t* mtr) mtr_t* mtr)
{ {
ulint page_no; ulint page_no;
trx_rsegf_t* rsegf; trx_rsegf_t* rsegf;
trx_sysf_t* sys_header;
ulint i;
buf_block_t* block; buf_block_t* block;
ut_ad(mtr); ut_ad(mtr);
ut_ad(mtr_memo_contains(mtr, fil_space_get_latch(space, NULL), ut_ad(mtr_memo_contains(mtr, fil_space_get_latch(space, NULL),
MTR_MEMO_X_LOCK)); MTR_MEMO_X_LOCK));
ut_ad(!sys_header == (space == SRV_TMP_SPACE_ID));
/* Allocate a new file segment for the rollback segment */ /* Allocate a new file segment for the rollback segment */
block = fseg_create(space, 0, TRX_RSEG + TRX_RSEG_FSEG_HEADER, mtr); block = fseg_create(space, 0, TRX_RSEG + TRX_RSEG_FSEG_HEADER, mtr);
...@@ -85,21 +86,25 @@ trx_rseg_header_create( ...@@ -85,21 +86,25 @@ trx_rseg_header_create(
flst_init(rsegf + TRX_RSEG_HISTORY, mtr); flst_init(rsegf + TRX_RSEG_HISTORY, mtr);
/* Reset the undo log slots */ /* Reset the undo log slots */
for (i = 0; i < TRX_RSEG_N_SLOTS; i++) { for (ulint i = 0; i < TRX_RSEG_N_SLOTS; i++) {
trx_rsegf_set_nth_undo(rsegf, i, FIL_NULL, mtr); trx_rsegf_set_nth_undo(rsegf, i, FIL_NULL, mtr);
} }
if (space != SRV_TMP_SPACE_ID) { if (sys_header) {
/* Add the rollback segment info to the free slot in /* Add the rollback segment info to the free slot in
the trx system header */ the trx system header */
sys_header = trx_sysf_get(mtr); mlog_write_ulint(TRX_SYS + TRX_SYS_RSEGS
+ TRX_SYS_RSEG_SPACE
trx_sysf_rseg_set_space(sys_header, rseg_slot_no, space, mtr); + rseg_id * TRX_SYS_RSEG_SLOT_SIZE
+ sys_header->frame,
trx_sysf_rseg_set_page_no( space, MLOG_4BYTES, mtr);
sys_header, rseg_slot_no, page_no, mtr); mlog_write_ulint(TRX_SYS + TRX_SYS_RSEGS
+ TRX_SYS_RSEG_PAGE_NO
+ rseg_id * TRX_SYS_RSEG_SLOT_SIZE
+ sys_header->frame,
page_no, MLOG_4BYTES, mtr);
} }
return(page_no); return(page_no);
...@@ -228,22 +233,23 @@ trx_rseg_array_init() ...@@ -228,22 +233,23 @@ trx_rseg_array_init()
{ {
mtr_t mtr; mtr_t mtr;
for (ulint i = 0; i < TRX_SYS_N_RSEGS; i++) { for (ulint rseg_id = 0; rseg_id < TRX_SYS_N_RSEGS; rseg_id++) {
mtr.start(); mtr.start();
trx_sysf_t* sys_header = trx_sysf_get(&mtr); if (const buf_block_t* sys = trx_sysf_get(&mtr, false)) {
ulint page_no = trx_sysf_rseg_get_page_no( const uint32_t page_no = trx_sysf_rseg_get_page_no(
sys_header, i, &mtr); sys, rseg_id);
if (page_no != FIL_NULL) { if (page_no != FIL_NULL) {
trx_rseg_t* rseg = trx_rseg_mem_create( trx_rseg_t* rseg = trx_rseg_mem_create(
i, rseg_id, trx_sysf_rseg_get_space(
trx_sysf_rseg_get_space(sys_header, i, &mtr), sys, rseg_id),
page_no); page_no);
ut_ad(rseg->is_persistent()); ut_ad(rseg->is_persistent());
ut_ad(!trx_sys.rseg_array[rseg->id]); ut_ad(rseg->id == rseg_id);
trx_sys.rseg_array[rseg->id] = rseg; ut_ad(!trx_sys.rseg_array[rseg_id]);
trx_sys.rseg_array[rseg_id] = rseg;
trx_rseg_mem_restore(rseg, &mtr); trx_rseg_mem_restore(rseg, &mtr);
} }
}
mtr.commit(); mtr.commit();
} }
...@@ -269,24 +275,23 @@ trx_rseg_create(ulint space_id) ...@@ -269,24 +275,23 @@ trx_rseg_create(ulint space_id)
mtr_x_lock_space(space_id, &mtr); mtr_x_lock_space(space_id, &mtr);
ut_ad(space->purpose == FIL_TYPE_TABLESPACE); ut_ad(space->purpose == FIL_TYPE_TABLESPACE);
ulint slot_no = trx_sysf_rseg_find_free(&mtr); if (buf_block_t* sys_header = trx_sysf_get(&mtr)) {
ulint page_no = slot_no == ULINT_UNDEFINED ulint rseg_id = trx_sys_rseg_find_free(sys_header);
ulint page_no = rseg_id == ULINT_UNDEFINED
? FIL_NULL ? FIL_NULL
: trx_rseg_header_create(space_id, ULINT_MAX, slot_no, &mtr); : trx_rseg_header_create(space_id, ULINT_MAX,
rseg_id, sys_header, &mtr);
if (page_no != FIL_NULL) { if (page_no != FIL_NULL) {
trx_sysf_t* sys_header = trx_sysf_get(&mtr); ut_ad(trx_sysf_rseg_get_space(sys_header, rseg_id)
== space_id);
ulint id = trx_sysf_rseg_get_space( rseg = trx_rseg_mem_create(rseg_id, space_id, page_no);
sys_header, slot_no, &mtr); ut_ad(rseg->id == rseg_id);
ut_a(id == space_id);
rseg = trx_rseg_mem_create(slot_no, space_id, page_no);
ut_ad(rseg->is_persistent()); ut_ad(rseg->is_persistent());
ut_ad(!trx_sys.rseg_array[rseg->id]); ut_ad(!trx_sys.rseg_array[rseg->id]);
trx_sys.rseg_array[rseg->id] = rseg; trx_sys.rseg_array[rseg->id] = rseg;
trx_rseg_mem_restore(rseg, &mtr); trx_rseg_mem_restore(rseg, &mtr);
} }
}
mtr.commit(); mtr.commit();
...@@ -309,7 +314,7 @@ trx_temp_rseg_create() ...@@ -309,7 +314,7 @@ trx_temp_rseg_create()
ut_ad(space->purpose == FIL_TYPE_TEMPORARY); ut_ad(space->purpose == FIL_TYPE_TEMPORARY);
ulint page_no = trx_rseg_header_create( ulint page_no = trx_rseg_header_create(
SRV_TMP_SPACE_ID, ULINT_MAX, i, &mtr); SRV_TMP_SPACE_ID, ULINT_MAX, i, NULL, &mtr);
trx_rseg_t* rseg = trx_rseg_mem_create( trx_rseg_t* rseg = trx_rseg_mem_create(
i, SRV_TMP_SPACE_ID, page_no); i, SRV_TMP_SPACE_ID, page_no);
ut_ad(!rseg->is_persistent()); ut_ad(!rseg->is_persistent());
...@@ -332,54 +337,39 @@ trx_rseg_get_n_undo_tablespaces( ...@@ -332,54 +337,39 @@ trx_rseg_get_n_undo_tablespaces(
ulint* space_ids) /*!< out: array of space ids of ulint* space_ids) /*!< out: array of space ids of
UNDO tablespaces */ UNDO tablespaces */
{ {
ulint i;
mtr_t mtr; mtr_t mtr;
trx_sysf_t* sys_header; mtr.start();
ulint n_undo_tablespaces = 0;
mtr_start(&mtr);
sys_header = trx_sysf_get(&mtr); buf_block_t* sys_header = trx_sysf_get(&mtr, false);
if (!sys_header) {
mtr.commit();
return 0;
}
for (i = 0; i < TRX_SYS_N_RSEGS; i++) { ulint* end = space_ids;
ulint page_no;
ulint space;
page_no = trx_sysf_rseg_get_page_no(sys_header, i, &mtr); for (ulint rseg_id = 0; rseg_id < TRX_SYS_N_RSEGS; rseg_id++) {
uint32_t page_no = trx_sysf_rseg_get_page_no(sys_header,
rseg_id);
if (page_no == FIL_NULL) { if (page_no == FIL_NULL) {
continue; continue;
} }
space = trx_sysf_rseg_get_space(sys_header, i, &mtr); if (ulint space = trx_sysf_rseg_get_space(sys_header,
rseg_id)) {
if (space != 0) { if (std::find(space_ids, end, space) == end) {
ulint j; *end++ = space;
ibool found = FALSE;
for (j = 0; j < n_undo_tablespaces; ++j) {
if (space_ids[j] == space) {
found = TRUE;
break;
} }
} }
if (!found) {
ut_a(n_undo_tablespaces <= i);
space_ids[n_undo_tablespaces++] = space;
} }
}
}
mtr_commit(&mtr);
ut_a(n_undo_tablespaces <= TRX_SYS_N_RSEGS); mtr.commit();
space_ids[n_undo_tablespaces] = ULINT_UNDEFINED; ut_a(end - space_ids <= TRX_SYS_N_RSEGS);
*end = ULINT_UNDEFINED;
if (n_undo_tablespaces > 0) { std::sort(space_ids, end);
std::sort(space_ids, space_ids + n_undo_tablespaces);
}
return(n_undo_tablespaces); return ulint(end - space_ids);
} }
/***************************************************************************** /*****************************************************************************
Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 1996, 2017, 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 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 the terms of the GNU General Public License as published by the Free Software
...@@ -101,7 +101,7 @@ void trx_sys_t::flush_max_trx_id() ...@@ -101,7 +101,7 @@ void trx_sys_t::flush_max_trx_id()
{ {
mtr_t mtr; mtr_t mtr;
mtr.start(); mtr.start();
mlog_write_ull(trx_sysf_get(&mtr) + TRX_SYS_TRX_ID_STORE, mlog_write_ull(TRX_SYS + TRX_SYS_TRX_ID_STORE + trx_sysf_get(&mtr)->frame,
trx_sys.get_max_trx_id(), &mtr); trx_sys.get_max_trx_id(), &mtr);
mtr.commit(); mtr.commit();
} }
...@@ -118,8 +118,8 @@ trx_sys_update_mysql_binlog_offset( ...@@ -118,8 +118,8 @@ trx_sys_update_mysql_binlog_offset(
/*===============================*/ /*===============================*/
const char* file_name,/*!< in: MySQL log file name */ const char* file_name,/*!< in: MySQL log file name */
int64_t offset, /*!< in: position in that log file */ int64_t offset, /*!< in: position in that log file */
trx_sysf_t* sys_header, /*!< in: trx sys header */ buf_block_t* sys_header, /*!< in,out: trx sys header */
mtr_t* mtr) /*!< in: mtr */ mtr_t* mtr) /*!< in,out: mini-transaction */
{ {
DBUG_PRINT("InnoDB",("trx_mysql_binlog_offset: %lld", (longlong) offset)); DBUG_PRINT("InnoDB",("trx_mysql_binlog_offset: %lld", (longlong) offset));
...@@ -132,27 +132,26 @@ trx_sys_update_mysql_binlog_offset( ...@@ -132,27 +132,26 @@ trx_sys_update_mysql_binlog_offset(
return; return;
} }
if (mach_read_from_4(TRX_SYS_MYSQL_LOG_MAGIC_N_FLD byte* p = TRX_SYS + TRX_SYS_MYSQL_LOG_MAGIC_N_FLD
+ TRX_SYS_MYSQL_LOG_INFO + sys_header) + TRX_SYS_MYSQL_LOG_INFO + sys_header->frame;
!= TRX_SYS_MYSQL_LOG_MAGIC_N) {
mlog_write_ulint(TRX_SYS_MYSQL_LOG_MAGIC_N_FLD if (mach_read_from_4(p) != TRX_SYS_MYSQL_LOG_MAGIC_N) {
+ TRX_SYS_MYSQL_LOG_INFO + sys_header, mlog_write_ulint(p,
TRX_SYS_MYSQL_LOG_MAGIC_N, TRX_SYS_MYSQL_LOG_MAGIC_N,
MLOG_4BYTES, mtr); MLOG_4BYTES, mtr);
} }
if (memcmp(file_name, TRX_SYS_MYSQL_LOG_NAME + TRX_SYS_MYSQL_LOG_INFO p = TRX_SYS + TRX_SYS_MYSQL_LOG_NAME + TRX_SYS_MYSQL_LOG_INFO
+ sys_header, len)) { + sys_header->frame;
mlog_write_string(TRX_SYS_MYSQL_LOG_NAME
+ TRX_SYS_MYSQL_LOG_INFO if (memcmp(file_name, p, len)) {
+ sys_header, mlog_write_string(p,
reinterpret_cast<const byte*>(file_name), reinterpret_cast<const byte*>(file_name),
len, mtr); len, mtr);
} }
mlog_write_ull(TRX_SYS_MYSQL_LOG_INFO + TRX_SYS_MYSQL_LOG_OFFSET mlog_write_ull(TRX_SYS_MYSQL_LOG_INFO + TRX_SYS_MYSQL_LOG_OFFSET
+ sys_header, offset, mtr); + TRX_SYS + sys_header->frame, offset, mtr);
} }
/** Display the MySQL binlog offset info if it is present in the trx /** Display the MySQL binlog offset info if it is present in the trx
...@@ -164,18 +163,20 @@ trx_sys_print_mysql_binlog_offset() ...@@ -164,18 +163,20 @@ trx_sys_print_mysql_binlog_offset()
mtr.start(); mtr.start();
const trx_sysf_t* sys_header = trx_sysf_get(&mtr); const buf_block_t* block = trx_sysf_get(&mtr, false);
if (mach_read_from_4(TRX_SYS_MYSQL_LOG_INFO if (block
+ TRX_SYS_MYSQL_LOG_MAGIC_N_FLD + sys_header) && mach_read_from_4(TRX_SYS + TRX_SYS_MYSQL_LOG_INFO
+ TRX_SYS_MYSQL_LOG_MAGIC_N_FLD
+ block->frame)
== TRX_SYS_MYSQL_LOG_MAGIC_N) { == TRX_SYS_MYSQL_LOG_MAGIC_N) {
ib::info() << "Last binlog file '" ib::info() << "Last binlog file '"
<< TRX_SYS_MYSQL_LOG_INFO + TRX_SYS_MYSQL_LOG_NAME << TRX_SYS_MYSQL_LOG_INFO + TRX_SYS_MYSQL_LOG_NAME
+ sys_header + TRX_SYS + block->frame
<< "', position " << "', position "
<< mach_read_from_8(TRX_SYS_MYSQL_LOG_INFO << mach_read_from_8(TRX_SYS_MYSQL_LOG_INFO
+ TRX_SYS_MYSQL_LOG_OFFSET + TRX_SYS_MYSQL_LOG_OFFSET
+ sys_header); + TRX_SYS + block->frame);
} }
mtr.commit(); mtr.commit();
...@@ -203,26 +204,26 @@ static inline void read_wsrep_xid_uuid(const XID* xid, unsigned char* buf) ...@@ -203,26 +204,26 @@ static inline void read_wsrep_xid_uuid(const XID* xid, unsigned char* buf)
#endif /* UNIV_DEBUG */ #endif /* UNIV_DEBUG */
/** Update WSREP XID info in sys_header of TRX_SYS_PAGE_NO = 5. /** Update WSREP XID info in the TRX_SYS page.
@param[in] xid Transaction XID @param[in] xid Transaction XID
@param[in,out] sys_header sys_header @param[in,out] sys_header TRX_SYS page
@param[in] mtr minitransaction */ @param[in,out] mtr mini-transaction */
UNIV_INTERN UNIV_INTERN
void void
trx_sys_update_wsrep_checkpoint( trx_sys_update_wsrep_checkpoint(
const XID* xid, const XID* xid,
trx_sysf_t* sys_header, buf_block_t* sys_header,
mtr_t* mtr) mtr_t* mtr)
{ {
ut_ad(xid->formatID == 1); ut_ad(xid->formatID == 1);
ut_ad(wsrep_is_wsrep_xid(xid)); ut_ad(wsrep_is_wsrep_xid(xid));
if (mach_read_from_4(sys_header + TRX_SYS_WSREP_XID_INFO byte* magic = TRX_SYS + TRX_SYS_WSREP_XID_INFO
+ TRX_SYS_WSREP_XID_MAGIC_N_FLD) + TRX_SYS_WSREP_XID_MAGIC_N_FLD
!= TRX_SYS_WSREP_XID_MAGIC_N) { + sys_header->frame;
mlog_write_ulint(sys_header + TRX_SYS_WSREP_XID_INFO
+ TRX_SYS_WSREP_XID_MAGIC_N_FLD, if (mach_read_from_4(magic) != TRX_SYS_WSREP_XID_MAGIC_N) {
TRX_SYS_WSREP_XID_MAGIC_N, mlog_write_ulint(magic, TRX_SYS_WSREP_XID_MAGIC_N,
MLOG_4BYTES, mtr); MLOG_4BYTES, mtr);
#ifdef UNIV_DEBUG #ifdef UNIV_DEBUG
} else { } else {
...@@ -242,21 +243,21 @@ trx_sys_update_wsrep_checkpoint( ...@@ -242,21 +243,21 @@ trx_sys_update_wsrep_checkpoint(
#endif /* UNIV_DEBUG */ #endif /* UNIV_DEBUG */
} }
mlog_write_ulint(sys_header + TRX_SYS_WSREP_XID_INFO mlog_write_ulint(TRX_SYS + TRX_SYS_WSREP_XID_INFO
+ TRX_SYS_WSREP_XID_FORMAT, + TRX_SYS_WSREP_XID_FORMAT + sys_header->frame,
(int)xid->formatID, uint32_t(xid->formatID),
MLOG_4BYTES, mtr); MLOG_4BYTES, mtr);
mlog_write_ulint(sys_header + TRX_SYS_WSREP_XID_INFO mlog_write_ulint(TRX_SYS + TRX_SYS_WSREP_XID_INFO
+ TRX_SYS_WSREP_XID_GTRID_LEN, + TRX_SYS_WSREP_XID_GTRID_LEN + sys_header->frame,
(int)xid->gtrid_length, uint32_t(xid->gtrid_length),
MLOG_4BYTES, mtr); MLOG_4BYTES, mtr);
mlog_write_ulint(sys_header + TRX_SYS_WSREP_XID_INFO mlog_write_ulint(TRX_SYS + TRX_SYS_WSREP_XID_INFO
+ TRX_SYS_WSREP_XID_BQUAL_LEN, + TRX_SYS_WSREP_XID_BQUAL_LEN + sys_header->frame,
(int)xid->bqual_length, uint32_t(xid->bqual_length),
MLOG_4BYTES, mtr); MLOG_4BYTES, mtr);
mlog_write_string(sys_header + TRX_SYS_WSREP_XID_INFO mlog_write_string(TRX_SYS + TRX_SYS_WSREP_XID_INFO
+ TRX_SYS_WSREP_XID_DATA, + TRX_SYS_WSREP_XID_DATA + sys_header->frame,
(const unsigned char*) xid->data, reinterpret_cast<const byte*>(xid->data),
XIDDATASIZE, mtr); XIDDATASIZE, mtr);
} }
...@@ -267,57 +268,57 @@ UNIV_INTERN ...@@ -267,57 +268,57 @@ UNIV_INTERN
bool bool
trx_sys_read_wsrep_checkpoint(XID* xid) trx_sys_read_wsrep_checkpoint(XID* xid)
{ {
trx_sysf_t* sys_header;
mtr_t mtr; mtr_t mtr;
ulint magic;
ut_ad(xid); ut_ad(xid);
mtr_start(&mtr); mtr.start();
sys_header = trx_sysf_get(&mtr); const buf_block_t* block = trx_sysf_get(&mtr, false);
if ((magic = mach_read_from_4(sys_header + TRX_SYS_WSREP_XID_INFO if (!block ||
+ TRX_SYS_WSREP_XID_MAGIC_N_FLD)) mach_read_from_4(TRX_SYS + TRX_SYS_WSREP_XID_INFO
+ TRX_SYS_WSREP_XID_MAGIC_N_FLD + block->frame)
!= TRX_SYS_WSREP_XID_MAGIC_N) { != TRX_SYS_WSREP_XID_MAGIC_N) {
memset(xid, 0, sizeof(*xid)); memset(xid, 0, sizeof(*xid));
long long seqno= -1; long long seqno= -1;
memcpy(xid->data + 24, &seqno, sizeof(long long)); memcpy(xid->data + 24, &seqno, sizeof(long long));
xid->formatID = -1; xid->formatID = -1;
mtr_commit(&mtr); mtr.commit();
return false; return false;
} }
xid->formatID = (int)mach_read_from_4( xid->formatID = (int)mach_read_from_4(
sys_header TRX_SYS + TRX_SYS_WSREP_XID_INFO + TRX_SYS_WSREP_XID_FORMAT
+ TRX_SYS_WSREP_XID_INFO + TRX_SYS_WSREP_XID_FORMAT); + block->frame);
xid->gtrid_length = (int)mach_read_from_4( xid->gtrid_length = (int)mach_read_from_4(
sys_header TRX_SYS + TRX_SYS_WSREP_XID_INFO + TRX_SYS_WSREP_XID_GTRID_LEN
+ TRX_SYS_WSREP_XID_INFO + TRX_SYS_WSREP_XID_GTRID_LEN); + block->frame);
xid->bqual_length = (int)mach_read_from_4( xid->bqual_length = (int)mach_read_from_4(
sys_header TRX_SYS + TRX_SYS_WSREP_XID_INFO + TRX_SYS_WSREP_XID_BQUAL_LEN
+ TRX_SYS_WSREP_XID_INFO + TRX_SYS_WSREP_XID_BQUAL_LEN); + block->frame);
ut_memcpy(xid->data, memcpy(xid->data,
sys_header + TRX_SYS_WSREP_XID_INFO + TRX_SYS_WSREP_XID_DATA, TRX_SYS + TRX_SYS_WSREP_XID_INFO + TRX_SYS_WSREP_XID_DATA
+ block->frame,
XIDDATASIZE); XIDDATASIZE);
mtr_commit(&mtr); mtr.commit();
return true; return true;
} }
#endif /* WITH_WSREP */ #endif /* WITH_WSREP */
/** @return an unallocated rollback segment slot in the TRX_SYS header /** Find an available rollback segment.
@param[in] sys_header
@return an unallocated rollback segment slot in the TRX_SYS header
@retval ULINT_UNDEFINED if not found */ @retval ULINT_UNDEFINED if not found */
ulint ulint
trx_sysf_rseg_find_free(mtr_t* mtr) trx_sys_rseg_find_free(const buf_block_t* sys_header)
{ {
trx_sysf_t* sys_header = trx_sysf_get(mtr); for (ulint rseg_id = 0; rseg_id < TRX_SYS_N_RSEGS; rseg_id++) {
if (trx_sysf_rseg_get_page_no(sys_header, rseg_id)
for (ulint i = 0; i < TRX_SYS_N_RSEGS; i++) {
if (trx_sysf_rseg_get_page_no(sys_header, i, mtr)
== FIL_NULL) { == FIL_NULL) {
return(i); return rseg_id;
} }
} }
...@@ -332,14 +333,15 @@ trx_sysf_get_n_rseg_slots() ...@@ -332,14 +333,15 @@ trx_sysf_get_n_rseg_slots()
mtr_t mtr; mtr_t mtr;
mtr.start(); mtr.start();
trx_sysf_t* sys_header = trx_sysf_get(&mtr);
srv_available_undo_logs = 0; srv_available_undo_logs = 0;
if (const buf_block_t* sys_header = trx_sysf_get(&mtr, false)) {
for (ulint i = 0; i < TRX_SYS_N_RSEGS; i++) { for (ulint rseg_id = 0; rseg_id < TRX_SYS_N_RSEGS; rseg_id++) {
srv_available_undo_logs srv_available_undo_logs
+= trx_sysf_rseg_get_page_no(sys_header, i, &mtr) += trx_sysf_rseg_get_page_no(sys_header,
rseg_id)
!= FIL_NULL; != FIL_NULL;
} }
}
mtr.commit(); mtr.commit();
} }
...@@ -353,7 +355,6 @@ trx_sysf_create( ...@@ -353,7 +355,6 @@ trx_sysf_create(
/*============*/ /*============*/
mtr_t* mtr) /*!< in: mtr */ mtr_t* mtr) /*!< in: mtr */
{ {
trx_sysf_t* sys_header;
ulint slot_no; ulint slot_no;
buf_block_t* block; buf_block_t* block;
page_t* page; page_t* page;
...@@ -387,15 +388,13 @@ trx_sysf_create( ...@@ -387,15 +388,13 @@ trx_sysf_create(
mlog_write_ulint(page + TRX_SYS_DOUBLEWRITE mlog_write_ulint(page + TRX_SYS_DOUBLEWRITE
+ TRX_SYS_DOUBLEWRITE_MAGIC, 0, MLOG_4BYTES, mtr); + TRX_SYS_DOUBLEWRITE_MAGIC, 0, MLOG_4BYTES, mtr);
sys_header = trx_sysf_get(mtr);
/* Start counting transaction ids from number 1 up */ /* Start counting transaction ids from number 1 up */
mach_write_to_8(sys_header + TRX_SYS_TRX_ID_STORE, 1); mach_write_to_8(TRX_SYS + TRX_SYS_TRX_ID_STORE + page, 1);
/* Reset the rollback segment slots. Old versions of InnoDB /* Reset the rollback segment slots. Old versions of InnoDB
(before MySQL 5.5) define TRX_SYS_N_RSEGS as 256 and expect (before MySQL 5.5) define TRX_SYS_N_RSEGS as 256 and expect
that the whole array is initialized. */ that the whole array is initialized. */
ptr = TRX_SYS_RSEGS + sys_header; ptr = TRX_SYS + TRX_SYS_RSEGS + page;
compile_time_assert(256 >= TRX_SYS_N_RSEGS); compile_time_assert(256 >= TRX_SYS_N_RSEGS);
memset(ptr, 0xff, 256 * TRX_SYS_RSEG_SLOT_SIZE); memset(ptr, 0xff, 256 * TRX_SYS_RSEG_SLOT_SIZE);
ptr += 256 * TRX_SYS_RSEG_SLOT_SIZE; ptr += 256 * TRX_SYS_RSEG_SLOT_SIZE;
...@@ -404,13 +403,13 @@ trx_sysf_create( ...@@ -404,13 +403,13 @@ trx_sysf_create(
/* Initialize all of the page. This part used to be uninitialized. */ /* Initialize all of the page. This part used to be uninitialized. */
memset(ptr, 0, UNIV_PAGE_SIZE - FIL_PAGE_DATA_END + page - ptr); memset(ptr, 0, UNIV_PAGE_SIZE - FIL_PAGE_DATA_END + page - ptr);
mlog_log_string(sys_header, UNIV_PAGE_SIZE - FIL_PAGE_DATA_END mlog_log_string(TRX_SYS + page, UNIV_PAGE_SIZE - FIL_PAGE_DATA_END
+ page - sys_header, mtr); - TRX_SYS, mtr);
/* Create the first rollback segment in the SYSTEM tablespace */ /* Create the first rollback segment in the SYSTEM tablespace */
slot_no = trx_sysf_rseg_find_free(mtr); slot_no = trx_sys_rseg_find_free(block);
page_no = trx_rseg_header_create(TRX_SYS_SPACE, page_no = trx_rseg_header_create(TRX_SYS_SPACE,
ULINT_MAX, slot_no, mtr); ULINT_MAX, slot_no, block, mtr);
ut_a(slot_no == TRX_SYS_SYSTEM_RSEG_ID); ut_a(slot_no == TRX_SYS_SYSTEM_RSEG_ID);
ut_a(page_no == FSP_FIRST_RSEG_PAGE_NO); ut_a(page_no == FSP_FIRST_RSEG_PAGE_NO);
...@@ -420,8 +419,6 @@ trx_sysf_create( ...@@ -420,8 +419,6 @@ trx_sysf_create(
void void
trx_sys_init_at_db_start() trx_sys_init_at_db_start()
{ {
trx_sysf_t* sys_header;
/* VERY important: after the database is started, max_trx_id value is /* VERY important: after the database is started, max_trx_id value is
divisible by TRX_SYS_TRX_ID_WRITE_MARGIN, and the 'if' in divisible by TRX_SYS_TRX_ID_WRITE_MARGIN, and the 'if' in
trx_sys.get_new_trx_id will evaluate to TRUE when the function trx_sys.get_new_trx_id will evaluate to TRUE when the function
...@@ -432,12 +429,16 @@ trx_sys_init_at_db_start() ...@@ -432,12 +429,16 @@ trx_sys_init_at_db_start()
mtr_t mtr; mtr_t mtr;
mtr.start(); mtr.start();
sys_header = trx_sysf_get(&mtr); buf_block_t* block = trx_sysf_get(&mtr);
trx_sys.init_max_trx_id(2 * TRX_SYS_TRX_ID_WRITE_MARGIN trx_id_t max_trx_id = block
+ ut_uint64_align_up(mach_read_from_8(sys_header ? 2 * TRX_SYS_TRX_ID_WRITE_MARGIN
+ TRX_SYS_TRX_ID_STORE), + ut_uint64_align_up(mach_read_from_8(TRX_SYS
TRX_SYS_TRX_ID_WRITE_MARGIN)); + TRX_SYS_TRX_ID_STORE
+ block->frame),
TRX_SYS_TRX_ID_WRITE_MARGIN)
: 0;
trx_sys.init_max_trx_id(max_trx_id);
mtr.commit(); mtr.commit();
......
...@@ -1333,11 +1333,11 @@ trx_write_serialisation_history( ...@@ -1333,11 +1333,11 @@ trx_write_serialisation_history(
MONITOR_INC(MONITOR_TRX_COMMIT_UNDO); MONITOR_INC(MONITOR_TRX_COMMIT_UNDO);
trx_sysf_t* sys_header = trx_sysf_get(mtr); buf_block_t* block = trx_sysf_get(mtr);
#ifdef WITH_WSREP #ifdef WITH_WSREP
/* Update latest MySQL wsrep XID in trx sys header. */ /* Update latest MySQL wsrep XID in trx sys header. */
if (wsrep_is_wsrep_xid(trx->xid)) { if (wsrep_is_wsrep_xid(trx->xid)) {
trx_sys_update_wsrep_checkpoint(trx->xid, sys_header, mtr); trx_sys_update_wsrep_checkpoint(trx->xid, block, mtr);
} }
#endif /* WITH_WSREP */ #endif /* WITH_WSREP */
...@@ -1351,8 +1351,7 @@ trx_write_serialisation_history( ...@@ -1351,8 +1351,7 @@ trx_write_serialisation_history(
trx_sys_update_mysql_binlog_offset( trx_sys_update_mysql_binlog_offset(
trx->mysql_log_file_name, trx->mysql_log_file_name,
trx->mysql_log_offset, trx->mysql_log_offset,
sys_header, block, mtr);
mtr);
trx->mysql_log_file_name = NULL; trx->mysql_log_file_name = NULL;
} }
......
...@@ -1745,6 +1745,7 @@ trx_undo_truncate_tablespace( ...@@ -1745,6 +1745,7 @@ trx_undo_truncate_tablespace(
mtr_start(&mtr); mtr_start(&mtr);
mtr_set_log_mode(&mtr, MTR_LOG_NO_REDO); mtr_set_log_mode(&mtr, MTR_LOG_NO_REDO);
mtr_x_lock(fil_space_get_latch(space_id, NULL), &mtr); mtr_x_lock(fil_space_get_latch(space_id, NULL), &mtr);
buf_block_t* sys_header = trx_sysf_get(&mtr);
for (ulint i = 0; i < undo_trunc->rsegs_size(); ++i) { for (ulint i = 0; i < undo_trunc->rsegs_size(); ++i) {
trx_rsegf_t* rseg_header; trx_rsegf_t* rseg_header;
...@@ -1752,7 +1753,7 @@ trx_undo_truncate_tablespace( ...@@ -1752,7 +1753,7 @@ trx_undo_truncate_tablespace(
trx_rseg_t* rseg = undo_trunc->get_ith_rseg(i); trx_rseg_t* rseg = undo_trunc->get_ith_rseg(i);
rseg->page_no = trx_rseg_header_create( rseg->page_no = trx_rseg_header_create(
space_id, ULINT_MAX, rseg->id, &mtr); space_id, ULINT_MAX, rseg->id, sys_header, &mtr);
rseg_header = trx_rsegf_get_new(space_id, rseg->page_no, &mtr); rseg_header = trx_rsegf_get_new(space_id, rseg->page_no, &mtr);
......
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