YoushouldhavereceivedacopyoftheGNUGeneralPublicLicensealong withthisprogram;ifnot,writetotheFreeSoftwareFoundation,Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA. */
staticvoid wsrep_rollback_high_priority(THD *thd, THD *rollbacker)
{
WSREP_DEBUG("Rollbacker aborting SR applier thd (%llu %lu)",
thd->thread_id, thd->real_id); void* orig_thread_stack= thd->thread_stack;
thd->thread_stack= rollbacker->thread_stack;
DBUG_ASSERT(thd->wsrep_cs().mode() == Wsrep_client_state::m_high_priority); /* Must be streaming and must have been removed from the
server state streaming appliers map. */
DBUG_ASSERT(thd->wsrep_trx().is_streaming());
DBUG_ASSERT(!Wsrep_server_state::instance().find_streaming_applier(
thd->wsrep_trx().server_id(),
thd->wsrep_trx().id()));
DBUG_ASSERT(thd->wsrep_applier_service);
/* Fragment removal should happen before rollback to make thetransactionnon-observableinSRtableaftertherollback completes.Forcorrectnesstheorderdoesnotmatterhere,
but currently it is mandated by checks in some MTR tests. */
wsrep_remove_streaming_fragments(thd, "high priority");
thd->wsrep_applier_service->rollback(wsrep::ws_handle(),
wsrep::ws_meta());
thd->wsrep_applier_service->after_apply();
thd->thread_stack= orig_thread_stack;
WSREP_DEBUG("rollbacker aborted thd: (%llu %lu)",
thd->thread_id, thd->real_id); /* Will free THD */
Wsrep_server_state::instance().server_service()
.release_high_priority_service(thd->wsrep_applier_service);
}
staticvoid wsrep_rollback_local(THD *thd, THD *rollbacker)
{
WSREP_DEBUG("Rollbacker aborting local thd (%llu %lu)",
thd->thread_id, thd->real_id); void* orig_thread_stack= thd->thread_stack;
thd->thread_stack= rollbacker->thread_stack; if (thd->wsrep_trx().is_streaming())
{
wsrep_remove_streaming_fragments(thd, "local");
} /* Set thd->event_scheduler.data temporarily to NULL to avoid
callbacks to threadpool wait_begin() during rollback. */ auto saved_esd= thd->event_scheduler.data;
thd->event_scheduler.data= 0;
mysql_mutex_lock(&thd->LOCK_thd_data); /* prepare THD for rollback processing */
thd->reset_for_next_command();
thd->lex->sql_command= SQLCOM_ROLLBACK;
mysql_mutex_unlock(&thd->LOCK_thd_data); /* Perform a client rollback, restore globals and signal thevictimonlywhenalltheresourceshavebeen
released */
thd->wsrep_cs().client_service().bf_rollback();
wsrep_reset_threadvars(thd); /* Assign saved event_scheduler.data back before letting
client to continue. */
thd->event_scheduler.data= saved_esd;
thd->thread_stack= orig_thread_stack;
thd->wsrep_cs().sync_rollback_complete();
WSREP_DEBUG("rollbacker aborted thd: (%llu %lu)",
thd->thread_id, thd->real_id);
}
/* Rollback methods below may free thd pointer. Do not try
to access it after method returns. */ if (wsrep_thd_is_applying(thd))
{
wsrep_rollback_high_priority(thd, rollbacker);
} else
{
wsrep_rollback_local(thd, rollbacker);
}
wsrep_store_threadvars(rollbacker);
thd_proc_info(rollbacker, "wsrep aborter idle");
}
{ /* Adopt the lock, it is being held by the caller. */
Wsrep_mutex wsm{&victim_thd->LOCK_thd_data};
wsrep::unique_lock<wsrep::mutex> lock{wsm, std::adopt_lock};
if (wsrep_thd_is_toi(bf_thd))
{
ret= victim_thd->wsrep_cs().total_order_bf_abort(lock, bf_seqno);
} else
{
DBUG_ASSERT(WSREP(victim_thd) ? victim_thd->wsrep_trx().active() : 1);
ret= victim_thd->wsrep_cs().bf_abort(lock, bf_seqno);
} if (ret)
{ /* BF abort should be allowed only once by wsrep-lib.*/
DBUG_ASSERT(victim_thd->wsrep_aborter == 0);
victim_thd->wsrep_aborter= bf_thd->thread_id;
wsrep_bf_aborts_counter++;
}
lock.release(); /* No unlock at the end of the scope. */
}
/* Sanity check for wsrep-lib calls to return with LOCK_thd_data held. */
mysql_mutex_assert_owner(&victim_thd->LOCK_thd_data);
if (WSREP(victim_thd) && !victim_thd->wsrep_trx().active())
{
WSREP_DEBUG("wsrep_bf_abort, BF abort for non active transaction." " Victim state %s bf state %s",
wsrep::to_c_string(victim_thd->wsrep_trx().state()),
wsrep::to_c_string(bf_thd->wsrep_trx().state()));
switch (victim_thd->wsrep_trx().state()) { case wsrep::transaction::s_aborting: /* fall through */ case wsrep::transaction::s_aborted:
WSREP_DEBUG("victim is aborting or has aborted"); break; default: break;
} /* victim may not have started transaction yet in wsrep context, but it may haveacquiredMDLlocks(duetoDDLexecution),andthishascausedBFconflict. suchcasedoesnotrequireabortinginwsreporreplicationproviderstate.
*/ if (victim_thd->current_backup_stage != BACKUP_FINISHED &&
wsrep_check_mode(WSREP_MODE_BF_MARIABACKUP))
{
WSREP_DEBUG("killing connection for non wsrep session");
victim_thd->awake_no_mutex(KILL_CONNECTION);
} returnfalse;
}
int wsrep_create_threadvars()
{ int ret= 0; if (thread_handling == SCHEDULER_TYPES_COUNT)
{ /* Caller should have called wsrep_reset_threadvars() before this
method. */
DBUG_ASSERT(!my_thread_var);
set_mysys_var(0);
ret= my_thread_init();
} return ret;
}
void wsrep_delete_threadvars()
{ if (thread_handling == SCHEDULER_TYPES_COUNT)
{ /* The caller should have called wsrep_store_threadvars() before
this method. */
DBUG_ASSERT(my_thread_var); /* Reset psi state to avoid deallocating applier thread
psi_thread. */ #ifdef HAVE_PSI_INTERFACE
PSI_thread *psi_thread= PSI_CALL_get_thread(); if (PSI_server)
{
PSI_server->set_thread(0);
} #endif/* HAVE_PSI_INTERFACE */
my_thread_end();
PSI_CALL_set_thread(psi_thread);
set_mysys_var(0);
}
}
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.