1
0
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:
Jan Lindström
2014-08-06 15:39:15 +03:00
parent e974b56438
commit df4dd593f2
327 changed files with 28127 additions and 332 deletions

View File

@@ -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