diff options
author | Alexey Yurchenko <ayurchen@gmail.com> | 2015-03-23 23:27:28 +0200 |
---|---|---|
committer | Nirbhay Choubey <nirbhay@mariadb.com> | 2015-05-08 17:41:06 -0400 |
commit | 4ed9ddd30eefbedb4bb2f96a0f0eb2ab18d283a0 (patch) | |
tree | 8b6080f6fd69dd9a456ce51f349fd77ff568905b | |
parent | f5bce5a6003e0591c822f217b63dc6b65a73000a (diff) | |
download | mariadb-git-4ed9ddd30eefbedb4bb2f96a0f0eb2ab18d283a0.tar.gz |
Refs codership/mysql-wsrep#33
1. factored XID-related functions to a separate wsrep_xid.cc unit.
2. refactored them to take refrences instead of pointers where appropriate
3. implemented wsrep_get/set_SE_position to take wsrep_uuid_t and wsrep_seqno_t instead of XID
4. call wsrep_set_SE_position() in wsrep_sst_received() to reinitialize SE checkpoint after SST was received, avoid assert() in setting code by first checking current position.
-rw-r--r-- | sql/CMakeLists.txt | 3 | ||||
-rw-r--r-- | sql/handler.cc | 5 | ||||
-rw-r--r-- | sql/sql_parse.cc | 1 | ||||
-rw-r--r-- | sql/wsrep_applier.cc | 9 | ||||
-rw-r--r-- | sql/wsrep_applier.h | 3 | ||||
-rw-r--r-- | sql/wsrep_hton.cc | 5 | ||||
-rw-r--r-- | sql/wsrep_mysqld.cc | 104 | ||||
-rw-r--r-- | sql/wsrep_mysqld.h | 12 | ||||
-rw-r--r-- | sql/wsrep_priv.h | 12 | ||||
-rw-r--r-- | sql/wsrep_sst.cc | 49 | ||||
-rw-r--r-- | sql/wsrep_utils.cc | 57 | ||||
-rw-r--r-- | sql/wsrep_var.cc | 38 | ||||
-rw-r--r-- | sql/wsrep_xid.cc | 150 | ||||
-rw-r--r-- | sql/wsrep_xid.h | 33 | ||||
-rw-r--r-- | storage/innobase/include/ha_prototypes.h | 5 | ||||
-rw-r--r-- | storage/xtradb/include/ha_prototypes.h | 5 |
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. |