Skip to content

Commit

Permalink
MDEV-15505 Fix wsrep XID storage byte order
Browse files Browse the repository at this point in the history
  • Loading branch information
dr-m committed Mar 21, 2018
2 parents 4359c6b + 33aad1d commit 865cec9
Show file tree
Hide file tree
Showing 9 changed files with 80 additions and 146 deletions.
4 changes: 4 additions & 0 deletions extra/mariabackup/CMakeLists.txt
Expand Up @@ -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
Expand Down
113 changes: 6 additions & 107 deletions extra/mariabackup/wsrep.cc
Expand Up @@ -44,119 +44,16 @@ permission notice:
#include <my_base.h>
#include <handler.h>
#include <trx0rseg.h>
#include <mysql/service_wsrep.h>

#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 <wsrep_api.h>

/*! 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<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)));
}

/***********************************************************************//**
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<const wsrep_uuid_t*>
(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. */
Expand All @@ -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
Expand All @@ -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;
}
Expand Down
6 changes: 6 additions & 0 deletions include/mysql/service_wsrep.h
Expand Up @@ -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);
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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);
Expand Down
9 changes: 6 additions & 3 deletions sql/handler.cc
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions sql/sql_plugin_services.ic
Expand Up @@ -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,
Expand Down
9 changes: 9 additions & 0 deletions sql/wsrep_dummy.cc
Expand Up @@ -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; }

Expand Down
1 change: 0 additions & 1 deletion sql/wsrep_mysqld.h
Expand Up @@ -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)
Expand Down
46 changes: 35 additions & 11 deletions sql/wsrep_xid.cc
Expand Up @@ -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))
Expand All @@ -38,16 +41,19 @@ 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)
{
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)
Expand All @@ -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)
Expand Down

0 comments on commit 865cec9

Please sign in to comment.