summaryrefslogtreecommitdiff
path: root/storage/innobase/trx/trx0rseg.cc
diff options
context:
space:
mode:
Diffstat (limited to 'storage/innobase/trx/trx0rseg.cc')
-rw-r--r--storage/innobase/trx/trx0rseg.cc110
1 files changed, 67 insertions, 43 deletions
diff --git a/storage/innobase/trx/trx0rseg.cc b/storage/innobase/trx/trx0rseg.cc
index 10092375ebd..a57a78b9408 100644
--- a/storage/innobase/trx/trx0rseg.cc
+++ b/storage/innobase/trx/trx0rseg.cc
@@ -43,6 +43,33 @@ static long long wsrep_seqno = -1;
/** The latest known WSREP XID UUID */
static unsigned char wsrep_uuid[16];
+/** Write the WSREP XID information into rollback segment header.
+@param[in,out] rseg_header rollback segment header
+@param[in] xid WSREP XID
+@param[in,out] mtr mini transaction */
+static void
+trx_rseg_write_wsrep_checkpoint(
+ trx_rsegf_t* rseg_header,
+ const XID* xid,
+ mtr_t* mtr)
+{
+ mlog_write_ulint(TRX_RSEG_WSREP_XID_FORMAT + rseg_header,
+ uint32_t(xid->formatID),
+ MLOG_4BYTES, mtr);
+
+ mlog_write_ulint(TRX_RSEG_WSREP_XID_GTRID_LEN + rseg_header,
+ uint32_t(xid->gtrid_length),
+ MLOG_4BYTES, mtr);
+
+ mlog_write_ulint(TRX_RSEG_WSREP_XID_BQUAL_LEN + rseg_header,
+ uint32_t(xid->bqual_length),
+ MLOG_4BYTES, mtr);
+
+ mlog_write_string(TRX_RSEG_WSREP_XID_DATA + rseg_header,
+ reinterpret_cast<const byte*>(xid->data),
+ XIDDATASIZE, mtr);
+}
+
/** Update the WSREP XID information in rollback segment header.
@param[in,out] rseg_header rollback segment header
@param[in] xid WSREP XID
@@ -60,29 +87,28 @@ trx_rseg_update_wsrep_checkpoint(
long long xid_seqno = wsrep_xid_seqno(xid);
const byte* xid_uuid = wsrep_xid_uuid(xid);
- if (!memcmp(xid_uuid, wsrep_uuid, sizeof wsrep_uuid)) {
+ if (xid_seqno != -1
+ && !memcmp(xid_uuid, wsrep_uuid, sizeof wsrep_uuid)) {
ut_ad(xid_seqno > wsrep_seqno);
} else {
memcpy(wsrep_uuid, xid_uuid, sizeof wsrep_uuid);
}
wsrep_seqno = xid_seqno;
#endif /* UNIV_DEBUG */
+ trx_rseg_write_wsrep_checkpoint(rseg_header, xid, mtr);
+}
- mlog_write_ulint(TRX_RSEG_WSREP_XID_FORMAT + rseg_header,
- uint32_t(xid->formatID),
- MLOG_4BYTES, mtr);
-
- mlog_write_ulint(TRX_RSEG_WSREP_XID_GTRID_LEN + rseg_header,
- uint32_t(xid->gtrid_length),
- MLOG_4BYTES, mtr);
-
- mlog_write_ulint(TRX_RSEG_WSREP_XID_BQUAL_LEN + rseg_header,
- uint32_t(xid->bqual_length),
- MLOG_4BYTES, mtr);
-
- mlog_write_string(TRX_RSEG_WSREP_XID_DATA + rseg_header,
- reinterpret_cast<const byte*>(xid->data),
- XIDDATASIZE, mtr);
+/** Clear the WSREP XID information from rollback segment header.
+@param[in,out] rseg_header Rollback segment header
+@param[in,out] mtr mini-transaction */
+static void
+trx_rseg_clear_wsrep_checkpoint(
+ trx_rsegf_t* rseg_header,
+ mtr_t* mtr)
+{
+ mlog_memset(rseg_header + TRX_RSEG_WSREP_XID_INFO,
+ TRX_RSEG_WSREP_XID_DATA + XIDDATASIZE
+ - TRX_RSEG_WSREP_XID_INFO, 0, mtr);
}
/** Update WSREP checkpoint XID in first rollback segment header
@@ -97,6 +123,13 @@ void trx_rseg_update_wsrep_checkpoint(const XID* xid)
mtr_t mtr;
mtr.start();
+ const byte* xid_uuid = wsrep_xid_uuid(xid);
+ /* We must make check against wsrep_uuid here, the
+ trx_rseg_update_wsrep_checkpoint() writes over wsrep_uuid with
+ xid contents in debug mode and the memcmp() will never give nonzero
+ result. */
+ const bool must_clear_rsegs = memcmp(wsrep_uuid, xid_uuid,
+ sizeof wsrep_uuid);
const trx_rseg_t* rseg = trx_sys.rseg_array[0];
trx_rsegf_t* rseg_header = trx_rsegf_get(rseg->space, rseg->page_no,
@@ -107,10 +140,7 @@ void trx_rseg_update_wsrep_checkpoint(const XID* xid)
trx_rseg_update_wsrep_checkpoint(rseg_header, xid, &mtr);
- const byte* xid_uuid = wsrep_xid_uuid(xid);
- if (memcmp(wsrep_uuid, xid_uuid, sizeof wsrep_uuid)) {
- memcpy(wsrep_uuid, xid_uuid, sizeof wsrep_uuid);
-
+ if (must_clear_rsegs) {
/* Because the UUID part of the WSREP XID differed
from current_xid_uuid, the WSREP group UUID was
changed, and we must reset the XID in all rollback
@@ -118,10 +148,11 @@ void trx_rseg_update_wsrep_checkpoint(const XID* xid)
for (ulint rseg_id = 1; rseg_id < TRX_SYS_N_RSEGS; ++rseg_id) {
if (const trx_rseg_t* rseg =
trx_sys.rseg_array[rseg_id]) {
- trx_rseg_update_wsrep_checkpoint(
+ trx_rseg_clear_wsrep_checkpoint(
trx_rsegf_get(rseg->space,
- rseg->page_no, &mtr),
- xid, &mtr);
+ rseg->page_no,
+ &mtr),
+ &mtr);
}
}
}
@@ -252,12 +283,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.
@@ -289,22 +318,17 @@ trx_rseg_header_create(
buf_block_dbg_add_level(block, SYNC_RSEG_HEADER_NEW);
- mlog_write_ulint(TRX_RSEG + TRX_RSEG_FORMAT + block->frame, 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(TRX_RSEG + TRX_RSEG_HISTORY_SIZE + block->frame, 0,
- MLOG_4BYTES, mtr);
- flst_init(TRX_RSEG + TRX_RSEG_HISTORY + block->frame, mtr);
- trx_rsegf_t* rsegf = TRX_RSEG + block->frame;
+ flst_init(block, TRX_RSEG_HISTORY + TRX_RSEG, mtr);
/* Reset the undo log slots */
- for (ulint i = 0; i < TRX_RSEG_N_SLOTS; i++) {
- /* This is generating a lot of redo log. MariaDB 10.4
- introduced MLOG_MEMSET to reduce the redo log volume. */
- 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
@@ -475,8 +499,8 @@ trx_rseg_mem_restore(trx_rseg_t* rseg, trx_id_t& max_trx_id, mtr_t* mtr)
rseg->curr_size = mach_read_from_4(rseg_header + TRX_RSEG_HISTORY_SIZE)
+ 1 + trx_undo_lists_init(rseg, max_trx_id, rseg_header);
- if (ulint len = flst_get_len(rseg_header + TRX_RSEG_HISTORY)) {
- trx_sys.history_add(int32(len));
+ if (auto len = flst_get_len(rseg_header + TRX_RSEG_HISTORY)) {
+ trx_sys.rseg_history_len += len;
fil_addr_t node_addr = trx_purge_get_log_from_hist(
flst_get_last(rseg_header + TRX_RSEG_HISTORY, mtr));