/* We must make check against wsrep_uuid here, the trx_rseg_update_wsrep_checkpoint()writesoverwsrep_uuidwithxid contentsindebugmodeandthememcmp()willnevergivenonzero
result. */ constbool must_clear_rsegs=
memcmp(wsrep_uuid, wsrep_xid_uuid(xid), sizeof wsrep_uuid);
if (UNIV_UNLIKELY(mach_read_from_4(TRX_RSEG + TRX_RSEG_FORMAT +
rseg_header->page.frame)))
trx_rseg_format_upgrade(rseg_header, mtr);
if (must_clear_rsegs) /* Because the UUID part of the WSREP XID differed from current_xid_uuid,theWSREPgroupUUIDwaschanged,andwemust
reset the XID in all rollback segment headers. */ for (ulint rseg_id= 1; rseg_id < TRX_SYS_N_RSEGS; ++rseg_id) if (buf_block_t* block= trx_sys.rseg_array[rseg_id].get(mtr, &err))
mtr->memset(block, TRX_RSEG + TRX_RSEG_WSREP_XID_INFO,
TRX_RSEG_WSREP_XID_DATA + XIDDATASIZE -
TRX_RSEG_WSREP_XID_INFO, 0); return err;
}
/** Read the WSREP XID from the TRX_SYS page (in case of upgrade). @param[in]pageTRX_SYSpage @param[out]xidWSREPXID(ifpresent)
@return whether the WSREP XID is present */ staticbool trx_rseg_init_wsrep_xid(const page_t* page, XID& xid)
{ if (memcmp(TRX_SYS + TRX_SYS_WSREP_XID_INFO + page,
field_ref_zero, TRX_SYS_WSREP_XID_LEN) == 0) { returnfalse;
}
/** Upgrade a rollback segment header page to MariaDB 10.3 format. @param[in,out]rseg_headerrollbacksegmentheaderpage
@param[in,out] mtr mini-transaction */ void trx_rseg_format_upgrade(buf_block_t *rseg_header, mtr_t *mtr)
{
mtr->memset(rseg_header, TRX_RSEG + TRX_RSEG_FORMAT, 4, 0); /* Clear also possible garbage at the end of the page. Old
InnoDB versions did not initialize unused parts of pages. */
mtr->memset(rseg_header, TRX_RSEG + TRX_RSEG_MAX_TRX_ID + 8,
srv_page_size
- (FIL_PAGE_DATA_END + TRX_RSEG + TRX_RSEG_MAX_TRX_ID + 8), 0);
}
/* Always prefer a position from rollback segment over
a legacy position from before version 10.3.5. */ int cmp= *trx_sys.recovered_binlog_filename &&
!trx_sys.recovered_binlog_is_legacy_pos
? strncmp(reinterpret_cast<constchar*>(binlog_name),
trx_sys.recovered_binlog_filename,
TRX_RSEG_BINLOG_NAME_LEN)
: 1;
if (cmp >= 0) {
uint64_t binlog_offset =
mach_read_from_8(TRX_RSEG + TRX_RSEG_BINLOG_OFFSET +
rseg_hdr->page.frame); if (cmp)
{
memcpy(trx_sys.recovered_binlog_filename, binlog_name,
TRX_RSEG_BINLOG_NAME_LEN);
trx_sys.recovered_binlog_offset= binlog_offset;
} elseif (binlog_offset > trx_sys.recovered_binlog_offset)
trx_sys.recovered_binlog_offset= binlog_offset;
trx_sys.recovered_binlog_is_legacy_pos= false;
}
} #ifdef WITH_WSREP
XID tmp_xid;
tmp_xid.null(); /* Update recovered wsrep xid only if we found wsrep xid from rsegheaderpageandreadxidseqnoislargerthancurrently
recovered xid seqno. */ if (trx_rseg_read_wsrep_checkpoint(rseg_hdr, tmp_xid) &&
wsrep_xid_seqno(&tmp_xid) > wsrep_xid_seqno(&trx_sys.recovered_wsrep_xid))
trx_sys.recovered_wsrep_xid.set(&tmp_xid); #endif
}
if (srv_operation == SRV_OPERATION_RESTORE) /* mariabackup --prepare only deals with theredologandthedatafiles,notwith
transactions or the data dictionary. */ return DB_SUCCESS;
/* Initialize the undo log lists according to the rseg header */
trx_id_t id= mach_read_from_8(block->page.frame + node_addr.boffset +
TRX_UNDO_TRX_ID); if (id > rseg->needs_purge)
rseg->needs_purge= id;
id= mach_read_from_8(block->page.frame + node_addr.boffset +
TRX_UNDO_TRX_NO); if (id > rseg->needs_purge)
rseg->needs_purge= id;
rseg->set_last_commit(node_addr.boffset, id);
if (rseg->last_page_no != FIL_NULL) /* There is no need to cover this operation by the purge
mutex because we are still bootstrapping. */
purge_sys.enqueue(*rseg);
}
/** Read binlog metadata from the TRX_SYS page, in case we are upgrading
from MySQL or a MariaDB version older than 10.3.5. */ staticvoid trx_rseg_init_binlog_info(const page_t* page)
{ if (mach_read_from_4(TRX_SYS + TRX_SYS_MYSQL_LOG_INFO
+ TRX_SYS_MYSQL_LOG_MAGIC_N_FLD
+ page)
== TRX_SYS_MYSQL_LOG_MAGIC_N) {
memcpy(trx_sys.recovered_binlog_filename,
TRX_SYS_MYSQL_LOG_INFO + TRX_SYS_MYSQL_LOG_NAME
+ TRX_SYS + page, TRX_SYS_MYSQL_LOG_NAME_LEN);
trx_sys.recovered_binlog_offset = mach_read_from_8(
TRX_SYS_MYSQL_LOG_INFO + TRX_SYS_MYSQL_LOG_OFFSET
+ TRX_SYS + page);
trx_sys.recovered_binlog_is_legacy_pos= true;
}
}
/** Initialize or recover the rollback segments at startup. */
dberr_t trx_rseg_array_init()
{
trx_id_t max_trx_id = 0;
*trx_sys.recovered_binlog_filename = '\0';
trx_sys.recovered_binlog_offset = 0;
trx_sys.recovered_binlog_is_legacy_pos= false; #ifdef WITH_WSREP
trx_sys.recovered_wsrep_xid.null();
XID wsrep_sys_xid;
wsrep_sys_xid.null(); bool wsrep_xid_in_rseg_found = false; #endif
mtr_t mtr{nullptr};
dberr_t err = DB_SUCCESS; /* mariabackup --prepare only deals with the redo log and the data files,notwithtransactionsorthedatadictionary,that'swhy trx_lists_init_at_db_start()doesnotinvokepurge_sys.create()and purgequeuemutexstaysuninitialized,andtrx_rseg_mem_restore()quits
before initializing undo log lists. */ if (srv_operation != SRV_OPERATION_RESTORE) /* Acquiring purge queue mutex here should be fine from the deadlockpreventionpointofview,becauseexecutingthat functionisaprerequisiteforstartingthepurgesubsystemor
any transactions. */
purge_sys.queue_lock(); for (ulint rseg_id = 0; rseg_id < TRX_SYS_N_RSEGS; rseg_id++) {
mtr.start(); if (const buf_block_t* sys = trx_sysf_get(&mtr, true)) { if (rseg_id == 0) { /* In case this is an upgrade from beforeMariaDB10.3.5,fetchthebase
information from the TRX_SYS page. */
max_trx_id = mach_read_from_8(
TRX_SYS + TRX_SYS_TRX_ID_STORE
+ sys->page.frame);
trx_rseg_init_binlog_info(sys->page.frame); #ifdef WITH_WSREP if (trx_rseg_init_wsrep_xid(
sys->page.frame, trx_sys.recovered_wsrep_xid)) {
wsrep_sys_xid.set(
&trx_sys.recovered_wsrep_xid);
} #endif
}
mtr.commit();
} if (srv_operation != SRV_OPERATION_RESTORE)
purge_sys.queue_unlock(); if (err != DB_SUCCESS) { for (auto& rseg : trx_sys.rseg_array) { while (auto u = UT_LIST_GET_FIRST(rseg.undo_list)) {
UT_LIST_REMOVE(rseg.undo_list, u);
ut_free(u);
}
} return err;
}
#ifdef WITH_WSREP if (srv_operation == SRV_OPERATION_NORMAL && !wsrep_sys_xid.is_null()) { /* Upgrade from a version prior to 10.3.5, whereWSREPXIDwasstoredinTRX_SYSpage. IfnorollbacksegmenthasaWSREPXIDset, wemustcopytheXIDfoundinTRX_SYSpage
to rollback segments. */
mtr.start();
if (!wsrep_xid_in_rseg_found) {
trx_rseg_update_wsrep_checkpoint(&wsrep_sys_xid, &mtr);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.