summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSeppo Jaakola <seppo.jaakola@codership.com>2013-11-27 00:18:44 +0200
committerSeppo Jaakola <seppo.jaakola@codership.com>2013-11-27 00:18:44 +0200
commitb098b7a84c374ee7e5a133cbf16be643609c1543 (patch)
tree7ccafb77802062c13a0fa5f2a316cd3cfbaca872
parent6422d276fa8d1217aa68be1d90c712efa4d71409 (diff)
downloadmariadb-git-b098b7a84c374ee7e5a133cbf16be643609c1543.tar.gz
bzr merge -r3904..3928 lp:codership-mysql/5.5
This is now otherwise on level wsrep-25.9, but storage/innobase has not been fully merged wsrep-5.5 is not good source for that, so we probably have to cherry pick innodb changes from wsrep-5.6
-rw-r--r--cmake/wsrep.cmake2
-rw-r--r--sql/log.cc1
-rw-r--r--sql/mdl.h7
-rw-r--r--sql/mysqld.cc8
-rw-r--r--sql/sql_class.cc1
-rw-r--r--sql/sql_class.h4
-rw-r--r--sql/sql_parse.cc38
-rw-r--r--sql/sql_table.cc13
-rw-r--r--sql/sys_vars.cc10
-rw-r--r--sql/transaction.cc7
-rw-r--r--sql/wsrep_applier.h38
-rw-r--r--sql/wsrep_hton.cc2
-rw-r--r--sql/wsrep_mysqld.cc34
-rw-r--r--sql/wsrep_mysqld.h2
-rw-r--r--sql/wsrep_thd.cc19
-rw-r--r--sql/wsrep_thd.h1
-rw-r--r--storage/innobase/handler/ha_innodb.cc15
-rw-r--r--storage/innobase/include/trx0sys.h9
-rw-r--r--storage/innobase/trx/trx0trx.cc13
-rw-r--r--wsrep.moved/CMakeLists.txt (renamed from wsrep/CMakeLists.txt)0
-rw-r--r--wsrep.moved/Makefile.am (renamed from wsrep/Makefile.am)0
-rw-r--r--wsrep.moved/wsrep_api.h1110
-rw-r--r--wsrep.moved/wsrep_dummy.c383
-rw-r--r--wsrep.moved/wsrep_loader.c (renamed from wsrep/wsrep_loader.c)0
-rw-r--r--wsrep.moved/wsrep_uuid.c (renamed from wsrep/wsrep_uuid.c)0
-rw-r--r--wsrep/wsrep_api.h14
-rw-r--r--wsrep/wsrep_dummy.c56
27 files changed, 1705 insertions, 82 deletions
diff --git a/cmake/wsrep.cmake b/cmake/wsrep.cmake
index 6a4e9a21049..c75b5f0b99b 100644
--- a/cmake/wsrep.cmake
+++ b/cmake/wsrep.cmake
@@ -17,7 +17,7 @@
# so WSREP_VERSION is produced regardless
# Set the patch version
-SET(WSREP_PATCH_VERSION "7.6")
+SET(WSREP_PATCH_VERSION "9")
# Obtain patch revision number
SET(WSREP_PATCH_REVNO $ENV{WSREP_REV})
diff --git a/sql/log.cc b/sql/log.cc
index d5cafb7de0a..9462c28301d 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -6195,6 +6195,7 @@ int MYSQL_BIN_LOG::rotate(bool force_rotate, bool* check_purge)
#ifdef WITH_WSREP
if (WSREP_ON && wsrep_to_isolation)
{
+ *check_purge= false;
WSREP_DEBUG("avoiding binlog rotate due to TO isolation: %d",
wsrep_to_isolation);
DBUG_RETURN(0);
diff --git a/sql/mdl.h b/sql/mdl.h
index 498c9fc3ba3..8d22eff1eff 100644
--- a/sql/mdl.h
+++ b/sql/mdl.h
@@ -770,6 +770,13 @@ public:
m_tickets[MDL_EXPLICIT].is_empty());
}
+#ifdef WITH_WSREP
+ inline bool has_transactional_locks() const
+ {
+ return !m_tickets[MDL_TRANSACTION].is_empty();
+ }
+#endif /* WITH_WSREP */
+
MDL_savepoint mdl_savepoint()
{
return MDL_savepoint(m_tickets[MDL_STATEMENT].front(),
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 7b825574a7f..ecc29fe6303 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -8453,8 +8453,9 @@ SHOW_VAR status_vars[]= {
{"wsrep_cluster_state_uuid", (char*) &wsrep_cluster_state_uuid,SHOW_CHAR_PTR},
{"wsrep_cluster_conf_id", (char*) &wsrep_cluster_conf_id, SHOW_LONGLONG},
{"wsrep_cluster_status", (char*) &wsrep_cluster_status, SHOW_CHAR_PTR},
- {"wsrep_cluster_size", (char*) &wsrep_cluster_size, SHOW_LONG},
- {"wsrep_local_index", (char*) &wsrep_local_index, SHOW_LONG},
+ {"wsrep_cluster_size", (char*) &wsrep_cluster_size, SHOW_LONG_NOFLUSH},
+ {"wsrep_local_index", (char*) &wsrep_local_index, SHOW_LONG_NOFLUSH},
+ {"wsrep_local_bf_aborts", (char*) &wsrep_show_bf_aborts, SHOW_FUNC},
{"wsrep_provider_name", (char*) &wsrep_provider_name, SHOW_CHAR_PTR},
{"wsrep_provider_version", (char*) &wsrep_provider_version, SHOW_CHAR_PTR},
{"wsrep_provider_vendor", (char*) &wsrep_provider_vendor, SHOW_CHAR_PTR},
@@ -9798,6 +9799,9 @@ void refresh_status(THD *thd)
/* Reset some global variables */
reset_status_vars();
+#ifdef WITH_WSREP
+ wsrep->stats_reset(wsrep);
+#endif /* WITH_WSREP */
/* Reset the counters of all key caches (default and named). */
process_key_caches(reset_key_cache_counters, 0);
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index f367ca293c8..7d87e245035 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -1022,6 +1022,7 @@ THD::THD()
wsrep_applier(is_applier),
wsrep_applier_closing(FALSE),
wsrep_client_thread(0),
+ wsrep_apply_toi(false),
#endif
m_parser_state(NULL),
#if defined(ENABLED_DEBUG_SYNC)
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 24132fb0913..946d69a2759 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -61,9 +61,12 @@ void set_thd_stage_info(void *thd,
#include "wsrep_mysqld.h"
struct wsrep_thd_shadow {
ulonglong options;
+ uint server_status;
enum wsrep_exec_mode wsrep_exec_mode;
Vio *vio;
ulong tx_isolation;
+ char *db;
+ size_t db_length;
};
#endif
class Reprepare_observer;
@@ -2563,6 +2566,7 @@ public:
const char* wsrep_TOI_pre_query; /* a query to apply before
the actual TOI query */
size_t wsrep_TOI_pre_query_len;
+ bool wsrep_apply_toi; /* applier processing in TOI */
#endif /* WITH_WSREP */
/**
Internal parser state.
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 3abedd40047..3b4c2dee2bb 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -1858,12 +1858,15 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
if ((thd->wsrep_conflict_state != REPLAYING) &&
(thd->wsrep_conflict_state != RETRY_AUTOCOMMIT))
{
+ mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
thd->update_server_status();
thd->protocol->end_statement();
query_cache_end_of_result(thd);
+ }
+ else
+ {
+ mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
}
- mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
-
} else { /* if (WSREP(thd))... */
#endif /* WITH_WSREP */
DBUG_ASSERT(thd->derived_tables == NULL &&
@@ -3249,8 +3252,11 @@ case SQLCOM_PREPARE:
else
{
#ifdef WITH_WSREP
- if (!thd->is_current_stmt_binlog_format_row() ||
- !(create_info.options & HA_LEX_CREATE_TMP_TABLE))
+ /* in STATEMENT format, we probably have to replicate also temporary
+ tables, like mysql replication does
+ */
+ if (!thd->is_current_stmt_binlog_format_row() ||
+ !(create_info.options & HA_LEX_CREATE_TMP_TABLE))
WSREP_TO_ISOLATION_BEGIN(create_table->db, create_table->table_name,
NULL)
#endif /* WITH_WSREP */
@@ -5455,7 +5461,22 @@ finish:
{
thd->mdl_context.release_statement_locks();
}
- WSREP_TO_ISOLATION_END
+ WSREP_TO_ISOLATION_END;
+
+#ifdef WITH_WSREP
+ /*
+ Force release of transactional locks if not in active MST and wsrep is on.
+ */
+ if (WSREP(thd) &&
+ ! thd->in_sub_stmt &&
+ ! thd->in_active_multi_stmt_transaction() &&
+ thd->mdl_context.has_transactional_locks())
+ {
+ WSREP_DEBUG("Forcing release of transactional locks for thd %lu",
+ thd->thread_id);
+ thd->mdl_context.release_transactional_locks();
+ }
+#endif /* WITH_WSREP */
DBUG_RETURN(res || thd->is_error());
}
@@ -6356,7 +6377,12 @@ void THD::reset_for_next_command(bool calculate_userstat)
thd->stmt_depends_on_first_successful_insert_id_in_prev_stmt= 0;
#ifdef WITH_WSREP
- if (WSREP(thd)) {
+ /*
+ Autoinc variables should be adjusted only for locally executed
+ transactions. Appliers and replayers are either processing ROW
+ events or get autoinc variable values from Query_log_event.
+ */
+ if (WSREP(thd) && thd->wsrep_exec_mode == LOCAL_STATE) {
if (wsrep_auto_increment_control)
{
if (thd->variables.auto_increment_offset !=
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 2c268207494..d113ea85a26 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -4898,12 +4898,23 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, TABLE_LIST* src_table,
break;
}
}
- if (!is_tmp_table)
+ if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
{
+ /* CREATE TEMPORARY TABLE LIKE must be skipped from replication */
+ WSREP_DEBUG("CREATE TEMPORARY TABLE LIKE... skipped replication\n %s",
+ thd->query());
+ }
+ else if (!is_tmp_table)
+ {
+ /* this is straight CREATE TABLE LIKE... eith no tmp tables */
WSREP_TO_ISOLATION_BEGIN(table->db, table->table_name, NULL);
}
else
{
+ /* here we have CREATE TABLE LIKE <temporary table>
+ the temporary table definition will be needed in slaves to
+ enable the create to succeed
+ */
TABLE_LIST tbl;
bzero((void*) &tbl, sizeof(tbl));
tbl.db= src_table->db;
diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc
index 37e5f3315e3..18defddb36f 100644
--- a/sql/sys_vars.cc
+++ b/sql/sys_vars.cc
@@ -4092,7 +4092,7 @@ static Sys_var_charptr Sys_wsrep_data_home_dir(
static Sys_var_charptr Sys_wsrep_cluster_name(
"wsrep_cluster_name", "Name for the cluster",
- GLOBAL_VAR(wsrep_cluster_name), CMD_LINE(REQUIRED_ARG),
+ PREALLOCATED GLOBAL_VAR(wsrep_cluster_name), CMD_LINE(REQUIRED_ARG),
IN_FS_CHARSET, DEFAULT(wsrep_cluster_name),
NO_MUTEX_GUARD, NOT_IN_BINLOG,
ON_CHECK(wsrep_cluster_name_check),
@@ -4110,13 +4110,13 @@ static Sys_var_charptr Sys_wsrep_cluster_address (
static Sys_var_charptr Sys_wsrep_node_name (
"wsrep_node_name", "Node name",
- GLOBAL_VAR(wsrep_node_name), CMD_LINE(REQUIRED_ARG),
+ PREALLOCATED GLOBAL_VAR(wsrep_node_name), CMD_LINE(REQUIRED_ARG),
IN_FS_CHARSET, DEFAULT(wsrep_node_name),
NO_MUTEX_GUARD, NOT_IN_BINLOG);
static Sys_var_charptr Sys_wsrep_node_address (
"wsrep_node_address", "Node address",
- GLOBAL_VAR(wsrep_node_address), CMD_LINE(REQUIRED_ARG),
+ PREALLOCATED GLOBAL_VAR(wsrep_node_address), CMD_LINE(REQUIRED_ARG),
IN_FS_CHARSET, DEFAULT(wsrep_node_address),
NO_MUTEX_GUARD, NOT_IN_BINLOG,
ON_CHECK(wsrep_node_address_check),
@@ -4124,7 +4124,7 @@ static Sys_var_charptr Sys_wsrep_node_address (
static Sys_var_charptr Sys_wsrep_node_incoming_address(
"wsrep_node_incoming_address", "Client connection address",
- GLOBAL_VAR(wsrep_node_incoming_address),CMD_LINE(REQUIRED_ARG),
+ PREALLOCATED GLOBAL_VAR(wsrep_node_incoming_address),CMD_LINE(REQUIRED_ARG),
IN_FS_CHARSET, DEFAULT(wsrep_node_incoming_address),
NO_MUTEX_GUARD, NOT_IN_BINLOG);
@@ -4216,7 +4216,7 @@ static Sys_var_mybool Sys_wsrep_on (
static Sys_var_charptr Sys_wsrep_start_position (
"wsrep_start_position", "global transaction position to start from ",
- GLOBAL_VAR(wsrep_start_position),
+ PREALLOCATED GLOBAL_VAR(wsrep_start_position),
CMD_LINE(REQUIRED_ARG, OPT_WSREP_START_POSITION),
IN_FS_CHARSET, DEFAULT(wsrep_start_position),
NO_MUTEX_GUARD, NOT_IN_BINLOG,
diff --git a/sql/transaction.cc b/sql/transaction.cc
index 5195e456432..be1330d0a97 100644
--- a/sql/transaction.cc
+++ b/sql/transaction.cc
@@ -423,14 +423,7 @@ bool trans_rollback_stmt(THD *thd)
#endif /* WITH_WSREP */
ha_rollback_trans(thd, FALSE);
if (thd->transaction_rollback_request && !thd->in_sub_stmt)
-#ifdef WITH_WSREP
- {
- wsrep_register_hton(thd, TRUE);
-#endif /* WITH_WSREP */
ha_rollback_trans(thd, TRUE);
-#ifdef WITH_WSREP
- }
-#endif /* WITH_WSREP */
if (! thd->in_active_multi_stmt_transaction())
{
thd->tx_isolation= (enum_tx_isolation) thd->variables.tx_isolation;
diff --git a/sql/wsrep_applier.h b/sql/wsrep_applier.h
new file mode 100644
index 00000000000..816970db67c
--- /dev/null
+++ b/sql/wsrep_applier.h
@@ -0,0 +1,38 @@
+/* Copyright 2013 Codership Oy <http://www.codership.com>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#ifndef WSREP_APPLIER_H
+#define WSREP_APPLIER_H
+
+#include <sys/types.h>
+
+/* wsrep callback prototypes */
+
+wsrep_cb_status_t wsrep_apply_cb(void *ctx,
+ const void* buf, size_t buf_len,
+ uint32_t flags,
+ const wsrep_trx_meta_t* meta);
+
+wsrep_cb_status_t wsrep_commit_cb(void *ctx,
+ uint32_t flags,
+ const wsrep_trx_meta_t* meta,
+ wsrep_bool_t* exit,
+ bool commit);
+
+wsrep_cb_status_t wsrep_unordered_cb(void* ctx,
+ const void* data,
+ size_t size);
+
+#endif /* WSREP_APPLIER_H */
diff --git a/sql/wsrep_hton.cc b/sql/wsrep_hton.cc
index 24f193e8c7b..1a3b3d64cbe 100644
--- a/sql/wsrep_hton.cc
+++ b/sql/wsrep_hton.cc
@@ -68,7 +68,7 @@ handlerton *wsrep_hton;
*/
void wsrep_register_hton(THD* thd, bool all)
{
- if (thd->wsrep_exec_mode != TOTAL_ORDER)
+ if (thd->wsrep_exec_mode != TOTAL_ORDER && !thd->wsrep_apply_toi)
{
THD_TRANS *trans=all ? &thd->transaction.all : &thd->transaction.stmt;
for (Ha_trx_info *i= trans->ha_list; WSREP(thd) && i; i = i->next())
diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc
index a842aa84fc9..137841c776f 100644
--- a/sql/wsrep_mysqld.cc
+++ b/sql/wsrep_mysqld.cc
@@ -22,6 +22,7 @@
#include "wsrep_utils.h"
#include "wsrep_var.h"
#include "wsrep_binlog.h"
+#include "wsrep_applier.h"
#include <cstdio>
#include <cstdlib>
#include "log_event.h"
@@ -86,6 +87,7 @@ long long wsrep_cluster_conf_id = WSREP_SEQNO_UNDEFINED;
const char* wsrep_cluster_status = cluster_status_str[WSREP_VIEW_DISCONNECTED];
long wsrep_cluster_size = 0;
long wsrep_local_index = -1;
+long long wsrep_local_bf_aborts = 0;
const char* wsrep_provider_name = provider_name;
const char* wsrep_provider_version = provider_version;
const char* wsrep_provider_vendor = provider_vendor;
@@ -101,18 +103,6 @@ long wsrep_protocol_version = 2;
// if there was no state gap on receiving first view event.
static my_bool wsrep_startup = TRUE;
-extern wsrep_cb_status_t wsrep_apply_cb(void *ctx,
- const void* buf, size_t buf_len,
- const wsrep_trx_meta_t* meta);
-
-extern wsrep_cb_status_t wsrep_commit_cb(void *ctx,
- const wsrep_trx_meta_t* meta,
- wsrep_bool_t *exit,
- wsrep_bool_t commit);
-
-extern wsrep_cb_status_t wsrep_unordered_cb(void* ctx,
- const void* data,
- size_t size);
static void wsrep_log_cb(wsrep_log_level_t level, const char *msg) {
switch (level) {
@@ -1326,6 +1316,20 @@ int wsrep_to_isolation_begin(THD *thd, char *db_, char *table_,
WSREP_DEBUG("thread holds MDL locks at TI begin: %s %lu",
thd->query(), thd->thread_id);
}
+
+ /*
+ It makes sense to set auto_increment_* to defaults in TOI operations.
+ Must be done before wsrep_TOI_begin() since Query_log_event encapsulating
+ TOI statement and auto inc variables for wsrep replication is constructed
+ there. Variables are reset back in THD::reset_for_next_command() before
+ processing of next command.
+ */
+ if (wsrep_auto_increment_control)
+ {
+ thd->variables.auto_increment_offset = 1;
+ thd->variables.auto_increment_increment = 1;
+ }
+
if (thd->variables.wsrep_on && thd->wsrep_exec_mode==LOCAL_STATE)
{
switch (wsrep_OSU_method_options) {
@@ -1336,12 +1340,6 @@ int wsrep_to_isolation_begin(THD *thd, char *db_, char *table_,
if (!ret)
{
thd->wsrep_exec_mode= TOTAL_ORDER;
- /* It makes sense to set auto_increment_* to defaults in TOI operations */
- if (wsrep_auto_increment_control)
- {
- thd->variables.auto_increment_offset = 1;
- thd->variables.auto_increment_increment = 1;
- }
}
}
return ret;
diff --git a/sql/wsrep_mysqld.h b/sql/wsrep_mysqld.h
index c5647f8d984..8580729c389 100644
--- a/sql/wsrep_mysqld.h
+++ b/sql/wsrep_mysqld.h
@@ -94,7 +94,6 @@ extern my_bool wsrep_recovery;
extern my_bool wsrep_replicate_myisam;
extern my_bool wsrep_log_conflicts;
extern ulong wsrep_mysql_replication_bundle;
-extern ulong wsrep_mysql_replication_bundle;
extern my_bool wsrep_load_data_splitting;
enum enum_wsrep_OSU_method { WSREP_OSU_TOI, WSREP_OSU_RSU };
@@ -107,6 +106,7 @@ extern long long wsrep_cluster_conf_id;
extern const char* wsrep_cluster_status;
extern long wsrep_cluster_size;
extern long wsrep_local_index;
+extern long long wsrep_local_bf_aborts;
extern const char* wsrep_provider_name;
extern const char* wsrep_provider_version;
extern const char* wsrep_provider_vendor;
diff --git a/sql/wsrep_thd.cc b/sql/wsrep_thd.cc
index c25281b7a77..1ea9b84a692 100644
--- a/sql/wsrep_thd.cc
+++ b/sql/wsrep_thd.cc
@@ -23,12 +23,24 @@
#include "sql_base.h" // close_thread_tables()
#include "mysqld.h" // start_wsrep_THD();
+static long long wsrep_bf_aborts_counter = 0;
+
+int wsrep_show_bf_aborts (THD *thd, SHOW_VAR *var, char *buff)
+{
+ wsrep_local_bf_aborts = my_atomic_load64(&wsrep_bf_aborts_counter);
+ var->type = SHOW_LONGLONG;
+ var->value = (char*)&wsrep_local_bf_aborts;
+ return 0;
+}
+
/* must have (&thd->LOCK_wsrep_thd) */
void wsrep_client_rollback(THD *thd)
{
WSREP_DEBUG("client rollback due to BF abort for (%ld), query: %s",
thd->thread_id, thd->query());
+ my_atomic_add64(&wsrep_bf_aborts_counter, 1);
+
thd->wsrep_conflict_state= ABORTING;
mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
trans_rollback(thd);
@@ -79,6 +91,7 @@ static Relay_log_info* wsrep_relay_log_init(const char* log_fname)
static void wsrep_prepare_bf_thd(THD *thd, struct wsrep_thd_shadow* shadow)
{
shadow->options = thd->variables.option_bits;
+ shadow->server_status = thd->server_status;
shadow->wsrep_exec_mode = thd->wsrep_exec_mode;
shadow->vio = thd->net.vio;
@@ -96,14 +109,20 @@ static void wsrep_prepare_bf_thd(THD *thd, struct wsrep_thd_shadow* shadow)
shadow->tx_isolation = thd->variables.tx_isolation;
thd->variables.tx_isolation = ISO_READ_COMMITTED;
thd->tx_isolation = ISO_READ_COMMITTED;
+
+ shadow->db = thd->db;
+ shadow->db_length = thd->db_length;
+ thd->reset_db(NULL, 0);
}
static void wsrep_return_from_bf_mode(THD *thd, struct wsrep_thd_shadow* shadow)
{
thd->variables.option_bits = shadow->options;
+ thd->server_status = shadow->server_status;
thd->wsrep_exec_mode = shadow->wsrep_exec_mode;
thd->net.vio = shadow->vio;
thd->variables.tx_isolation = shadow->tx_isolation;
+ thd->reset_db(shadow->db, shadow->db_length);
}
void wsrep_replay_transaction(THD *thd)
diff --git a/sql/wsrep_thd.h b/sql/wsrep_thd.h
index 2397230b0a2..bded13b5684 100644
--- a/sql/wsrep_thd.h
+++ b/sql/wsrep_thd.h
@@ -18,6 +18,7 @@
#include "sql_class.h"
+int wsrep_show_bf_aborts (THD *thd, SHOW_VAR *var, char *buff);
void wsrep_client_rollback(THD *thd);
void wsrep_replay_transaction(THD *thd);
void wsrep_create_appliers(long threads);
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index 32c9ea3aa6a..30bfdf23e0f 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -7201,9 +7201,9 @@ no_commit:
DBUG_RETURN(1);
}
- binlog_hton->commit(binlog_hton, user_thd, 1);
-
- wsrep_cleanup_transaction(user_thd);
+ if (binlog_hton->commit(binlog_hton, user_thd, 1))
+ DBUG_RETURN(1);
+ wsrep_post_commit(user_thd, TRUE);
#endif /* WITH_WSREP */
/* Source table is not in InnoDB format:
no need to re-acquire locks on it. */
@@ -7224,8 +7224,10 @@ no_commit:
case WSREP_TRX_ERROR:
DBUG_RETURN(1);
}
- binlog_hton->commit(binlog_hton, user_thd, 1);
- wsrep_cleanup_transaction(user_thd);
+
+ if (binlog_hton->commit(binlog_hton, user_thd, 1))
+ DBUG_RETURN(1);
+ wsrep_post_commit(user_thd, TRUE);
#endif /* WITH_WSREP */
/* Ensure that there are no other table locks than
LOCK_IX and LOCK_AUTO_INC on the destination table. */
@@ -16889,7 +16891,8 @@ static int innobase_wsrep_set_checkpoint(handlerton* hton, const XID* xid)
if (wsrep_is_wsrep_xid(xid)) {
mtr_t mtr;
mtr_start(&mtr);
- trx_sys_update_wsrep_checkpoint(xid, &mtr);
+ trx_sysf_t* sys_header = trx_sysf_get(&mtr);
+ trx_sys_update_wsrep_checkpoint(xid, sys_header, &mtr);
mtr_commit(&mtr);
return 0;
} else {
diff --git a/storage/innobase/include/trx0sys.h b/storage/innobase/include/trx0sys.h
index 5cff7e8b9ed..cbc64ecc3c9 100644
--- a/storage/innobase/include/trx0sys.h
+++ b/storage/innobase/include/trx0sys.h
@@ -296,6 +296,9 @@ trx_sys_update_mysql_binlog_offset(
ib_int64_t offset, /*!< in: position in that log file */
ulint field, /*!< in: offset of the MySQL log info field in
the trx sys header */
+#ifdef WITH_WSREP
+ trx_sysf_t* sys_header, /*!< in: trx sys header */
+#endif /* WITH_WSREP */
mtr_t* mtr); /*!< in: mtr */
/*****************************************************************//**
Prints to stderr the MySQL binlog offset info in the trx system header if
@@ -308,8 +311,10 @@ trx_sys_print_mysql_binlog_offset(void);
/** Update WSREP checkpoint XID in sys header. */
void
trx_sys_update_wsrep_checkpoint(
- const XID* xid, /*!< in: WSREP XID */
- mtr_t* mtr); /*!< in: mtr */
+ const XID* xid, /*!< in: WSREP XID */
+ trx_sysf_t* sys_header, /*!< in: sys_header */
+ mtr_t* mtr); /*!< in: mtr */
+
void
/** Read WSREP checkpoint XID from sys header. */
trx_sys_read_wsrep_checkpoint(
diff --git a/storage/innobase/trx/trx0trx.cc b/storage/innobase/trx/trx0trx.cc
index 4ff18563c29..c678b8a5132 100644
--- a/storage/innobase/trx/trx0trx.cc
+++ b/storage/innobase/trx/trx0trx.cc
@@ -840,7 +840,9 @@ trx_write_serialisation_history(
/*============================*/
trx_t* trx) /*!< in: transaction */
{
-
+#ifdef WITH_WSREP
+ trx_sysf_t* sys_header;
+#endif /* WITH_WSREP */
mtr_t mtr;
trx_rseg_t* rseg;
@@ -891,10 +893,11 @@ trx_write_serialisation_history(
MONITOR_INC(MONITOR_TRX_COMMIT_UNDO);
#ifdef WITH_WSREP
+ sys_header = trx_sysf_get(&mtr);
/* Update latest MySQL wsrep XID in trx sys header. */
if (wsrep_is_wsrep_xid(&trx->xid))
{
- //trx_sys_update_wsrep_checkpoint(&trx->xid, &mtr);
+ trx_sys_update_wsrep_checkpoint(&trx->xid, &mtr);
}
#endif /* WITH_WSREP */
@@ -908,7 +911,11 @@ trx_write_serialisation_history(
trx_sys_update_mysql_binlog_offset(
trx->mysql_log_file_name,
trx->mysql_log_offset,
- TRX_SYS_MYSQL_LOG_INFO, &mtr);
+ TRX_SYS_MYSQL_LOG_INFO,
+#ifdef WITH_WSREP
+ sys_header,
+#endif /* WITH_WSREP */
+ &mtr);
trx->mysql_log_file_name = NULL;
}
diff --git a/wsrep/CMakeLists.txt b/wsrep.moved/CMakeLists.txt
index 11d0e34d1b0..11d0e34d1b0 100644
--- a/wsrep/CMakeLists.txt
+++ b/wsrep.moved/CMakeLists.txt
diff --git a/wsrep/Makefile.am b/wsrep.moved/Makefile.am
index 40e4b501e86..40e4b501e86 100644
--- a/wsrep/Makefile.am
+++ b/wsrep.moved/Makefile.am
diff --git a/wsrep.moved/wsrep_api.h b/wsrep.moved/wsrep_api.h
new file mode 100644
index 00000000000..987a47db578
--- /dev/null
+++ b/wsrep.moved/wsrep_api.h
@@ -0,0 +1,1110 @@
+/* Copyright (C) 2009-2013 Codership Oy <info@codership.com>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+/*!
+ @file wsrep API declaration.
+
+ HOW TO READ THIS FILE.
+
+ Due to C language rules this header layout doesn't lend itself to intuitive
+ reading. So here's the scoop: in the end this header declares two main types:
+
+ * struct wsrep_init_args
+
+ and
+
+ * struct wsrep
+
+ wsrep_init_args contains initialization parameters for wsrep provider like
+ names, addresses, etc. and pointers to callbacks. The callbacks will be called
+ by provider when it needs to do something application-specific, like log a
+ message or apply a writeset. It should be passed to init() call from
+ wsrep API. It is an application part of wsrep API contract.
+
+ struct wsrep is the interface to wsrep provider. It contains all wsrep API
+ calls. It is a provider part of wsrep API contract.
+
+ Finally, wsrep_load() method loads (dlopens) wsrep provider library. It is
+ defined in wsrep_loader.c unit and is part of libwsrep.a (which is not a
+ wsrep provider, but a convenience library).
+
+ wsrep_unload() does the reverse.
+
+*/
+#ifndef WSREP_H
+#define WSREP_H
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <time.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**************************************************************************
+ * *
+ * wsrep replication API *
+ * *
+ **************************************************************************/
+
+#define WSREP_INTERFACE_VERSION "24"
+
+/*! Empty backend spec */
+#define WSREP_NONE "none"
+
+
+/*!
+ * @brief log severity levels, passed as first argument to log handler
+ */
+typedef enum wsrep_log_level
+{
+ WSREP_LOG_FATAL, //!< Unrecoverable error, application must quit.
+ WSREP_LOG_ERROR, //!< Operation failed, must be repeated.
+ WSREP_LOG_WARN, //!< Unexpected condition, but no operational failure.
+ WSREP_LOG_INFO, //!< Informational message.
+ WSREP_LOG_DEBUG //!< Debug message. Shows only of compiled with debug.
+} wsrep_log_level_t;
+
+/*!
+ * @brief error log handler
+ *
+ * All messages from wsrep provider are directed to this
+ * handler, if present.
+ *
+ * @param level log level
+ * @param message log message
+ */
+typedef void (*wsrep_log_cb_t)(wsrep_log_level_t, const char *);
+
+
+/*!
+ * Certain provider capabilities application may want to know about
+ */
+#define WSREP_CAP_MULTI_MASTER ( 1ULL << 0 )
+#define WSREP_CAP_CERTIFICATION ( 1ULL << 1 )
+#define WSREP_CAP_PARALLEL_APPLYING ( 1ULL << 2 )
+#define WSREP_CAP_TRX_REPLAY ( 1ULL << 3 )
+#define WSREP_CAP_ISOLATION ( 1ULL << 4 )
+#define WSREP_CAP_PAUSE ( 1ULL << 5 )
+#define WSREP_CAP_CAUSAL_READS ( 1ULL << 6 )
+#define WSREP_CAP_CAUSAL_TRX ( 1ULL << 7 )
+#define WSREP_CAP_INCREMENTAL_WRITESET ( 1ULL << 8 )
+#define WSREP_CAP_SESSION_LOCKS ( 1ULL << 9 )
+#define WSREP_CAP_DISTRIBUTED_LOCKS ( 1ULL << 10 )
+#define WSREP_CAP_CONSISTENCY_CHECK ( 1ULL << 11 )
+#define WSREP_CAP_UNORDERED ( 1ULL << 12 )
+#define WSREP_CAP_ANNOTATION ( 1ULL << 13 )
+#define WSREP_CAP_PREORDERED ( 1ULL << 14 )
+
+
+/*!
+ * Writeset flags
+ *
+ * COMMIT the writeset and all preceding writesets must be committed
+ * ROLLBACK all preceding writesets in a transaction must be rolled back
+ * PA_UNSAFE the writeset cannot be applied in parallel
+ * ISOLATION the writeset must be applied AND committed in isolation
+ * COMMUTATIVE the order in which the writeset is applied does not matter
+ * NATIVE the writeset contains another writeset in this provider format
+ *
+ * Note that some of the flags are mutually exclusive (e.g. COMMIT and
+ * ROLLBACK).
+ */
+#define WSREP_FLAG_COMMIT ( 1ULL << 0 )
+#define WSREP_FLAG_ROLLBACK ( 1ULL << 1 )
+#define WSREP_FLAG_PA_UNSAFE ( 1ULL << 3 )
+#define WSREP_FLAG_ISOLATION ( 1ULL << 2 )
+#define WSREP_FLAG_COMMUTATIVE ( 1ULL << 4 )
+#define WSREP_FLAG_NATIVE ( 1ULL << 5 )
+
+
+typedef uint64_t wsrep_trx_id_t; //!< application transaction ID
+typedef uint64_t wsrep_conn_id_t; //!< application connection ID
+typedef int64_t wsrep_seqno_t; //!< sequence number of a writeset, etc.
+typedef _Bool wsrep_bool_t; //!< should be the same as standard (C99) bool
+
+/*! undefined seqno */
+#define WSREP_SEQNO_UNDEFINED (-1)
+
+
+/*! wsrep provider status codes */
+typedef enum wsrep_status
+{
+ WSREP_OK = 0, //!< success
+ WSREP_WARNING, //!< minor warning, error logged
+ WSREP_TRX_MISSING, //!< transaction is not known by wsrep
+ WSREP_TRX_FAIL, //!< transaction aborted, server can continue
+ WSREP_BF_ABORT, //!< trx was victim of brute force abort
+ WSREP_SIZE_EXCEEDED, //!< data exceeded maximum supported size
+ WSREP_CONN_FAIL, //!< error in client connection, must abort
+ WSREP_NODE_FAIL, //!< error in node state, wsrep must reinit
+ WSREP_FATAL, //!< fatal error, server must abort
+ WSREP_NOT_IMPLEMENTED //!< feature not implemented
+} wsrep_status_t;
+
+
+/*! wsrep callbacks status codes */
+typedef enum wsrep_cb_status
+{
+ WSREP_CB_SUCCESS = 0, //!< success (as in "not critical failure")
+ WSREP_CB_FAILURE //!< critical failure (consistency violation)
+ /* Technically, wsrep provider has no use for specific failure codes since
+ * there is nothing it can do about it but abort execution. Therefore any
+ * positive number shall indicate a critical failure. Optionally that value
+ * may be used by provider to come to a consensus about state consistency
+ * in a group of nodes. */
+} wsrep_cb_status_t;
+
+
+/*!
+ * UUID type - for all unique IDs
+ */
+typedef struct wsrep_uuid {
+ uint8_t data[16];
+} wsrep_uuid_t;
+
+/*! Undefined UUID */
+static const wsrep_uuid_t WSREP_UUID_UNDEFINED = {{0,}};
+
+/*! UUID string representation length, terminating '\0' not included */
+#define WSREP_UUID_STR_LEN 36
+
+/*!
+ * Scan UUID from string
+ * @return length of UUID string representation or negative error code
+ */
+extern int
+wsrep_uuid_scan (const char* str, size_t str_len, wsrep_uuid_t* uuid);
+
+/*!
+ * Print UUID to string
+ * @return length of UUID string representation or negative error code
+ */
+extern int
+wsrep_uuid_print (const wsrep_uuid_t* uuid, char* str, size_t str_len);
+
+#define WSREP_MEMBER_NAME_LEN 32 //!< maximum logical member name length
+#define WSREP_INCOMING_LEN 256 //!< max Domain Name length + 0x00
+
+
+/*!
+ * Global transaction identifier
+ */
+typedef struct wsrep_gtid
+{
+ wsrep_uuid_t uuid; /*!< History UUID */
+ wsrep_seqno_t seqno; /*!< Sequence number */
+} wsrep_gtid_t;
+
+/*! Undefined GTID */
+static const wsrep_gtid_t WSREP_GTID_UNDEFINED = {{{0, }}, -1};
+
+/*! Minimum number of bytes guaranteed to store GTID string representation,
+ * terminating '\0' not included (36 + 1 + 20) */
+#define WSREP_GTID_STR_LEN 57
+
+
+/*!
+ * Scan GTID from string
+ * @return length of GTID string representation or negative error code
+ */
+extern int
+wsrep_gtid_scan(const char* str, size_t str_len, wsrep_gtid_t* gtid);
+
+/*!
+ * Print GTID to string
+ * @return length of GTID string representation or negative error code
+ */
+extern int
+wsrep_gtid_print(const wsrep_gtid_t* gtid, char* str, size_t str_len);
+
+
+/*!
+ * Transaction meta data
+ */
+typedef struct wsrep_trx_meta
+{
+ wsrep_gtid_t gtid; /*!< Global transaction identifier */
+ wsrep_seqno_t depends_on; /*!< Sequence number part of the last transaction
+ this transaction depends on */
+} wsrep_trx_meta_t;
+
+
+/*!
+ * member status
+ */
+typedef enum wsrep_member_status {
+ WSREP_MEMBER_UNDEFINED, //!< undefined state
+ WSREP_MEMBER_JOINER, //!< incomplete state, requested state transfer
+ WSREP_MEMBER_DONOR, //!< complete state, donates state transfer
+ WSREP_MEMBER_JOINED, //!< complete state
+ WSREP_MEMBER_SYNCED, //!< complete state, synchronized with group
+ WSREP_MEMBER_ERROR, //!< this and above is provider-specific error code
+ WSREP_MEMBER_MAX
+} wsrep_member_status_t;
+
+/*!
+ * static information about a group member (some fields are tentative yet)
+ */
+typedef struct wsrep_member_info {
+ wsrep_uuid_t id; //!< group-wide unique member ID
+ char name[WSREP_MEMBER_NAME_LEN]; //!< human-readable name
+ char incoming[WSREP_INCOMING_LEN]; //!< address for client requests
+} wsrep_member_info_t;
+
+/*!
+ * group status
+ */
+typedef enum wsrep_view_status {
+ WSREP_VIEW_PRIMARY, //!< primary group configuration (quorum present)
+ WSREP_VIEW_NON_PRIMARY, //!< non-primary group configuration (quorum lost)
+ WSREP_VIEW_DISCONNECTED, //!< not connected to group, retrying.
+ WSREP_VIEW_MAX
+} wsrep_view_status_t;
+
+/*!
+ * view of the group
+ */
+typedef struct wsrep_view_info {
+ wsrep_gtid_t state_id; //!< global state ID
+ wsrep_seqno_t view; //!< global view number
+ wsrep_view_status_t status; //!< view status
+ wsrep_bool_t state_gap; //!< gap between global and local states
+ int my_idx; //!< index of this member in the view
+ int memb_num; //!< number of members in the view
+ int proto_ver; //!< application protocol agreed on the view
+ wsrep_member_info_t members[1];//!< array of member information
+} wsrep_view_info_t;
+
+/*!
+ * Magic string to tell provider to engage into trivial (empty) state transfer.
+ * No data will be passed, but the node shall be considered JOINED.
+ * Should be passed in sst_req parameter of wsrep_view_cb_t.
+ */
+#define WSREP_STATE_TRANSFER_TRIVIAL "trivial"
+
+/*!
+ * Magic string to tell provider not to engage in state transfer at all.
+ * The member will stay in WSREP_MEMBER_UNDEFINED state but will keep on
+ * receiving all writesets.
+ * Should be passed in sst_req parameter of wsrep_view_cb_t.
+ */
+#define WSREP_STATE_TRANSFER_NONE "none"
+
+/*!
+ * @brief group view handler
+ *
+ * This handler is called in total order corresponding to the group
+ * configuration change. It is to provide a vital information about
+ * new group view. If view info indicates existence of discontinuity
+ * between group and member states, state transfer request message
+ * should be filled in by the callback implementation.
+ *
+ * @note Currently it is assumed that sst_req is allocated using
+ * malloc()/calloc()/realloc() and it will be freed by
+ * wsrep implementation.
+ *
+ * @param app_ctx application context
+ * @param recv_ctx receiver context
+ * @param view new view on the group
+ * @param state current state
+ * @param state_len lenght of current state
+ * @param sst_req location to store SST request
+ * @param sst_req_len location to store SST request length or error code,
+ * value of 0 means no SST.
+ */
+typedef enum wsrep_cb_status (*wsrep_view_cb_t) (
+ void* app_ctx,
+ void* recv_ctx,
+ const wsrep_view_info_t* view,
+ const char* state,
+ size_t state_len,
+ void** sst_req,
+ size_t* sst_req_len
+);
+
+
+/*!
+ * @brief apply callback
+ *
+ * This handler is called from wsrep library to apply replicated writeset
+ * Must support brute force applying for multi-master operation
+ *
+ * @param recv_ctx receiver context pointer provided by the application
+ * @param data data buffer containing the writeset
+ * @param size data buffer size
+ * @param meta transaction meta data of the writeset to be applied
+ *
+ * @return success code:
+ * @retval WSREP_OK
+ * @retval WSREP_NOT_IMPLEMENTED appl. does not support the writeset format
+ * @retval WSREP_ERROR failed to apply the writeset
+ */
+typedef enum wsrep_cb_status (*wsrep_apply_cb_t) (
+ void* recv_ctx,
+ const void* data,
+ size_t size,
+ const wsrep_trx_meta_t* meta
+);
+
+
+/*!
+ * @brief commit callback
+ *
+ * This handler is called to commit the changes made by apply callback.
+ *
+ * @param recv_ctx receiver context pointer provided by the application
+ * @param meta transaction meta data of the writeset to be committed
+ * @param exit set to true to exit recv loop
+ * @param commit true - commit writeset, false - rollback writeset
+ *
+ * @return success code:
+ * @retval WSREP_OK
+ * @retval WSREP_ERROR call failed
+ */
+typedef enum wsrep_cb_status (*wsrep_commit_cb_t) (
+ void* recv_ctx,
+ const wsrep_trx_meta_t* meta,
+ wsrep_bool_t* exit,
+ wsrep_bool_t commit
+);
+
+
+/*!
+ * @brief unordered callback
+ *
+ * This handler is called to execute unordered actions (actions that need not
+ * to be executed in any particular order) attached to writeset.
+ *
+ * @param recv_ctx receiver context pointer provided by the application
+ * @param data data buffer containing the writeset
+ * @param size data buffer size
+ */
+typedef enum wsrep_cb_status (*wsrep_unordered_cb_t) (
+ void* recv_ctx,
+ const void* data,
+ size_t size
+);
+
+
+/*!
+ * @brief a callback to donate state snapshot
+ *
+ * This handler is called from wsrep library when it needs this node
+ * to deliver state to a new cluster member.
+ * No state changes will be committed for the duration of this call.
+ * Wsrep implementation may provide internal state to be transmitted
+ * to new cluster member for initial state.
+ *
+ * @param app_ctx application context
+ * @param recv_ctx receiver context
+ * @param msg state transfer request message
+ * @param msg_len state transfer request message length
+ * @param gtid current state ID on this node
+ * @param state current wsrep internal state buffer
+ * @param state_len current wsrep internal state buffer len
+ * @param bypass bypass snapshot transfer, only transfer uuid:seqno pair
+ */
+typedef enum wsrep_cb_status (*wsrep_sst_donate_cb_t) (
+ void* app_ctx,
+ void* recv_ctx,
+ const void* msg,
+ size_t msg_len,
+ const wsrep_gtid_t* state_id,
+ const char* state,
+ size_t state_len,
+ wsrep_bool_t bypass
+);
+
+
+/*!
+ * @brief a callback to signal application that wsrep state is synced
+ * with cluster
+ *
+ * This callback is called after wsrep library has got in sync with
+ * rest of the cluster.
+ *
+ * @param app_ctx application context
+ */
+typedef void (*wsrep_synced_cb_t) (void* app_ctx);
+
+
+/*!
+ * Initialization parameters for wsrep provider.
+ */
+struct wsrep_init_args
+{
+ void* app_ctx; //!< Application context for callbacks
+
+ /* Configuration parameters */
+ const char* node_name; //!< Symbolic name of this node (e.g. hostname)
+ const char* node_address; //!< Address to be used by wsrep provider
+ const char* node_incoming; //!< Address for incoming client connections
+ const char* data_dir; //!< Directory where wsrep files are kept if any
+ const char* options; //!< Provider-specific configuration string
+ int proto_ver; //!< Max supported application protocol version
+
+ /* Application initial state information. */
+ const wsrep_gtid_t* state_id; //!< Application state GTID
+ const char* state; //!< Initial state for wsrep provider
+ size_t state_len; //!< Length of state buffer
+
+ /* Application callbacks */
+ wsrep_log_cb_t logger_cb; //!< logging handler
+ wsrep_view_cb_t view_handler_cb; //!< group view change handler
+
+ /* Applier callbacks */
+ wsrep_apply_cb_t apply_cb; //!< apply callback
+ wsrep_commit_cb_t commit_cb; //!< commit callback
+ wsrep_unordered_cb_t unordered_cb; //!< callback for unordered actions
+
+ /* State Snapshot Transfer callbacks */
+ wsrep_sst_donate_cb_t sst_donate_cb; //!< starting to donate
+ wsrep_synced_cb_t synced_cb; //!< synced with group
+};
+
+
+/*! Type of the stats variable value in struct wsrep_status_var */
+typedef enum wsrep_var_type
+{
+ WSREP_VAR_STRING, //!< pointer to null-terminated string
+ WSREP_VAR_INT64, //!< int64_t
+ WSREP_VAR_DOUBLE //!< double
+}
+wsrep_var_type_t;
+
+/*! Generalized stats variable representation */
+struct wsrep_stats_var
+{
+ const char* name; //!< variable name
+ wsrep_var_type_t type; //!< variable value type
+ union {
+ int64_t _int64;
+ double _double;
+ const char* _string;
+ } value; //!< variable value
+};
+
+
+/*! Abstract data buffer structure */
+typedef struct wsrep_buf
+{
+ const void* ptr; /*!< Pointer to data buffer */
+ size_t len; /*!< Length of buffer */
+} wsrep_buf_t;
+
+/*! Key struct used to pass certification keys for transaction handling calls.
+ * A key consists of zero or more key parts. */
+typedef struct wsrep_key
+{
+ const wsrep_buf_t* key_parts; /*!< Array of key parts */
+ size_t key_parts_num; /*!< Number of key parts */
+} wsrep_key_t;
+
+/*! Key type:
+ * EXCLUSIVE conflicts with any key type
+ * SEMI reserved. If not supported, should be interpeted as EXCLUSIVE
+ * SHARED conflicts only with EXCLUSIVE keys */
+typedef enum wsrep_key_type
+{
+ WSREP_KEY_SHARED = 0,
+ WSREP_KEY_SEMI,
+ WSREP_KEY_EXCLUSIVE
+} wsrep_key_type_t;
+
+/*! Data type:
+ * ORDERED state modification event that should be applied and committed
+ * in order.
+ * UNORDERED some action that does not modify state and execution of which is
+ * optional and does not need to happen in order.
+ * ANNOTATION (human readable) writeset annotation. */
+typedef enum wsrep_data_type
+{
+ WSREP_DATA_ORDERED = 0,
+ WSREP_DATA_UNORDERED,
+ WSREP_DATA_ANNOTATION
+} wsrep_data_type_t;
+
+
+/*! Transaction handle struct passed for wsrep transaction handling calls */
+typedef struct wsrep_ws_handle
+{
+ wsrep_trx_id_t trx_id; //!< transaction ID
+ void* opaque; //!< opaque provider transaction context data
+} wsrep_ws_handle_t;
+
+/*!
+ * @brief Helper method to reset trx writeset handle state when trx id changes
+ *
+ * Instead of passing wsrep_ws_handle_t directly to wsrep calls,
+ * wrapping handle with this call offloads bookkeeping from
+ * application.
+ */
+static inline wsrep_ws_handle_t* wsrep_ws_handle_for_trx(
+ wsrep_ws_handle_t* ws_handle,
+ wsrep_trx_id_t trx_id)
+{
+ if (ws_handle->trx_id != trx_id)
+ {
+ ws_handle->trx_id = trx_id;
+ ws_handle->opaque = NULL;
+ }
+ return ws_handle;
+}
+
+
+/*!
+ * A handle for processing preordered actions.
+ * Must be initialized to WSREP_PO_INITIALIZER before use.
+ */
+typedef struct wsrep_po_handle { void* opaque; } wsrep_po_handle_t;
+
+static const wsrep_po_handle_t WSREP_PO_INITIALIZER = { NULL };
+
+
+typedef struct wsrep wsrep_t;
+/*!
+ * wsrep interface for dynamically loadable libraries
+ */
+struct wsrep {
+
+ const char *version; //!< interface version string
+
+ /*!
+ * @brief Initializes wsrep provider
+ *
+ * @param wsrep provider handle
+ * @param args wsrep initialization parameters
+ */
+ wsrep_status_t (*init) (wsrep_t* wsrep,
+ const struct wsrep_init_args* args);
+
+ /*!
+ * @brief Returns provider capabilities flag bitmap
+ *
+ * @param wsrep provider handle
+ */
+ uint64_t (*capabilities) (wsrep_t* wsrep);
+
+ /*!
+ * @brief Passes provider-specific configuration string to provider.
+ *
+ * @param wsrep provider handle
+ * @param conf configuration string
+ *
+ * @retval WSREP_OK configuration string was parsed successfully
+ * @retval WSREP_WARNING could't not parse conf string, no action taken
+ */
+ wsrep_status_t (*options_set) (wsrep_t* wsrep, const char* conf);
+
+ /*!
+ * @brief Returns provider-specific string with current configuration values.
+ *
+ * @param wsrep provider handle
+ *
+ * @return a dynamically allocated string with current configuration
+ * parameter values
+ */
+ char* (*options_get) (wsrep_t* wsrep);
+
+ /*!
+ * @brief Opens connection to cluster
+ *
+ * Returns when either node is ready to operate as a part of the clsuter
+ * or fails to reach operating status.
+ *
+ * @param wsrep provider handle
+ * @param cluster_name unique symbolic cluster name
+ * @param cluster_url URL-like cluster address (backend://address)
+ * @param state_donor name of the node to be asked for state transfer.
+ * @param bootstrap a flag to request initialization of a new wsrep
+ * service rather then a connection to the existing one.
+ * clister_url may still carry important initialization
+ * parameters, like backend spec and/or listen address.
+ */
+ wsrep_status_t (*connect) (wsrep_t* wsrep,
+ const char* cluster_name,
+ const char* cluster_url,
+ const char* state_donor,
+ wsrep_bool_t bootstrap);
+
+ /*!
+ * @brief Closes connection to cluster.
+ *
+ * If state_uuid and/or state_seqno is not NULL, will store final state
+ * in there.
+ *
+ * @param wsrep this wsrep handler
+ */
+ wsrep_status_t (*disconnect)(wsrep_t* wsrep);
+
+ /*!
+ * @brief start receiving replication events
+ *
+ * This function never returns
+ *
+ * @param wsrep provider handle
+ * @param recv_ctx receiver context
+ */
+ wsrep_status_t (*recv)(wsrep_t* wsrep, void* recv_ctx);
+
+ /*!
+ * @brief Replicates/logs result of transaction to other nodes and allocates
+ * required resources.
+ *
+ * Must be called before transaction commit. Returns success code, which
+ * caller must check.
+ * In case of WSREP_OK, starts commit critical section, transaction can
+ * commit. Otherwise transaction must rollback.
+ *
+ * @param wsrep provider handle
+ * @param ws_handle writeset of committing transaction
+ * @param conn_id connection ID
+ * @param flags fine tuning the replication WSREP_FLAG_*
+ * @param meta transaction meta data
+ *
+ * @retval WSREP_OK cluster-wide commit succeeded
+ * @retval WSREP_TRX_FAIL must rollback transaction
+ * @retval WSREP_CONN_FAIL must close client connection
+ * @retval WSREP_NODE_FAIL must close all connections and reinit
+ */
+ wsrep_status_t (*pre_commit)(wsrep_t* wsrep,
+ wsrep_conn_id_t conn_id,
+ wsrep_ws_handle_t* ws_handle,
+ uint64_t flags,
+ wsrep_trx_meta_t* meta);
+
+ /*!
+ * @brief Releases resources after transaction commit.
+ *
+ * Ends commit critical section.
+ *
+ * @param wsrep provider handle
+ * @param ws_handle writeset of committing transaction
+ * @retval WSREP_OK post_commit succeeded
+ */
+ wsrep_status_t (*post_commit) (wsrep_t* wsrep,
+ wsrep_ws_handle_t* ws_handle);
+
+ /*!
+ * @brief Releases resources after transaction rollback.
+ *
+ * @param wsrep provider handle
+ * @param ws_handle writeset of committing transaction
+ * @retval WSREP_OK post_rollback succeeded
+ */
+ wsrep_status_t (*post_rollback)(wsrep_t* wsrep,
+ wsrep_ws_handle_t* ws_handle);
+
+ /*!
+ * @brief Replay trx as a slave writeset
+ *
+ * If local trx has been aborted by brute force, and it has already
+ * replicated before this abort, we must try if we can apply it as
+ * slave trx. Note that slave nodes see only trx writesets and certification
+ * test based on write set content can be different to DBMS lock conflicts.
+ *
+ * @param wsrep provider handle
+ * @param ws_handle writeset of committing transaction
+ * @param trx_ctx transaction context
+ *
+ * @retval WSREP_OK cluster commit succeeded
+ * @retval WSREP_TRX_FAIL must rollback transaction
+ * @retval WSREP_BF_ABORT brute force abort happened after trx replicated
+ * must rollback transaction and try to replay
+ * @retval WSREP_CONN_FAIL must close client connection
+ * @retval WSREP_NODE_FAIL must close all connections and reinit
+ */
+ wsrep_status_t (*replay_trx)(wsrep_t* wsrep,
+ wsrep_ws_handle_t* ws_handle,
+ void* trx_ctx);
+
+ /*!
+ * @brief Abort pre_commit() call of another thread.
+ *
+ * It is possible, that some high-priority transaction needs to abort
+ * another transaction which is in pre_commit() call waiting for resources.
+ *
+ * The kill routine checks that abort is not attmpted against a transaction
+ * which is front of the caller (in total order).
+ *
+ * @param wsrep provider handle
+ * @param bf_seqno seqno of brute force trx, running this cancel
+ * @param victim_trx transaction to be aborted, and which is committing
+ *
+ * @retval WSREP_OK abort secceded
+ * @retval WSREP_WARNING abort failed
+ */
+ wsrep_status_t (*abort_pre_commit)(wsrep_t* wsrep,
+ wsrep_seqno_t bf_seqno,
+ wsrep_trx_id_t victim_trx);
+
+ /*!
+ * @brief Appends a row reference to transaction writeset
+ *
+ * Both copy flag and key_type can be ignored by provider (key type
+ * interpreted as WSREP_KEY_EXCLUSIVE).
+ *
+ * @param wsrep provider handle
+ * @param ws_handle writeset handle
+ * @param keys array of keys
+ * @param count length of the array of keys
+ * @param type type ot the key
+ * @param copy can be set to FALSE if keys persist through commit.
+ */
+ wsrep_status_t (*append_key)(wsrep_t* wsrep,
+ wsrep_ws_handle_t* ws_handle,
+ const wsrep_key_t* keys,
+ size_t count,
+ enum wsrep_key_type type,
+ wsrep_bool_t copy);
+
+ /*!
+ * @brief Appends data to transaction writeset
+ *
+ * This method can be called any time before commit and it
+ * appends a number of data buffers to transaction writeset.
+ *
+ * Both copy and unordered flags can be ignored by provider.
+ *
+ * @param wsrep provider handle
+ * @param ws_handle writeset handle
+ * @param data array of data buffers
+ * @param count buffer count
+ * @param type type of data
+ * @param copy can be set to FALSE if data persists through commit.
+ */
+ wsrep_status_t (*append_data)(wsrep_t* wsrep,
+ wsrep_ws_handle_t* ws_handle,
+ const struct wsrep_buf* data,
+ size_t count,
+ enum wsrep_data_type type,
+ wsrep_bool_t copy);
+
+ /*!
+ * @brief Get causal ordering for read operation
+ *
+ * This call will block until causal ordering with all possible
+ * preceding writes in the cluster is guaranteed. If pointer to
+ * gtid is non-null, the call stores the global transaction ID
+ * of the last transaction which is guaranteed to be ordered
+ * causally before this call.
+ *
+ * @param wsrep provider handle
+ * @param gtid location to store GTID
+ */
+ wsrep_status_t (*causal_read)(wsrep_t* wsrep, wsrep_gtid_t* gtid);
+
+ /*!
+ * @brief Clears allocated connection context.
+ *
+ * Whenever a new connection ID is passed to wsrep provider through
+ * any of the API calls, a connection context is allocated for this
+ * connection. This call is to explicitly notify provider fo connection
+ * closing.
+ *
+ * @param wsrep provider handle
+ * @param conn_id connection ID
+ * @param query the 'set database' query
+ * @param query_len length of query (does not end with 0)
+ */
+ wsrep_status_t (*free_connection)(wsrep_t* wsrep,
+ wsrep_conn_id_t conn_id);
+
+ /*!
+ * @brief Replicates a query and starts "total order isolation" section.
+ *
+ * Replicates the action spec and returns success code, which caller must
+ * check. Total order isolation continues until to_execute_end() is called.
+ *
+ * @param wsrep provider handle
+ * @param conn_id connection ID
+ * @param keys array of keys
+ * @param keys_num lenght of the array of keys
+ * @param action action buffer array to be executed
+ * @param count action buffer count
+ * @param meta transaction meta data
+ *
+ * @retval WSREP_OK cluster commit succeeded
+ * @retval WSREP_CONN_FAIL must close client connection
+ * @retval WSREP_NODE_FAIL must close all connections and reinit
+ */
+ wsrep_status_t (*to_execute_start)(wsrep_t* wsrep,
+ wsrep_conn_id_t conn_id,
+ const wsrep_key_t* keys,
+ size_t keys_num,
+ const struct wsrep_buf* action,
+ size_t count,
+ wsrep_trx_meta_t* meta);
+
+ /*!
+ * @brief Ends the total order isolation section.
+ *
+ * Marks the end of total order isolation. TO locks are freed
+ * and other transactions are free to commit from this point on.
+ *
+ * @param wsrep provider handle
+ * @param conn_id connection ID
+ *
+ * @retval WSREP_OK cluster commit succeeded
+ * @retval WSREP_CONN_FAIL must close client connection
+ * @retval WSREP_NODE_FAIL must close all connections and reinit
+ */
+ wsrep_status_t (*to_execute_end)(wsrep_t* wsrep, wsrep_conn_id_t conn_id);
+
+ /*!
+ * @brief Collects preordered replication events into a writeset.
+ *
+ * @param wsrep wsrep provider handle
+ * @param handle a handle associated with a given writeset
+ * @param data an array of data buffers.
+ * @param count length of data buffer array.
+ * @param copy whether provider needs to make a copy of events.
+ *
+ * @retval WSREP_OK cluster-wide commit succeeded
+ * @retval WSREP_TRX_FAIL operation failed (e.g. trx size exceeded limit)
+ * @retval WSREP_NODE_FAIL must close all connections and reinit
+ */
+ wsrep_status_t (*preordered_collect) (wsrep_t* wsrep,
+ wsrep_po_handle_t* handle,
+ const struct wsrep_buf* data,
+ size_t count,
+ wsrep_bool_t copy);
+
+ /*!
+ * @brief "Commits" preordered writeset to cluster.
+ *
+ * The contract is that the writeset will be committed in the same (partial)
+ * order this method was called. Frees resources associated with the writeset
+ * handle and reinitializes the handle.
+ *
+ * @param wsrep wsrep provider handle
+ * @param po_handle a handle associated with a given writeset
+ * @param source_id ID of the event producer, also serves as the partial order
+ * or stream ID - events with different source_ids won't be
+ * ordered with respect to each other.
+ * @param flags WSREP_FLAG_... flags
+ * @param pa_range the number of preceding events this event can be processed
+ * in parallel with. A value of 0 means strict serial
+ * processing. Note: commits always happen in wsrep order.
+ * @param commit 'true' to commit writeset to cluster (replicate) or
+ * 'false' to rollback (cancel) the writeset.
+ *
+ * @retval WSREP_OK cluster-wide commit succeeded
+ * @retval WSREP_TRX_FAIL operation failed (e.g. NON-PRIMARY component)
+ * @retval WSREP_NODE_FAIL must close all connections and reinit
+ */
+ wsrep_status_t (*preordered_commit) (wsrep_t* wsrep,
+ wsrep_po_handle_t* handle,
+ const wsrep_uuid_t* source_id,
+ uint64_t flags,
+ int pa_range,
+ wsrep_bool_t commit);
+
+ /*!
+ * @brief Signals to wsrep provider that state snapshot has been sent to
+ * joiner.
+ *
+ * @param wsrep provider handle
+ * @param state_id state ID
+ * @param rcode 0 or negative error code of the operation.
+ */
+ wsrep_status_t (*sst_sent)(wsrep_t* wsrep,
+ const wsrep_gtid_t* state_id,
+ int rcode);
+
+ /*!
+ * @brief Signals to wsrep provider that new state snapshot has been received.
+ * May deadlock if called from sst_prepare_cb.
+ *
+ * @param wsrep provider handle
+ * @param state_id state ID
+ * @param state initial state provided by SST donor
+ * @param state_len length of state buffer
+ * @param rcode 0 or negative error code of the operation.
+ */
+ wsrep_status_t (*sst_received)(wsrep_t* wsrep,
+ const wsrep_gtid_t* state_id,
+ const void* state,
+ size_t state_len,
+ int rcode);
+
+
+ /*!
+ * @brief Generate request for consistent snapshot.
+ *
+ * If successfull, this call will generate internally SST request
+ * which in turn triggers calling SST donate callback on the nodes
+ * specified in donor_spec. If donor_spec is null, callback is
+ * called only locally. This call will block until sst_sent is called
+ * from callback.
+ *
+ * @param wsrep provider handle
+ * @param msg context message for SST donate callback
+ * @param msg_len length of context message
+ * @param donor_spec list of snapshot donors
+ */
+ wsrep_status_t (*snapshot)(wsrep_t* wsrep,
+ const void* msg,
+ size_t msg_len,
+ const char* donor_spec);
+
+ /*!
+ * @brief Returns an array fo status variables.
+ * Array is terminated by Null variable name.
+ *
+ * @param wsrep provider handle
+ * @return array of struct wsrep_status_var.
+ */
+ struct wsrep_stats_var* (*stats_get) (wsrep_t* wsrep);
+
+ /*!
+ * @brief Release resources that might be associated with the array.
+ *
+ * @param wsrep provider handle.
+ * @param var_array array returned by stats_get().
+ */
+ void (*stats_free) (wsrep_t* wsrep, struct wsrep_stats_var* var_array);
+
+ /*!
+ * @brief Reset some stats variables to inital value, provider-dependent.
+ *
+ * @param wsrep provider handle.
+ */
+ void (*stats_reset) (wsrep_t* wsrep);
+
+ /*!
+ * @brief Pauses writeset applying/committing.
+ *
+ * @return global sequence number of the paused state or negative error code.
+ */
+ wsrep_seqno_t (*pause) (wsrep_t* wsrep);
+
+ /*!
+ * @brief Resumes writeset applying/committing.
+ */
+ wsrep_status_t (*resume) (wsrep_t* wsrep);
+
+ /*!
+ * @brief Desynchronize from cluster
+ *
+ * Effectively turns off flow control for this node, allowing it
+ * to fall behind the cluster.
+ */
+ wsrep_status_t (*desync) (wsrep_t* wsrep);
+
+ /*!
+ * @brief Request to resynchronize with cluster.
+ *
+ * Effectively turns on flow control. Asynchronous - actual synchronization
+ * event to be deliverred via sync_cb.
+ */
+ wsrep_status_t (*resync) (wsrep_t* wsrep);
+
+ /*!
+ * @brief Acquire global named lock
+ *
+ * @param wsrep wsrep provider handle
+ * @param name lock name
+ * @param shared shared or exclusive lock
+ * @param owner 64-bit owner ID
+ * @param tout timeout in nanoseconds.
+ * 0 - return immediately, -1 wait forever.
+ * @return wsrep status or negative error code
+ * @retval -EDEADLK lock was already acquired by this thread
+ * @retval -EBUSY lock was busy
+ */
+ wsrep_status_t (*lock) (wsrep_t* wsrep,
+ const char* name, wsrep_bool_t shared,
+ uint64_t owner, int64_t tout);
+
+ /*!
+ * @brief Release global named lock
+ *
+ * @param wsrep wsrep provider handle
+ * @param name lock name
+ * @param owner 64-bit owner ID
+ * @return wsrep status or negative error code
+ * @retval -EPERM lock does not belong to this owner
+ */
+ wsrep_status_t (*unlock) (wsrep_t* wsrep, const char* name, uint64_t owner);
+
+ /*!
+ * @brief Check if global named lock is locked
+ *
+ * @param wsrep wsrep provider handle
+ * @param name lock name
+ * @param owner if not NULL will contain 64-bit owner ID
+ * @param node if not NULL will contain owner's node UUID
+ * @return true if lock is locked
+ */
+ wsrep_bool_t (*is_locked) (wsrep_t* wsrep, const char* name, uint64_t* conn,
+ wsrep_uuid_t* node);
+
+ /*!
+ * wsrep provider name
+ */
+ const char* provider_name;
+
+ /*!
+ * wsrep provider version
+ */
+ const char* provider_version;
+
+ /*!
+ * wsrep provider vendor name
+ */
+ const char* provider_vendor;
+
+ /*!
+ * @brief Frees allocated resources before unloading the library.
+ * @param wsrep provider handle
+ */
+ void (*free)(wsrep_t* wsrep);
+
+ void *dlh; //!< reserved for future use
+ void *ctx; //!< reserved for implemetation private context
+};
+
+
+/*!
+ *
+ * @brief Loads wsrep library
+ *
+ * @param spec path to wsrep library. If NULL or WSREP_NONE initialises dummy
+ * pass-through implementation.
+ * @param hptr wsrep handle
+ * @param log_cb callback to handle loader messages. Otherwise writes to stderr.
+ *
+ * @return zero on success, errno on failure
+ */
+int wsrep_load(const char* spec, wsrep_t** hptr, wsrep_log_cb_t log_cb);
+
+/*!
+ * @brief Unloads wsrep library and frees associated resources
+ *
+ * @param hptr wsrep handler pointer
+ */
+void wsrep_unload(wsrep_t* hptr);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* WSREP_H */
diff --git a/wsrep.moved/wsrep_dummy.c b/wsrep.moved/wsrep_dummy.c
new file mode 100644
index 00000000000..33b61e6821f
--- /dev/null
+++ b/wsrep.moved/wsrep_dummy.c
@@ -0,0 +1,383 @@
+/* Copyright (C) 2009-2010 Codership Oy <info@codersihp.com>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*! @file Dummy wsrep API implementation. */
+
+#include "wsrep_api.h"
+
+#include <errno.h>
+#include <stdbool.h>
+
+/*! Dummy backend context. */
+typedef struct wsrep_dummy
+{
+ wsrep_log_cb_t log_fn;
+} wsrep_dummy_t;
+
+/* Get pointer to wsrep_dummy context from wsrep_t pointer */
+#define WSREP_DUMMY(_p) ((wsrep_dummy_t *) (_p)->ctx)
+
+/* Trace function usage a-la DBUG */
+#define WSREP_DBUG_ENTER(_w) do { \
+ if (WSREP_DUMMY(_w)) { \
+ if (WSREP_DUMMY(_w)->log_fn) \
+ WSREP_DUMMY(_w)->log_fn(WSREP_LOG_DEBUG, __FUNCTION__); \
+ } \
+ } while (0)
+
+
+static void dummy_free(wsrep_t *w)
+{
+ WSREP_DBUG_ENTER(w);
+ free(w->ctx);
+ w->ctx = NULL;
+}
+
+static wsrep_status_t dummy_init (wsrep_t* w,
+ const struct wsrep_init_args* args)
+{
+ WSREP_DUMMY(w)->log_fn = args->logger_cb;
+ WSREP_DBUG_ENTER(w);
+ return WSREP_OK;
+}
+
+static uint64_t dummy_capabilities (wsrep_t* w __attribute__((unused)))
+{
+ return 0;
+}
+
+static wsrep_status_t dummy_options_set(
+ wsrep_t* w,
+ const char* conf __attribute__((unused)))
+{
+ WSREP_DBUG_ENTER(w);
+ return WSREP_OK;
+}
+
+static char* dummy_options_get (wsrep_t* w)
+{
+ WSREP_DBUG_ENTER(w);
+ return NULL;
+}
+
+static wsrep_status_t dummy_connect(
+ wsrep_t* w,
+ const char* name __attribute__((unused)),
+ const char* url __attribute__((unused)),
+ const char* donor __attribute__((unused)),
+ wsrep_bool_t bootstrap __attribute__((unused)))
+{
+ WSREP_DBUG_ENTER(w);
+ return WSREP_OK;
+}
+
+static wsrep_status_t dummy_disconnect(wsrep_t* w)
+{
+ WSREP_DBUG_ENTER(w);
+ return WSREP_OK;
+}
+
+static wsrep_status_t dummy_recv(wsrep_t* w,
+ void* recv_ctx __attribute__((unused)))
+{
+ WSREP_DBUG_ENTER(w);
+ return WSREP_OK;
+}
+
+static wsrep_status_t dummy_pre_commit(
+ wsrep_t* w,
+ const wsrep_conn_id_t conn_id __attribute__((unused)),
+ wsrep_ws_handle_t* ws_handle __attribute__((unused)),
+// const struct wsrep_buf* data __attribute__((unused)),
+// const long count __attribute__((unused)),
+ uint64_t flags __attribute__((unused)),
+ wsrep_trx_meta_t* meta __attribute__((unused)))
+{
+ WSREP_DBUG_ENTER(w);
+ return WSREP_OK;
+}
+
+static wsrep_status_t dummy_post_commit(
+ wsrep_t* w,
+ wsrep_ws_handle_t* ws_handle __attribute__((unused)))
+{
+ WSREP_DBUG_ENTER(w);
+ return WSREP_OK;
+}
+
+static wsrep_status_t dummy_post_rollback(
+ wsrep_t* w,
+ wsrep_ws_handle_t* ws_handle __attribute__((unused)))
+{
+ WSREP_DBUG_ENTER(w);
+ return WSREP_OK;
+}
+
+static wsrep_status_t dummy_replay_trx(
+ wsrep_t* w,
+ wsrep_ws_handle_t* ws_handle __attribute__((unused)),
+ void* trx_ctx __attribute__((unused)))
+{
+ WSREP_DBUG_ENTER(w);
+ return WSREP_OK;
+}
+
+static wsrep_status_t dummy_abort_pre_commit(
+ wsrep_t* w,
+ const wsrep_seqno_t bf_seqno __attribute__((unused)),
+ const wsrep_trx_id_t trx_id __attribute__((unused)))
+{
+ WSREP_DBUG_ENTER(w);
+ return WSREP_OK;
+}
+
+static wsrep_status_t dummy_append_key(
+ wsrep_t* w,
+ wsrep_ws_handle_t* ws_handle __attribute__((unused)),
+ const wsrep_key_t* key __attribute__((unused)),
+ const int key_num __attribute__((unused)),
+ const wsrep_key_type_t key_type __attribute__((unused)),
+ const bool copy __attribute__((unused)))
+{
+ WSREP_DBUG_ENTER(w);
+ return WSREP_OK;
+}
+
+static wsrep_status_t dummy_append_data(
+ wsrep_t* w,
+ wsrep_ws_handle_t* ws_handle __attribute__((unused)),
+ const struct wsrep_buf* data __attribute__((unused)),
+ const int count __attribute__((unused)),
+ const wsrep_data_type_t type __attribute__((unused)),
+ const bool copy __attribute__((unused)))
+{
+ WSREP_DBUG_ENTER(w);
+ return WSREP_OK;
+}
+
+static wsrep_status_t dummy_causal_read(
+ wsrep_t* w,
+ wsrep_gtid_t* gtid __attribute__((unused)))
+{
+ WSREP_DBUG_ENTER(w);
+ return WSREP_OK;
+}
+
+static wsrep_status_t dummy_free_connection(
+ wsrep_t* w,
+ const wsrep_conn_id_t conn_id __attribute__((unused)))
+{
+ WSREP_DBUG_ENTER(w);
+ return WSREP_OK;
+}
+
+static wsrep_status_t dummy_to_execute_start(
+ wsrep_t* w,
+ const wsrep_conn_id_t conn_id __attribute__((unused)),
+ const wsrep_key_t* key __attribute__((unused)),
+ const int key_num __attribute__((unused)),
+ const struct wsrep_buf* data __attribute__((unused)),
+ const int count __attribute__((unused)),
+ wsrep_trx_meta_t* meta __attribute__((unused)))
+{
+ WSREP_DBUG_ENTER(w);
+ return WSREP_OK;
+}
+
+static wsrep_status_t dummy_to_execute_end(
+ wsrep_t* w,
+ const wsrep_conn_id_t conn_id __attribute__((unused)))
+{
+ WSREP_DBUG_ENTER(w);
+ return WSREP_OK;
+}
+
+static wsrep_status_t dummy_preordered(
+ wsrep_t* w,
+ const wsrep_uuid_t* source_id __attribute__((unused)),
+ int pa_range __attribute__((unused)),
+ const struct wsrep_buf* data __attribute__((unused)),
+ int count __attribute__((unused)),
+ uint64_t flags __attribute__((unused)),
+ wsrep_bool_t copy __attribute__((unused)))
+{
+ WSREP_DBUG_ENTER(w);
+ return WSREP_OK;
+}
+
+static wsrep_status_t dummy_sst_sent(
+ wsrep_t* w,
+ const wsrep_uuid_t* uuid __attribute__((unused)),
+ wsrep_seqno_t seqno __attribute__((unused)))
+{
+ WSREP_DBUG_ENTER(w);
+ return WSREP_OK;
+}
+
+static wsrep_status_t dummy_sst_received(
+ wsrep_t* w,
+ const wsrep_uuid_t* uuid __attribute__((unused)),
+ const wsrep_seqno_t seqno __attribute__((unused)),
+ const char* state __attribute__((unused)),
+ const size_t state_len __attribute__((unused)))
+{
+ WSREP_DBUG_ENTER(w);
+ return WSREP_OK;
+}
+
+static wsrep_status_t dummy_snapshot(
+ wsrep_t* w,
+ const void* msg __attribute__((unused)),
+ const int msg_len __attribute__((unused)),
+ const char* donor_spec __attribute__((unused)))
+{
+ WSREP_DBUG_ENTER(w);
+ return WSREP_OK;
+}
+
+static struct wsrep_stats_var dummy_stats[] = {
+ { NULL, WSREP_VAR_STRING, { 0 } }
+};
+
+static struct wsrep_stats_var* dummy_stats_get (wsrep_t* w)
+{
+ WSREP_DBUG_ENTER(w);
+ return dummy_stats;
+}
+
+static void dummy_stats_free (
+ wsrep_t* w,
+ struct wsrep_stats_var* stats __attribute__((unused)))
+{
+ WSREP_DBUG_ENTER(w);
+}
+
+static void dummy_stats_reset (wsrep_t* w)
+{
+ WSREP_DBUG_ENTER(w);
+}
+
+static wsrep_seqno_t dummy_pause (wsrep_t* w)
+{
+ WSREP_DBUG_ENTER(w);
+ return -ENOSYS;
+}
+
+static wsrep_status_t dummy_resume (wsrep_t* w)
+{
+ WSREP_DBUG_ENTER(w);
+ return WSREP_OK;
+}
+
+static wsrep_status_t dummy_desync (wsrep_t* w)
+{
+ WSREP_DBUG_ENTER(w);
+ return WSREP_NOT_IMPLEMENTED;
+}
+
+static wsrep_status_t dummy_resync (wsrep_t* w)
+{
+ WSREP_DBUG_ENTER(w);
+ return WSREP_OK;
+}
+
+static wsrep_status_t dummy_lock (wsrep_t* w,
+ const char* s __attribute__((unused)),
+ bool r __attribute__((unused)),
+ uint64_t o __attribute__((unused)),
+ int64_t t __attribute__((unused)))
+{
+ WSREP_DBUG_ENTER(w);
+ return WSREP_NOT_IMPLEMENTED;
+}
+
+static wsrep_status_t dummy_unlock (wsrep_t* w,
+ const char* s __attribute__((unused)),
+ uint64_t o __attribute__((unused)))
+{
+ WSREP_DBUG_ENTER(w);
+ return WSREP_OK;
+}
+
+static bool dummy_is_locked (wsrep_t* w,
+ const char* s __attribute__((unused)),
+ uint64_t* o __attribute__((unused)),
+ wsrep_uuid_t* t __attribute__((unused)))
+{
+ WSREP_DBUG_ENTER(w);
+ return false;
+}
+
+static wsrep_t dummy_iface = {
+ WSREP_INTERFACE_VERSION,
+ &dummy_init,
+ &dummy_capabilities,
+ &dummy_options_set,
+ &dummy_options_get,
+ &dummy_connect,
+ &dummy_disconnect,
+ &dummy_recv,
+ &dummy_pre_commit,
+ &dummy_post_commit,
+ &dummy_post_rollback,
+ &dummy_replay_trx,
+ &dummy_abort_pre_commit,
+ &dummy_append_key,
+ &dummy_append_data,
+ &dummy_causal_read,
+ &dummy_free_connection,
+ &dummy_to_execute_start,
+ &dummy_to_execute_end,
+ &dummy_preordered,
+ &dummy_sst_sent,
+ &dummy_sst_received,
+ &dummy_snapshot,
+ &dummy_stats_get,
+ &dummy_stats_free,
+ &dummy_stats_reset,
+ &dummy_pause,
+ &dummy_resume,
+ &dummy_desync,
+ &dummy_resync,
+ &dummy_lock,
+ &dummy_unlock,
+ &dummy_is_locked,
+ WSREP_NONE,
+ WSREP_INTERFACE_VERSION,
+ "Codership Oy <info@codership.com>",
+ 0xdeadbeef,
+ &dummy_free,
+ NULL,
+ NULL
+};
+
+int wsrep_dummy_loader(wsrep_t* w)
+{
+ if (!w)
+ return EINVAL;
+
+ *w = dummy_iface;
+
+ // allocate private context
+ if (!(w->ctx = malloc(sizeof(wsrep_dummy_t))))
+ return ENOMEM;
+
+ // initialize private context
+ WSREP_DUMMY(w)->log_fn = NULL;
+
+ return 0;
+}
+
diff --git a/wsrep/wsrep_loader.c b/wsrep.moved/wsrep_loader.c
index 8ae6ea962ec..8ae6ea962ec 100644
--- a/wsrep/wsrep_loader.c
+++ b/wsrep.moved/wsrep_loader.c
diff --git a/wsrep/wsrep_uuid.c b/wsrep.moved/wsrep_uuid.c
index baa95b2578a..baa95b2578a 100644
--- a/wsrep/wsrep_uuid.c
+++ b/wsrep.moved/wsrep_uuid.c
diff --git a/wsrep/wsrep_api.h b/wsrep/wsrep_api.h
index 987a47db578..f713de66d57 100644
--- a/wsrep/wsrep_api.h
+++ b/wsrep/wsrep_api.h
@@ -63,7 +63,7 @@ extern "C" {
* *
**************************************************************************/
-#define WSREP_INTERFACE_VERSION "24"
+#define WSREP_INTERFACE_VERSION "25"
/*! Empty backend spec */
#define WSREP_NONE "none"
@@ -118,8 +118,8 @@ typedef void (*wsrep_log_cb_t)(wsrep_log_level_t, const char *);
*
* COMMIT the writeset and all preceding writesets must be committed
* ROLLBACK all preceding writesets in a transaction must be rolled back
- * PA_UNSAFE the writeset cannot be applied in parallel
* ISOLATION the writeset must be applied AND committed in isolation
+ * PA_UNSAFE the writeset cannot be applied in parallel
* COMMUTATIVE the order in which the writeset is applied does not matter
* NATIVE the writeset contains another writeset in this provider format
*
@@ -128,8 +128,8 @@ typedef void (*wsrep_log_cb_t)(wsrep_log_level_t, const char *);
*/
#define WSREP_FLAG_COMMIT ( 1ULL << 0 )
#define WSREP_FLAG_ROLLBACK ( 1ULL << 1 )
-#define WSREP_FLAG_PA_UNSAFE ( 1ULL << 3 )
#define WSREP_FLAG_ISOLATION ( 1ULL << 2 )
+#define WSREP_FLAG_PA_UNSAFE ( 1ULL << 3 )
#define WSREP_FLAG_COMMUTATIVE ( 1ULL << 4 )
#define WSREP_FLAG_NATIVE ( 1ULL << 5 )
@@ -349,6 +349,7 @@ typedef enum wsrep_cb_status (*wsrep_view_cb_t) (
* @param recv_ctx receiver context pointer provided by the application
* @param data data buffer containing the writeset
* @param size data buffer size
+ * @param flags WSREP_FLAG_... flags
* @param meta transaction meta data of the writeset to be applied
*
* @return success code:
@@ -360,6 +361,7 @@ typedef enum wsrep_cb_status (*wsrep_apply_cb_t) (
void* recv_ctx,
const void* data,
size_t size,
+ uint32_t flags,
const wsrep_trx_meta_t* meta
);
@@ -370,6 +372,7 @@ typedef enum wsrep_cb_status (*wsrep_apply_cb_t) (
* This handler is called to commit the changes made by apply callback.
*
* @param recv_ctx receiver context pointer provided by the application
+ * @param flags WSREP_FLAG_... flags
* @param meta transaction meta data of the writeset to be committed
* @param exit set to true to exit recv loop
* @param commit true - commit writeset, false - rollback writeset
@@ -380,6 +383,7 @@ typedef enum wsrep_cb_status (*wsrep_apply_cb_t) (
*/
typedef enum wsrep_cb_status (*wsrep_commit_cb_t) (
void* recv_ctx,
+ uint32_t flags,
const wsrep_trx_meta_t* meta,
wsrep_bool_t* exit,
wsrep_bool_t commit
@@ -687,7 +691,7 @@ struct wsrep {
wsrep_status_t (*pre_commit)(wsrep_t* wsrep,
wsrep_conn_id_t conn_id,
wsrep_ws_handle_t* ws_handle,
- uint64_t flags,
+ uint32_t flags,
wsrep_trx_meta_t* meta);
/*!
@@ -913,7 +917,7 @@ struct wsrep {
wsrep_status_t (*preordered_commit) (wsrep_t* wsrep,
wsrep_po_handle_t* handle,
const wsrep_uuid_t* source_id,
- uint64_t flags,
+ uint32_t flags,
int pa_range,
wsrep_bool_t commit);
diff --git a/wsrep/wsrep_dummy.c b/wsrep/wsrep_dummy.c
index 33b61e6821f..3c7a7c2e354 100644
--- a/wsrep/wsrep_dummy.c
+++ b/wsrep/wsrep_dummy.c
@@ -101,9 +101,7 @@ static wsrep_status_t dummy_pre_commit(
wsrep_t* w,
const wsrep_conn_id_t conn_id __attribute__((unused)),
wsrep_ws_handle_t* ws_handle __attribute__((unused)),
-// const struct wsrep_buf* data __attribute__((unused)),
-// const long count __attribute__((unused)),
- uint64_t flags __attribute__((unused)),
+ uint32_t flags __attribute__((unused)),
wsrep_trx_meta_t* meta __attribute__((unused)))
{
WSREP_DBUG_ENTER(w);
@@ -148,7 +146,7 @@ static wsrep_status_t dummy_append_key(
wsrep_t* w,
wsrep_ws_handle_t* ws_handle __attribute__((unused)),
const wsrep_key_t* key __attribute__((unused)),
- const int key_num __attribute__((unused)),
+ const size_t key_num __attribute__((unused)),
const wsrep_key_type_t key_type __attribute__((unused)),
const bool copy __attribute__((unused)))
{
@@ -160,7 +158,7 @@ static wsrep_status_t dummy_append_data(
wsrep_t* w,
wsrep_ws_handle_t* ws_handle __attribute__((unused)),
const struct wsrep_buf* data __attribute__((unused)),
- const int count __attribute__((unused)),
+ const size_t count __attribute__((unused)),
const wsrep_data_type_t type __attribute__((unused)),
const bool copy __attribute__((unused)))
{
@@ -188,9 +186,9 @@ static wsrep_status_t dummy_to_execute_start(
wsrep_t* w,
const wsrep_conn_id_t conn_id __attribute__((unused)),
const wsrep_key_t* key __attribute__((unused)),
- const int key_num __attribute__((unused)),
+ const size_t key_num __attribute__((unused)),
const struct wsrep_buf* data __attribute__((unused)),
- const int count __attribute__((unused)),
+ const size_t count __attribute__((unused)),
wsrep_trx_meta_t* meta __attribute__((unused)))
{
WSREP_DBUG_ENTER(w);
@@ -205,14 +203,24 @@ static wsrep_status_t dummy_to_execute_end(
return WSREP_OK;
}
-static wsrep_status_t dummy_preordered(
- wsrep_t* w,
- const wsrep_uuid_t* source_id __attribute__((unused)),
- int pa_range __attribute__((unused)),
- const struct wsrep_buf* data __attribute__((unused)),
- int count __attribute__((unused)),
- uint64_t flags __attribute__((unused)),
- wsrep_bool_t copy __attribute__((unused)))
+static wsrep_status_t dummy_preordered_collect(
+ wsrep_t* w,
+ wsrep_po_handle_t* handle __attribute__((unused)),
+ const struct wsrep_buf* data __attribute__((unused)),
+ size_t count __attribute__((unused)),
+ wsrep_bool_t copy __attribute__((unused)))
+{
+ WSREP_DBUG_ENTER(w);
+ return WSREP_OK;
+}
+
+static wsrep_status_t dummy_preordered_commit(
+ wsrep_t* w,
+ wsrep_po_handle_t* handle __attribute__((unused)),
+ const wsrep_uuid_t* source_id __attribute__((unused)),
+ uint32_t flags __attribute__((unused)),
+ int pa_range __attribute__((unused)),
+ wsrep_bool_t commit __attribute__((unused)))
{
WSREP_DBUG_ENTER(w);
return WSREP_OK;
@@ -220,8 +228,8 @@ static wsrep_status_t dummy_preordered(
static wsrep_status_t dummy_sst_sent(
wsrep_t* w,
- const wsrep_uuid_t* uuid __attribute__((unused)),
- wsrep_seqno_t seqno __attribute__((unused)))
+ const wsrep_gtid_t* state_id __attribute__((unused)),
+ const int rcode __attribute__((unused)))
{
WSREP_DBUG_ENTER(w);
return WSREP_OK;
@@ -229,10 +237,10 @@ static wsrep_status_t dummy_sst_sent(
static wsrep_status_t dummy_sst_received(
wsrep_t* w,
- const wsrep_uuid_t* uuid __attribute__((unused)),
- const wsrep_seqno_t seqno __attribute__((unused)),
- const char* state __attribute__((unused)),
- const size_t state_len __attribute__((unused)))
+ const wsrep_gtid_t* state_id __attribute__((unused)),
+ const void* state __attribute__((unused)),
+ const size_t state_len __attribute__((unused)),
+ const int rcode __attribute__((unused)))
{
WSREP_DBUG_ENTER(w);
return WSREP_OK;
@@ -241,7 +249,7 @@ static wsrep_status_t dummy_sst_received(
static wsrep_status_t dummy_snapshot(
wsrep_t* w,
const void* msg __attribute__((unused)),
- const int msg_len __attribute__((unused)),
+ const size_t msg_len __attribute__((unused)),
const char* donor_spec __attribute__((unused)))
{
WSREP_DBUG_ENTER(w);
@@ -341,7 +349,8 @@ static wsrep_t dummy_iface = {
&dummy_free_connection,
&dummy_to_execute_start,
&dummy_to_execute_end,
- &dummy_preordered,
+ &dummy_preordered_collect,
+ &dummy_preordered_commit,
&dummy_sst_sent,
&dummy_sst_received,
&dummy_snapshot,
@@ -358,7 +367,6 @@ static wsrep_t dummy_iface = {
WSREP_NONE,
WSREP_INTERFACE_VERSION,
"Codership Oy <info@codership.com>",
- 0xdeadbeef,
&dummy_free,
NULL,
NULL