summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sql/CMakeLists.txt3
-rw-r--r--sql/handler.cc5
-rw-r--r--sql/sql_parse.cc1
-rw-r--r--sql/wsrep_applier.cc9
-rw-r--r--sql/wsrep_applier.h3
-rw-r--r--sql/wsrep_hton.cc5
-rw-r--r--sql/wsrep_mysqld.cc104
-rw-r--r--sql/wsrep_mysqld.h12
-rw-r--r--sql/wsrep_priv.h12
-rw-r--r--sql/wsrep_sst.cc49
-rw-r--r--sql/wsrep_utils.cc57
-rw-r--r--sql/wsrep_var.cc38
-rw-r--r--sql/wsrep_xid.cc150
-rw-r--r--sql/wsrep_xid.h33
-rw-r--r--storage/innobase/include/ha_prototypes.h5
-rw-r--r--storage/xtradb/include/ha_prototypes.h5
16 files changed, 292 insertions, 199 deletions
diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt
index 26dfad83810..c28d475d274 100644
--- a/sql/CMakeLists.txt
+++ b/sql/CMakeLists.txt
@@ -44,12 +44,13 @@ ENDIF()
IF(WITH_WSREP)
SET(WSREP_SOURCES
+ wsrep_utils.cc
+ wsrep_xid.cc
wsrep_check_opts.cc
wsrep_hton.cc
wsrep_mysqld.cc
wsrep_notify.cc
wsrep_sst.cc
- wsrep_utils.cc
wsrep_var.cc
wsrep_binlog.cc
wsrep_applier.cc
diff --git a/sql/handler.cc b/sql/handler.cc
index 18cf61906a6..6a69af0b900 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -53,6 +53,7 @@
#ifdef WITH_WSREP
#include "wsrep_mysqld.h"
+#include "wsrep_xid.h"
#endif
/*
While we have legacy_db_type, we have this array to
@@ -1468,7 +1469,7 @@ int ha_commit_trans(THD *thd, bool all)
if (!error && wsrep_is_wsrep_xid(&thd->transaction.xid_state.xid))
{
// xid was rewritten by wsrep
- xid= wsrep_xid_seqno(&thd->transaction.xid_state.xid);
+ xid= wsrep_xid_seqno(thd->transaction.xid_state.xid);
}
#endif // WITH_WSREP
if (!is_real_trans)
@@ -1851,7 +1852,7 @@ static my_bool xarecover_handlerton(THD *unused, plugin_ref plugin,
{
#ifdef WITH_WSREP
my_xid x=(wsrep_is_wsrep_xid(&info->list[i]) ?
- wsrep_xid_seqno(&info->list[i]) :
+ wsrep_xid_seqno(info->list[i]) :
info->list[i].get_my_xid());
#else
my_xid x=info->list[i].get_my_xid();
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 29e9a9e7da9..a67674448c7 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -106,6 +106,7 @@
#ifdef WITH_WSREP
#include "wsrep_mysqld.h"
#include "wsrep_thd.h"
+#include "wsrep_binlog.h"
static void wsrep_mysql_parse(THD *thd, char *rawbuf, uint length,
Parser_state *parser_state);
#endif /* WITH_WSREP */
diff --git a/sql/wsrep_applier.cc b/sql/wsrep_applier.cc
index 8e5c49332a7..9fdc3952f3f 100644
--- a/sql/wsrep_applier.cc
+++ b/sql/wsrep_applier.cc
@@ -1,4 +1,4 @@
-/* Copyright (C) 2013 Codership Oy <info@codership.com>
+/* Copyright (C) 2013-2015 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
@@ -13,11 +13,12 @@
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */
+#include "wsrep_applier.h"
#include "wsrep_priv.h"
#include "wsrep_binlog.h" // wsrep_dump_rbr_buf()
+#include "wsrep_xid.h"
-#include "log_event.h" // EVENT_LEN_OFFSET, etc.
-#include "wsrep_applier.h"
+#include "log_event.h" // class THD, EVENT_LEN_OFFSET, etc.
/*
read the first event from (*buf). The size of the (*buf) is (*buf_len).
@@ -150,7 +151,7 @@ static wsrep_cb_status_t wsrep_apply_events(THD* thd,
thd->set_server_id(ev->server_id);
thd->set_time(); // time the query
wsrep_xid_init(&thd->transaction.xid_state.xid,
- &thd->wsrep_trx_meta.gtid.uuid,
+ thd->wsrep_trx_meta.gtid.uuid,
thd->wsrep_trx_meta.gtid.seqno);
thd->lex->current_select= 0;
if (!ev->when)
diff --git a/sql/wsrep_applier.h b/sql/wsrep_applier.h
index 816970db67c..424db466e53 100644
--- a/sql/wsrep_applier.h
+++ b/sql/wsrep_applier.h
@@ -16,7 +16,8 @@
#ifndef WSREP_APPLIER_H
#define WSREP_APPLIER_H
-#include <sys/types.h>
+#include <my_config.h>
+#include "../wsrep/wsrep_api.h"
/* wsrep callback prototypes */
diff --git a/sql/wsrep_hton.cc b/sql/wsrep_hton.cc
index 284c9d26d62..144196aab2e 100644
--- a/sql/wsrep_hton.cc
+++ b/sql/wsrep_hton.cc
@@ -1,4 +1,4 @@
-/* Copyright 2008 Codership Oy <http://www.codership.com>
+/* Copyright 2008-2015 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
@@ -19,6 +19,7 @@
#include <sql_class.h>
#include "wsrep_mysqld.h"
#include "wsrep_binlog.h"
+#include "wsrep_xid.h"
#include <cstdio>
#include <cstdlib>
@@ -497,7 +498,7 @@ wsrep_run_wsrep_commit(THD *thd, handlerton *hton, bool all)
if (thd->transaction.xid_state.xid.get_my_xid())
{
wsrep_xid_init(&thd->transaction.xid_state.xid,
- &thd->wsrep_trx_meta.gtid.uuid,
+ thd->wsrep_trx_meta.gtid.uuid,
thd->wsrep_trx_meta.gtid.seqno);
}
DBUG_PRINT("wsrep", ("replicating commit success"));
diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc
index 08698c6e9fa..7cfde65ebf1 100644
--- a/sql/wsrep_mysqld.cc
+++ b/sql/wsrep_mysqld.cc
@@ -1,4 +1,4 @@
-/* Copyright 2008-2013 Codership Oy <http://www.codership.com>
+/* Copyright 2008-2015 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
@@ -23,6 +23,7 @@
#include "wsrep_var.h"
#include "wsrep_binlog.h"
#include "wsrep_applier.h"
+#include "wsrep_xid.h"
#include <cstdio>
#include <cstdlib>
#include "log_event.h"
@@ -158,63 +159,22 @@ static void wsrep_log_states (wsrep_log_level_t const level,
wsrep_log_cb (level, msg);
}
-static my_bool set_SE_checkpoint(THD* unused, plugin_ref plugin, void* arg)
-{
- XID* xid= reinterpret_cast<XID*>(arg);
- handlerton* hton= plugin_data(plugin, handlerton *);
- if (hton->db_type == DB_TYPE_INNODB)
- {
- const wsrep_uuid_t* uuid(wsrep_xid_uuid(xid));
- char uuid_str[40] = {0, };
- wsrep_uuid_print(uuid, uuid_str, sizeof(uuid_str));
- WSREP_DEBUG("Set WSREPXid for InnoDB: %s:%lld",
- uuid_str, (long long)wsrep_xid_seqno(xid));
- hton->wsrep_set_checkpoint(hton, xid);
- }
- return FALSE;
-}
-
-void wsrep_set_SE_checkpoint(XID* xid)
-{
- plugin_foreach(NULL, set_SE_checkpoint, MYSQL_STORAGE_ENGINE_PLUGIN, xid);
-}
-
-static my_bool get_SE_checkpoint(THD* unused, plugin_ref plugin, void* arg)
-{
- XID* xid= reinterpret_cast<XID*>(arg);
- handlerton* hton= plugin_data(plugin, handlerton *);
- if (hton->db_type == DB_TYPE_INNODB)
- {
- hton->wsrep_get_checkpoint(hton, xid);
- const wsrep_uuid_t* uuid(wsrep_xid_uuid(xid));
- char uuid_str[40] = {0, };
- wsrep_uuid_print(uuid, uuid_str, sizeof(uuid_str));
- WSREP_DEBUG("Read WSREPXid from InnoDB: %s:%lld",
- uuid_str, (long long)wsrep_xid_seqno(xid));
-
- }
- return FALSE;
-}
-
-void wsrep_get_SE_checkpoint(XID* xid)
-{
- plugin_foreach(NULL, get_SE_checkpoint, MYSQL_STORAGE_ENGINE_PLUGIN, xid);
-}
-
#ifdef GTID_SUPPORT
-void wsrep_init_sidno(const wsrep_uuid_t& uuid)
+void wsrep_init_sidno(const wsrep_uuid_t& wsrep_uuid)
{
/* generate new Sid map entry from inverted uuid */
rpl_sid sid;
wsrep_uuid_t ltid_uuid;
+
for (size_t i= 0; i < sizeof(ltid_uuid.data); ++i)
{
- ltid_uuid.data[i] = ~local_uuid.data[i];
+ ltid_uuid.data[i] = ~wsrep_uuid.data[i];
}
+
sid.copy_from(ltid_uuid.data);
global_sid_lock->wrlock();
wsrep_sidno= global_sid_map->add_sid(sid);
- WSREP_INFO("inited wsrep sidno %d", wsrep_sidno);
+ WSREP_INFO("Initialized wsrep sidno %d", wsrep_sidno);
global_sid_lock->unlock();
}
#endif /* GTID_SUPPORT */
@@ -355,13 +315,11 @@ wsrep_view_handler_cb (void* app_ctx,
local_seqno= view->state_id.seqno;
}
/* Init storage engine XIDs from first view */
- XID xid;
- wsrep_xid_init(&xid, &local_uuid, local_seqno);
- wsrep_set_SE_checkpoint(&xid);
- new_status= WSREP_MEMBER_JOINED;
+ wsrep_set_SE_checkpoint(local_uuid, local_seqno);
#ifdef GTID_SUPPORT
wsrep_init_sidno(local_uuid);
#endif /* GTID_SUPPORT */
+ new_status= WSREP_MEMBER_JOINED;
}
// just some sanity check
@@ -471,38 +429,28 @@ static void wsrep_synced_cb(void* app_ctx)
static void wsrep_init_position()
{
/* read XIDs from storage engines */
- XID xid;
- memset(&xid, 0, sizeof(xid));
- xid.formatID= -1;
- wsrep_get_SE_checkpoint(&xid);
+ wsrep_uuid_t uuid;
+ wsrep_seqno_t seqno;
+ wsrep_get_SE_checkpoint(uuid, seqno);
- if (xid.formatID == -1)
+ if (!memcmp(&uuid, &WSREP_UUID_UNDEFINED, sizeof(wsrep_uuid_t)))
{
WSREP_INFO("Read nil XID from storage engines, skipping position init");
return;
}
- else if (!wsrep_is_wsrep_xid(&xid))
- {
- WSREP_WARN("Read non-wsrep XID from storage engines, skipping position init");
- return;
- }
-
- const wsrep_uuid_t* uuid= wsrep_xid_uuid(&xid);
- const wsrep_seqno_t seqno= wsrep_xid_seqno(&xid);
char uuid_str[40] = {0, };
- wsrep_uuid_print(uuid, uuid_str, sizeof(uuid_str));
+ wsrep_uuid_print(&uuid, uuid_str, sizeof(uuid_str));
WSREP_INFO("Initial position: %s:%lld", uuid_str, (long long)seqno);
-
if (!memcmp(&local_uuid, &WSREP_UUID_UNDEFINED, sizeof(local_uuid)) &&
local_seqno == WSREP_SEQNO_UNDEFINED)
{
// Initial state
- local_uuid= *uuid;
+ local_uuid= uuid;
local_seqno= seqno;
}
- else if (memcmp(&local_uuid, uuid, sizeof(local_uuid)) ||
+ else if (memcmp(&local_uuid, &uuid, sizeof(local_uuid)) ||
local_seqno != seqno)
{
WSREP_WARN("Initial position was provided by configuration or SST, "
@@ -758,14 +706,12 @@ void wsrep_recover()
uuid_str, (long long)local_seqno);
return;
}
- XID xid;
- memset(&xid, 0, sizeof(xid));
- xid.formatID= -1;
- wsrep_get_SE_checkpoint(&xid);
+ wsrep_uuid_t uuid;
+ wsrep_seqno_t seqno;
+ wsrep_get_SE_checkpoint(uuid, seqno);
char uuid_str[40];
- wsrep_uuid_print(wsrep_xid_uuid(&xid), uuid_str, sizeof(uuid_str));
- WSREP_INFO("Recovered position: %s:%lld", uuid_str,
- (long long)wsrep_xid_seqno(&xid));
+ wsrep_uuid_print(&uuid, uuid_str, sizeof(uuid_str));
+ WSREP_INFO("Recovered position: %s:%lld", uuid_str, (long long)seqno);
}
@@ -1324,11 +1270,9 @@ static void wsrep_TOI_end(THD *thd) {
WSREP_DEBUG("TO END: %lld, %d : %s", (long long)wsrep_thd_trx_seqno(thd),
thd->wsrep_exec_mode, (thd->query()) ? thd->query() : "void");
-
- XID xid;
- wsrep_xid_init(&xid, &thd->wsrep_trx_meta.gtid.uuid,
- thd->wsrep_trx_meta.gtid.seqno);
- wsrep_set_SE_checkpoint(&xid);
+
+ wsrep_set_SE_checkpoint(thd->wsrep_trx_meta.gtid.uuid,
+ thd->wsrep_trx_meta.gtid.seqno);
WSREP_DEBUG("TO END: %lld, update seqno",
(long long)wsrep_thd_trx_seqno(thd));
diff --git a/sql/wsrep_mysqld.h b/sql/wsrep_mysqld.h
index 4bd2489210a..79a16e5f8d1 100644
--- a/sql/wsrep_mysqld.h
+++ b/sql/wsrep_mysqld.h
@@ -1,4 +1,4 @@
-/* Copyright 2008-2013 Codership Oy <http://www.codership.com>
+/* Copyright 2008-2015 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
@@ -321,13 +321,7 @@ int wsrep_create_trigger_query(THD *thd, uchar** buf, size_t* buf_len);
int wsrep_create_event_query(THD *thd, uchar** buf, size_t* buf_len);
int wsrep_alter_event_query(THD *thd, uchar** buf, size_t* buf_len);
-struct xid_t;
-void wsrep_get_SE_checkpoint(xid_t*);
-void wsrep_set_SE_checkpoint(xid_t*);
+#ifdef GTID_SUPPORT
void wsrep_init_sidno(const wsrep_uuid_t&);
-void wsrep_xid_init(xid_t*, const wsrep_uuid_t*, wsrep_seqno_t);
-const wsrep_uuid_t* wsrep_xid_uuid(const xid_t*);
-wsrep_seqno_t wsrep_xid_seqno(const xid_t*);
-extern "C" int wsrep_is_wsrep_xid(const void* xid);
-
+#endif /* GTID_SUPPORT */
#endif /* WSREP_MYSQLD_H */
diff --git a/sql/wsrep_priv.h b/sql/wsrep_priv.h
index 5c66587d757..30dce78c1a4 100644
--- a/sql/wsrep_priv.h
+++ b/sql/wsrep_priv.h
@@ -32,22 +32,20 @@ ssize_t wsrep_sst_prepare (void** msg);
wsrep_cb_status wsrep_sst_donate_cb (void* app_ctx,
void* recv_ctx,
const void* msg, size_t msg_len,
- const wsrep_gtid_t* current_id,
+ const wsrep_gtid_t* state_id,
const char* state, size_t state_len,
bool bypass);
-extern unsigned int wsrep_check_ip (const char* addr);
-extern size_t wsrep_guess_ip (char* buf, size_t buf_len);
-extern size_t wsrep_guess_address(char* buf, size_t buf_len);
extern wsrep_uuid_t local_uuid;
extern wsrep_seqno_t local_seqno;
// a helper function
-extern void wsrep_sst_received(wsrep_t*, const wsrep_uuid_t*, wsrep_seqno_t,
- const void*, size_t);
+void wsrep_sst_received(wsrep_t*, const wsrep_uuid_t&, wsrep_seqno_t,
+ const void*, size_t);
/*! SST thread signals init thread about sst completion */
-extern void wsrep_sst_complete(const wsrep_uuid_t*, wsrep_seqno_t, bool);
+void wsrep_sst_complete(const wsrep_uuid_t*, wsrep_seqno_t, bool);
void wsrep_notify_status (wsrep_member_status_t new_status,
const wsrep_view_info_t* view = 0);
+
#endif /* WSREP_PRIV_H */
diff --git a/sql/wsrep_sst.cc b/sql/wsrep_sst.cc
index 0de4a474653..73fd9d9a0f5 100644
--- a/sql/wsrep_sst.cc
+++ b/sql/wsrep_sst.cc
@@ -1,4 +1,4 @@
-/* Copyright 2008-2012 Codership Oy <http://www.codership.com>
+/* Copyright 2008-2015 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
@@ -26,6 +26,7 @@
#include <sql_parse.h>
#include "wsrep_priv.h"
#include "wsrep_utils.h"
+#include "wsrep_xid.h"
#include <cstdio>
#include <cstdlib>
@@ -244,20 +245,42 @@ void wsrep_sst_complete (const wsrep_uuid_t* sst_uuid,
mysql_mutex_unlock (&LOCK_wsrep_sst);
}
-void wsrep_sst_received (wsrep_t* const wsrep,
- const wsrep_uuid_t* const uuid,
- wsrep_seqno_t const seqno,
- const void* const state,
- size_t const state_len)
+void wsrep_sst_received (wsrep_t* const wsrep,
+ const wsrep_uuid_t& uuid,
+ wsrep_seqno_t const seqno,
+ const void* const state,
+ size_t const state_len)
{
- int const rcode(seqno < 0 ? seqno : 0);
- wsrep_gtid_t const state_id = {
- *uuid, (rcode ? WSREP_SEQNO_UNDEFINED : seqno)
- };
+ wsrep_get_SE_checkpoint(local_uuid, local_seqno);
+
+ if (memcmp(&local_uuid, &uuid, sizeof(wsrep_uuid_t)) ||
+ local_seqno < seqno || seqno < 0)
+ {
+ wsrep_set_SE_checkpoint(uuid, seqno);
+ local_uuid = uuid;
+ local_seqno = seqno;
+ }
+ else if (local_seqno > seqno)
+ {
+ WSREP_WARN("SST postion is in the past: %lld, current: %lld. "
+ "Can't continue.",
+ (long long)seqno, (long long)local_seqno);
+ unireg_abort(1);
+ }
+
#ifdef GTID_SUPPORT
- wsrep_init_sidno(state_id.uuid);
+ wsrep_init_sidno(uuid);
#endif /* GTID_SUPPORT */
- wsrep->sst_received(wsrep, &state_id, state, state_len, rcode);
+
+ if (wsrep)
+ {
+ int const rcode(seqno < 0 ? seqno : 0);
+ wsrep_gtid_t const state_id = {
+ uuid, (rcode ? WSREP_SEQNO_UNDEFINED : seqno)
+ };
+
+ wsrep->sst_received(wsrep, &state_id, state, state_len, rcode);
+ }
}
// Let applier threads to continue
@@ -266,7 +289,7 @@ void wsrep_sst_continue ()
if (sst_needed)
{
WSREP_INFO("Signalling provider to continue.");
- wsrep_sst_received (wsrep, &local_uuid, local_seqno, NULL, 0);
+ wsrep_sst_received (wsrep, local_uuid, local_seqno, NULL, 0);
}
}
diff --git a/sql/wsrep_utils.cc b/sql/wsrep_utils.cc
index a62fc4ec2ed..7a87d38d430 100644
--- a/sql/wsrep_utils.cc
+++ b/sql/wsrep_utils.cc
@@ -1,4 +1,4 @@
-/* Copyright 2010 Codership Oy <http://www.codership.com>
+/* Copyright 2010-2015 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
@@ -467,58 +467,3 @@ size_t wsrep_guess_ip (char* buf, size_t buf_len)
return 0;
}
-
-/*
- * WSREPXid
- */
-
-#define WSREP_XID_PREFIX "WSREPXid"
-#define WSREP_XID_PREFIX_LEN MYSQL_XID_PREFIX_LEN
-#define WSREP_XID_UUID_OFFSET 8
-#define WSREP_XID_SEQNO_OFFSET (WSREP_XID_UUID_OFFSET + sizeof(wsrep_uuid_t))
-#define WSREP_XID_GTRID_LEN (WSREP_XID_SEQNO_OFFSET + sizeof(wsrep_seqno_t))
-
-void wsrep_xid_init(XID* xid, const wsrep_uuid_t* uuid, wsrep_seqno_t seqno)
-{
- xid->formatID= 1;
- xid->gtrid_length= WSREP_XID_GTRID_LEN;
- xid->bqual_length= 0;
- memset(xid->data, 0, sizeof(xid->data));
- memcpy(xid->data, WSREP_XID_PREFIX, WSREP_XID_PREFIX_LEN);
- memcpy(xid->data + WSREP_XID_UUID_OFFSET, uuid, sizeof(wsrep_uuid_t));
- memcpy(xid->data + WSREP_XID_SEQNO_OFFSET, &seqno, sizeof(wsrep_seqno_t));
-}
-
-const wsrep_uuid_t* wsrep_xid_uuid(const XID* xid)
-{
- if (wsrep_is_wsrep_xid(xid))
- return reinterpret_cast<const wsrep_uuid_t*>(xid->data
- + WSREP_XID_UUID_OFFSET);
- else
- return &WSREP_UUID_UNDEFINED;
-}
-
-wsrep_seqno_t wsrep_xid_seqno(const XID* xid)
-{
-
- if (wsrep_is_wsrep_xid(xid))
- {
- wsrep_seqno_t seqno;
- memcpy(&seqno, xid->data + WSREP_XID_SEQNO_OFFSET, sizeof(wsrep_seqno_t));
- return seqno;
- }
- else
- {
- return WSREP_SEQNO_UNDEFINED;
- }
-}
-
-extern
-int wsrep_is_wsrep_xid(const void* xid_ptr)
-{
- const XID* xid= reinterpret_cast<const XID*>(xid_ptr);
- return (xid->formatID == 1 &&
- xid->gtrid_length == WSREP_XID_GTRID_LEN &&
- xid->bqual_length == 0 &&
- !memcmp(xid->data, WSREP_XID_PREFIX, WSREP_XID_PREFIX_LEN));
-}
diff --git a/sql/wsrep_var.cc b/sql/wsrep_var.cc
index 87698576c44..00b9ce3e4e8 100644
--- a/sql/wsrep_var.cc
+++ b/sql/wsrep_var.cc
@@ -1,4 +1,4 @@
-/* Copyright 2008 Codership Oy <http://www.codership.com>
+/* Copyright 2008-2015 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
@@ -22,6 +22,7 @@
#include <sql_acl.h>
#include "wsrep_priv.h"
#include "wsrep_thd.h"
+#include "wsrep_xid.h"
#include <my_dir.h>
#include <cstdio>
#include <cstdlib>
@@ -140,29 +141,30 @@ err:
return 1;
}
-void wsrep_set_local_position (const char* value)
+static
+void wsrep_set_local_position(const char* const value, bool const sst)
{
- size_t value_len = strlen (value);
- size_t uuid_len = wsrep_uuid_scan (value, value_len, &local_uuid);
+ size_t const value_len = strlen(value);
+ wsrep_uuid_t uuid;
+ size_t const uuid_len = wsrep_uuid_scan(value, value_len, &uuid);
+ wsrep_seqno_t const seqno = strtoll(value + uuid_len + 1, NULL, 10);
- local_seqno = strtoll (value + uuid_len + 1, NULL, 10);
-
- XID xid;
- wsrep_xid_init(&xid, &local_uuid, local_seqno);
- wsrep_set_SE_checkpoint(&xid);
- WSREP_INFO ("wsrep_start_position var submitted: '%s'", wsrep_start_position);
+ if (sst) {
+ wsrep_sst_received (wsrep, uuid, seqno, NULL, 0);
+ } else {
+ // initialization
+ local_uuid = uuid;
+ local_seqno = seqno;
+ }
}
bool wsrep_start_position_update (sys_var *self, THD* thd, enum_var_type type)
{
+ WSREP_INFO ("wsrep_start_position var submitted: '%s'",
+ wsrep_start_position);
// since this value passed wsrep_start_position_check, don't check anything
// here
- wsrep_set_local_position (wsrep_start_position);
-
- if (wsrep) {
- wsrep_sst_received (wsrep, &local_uuid, local_seqno, NULL, 0);
- }
-
+ wsrep_set_local_position (wsrep_start_position, true);
return 0;
}
@@ -175,7 +177,7 @@ void wsrep_start_position_init (const char* val)
return;
}
- wsrep_set_local_position (val);
+ wsrep_set_local_position (val, false);
}
static bool refresh_provider_options()
@@ -212,7 +214,7 @@ static int wsrep_provider_verify (const char* provider_str)
return 1;
/* check that provider file exists */
- bzero(&f_stat, sizeof(MY_STAT));
+ memset(&f_stat, 0, sizeof(MY_STAT));
if (!my_stat(path, &f_stat, MYF(0)))
{
return 1;
diff --git a/sql/wsrep_xid.cc b/sql/wsrep_xid.cc
new file mode 100644
index 00000000000..056da5748b9
--- /dev/null
+++ b/sql/wsrep_xid.cc
@@ -0,0 +1,150 @@
+/* Copyright 2015 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
+ */
+
+//! @file some utility functions and classes not directly related to replication
+
+#include "wsrep_xid.h"
+#include "sql_class.h"
+#include "wsrep_mysqld.h" // for logging macros
+
+/*
+ * WSREPXid
+ */
+
+#define WSREP_XID_PREFIX "WSREPXid"
+#define WSREP_XID_PREFIX_LEN MYSQL_XID_PREFIX_LEN
+#define WSREP_XID_UUID_OFFSET 8
+#define WSREP_XID_SEQNO_OFFSET (WSREP_XID_UUID_OFFSET + sizeof(wsrep_uuid_t))
+#define WSREP_XID_GTRID_LEN (WSREP_XID_SEQNO_OFFSET + sizeof(wsrep_seqno_t))
+
+void wsrep_xid_init(XID* xid, const wsrep_uuid_t& uuid, wsrep_seqno_t seqno)
+{
+ xid->formatID= 1;
+ xid->gtrid_length= WSREP_XID_GTRID_LEN;
+ xid->bqual_length= 0;
+ memset(xid->data, 0, sizeof(xid->data));
+ memcpy(xid->data, WSREP_XID_PREFIX, WSREP_XID_PREFIX_LEN);
+ memcpy(xid->data + WSREP_XID_UUID_OFFSET, &uuid, sizeof(wsrep_uuid_t));
+ memcpy(xid->data + WSREP_XID_SEQNO_OFFSET, &seqno, sizeof(wsrep_seqno_t));
+}
+
+int wsrep_is_wsrep_xid(const void* xid_ptr)
+{
+ const XID* xid= reinterpret_cast<const XID*>(xid_ptr);
+ return (xid->formatID == 1 &&
+ xid->gtrid_length == WSREP_XID_GTRID_LEN &&
+ xid->bqual_length == 0 &&
+ !memcmp(xid->data, WSREP_XID_PREFIX, WSREP_XID_PREFIX_LEN));
+}
+
+const wsrep_uuid_t* wsrep_xid_uuid(const XID& xid)
+{
+ if (wsrep_is_wsrep_xid(&xid))
+ return reinterpret_cast<const wsrep_uuid_t*>(xid.data
+ + WSREP_XID_UUID_OFFSET);
+ else
+ return &WSREP_UUID_UNDEFINED;
+}
+
+wsrep_seqno_t wsrep_xid_seqno(const XID& xid)
+{
+ if (wsrep_is_wsrep_xid(&xid))
+ {
+ wsrep_seqno_t seqno;
+ memcpy(&seqno, xid.data + WSREP_XID_SEQNO_OFFSET, sizeof(wsrep_seqno_t));
+ return seqno;
+ }
+ else
+ {
+ return WSREP_SEQNO_UNDEFINED;
+ }
+}
+
+static my_bool set_SE_checkpoint(THD* unused, plugin_ref plugin, void* arg)
+{
+ XID* xid= static_cast<XID*>(arg);
+ handlerton* hton= plugin_data(plugin, handlerton *);
+
+ if (hton->db_type == DB_TYPE_INNODB)
+ {
+ const wsrep_uuid_t* uuid(wsrep_xid_uuid(*xid));
+ char uuid_str[40] = {0, };
+ wsrep_uuid_print(uuid, uuid_str, sizeof(uuid_str));
+ WSREP_DEBUG("Set WSREPXid for InnoDB: %s:%lld",
+ uuid_str, (long long)wsrep_xid_seqno(*xid));
+ hton->wsrep_set_checkpoint(hton, xid);
+ }
+
+ return FALSE;
+}
+
+void wsrep_set_SE_checkpoint(XID& xid)
+{
+ plugin_foreach(NULL, set_SE_checkpoint, MYSQL_STORAGE_ENGINE_PLUGIN, &xid);
+}
+
+void wsrep_set_SE_checkpoint(const wsrep_uuid_t& uuid, wsrep_seqno_t seqno)
+{
+ XID xid;
+ wsrep_xid_init(&xid, uuid, seqno);
+ wsrep_set_SE_checkpoint(xid);
+}
+
+static my_bool get_SE_checkpoint(THD* unused, plugin_ref plugin, void* arg)
+{
+ XID* xid= reinterpret_cast<XID*>(arg);
+ handlerton* hton= plugin_data(plugin, handlerton *);
+
+ if (hton->db_type == DB_TYPE_INNODB)
+ {
+ hton->wsrep_get_checkpoint(hton, xid);
+ const wsrep_uuid_t* uuid(wsrep_xid_uuid(*xid));
+ char uuid_str[40] = {0, };
+ wsrep_uuid_print(uuid, uuid_str, sizeof(uuid_str));
+ WSREP_DEBUG("Read WSREPXid from InnoDB: %s:%lld",
+ uuid_str, (long long)wsrep_xid_seqno(*xid));
+ }
+
+ return FALSE;
+}
+
+void wsrep_get_SE_checkpoint(XID& xid)
+{
+ plugin_foreach(NULL, get_SE_checkpoint, MYSQL_STORAGE_ENGINE_PLUGIN, &xid);
+}
+
+void wsrep_get_SE_checkpoint(wsrep_uuid_t& uuid, wsrep_seqno_t& seqno)
+{
+ uuid= WSREP_UUID_UNDEFINED;
+ seqno= WSREP_SEQNO_UNDEFINED;
+
+ XID xid;
+ memset(&xid, 0, sizeof(xid));
+ xid.formatID= -1;
+
+ wsrep_get_SE_checkpoint(xid);
+
+ if (xid.formatID == -1) return; // nil XID
+
+ if (!wsrep_is_wsrep_xid(&xid))
+ {
+ WSREP_WARN("Read non-wsrep XID from storage engines.");
+ return;
+ }
+
+ uuid= *wsrep_xid_uuid(xid);
+ seqno= wsrep_xid_seqno(xid);
+}
diff --git a/sql/wsrep_xid.h b/sql/wsrep_xid.h
new file mode 100644
index 00000000000..8a43e49c733
--- /dev/null
+++ b/sql/wsrep_xid.h
@@ -0,0 +1,33 @@
+/* Copyright (C) 2015 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. */
+
+#ifndef WSREP_XID_H
+#define WSREP_XID_H
+
+#include <my_config.h>
+#include "../wsrep/wsrep_api.h"
+#include "handler.h" // XID typedef
+
+void wsrep_xid_init(xid_t*, const wsrep_uuid_t&, wsrep_seqno_t);
+int wsrep_is_wsrep_xid(const void* xid);
+const wsrep_uuid_t* wsrep_xid_uuid(const XID&);
+wsrep_seqno_t wsrep_xid_seqno(const XID&);
+
+//void wsrep_get_SE_checkpoint(XID&); /* uncomment if needed */
+void wsrep_get_SE_checkpoint(wsrep_uuid_t&, wsrep_seqno_t&);
+//void wsrep_set_SE_checkpoint(XID&); /* uncomment if needed */
+void wsrep_set_SE_checkpoint(const wsrep_uuid_t&, wsrep_seqno_t);
+
+#endif /* WSREP_UTILS_H */
diff --git a/storage/innobase/include/ha_prototypes.h b/storage/innobase/include/ha_prototypes.h
index 5ecaa33fb96..bc588c6ecf0 100644
--- a/storage/innobase/include/ha_prototypes.h
+++ b/storage/innobase/include/ha_prototypes.h
@@ -299,9 +299,8 @@ int wsrep_trx_order_before(void *thd1, void *thd2);
int wsrep_innobase_mysql_sort(int mysql_type, uint charset_number,
unsigned char* str, unsigned int str_length,
unsigned int buf_length);
-int
-wsrep_on(void *thd_ptr);
-extern "C" int wsrep_is_wsrep_xid(const void*);
+int wsrep_on(void *thd_ptr);
+int wsrep_is_wsrep_xid(const void*);
#endif /* WITH_WSREP */
/**********************************************************************//**
Determines the connection character set.
diff --git a/storage/xtradb/include/ha_prototypes.h b/storage/xtradb/include/ha_prototypes.h
index 4ebaee3c89e..86ba7464905 100644
--- a/storage/xtradb/include/ha_prototypes.h
+++ b/storage/xtradb/include/ha_prototypes.h
@@ -298,9 +298,8 @@ int wsrep_trx_order_before(void *thd1, void *thd2);
int wsrep_innobase_mysql_sort(int mysql_type, uint charset_number,
unsigned char* str, unsigned int str_length,
unsigned int buf_length);
-int
-wsrep_on(void *thd_ptr);
-extern "C" int wsrep_is_wsrep_xid(const void*);
+int wsrep_on(void *thd_ptr);
+int wsrep_is_wsrep_xid(const void*);
#endif /* WITH_WSREP */
/**********************************************************************//**
Determines the connection character set.