diff --git a/extra/mariabackup/CMakeLists.txt b/extra/mariabackup/CMakeLists.txt index 78188d2f8e82c..f4ec59bbadc53 100644 --- a/extra/mariabackup/CMakeLists.txt +++ b/extra/mariabackup/CMakeLists.txt @@ -40,6 +40,10 @@ IF(NOT HAVE_SYSTEM_REGEX) INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/pcre) ENDIF() +IF(WITH_WSREP) + INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/wsrep) +ENDIF() + ADD_DEFINITIONS(-UMYSQL_SERVER) ######################################################################## # xtrabackup binary diff --git a/extra/mariabackup/wsrep.cc b/extra/mariabackup/wsrep.cc index fb66611b3eef9..fac1fdcf583ee 100644 --- a/extra/mariabackup/wsrep.cc +++ b/extra/mariabackup/wsrep.cc @@ -44,119 +44,16 @@ permission notice: #include #include #include +#include #include "common.h" #ifdef WITH_WSREP -#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)) -/*! undefined seqno */ -#define WSREP_SEQNO_UNDEFINED (-1) +#include /*! Name of file where Galera info is stored on recovery */ #define XB_GALERA_INFO_FILENAME "xtrabackup_galera_info" -/* Galera UUID type - for all unique IDs */ -typedef struct wsrep_uuid { - unsigned char data[16]; -} wsrep_uuid_t; - -/* sequence number of a writeset, etc. */ -typedef long long wsrep_seqno_t; - -/* Undefined UUID */ -static const wsrep_uuid_t WSREP_UUID_UNDEFINED = {{0,}}; - -/***********************************************************************//** -Check if a given WSREP XID is valid. - -@return true if valid. -*/ -static -bool -wsrep_is_wsrep_xid( -/*===============*/ - const void* xid_ptr) -{ - const XID* xid = reinterpret_cast(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))); -} - -/***********************************************************************//** -Retrieve binary WSREP UUID from XID. - -@return binary WSREP UUID represenataion, if UUID is valid, or - WSREP_UUID_UNDEFINED otherwise. -*/ -static -const wsrep_uuid_t* -wsrep_xid_uuid( -/*===========*/ - const XID* xid) -{ - if (wsrep_is_wsrep_xid(xid)) { - return(reinterpret_cast - (xid->data + WSREP_XID_UUID_OFFSET)); - } else { - return(&WSREP_UUID_UNDEFINED); - } -} - -/***********************************************************************//** -Retrieve WSREP seqno from XID. - -@return WSREP seqno, if it is valid, or WSREP_SEQNO_UNDEFINED otherwise. -*/ -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); - } -} - -/***********************************************************************//** -Write UUID to string. - -@return length of UUID string representation or -EMSGSIZE if string is too -short. -*/ -static -int -wsrep_uuid_print( -/*=============*/ - const wsrep_uuid_t* uuid, - char* str, - size_t str_len) -{ - if (str_len > 36) { - const unsigned char* u = uuid->data; - return snprintf(str, str_len, - "%02x%02x%02x%02x-%02x%02x-%02x%02x-" - "%02x%02x-%02x%02x%02x%02x%02x%02x", - u[ 0], u[ 1], u[ 2], u[ 3], u[ 4], u[ 5], u[ 6], - u[ 7], u[ 8], u[ 9], u[10], u[11], u[12], u[13], - u[14], u[15]); - } - else { - return -EMSGSIZE; - } -} - /*********************************************************************** Store Galera checkpoint info in the 'xtrabackup_galera_info' file, if that information is present in the trx system header. Otherwise, do nothing. */ @@ -167,7 +64,7 @@ xb_write_galera_info(bool incremental_prepare) FILE* fp; XID xid; char uuid_str[40]; - wsrep_seqno_t seqno; + long long seqno; MY_STAT statinfo; /* Do not overwrite existing an existing file to be compatible with @@ -186,7 +83,9 @@ xb_write_galera_info(bool incremental_prepare) return; } - if (wsrep_uuid_print(wsrep_xid_uuid(&xid), uuid_str, + wsrep_uuid_t uuid; + memcpy(uuid.data, wsrep_xid_uuid(&xid), sizeof(uuid.data)); + if (wsrep_uuid_print(&uuid, uuid_str, sizeof(uuid_str)) < 0) { return; } diff --git a/include/mysql/service_wsrep.h b/include/mysql/service_wsrep.h index bc5b2c67cdc02..1540a5e56fe1e 100644 --- a/include/mysql/service_wsrep.h +++ b/include/mysql/service_wsrep.h @@ -84,6 +84,8 @@ extern struct wsrep_service_st { void (*wsrep_aborting_thd_enqueue_func)(THD *thd); bool (*wsrep_consistency_check_func)(THD *thd); int (*wsrep_is_wsrep_xid_func)(const struct xid_t *xid); + long long (*wsrep_xid_seqno_func)(const struct xid_t *xid); + const unsigned char* (*wsrep_xid_uuid_func)(const struct xid_t *xid); void (*wsrep_lock_rollback_func)(); int (*wsrep_on_func)(MYSQL_THD); void (*wsrep_post_commit_func)(THD* thd, bool all); @@ -125,6 +127,8 @@ extern struct wsrep_service_st { #define wsrep_aborting_thd_enqueue(T) wsrep_service->wsrep_aborting_thd_enqueue_func(T) #define wsrep_consistency_check(T) wsrep_service->wsrep_consistency_check_func(T) #define wsrep_is_wsrep_xid(X) wsrep_service->wsrep_is_wsrep_xid_func(X) +#define wsrep_xid_seqno(X) wsrep_service->wsrep_xid_seqno_func(X) +#define wsrep_xid_uuid(X) wsrep_service->wsrep_xid_uuid_func(X) #define wsrep_lock_rollback() wsrep_service->wsrep_lock_rollback_func() #define wsrep_on(X) wsrep_service->wsrep_on_func(X) #define wsrep_post_commit(T,A) wsrep_service->wsrep_post_commit_func(T,A) @@ -182,6 +186,8 @@ enum wsrep_exec_mode wsrep_thd_exec_mode(THD *thd); enum wsrep_query_state wsrep_thd_query_state(THD *thd); enum wsrep_trx_status wsrep_run_wsrep_commit(THD *thd, bool all); int wsrep_is_wsrep_xid(const struct xid_t* xid); +long long wsrep_xid_seqno(const struct xid_t* xid); +const unsigned char* wsrep_xid_uuid(const struct xid_t* xid); int wsrep_on(MYSQL_THD thd); int wsrep_thd_retry_counter(THD *thd); int wsrep_trx_is_aborting(MYSQL_THD thd); diff --git a/sql/handler.cc b/sql/handler.cc index 3d85d4d132cc7..7662d68e51fc1 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -1484,11 +1484,13 @@ int ha_commit_trans(THD *thd, bool all) DEBUG_SYNC(thd, "ha_commit_trans_after_prepare"); DBUG_EXECUTE_IF("crash_commit_after_prepare", DBUG_SUICIDE();); +#ifdef WITH_WSREP if (!error && WSREP_ON && wsrep_is_wsrep_xid(&thd->transaction.xid_state.xid)) { // xid was rewritten by wsrep xid= wsrep_xid_seqno(thd->transaction.xid_state.xid); } +#endif /* WITH_WSREP */ if (!is_real_trans) { @@ -1914,9 +1916,10 @@ static my_bool xarecover_handlerton(THD *unused, plugin_ref plugin, got, hton_name(hton)->str); for (int i=0; i < got; i ++) { - my_xid x= WSREP_ON && wsrep_is_wsrep_xid(&info->list[i]) ? - wsrep_xid_seqno(info->list[i]) : - info->list[i].get_my_xid(); + my_xid x= IF_WSREP(WSREP_ON && wsrep_is_wsrep_xid(&info->list[i]) ? + wsrep_xid_seqno(info->list[i]) : + info->list[i].get_my_xid(), + info->list[i].get_my_xid()); if (!x) // not "mine" - that is generated by external TM { #ifndef DBUG_OFF diff --git a/sql/sql_plugin_services.ic b/sql/sql_plugin_services.ic index ea6aefa599330..47decf3897307 100644 --- a/sql/sql_plugin_services.ic +++ b/sql/sql_plugin_services.ic @@ -154,6 +154,8 @@ static struct wsrep_service_st wsrep_handler = { wsrep_aborting_thd_enqueue, wsrep_consistency_check, wsrep_is_wsrep_xid, + wsrep_xid_seqno, + wsrep_xid_uuid, wsrep_lock_rollback, wsrep_on, wsrep_post_commit, diff --git a/sql/wsrep_dummy.cc b/sql/wsrep_dummy.cc index c83f64e9cb4f8..0b6e7e0d5bbab 100644 --- a/sql/wsrep_dummy.cc +++ b/sql/wsrep_dummy.cc @@ -29,6 +29,15 @@ enum wsrep_conflict_state wsrep_thd_conflict_state(THD *, my_bool) int wsrep_is_wsrep_xid(const XID*) { return 0; } +long long wsrep_xid_seqno(const XID* x) +{ return -1; } + +const unsigned char* wsrep_xid_uuid(const XID*) +{ + static const unsigned char uuid[16] = {0}; + return uuid; +} + bool wsrep_prepare_key(const uchar*, size_t, const uchar*, size_t, struct wsrep_buf*, size_t*) { return 0; } diff --git a/sql/wsrep_mysqld.h b/sql/wsrep_mysqld.h index 6ad13cd6f6a48..2cb35db01b7bf 100644 --- a/sql/wsrep_mysqld.h +++ b/sql/wsrep_mysqld.h @@ -328,7 +328,6 @@ bool wsrep_node_is_synced(); #define WSREP_FORMAT(my_format) ((ulong)my_format) #define WSREP_PROVIDER_EXISTS (0) #define wsrep_emulate_bin_log (0) -#define wsrep_xid_seqno(X) (0) #define wsrep_to_isolation (0) #define wsrep_init() (1) #define wsrep_prepend_PATH(X) diff --git a/sql/wsrep_xid.cc b/sql/wsrep_xid.cc index 5af39bfc2309a..618c98eade721 100644 --- a/sql/wsrep_xid.cc +++ b/sql/wsrep_xid.cc @@ -25,8 +25,11 @@ * WSREPXid */ -#define WSREP_XID_PREFIX "WSREPXid" -#define WSREP_XID_PREFIX_LEN MYSQL_XID_PREFIX_LEN +#define WSREP_XID_PREFIX "WSREPXi" +#define WSREP_XID_PREFIX_LEN 7 +#define WSREP_XID_VERSION_OFFSET WSREP_XID_PREFIX_LEN +#define WSREP_XID_VERSION_1 'd' +#define WSREP_XID_VERSION_2 'e' #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)) @@ -38,8 +41,9 @@ void wsrep_xid_init(XID* xid, const wsrep_uuid_t& uuid, wsrep_seqno_t seqno) xid->bqual_length= 0; memset(xid->data, 0, sizeof(xid->data)); memcpy(xid->data, WSREP_XID_PREFIX, WSREP_XID_PREFIX_LEN); + xid->data[WSREP_XID_VERSION_OFFSET] = WSREP_XID_VERSION_2; memcpy(xid->data + WSREP_XID_UUID_OFFSET, &uuid, sizeof(wsrep_uuid_t)); - memcpy(xid->data + WSREP_XID_SEQNO_OFFSET, &seqno, sizeof(wsrep_seqno_t)); + int8store(xid->data + WSREP_XID_SEQNO_OFFSET,seqno); } int wsrep_is_wsrep_xid(const XID* xid) @@ -47,7 +51,9 @@ int wsrep_is_wsrep_xid(const XID* xid) 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)); + !memcmp(xid->data, WSREP_XID_PREFIX, WSREP_XID_PREFIX_LEN) && + (xid->data[WSREP_XID_VERSION_OFFSET] == WSREP_XID_VERSION_1 || + xid->data[WSREP_XID_VERSION_OFFSET] == WSREP_XID_VERSION_2)); } const wsrep_uuid_t* wsrep_xid_uuid(const XID& xid) @@ -59,18 +65,36 @@ const wsrep_uuid_t* wsrep_xid_uuid(const XID& xid) return &WSREP_UUID_UNDEFINED; } +const unsigned char* wsrep_xid_uuid(const xid_t* xid) +{ + DBUG_ASSERT(xid); + return wsrep_xid_uuid(*xid)->data; +} + wsrep_seqno_t wsrep_xid_seqno(const XID& xid) { + wsrep_seqno_t ret= WSREP_SEQNO_UNDEFINED; 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; + switch (xid.data[WSREP_XID_VERSION_OFFSET]) + { + case WSREP_XID_VERSION_1: + memcpy(&ret, xid.data + WSREP_XID_SEQNO_OFFSET, sizeof ret); + break; + case WSREP_XID_VERSION_2: + ret= sint8korr(xid.data + WSREP_XID_SEQNO_OFFSET); + break; + default: + break; + } } + return ret; +} + +long long wsrep_xid_seqno(const xid_t* xid) +{ + DBUG_ASSERT(xid); + return wsrep_xid_seqno(*xid); } static my_bool set_SE_checkpoint(THD* unused, plugin_ref plugin, void* arg) diff --git a/storage/innobase/trx/trx0rseg.cc b/storage/innobase/trx/trx0rseg.cc index 132c5d119f2be..a1f2c2aec6ea0 100644 --- a/storage/innobase/trx/trx0rseg.cc +++ b/storage/innobase/trx/trx0rseg.cc @@ -35,6 +35,7 @@ Created 3/26/1996 Heikki Tuuri #include #ifdef WITH_WSREP +#include #ifdef UNIV_DEBUG /** The latest known WSREP XID sequence number */ @@ -43,24 +44,6 @@ static long long wsrep_seqno = -1; /** The latest known WSREP XID UUID */ static unsigned char wsrep_uuid[16]; -/** Read WSREP XID UUID. -@param[in] xid WSREP XID -@return Pointer to the first byte of the UUID. -*/ - -static inline const byte* read_wsrep_xid_uuid(const XID* xid) -{ - return reinterpret_cast(xid->data + 8); -} - -/** Read WSREP XID seqno */ -static inline long long read_wsrep_xid_seqno(const XID* xid) -{ - long long seqno; - memcpy(&seqno, xid->data + 24, sizeof(long long)); - return seqno; -} - /** Update the WSREP XID information in rollback segment header. @param[in,out] rseg_header rollback segment header @param[in] xid WSREP XID @@ -71,12 +54,12 @@ trx_rseg_update_wsrep_checkpoint( const XID* xid, mtr_t* mtr) { - ut_ad(xid->formatID == 1); + ut_ad(wsrep_is_wsrep_xid(xid)); #ifdef UNIV_DEBUG /* Check that seqno is monotonically increasing */ - long long xid_seqno = read_wsrep_xid_seqno(xid); - const byte* xid_uuid = read_wsrep_xid_uuid(xid); + long long xid_seqno = wsrep_xid_seqno(xid); + const byte* xid_uuid = wsrep_xid_uuid(xid); if (!memcmp(xid_uuid, wsrep_uuid, sizeof wsrep_uuid)) { ut_ad(xid_seqno > wsrep_seqno); @@ -125,7 +108,7 @@ void trx_rseg_update_wsrep_checkpoint(const XID* xid) trx_rseg_update_wsrep_checkpoint(rseg_header, xid, &mtr); - const byte* xid_uuid = read_wsrep_xid_uuid(xid); + const byte* xid_uuid = wsrep_xid_uuid(xid); if (memcmp(wsrep_uuid, xid_uuid, sizeof wsrep_uuid)) { memcpy(wsrep_uuid, xid_uuid, sizeof wsrep_uuid); @@ -222,6 +205,11 @@ bool trx_rseg_read_wsrep_checkpoint(XID& xid) if (rseg_id == 0) { found = trx_rseg_init_wsrep_xid(sys->frame, xid); ut_ad(!found || xid.formatID == 1); + if (found) { + max_xid_seqno = wsrep_xid_seqno(&xid); + memcpy(wsrep_uuid, wsrep_xid_uuid(&xid), + sizeof wsrep_uuid); + } } const uint32_t page_no = trx_sysf_rseg_get_page_no( @@ -241,12 +229,12 @@ bool trx_rseg_read_wsrep_checkpoint(XID& xid) XID tmp_xid; long long tmp_seqno = 0; if (trx_rseg_read_wsrep_checkpoint(rseg_header, tmp_xid) - && (tmp_seqno = read_wsrep_xid_seqno(&tmp_xid)) + && (tmp_seqno = wsrep_xid_seqno(&tmp_xid)) > max_xid_seqno) { found = true; max_xid_seqno = tmp_seqno; xid = tmp_xid; - memcpy(wsrep_uuid, read_wsrep_xid_uuid(&tmp_xid), + memcpy(wsrep_uuid, wsrep_xid_uuid(&tmp_xid), sizeof wsrep_uuid); } }