mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
MDEV-6247: Merge 10.0-galera to 10.1.
Merged lp:maria/maria-10.0-galera up to revision 3879. Added a new functions to handler API to forcefully abort_transaction, producing fake_trx_id, get_checkpoint and set_checkpoint for XA. These were added for future possiblity to add more storage engines that could use galera replication.
This commit is contained in:
159
sql/handler.cc
159
sql/handler.cc
@@ -50,6 +50,9 @@
|
||||
#include "../storage/maria/ha_maria.h"
|
||||
#endif
|
||||
|
||||
#include "wsrep_mysqld.h"
|
||||
#include "wsrep.h"
|
||||
|
||||
/*
|
||||
While we have legacy_db_type, we have this array to
|
||||
check for dups and to find handlerton from legacy_db_type.
|
||||
@@ -1165,10 +1168,25 @@ int ha_prepare(THD *thd)
|
||||
{
|
||||
if ((err= ht->prepare(ht, thd, all)))
|
||||
{
|
||||
my_error(ER_ERROR_DURING_COMMIT, MYF(0), err);
|
||||
ha_rollback_trans(thd, all);
|
||||
error=1;
|
||||
break;
|
||||
#ifdef WITH_WSREP
|
||||
if (ht == wsrep_hton)
|
||||
{
|
||||
error= 1;
|
||||
/* avoid sending error, if we need to replay */
|
||||
if (thd->wsrep_conflict_state!= MUST_REPLAY)
|
||||
{
|
||||
my_error(ER_LOCK_DEADLOCK, MYF(0), err);
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
/* not wsrep hton, bail to native mysql behavior */
|
||||
my_error(ER_ERROR_DURING_COMMIT, MYF(0), err);
|
||||
ha_rollback_trans(thd, all);
|
||||
error=1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -1366,8 +1384,9 @@ int ha_commit_trans(THD *thd, bool all)
|
||||
mdl_request.init(MDL_key::COMMIT, "", "", MDL_INTENTION_EXCLUSIVE,
|
||||
MDL_EXPLICIT);
|
||||
|
||||
if (thd->mdl_context.acquire_lock(&mdl_request,
|
||||
thd->variables.lock_wait_timeout))
|
||||
if (IF_WSREP(!WSREP(thd),1) &&
|
||||
thd->mdl_context.acquire_lock(&mdl_request,
|
||||
thd->variables.lock_wait_timeout))
|
||||
{
|
||||
ha_rollback_trans(thd, all);
|
||||
thd->wakeup_subsequent_commits(1);
|
||||
@@ -1414,8 +1433,28 @@ int ha_commit_trans(THD *thd, bool all)
|
||||
err= ht->prepare(ht, thd, all);
|
||||
status_var_increment(thd->status_var.ha_prepare_count);
|
||||
if (err)
|
||||
my_error(ER_ERROR_DURING_COMMIT, MYF(0), err);
|
||||
|
||||
{
|
||||
#ifdef WITH_WSREP
|
||||
if (ht == wsrep_hton)
|
||||
{
|
||||
switch (err) {
|
||||
case WSREP_TRX_SIZE_EXCEEDED:
|
||||
/* give user size exeeded error from wsrep_api.h */
|
||||
my_error(ER_ERROR_DURING_COMMIT, MYF(0), WSREP_SIZE_EXCEEDED);
|
||||
break;
|
||||
case WSREP_TRX_CERT_FAIL:
|
||||
case WSREP_TRX_ERROR:
|
||||
/* avoid sending error, if we need to replay */
|
||||
if (thd->wsrep_conflict_state!= MUST_REPLAY)
|
||||
{
|
||||
my_error(ER_LOCK_DEADLOCK, MYF(0), err);
|
||||
}
|
||||
}
|
||||
goto err;
|
||||
}
|
||||
#endif /* WITH_WSREP */
|
||||
my_error(ER_ERROR_DURING_COMMIT, MYF(0), err);
|
||||
}
|
||||
if (err)
|
||||
goto err;
|
||||
|
||||
@@ -1425,6 +1464,14 @@ int ha_commit_trans(THD *thd, bool all)
|
||||
DEBUG_SYNC(thd, "ha_commit_trans_after_prepare");
|
||||
DBUG_EXECUTE_IF("crash_commit_after_prepare", DBUG_SUICIDE(););
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
if (!error && WSREP_ON && wsrep_is_wsrep_xid(&thd->transaction.xid_state.xid))
|
||||
{
|
||||
// xid was rewritten by wsrep
|
||||
xid= wsrep_xid_seqno(&thd->transaction.xid_state.xid);
|
||||
}
|
||||
#endif // WITH_WSREP
|
||||
|
||||
if (!is_real_trans)
|
||||
{
|
||||
error= commit_one_phase_2(thd, all, trans, is_real_trans);
|
||||
@@ -1801,7 +1848,10 @@ static my_bool xarecover_handlerton(THD *unused, plugin_ref plugin,
|
||||
got, hton_name(hton)->str);
|
||||
for (int i=0; i < got; i ++)
|
||||
{
|
||||
my_xid x=info->list[i].get_my_xid();
|
||||
my_xid x= IF_WSREP(WSREP_ON && wsrep_is_wsrep_xid(&info->list[i]) ?
|
||||
wsrep_xid_seqno(&info->list[i]) :
|
||||
info->list[i].get_my_xid(),
|
||||
info->list[i].get_my_xid());
|
||||
if (!x) // not "mine" - that is generated by external TM
|
||||
{
|
||||
#ifndef DBUG_OFF
|
||||
@@ -3086,10 +3136,12 @@ int handler::update_auto_increment()
|
||||
variables->auto_increment_increment);
|
||||
auto_inc_intervals_count++;
|
||||
/* Row-based replication does not need to store intervals in binlog */
|
||||
if (mysql_bin_log.is_open() && !thd->is_current_stmt_binlog_format_row())
|
||||
thd->auto_inc_intervals_in_cur_stmt_for_binlog.append(auto_inc_interval_for_cur_row.minimum(),
|
||||
auto_inc_interval_for_cur_row.values(),
|
||||
variables->auto_increment_increment);
|
||||
if (IF_WSREP(((WSREP(thd) && wsrep_emulate_bin_log ) || mysql_bin_log.is_open()), mysql_bin_log.is_open())
|
||||
&& !thd->is_current_stmt_binlog_format_row())
|
||||
thd->auto_inc_intervals_in_cur_stmt_for_binlog.
|
||||
append(auto_inc_interval_for_cur_row.minimum(),
|
||||
auto_inc_interval_for_cur_row.values(),
|
||||
variables->auto_increment_increment);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -5707,7 +5759,10 @@ static bool check_table_binlog_row_based(THD *thd, TABLE *table)
|
||||
return (thd->is_current_stmt_binlog_format_row() &&
|
||||
table->s->cached_row_logging_check &&
|
||||
(thd->variables.option_bits & OPTION_BIN_LOG) &&
|
||||
mysql_bin_log.is_open());
|
||||
/* applier and replayer should not binlog */
|
||||
(IF_WSREP((WSREP_EMULATE_BINLOG(thd) &&
|
||||
(thd->wsrep_exec_mode != REPL_RECV)) ||
|
||||
mysql_bin_log.is_open(), mysql_bin_log.is_open())));
|
||||
}
|
||||
|
||||
|
||||
@@ -5807,6 +5862,12 @@ static int binlog_log_row(TABLE* table,
|
||||
bool error= 0;
|
||||
THD *const thd= table->in_use;
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
/* only InnoDB tables will be replicated through binlog emulation */
|
||||
if (WSREP_EMULATE_BINLOG(thd) &&
|
||||
table->file->partition_ht()->db_type != DB_TYPE_INNODB)
|
||||
return 0;
|
||||
#endif /* WITH_WSREP */
|
||||
if (check_table_binlog_row_based(thd, table))
|
||||
{
|
||||
MY_BITMAP cols;
|
||||
@@ -6136,6 +6197,76 @@ void handler::set_lock_type(enum thr_lock_type lock)
|
||||
table->reginfo.lock_type= lock;
|
||||
}
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
/**
|
||||
@details
|
||||
This function makes the storage engine to force the victim transaction
|
||||
to abort. Currently, only innodb has this functionality, but any SE
|
||||
implementing the wsrep API should provide this service to support
|
||||
multi-master operation.
|
||||
|
||||
@param bf_thd brute force THD asking for the abort
|
||||
@param victim_thd victim THD to be aborted
|
||||
|
||||
@return
|
||||
always 0
|
||||
*/
|
||||
|
||||
int ha_abort_transaction(THD *bf_thd, THD *victim_thd, my_bool signal)
|
||||
{
|
||||
DBUG_ENTER("ha_abort_transaction");
|
||||
if (!WSREP(bf_thd) &&
|
||||
!(wsrep_OSU_method_options == WSREP_OSU_RSU &&
|
||||
bf_thd->wsrep_exec_mode == TOTAL_ORDER)) {
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
THD_TRANS *trans= &victim_thd->transaction.all;
|
||||
Ha_trx_info *ha_info= trans->ha_list, *ha_info_next;
|
||||
|
||||
for (; ha_info; ha_info= ha_info_next)
|
||||
{
|
||||
handlerton *hton= ha_info->ht();
|
||||
if (!hton->abort_transaction)
|
||||
{
|
||||
WSREP_WARN("cannot abort transaction");
|
||||
}
|
||||
else
|
||||
hton->abort_transaction(hton, bf_thd, victim_thd, signal);
|
||||
ha_info_next= ha_info->next();
|
||||
ha_info->reset(); /* keep it conveniently zero-filled */
|
||||
}
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
void ha_fake_trx_id(THD *thd)
|
||||
{
|
||||
DBUG_ENTER("ha_fake_trx_id");
|
||||
if (!WSREP(thd))
|
||||
{
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
THD_TRANS *trans= &thd->transaction.all;
|
||||
Ha_trx_info *ha_info= trans->ha_list, *ha_info_next;
|
||||
|
||||
for (; ha_info; ha_info= ha_info_next)
|
||||
{
|
||||
handlerton *hton= ha_info->ht();
|
||||
if (!hton->fake_trx_id)
|
||||
{
|
||||
WSREP_WARN("cannot get fake InnoDB transaction ID");
|
||||
}
|
||||
else
|
||||
hton->fake_trx_id(hton, thd);
|
||||
ha_info_next= ha_info->next();
|
||||
ha_info->reset(); /* keep it conveniently zero-filled */
|
||||
}
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
|
||||
#ifdef TRANS_LOG_MGM_EXAMPLE_CODE
|
||||
/*
|
||||
Example of transaction log management functions based on assumption that logs
|
||||
|
Reference in New Issue
Block a user