mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
MDEV-15505 New wsrep XID format for backwards compatibility
A new wsrep XID format was added to keep the XID implementation backwards compatible. Original version always reads XID seqno part in host byte order, the new version in little endian byte order. Wsrep XID will always be written in the new format. Included wsrep_api.h from service_wsrep.h for wsrep type definitions. Removed redundant wsrep XID code from mariabackup and included service_wsrep.h in order to use
This commit is contained in:
@@ -40,4 +40,5 @@ SET(WSREP_PROC_INFO ${WITH_WSREP})
|
|||||||
|
|
||||||
IF(WITH_WSREP)
|
IF(WITH_WSREP)
|
||||||
SET(WSREP_PATCH_VERSION "wsrep_${WSREP_VERSION}")
|
SET(WSREP_PATCH_VERSION "wsrep_${WSREP_VERSION}")
|
||||||
|
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/wsrep)
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
@@ -44,115 +44,14 @@ permission notice:
|
|||||||
#include <my_base.h>
|
#include <my_base.h>
|
||||||
#include <handler.h>
|
#include <handler.h>
|
||||||
#include <trx0rseg.h>
|
#include <trx0rseg.h>
|
||||||
|
#include <mysql/service_wsrep.h>
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#ifdef WITH_WSREP
|
#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)
|
|
||||||
|
|
||||||
/*! Name of file where Galera info is stored on recovery */
|
/*! Name of file where Galera info is stored on recovery */
|
||||||
#define XB_GALERA_INFO_FILENAME "xtrabackup_galera_info"
|
#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)) {
|
|
||||||
return sint8korr(xid->data + WSREP_XID_SEQNO_OFFSET);
|
|
||||||
} 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
|
Store Galera checkpoint info in the 'xtrabackup_galera_info' file, if that
|
||||||
information is present in the trx system header. Otherwise, do nothing. */
|
information is present in the trx system header. Otherwise, do nothing. */
|
||||||
@@ -182,7 +81,9 @@ xb_write_galera_info(bool incremental_prepare)
|
|||||||
return;
|
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) {
|
sizeof(uuid_str)) < 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@@ -22,6 +22,8 @@
|
|||||||
For engines that want to support galera.
|
For engines that want to support galera.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <wsrep_api.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
@@ -67,11 +69,7 @@ enum wsrep_trx_status {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct xid_t;
|
struct xid_t;
|
||||||
struct wsrep;
|
|
||||||
struct wsrep_ws_handle;
|
struct wsrep_ws_handle;
|
||||||
struct wsrep_buf;
|
|
||||||
/* must match to typedef in wsrep/wsrep_api.h */
|
|
||||||
typedef int64_t wsrep_seqno_t;
|
|
||||||
|
|
||||||
extern struct wsrep_service_st {
|
extern struct wsrep_service_st {
|
||||||
struct wsrep * (*get_wsrep_func)();
|
struct wsrep * (*get_wsrep_func)();
|
||||||
|
@@ -25,8 +25,11 @@
|
|||||||
* WSREPXid
|
* WSREPXid
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define WSREP_XID_PREFIX "WSREPXid"
|
#define WSREP_XID_PREFIX "WSREPXi"
|
||||||
#define WSREP_XID_PREFIX_LEN MYSQL_XID_PREFIX_LEN
|
#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_UUID_OFFSET 8
|
||||||
#define WSREP_XID_SEQNO_OFFSET (WSREP_XID_UUID_OFFSET + sizeof(wsrep_uuid_t))
|
#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))
|
#define WSREP_XID_GTRID_LEN (WSREP_XID_SEQNO_OFFSET + sizeof(wsrep_seqno_t))
|
||||||
@@ -38,6 +41,7 @@ void wsrep_xid_init(XID* xid, const wsrep_uuid_t& uuid, wsrep_seqno_t seqno)
|
|||||||
xid->bqual_length= 0;
|
xid->bqual_length= 0;
|
||||||
memset(xid->data, 0, sizeof(xid->data));
|
memset(xid->data, 0, sizeof(xid->data));
|
||||||
memcpy(xid->data, WSREP_XID_PREFIX, WSREP_XID_PREFIX_LEN);
|
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_UUID_OFFSET, &uuid, sizeof(wsrep_uuid_t));
|
||||||
int8store(xid->data + WSREP_XID_SEQNO_OFFSET,seqno);
|
int8store(xid->data + WSREP_XID_SEQNO_OFFSET,seqno);
|
||||||
}
|
}
|
||||||
@@ -47,7 +51,9 @@ int wsrep_is_wsrep_xid(const XID* xid)
|
|||||||
return (xid->formatID == 1 &&
|
return (xid->formatID == 1 &&
|
||||||
xid->gtrid_length == WSREP_XID_GTRID_LEN &&
|
xid->gtrid_length == WSREP_XID_GTRID_LEN &&
|
||||||
xid->bqual_length == 0 &&
|
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)
|
const wsrep_uuid_t* wsrep_xid_uuid(const XID& xid)
|
||||||
@@ -67,15 +73,23 @@ const unsigned char* wsrep_xid_uuid(const xid_t* xid)
|
|||||||
|
|
||||||
wsrep_seqno_t wsrep_xid_seqno(const XID& xid)
|
wsrep_seqno_t wsrep_xid_seqno(const XID& xid)
|
||||||
{
|
{
|
||||||
|
wsrep_seqno_t ret= WSREP_SEQNO_UNDEFINED;
|
||||||
if (wsrep_is_wsrep_xid(&xid))
|
if (wsrep_is_wsrep_xid(&xid))
|
||||||
{
|
{
|
||||||
return sint8korr(xid.data + WSREP_XID_SEQNO_OFFSET);
|
switch (xid.data[WSREP_XID_VERSION_OFFSET])
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
return WSREP_SEQNO_UNDEFINED;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
wsrep_seqno_t wsrep_xid_seqno(const xid_t* xid)
|
wsrep_seqno_t wsrep_xid_seqno(const xid_t* xid)
|
||||||
{
|
{
|
||||||
|
@@ -186,17 +186,6 @@ static bool trx_rseg_init_wsrep_xid(const page_t* page, XID& xid)
|
|||||||
memcpy(xid.data,
|
memcpy(xid.data,
|
||||||
TRX_SYS + TRX_SYS_WSREP_XID_INFO
|
TRX_SYS + TRX_SYS_WSREP_XID_INFO
|
||||||
+ TRX_SYS_WSREP_XID_DATA + page, XIDDATASIZE);
|
+ TRX_SYS_WSREP_XID_DATA + page, XIDDATASIZE);
|
||||||
|
|
||||||
/* Wsrep XID seqno part in TRX_SYS page was written in host byte
|
|
||||||
order. However, in the XID which gets written to the rollback
|
|
||||||
segment header the byte order is little endian. On big endian
|
|
||||||
machines swap the seqno part byte order. */
|
|
||||||
#ifdef WORDS_BIGENDIAN
|
|
||||||
wsrep_seqno_t seqno;
|
|
||||||
memcpy(&seqno, xid.data + 24, sizeof seqno);
|
|
||||||
mach_swap_byte_order(xid.data + 24, &seqno, sizeof seqno);
|
|
||||||
#endif /* WORDS_BIGENDIAN */
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -216,6 +205,11 @@ bool trx_rseg_read_wsrep_checkpoint(XID& xid)
|
|||||||
if (rseg_id == 0) {
|
if (rseg_id == 0) {
|
||||||
found = trx_rseg_init_wsrep_xid(sys->frame, xid);
|
found = trx_rseg_init_wsrep_xid(sys->frame, xid);
|
||||||
ut_ad(!found || xid.formatID == 1);
|
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(
|
const uint32_t page_no = trx_sysf_rseg_get_page_no(
|
||||||
|
Reference in New Issue
Block a user