From 3dc05157fe9bb62cc5ffd14b901e502bef313d1e Mon Sep 17 00:00:00 2001 From: Alexey Yurchenko Date: Sat, 28 Mar 2015 23:19:49 +0200 Subject: [PATCH 1/3] Added more diagnostic (process name and PID) to be printed in case port for rsync daemon on joiner is busy. --- scripts/wsrep_sst_rsync.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/wsrep_sst_rsync.sh b/scripts/wsrep_sst_rsync.sh index 8998f73a9eb..54a56528bc8 100644 --- a/scripts/wsrep_sst_rsync.sh +++ b/scripts/wsrep_sst_rsync.sh @@ -63,9 +63,10 @@ check_pid_and_port() grep -w '^rsync[[:space:]]\+'"$rsync_pid" 2>/dev/null) if [ -n "$port_info" -a -z "$is_rsync" ]; then - wsrep_log_error "rsync daemon port '$rsync_port' has been taken" + wsrep_log_error "rsync daemon port '$rsync_port' has been taken by: $port_info" exit 16 # EBUSY fi + check_pid $pid_file && \ [ -n "$port_info" ] && [ -n "$is_rsync" ] && \ [ $(cat $pid_file) -eq $rsync_pid ] From be78f8790c65085fe5ef7c7b2864262c590563cd Mon Sep 17 00:00:00 2001 From: Alexey Yurchenko Date: Sun, 29 Mar 2015 01:34:50 +0200 Subject: [PATCH 2/3] Refs codership/mysql-wsrep#104 - read/write seqno to XID always in little-endian format --- sql/wsrep_applier.cc | 2 +- sql/wsrep_hton.cc | 2 +- sql/wsrep_xid.cc | 61 +++++++++++++++++++++++++++------ sql/wsrep_xid.h | 9 ++--- storage/innobase/trx/trx0sys.cc | 30 +++++----------- 5 files changed, 66 insertions(+), 38 deletions(-) diff --git a/sql/wsrep_applier.cc b/sql/wsrep_applier.cc index e7562beb887..c0fcfa88a7b 100644 --- a/sql/wsrep_applier.cc +++ b/sql/wsrep_applier.cc @@ -144,7 +144,7 @@ static wsrep_cb_status_t wsrep_apply_events(THD* thd, thd->server_id = ev->server_id; // use the original server id for logging thd->set_time(); // time the query - wsrep_xid_init(&thd->transaction.xid_state.xid, + wsrep_xid_init(thd->transaction.xid_state.xid, thd->wsrep_trx_meta.gtid.uuid, thd->wsrep_trx_meta.gtid.seqno); thd->lex->current_select= 0; diff --git a/sql/wsrep_hton.cc b/sql/wsrep_hton.cc index 0e69fec84cc..a14faa3b9ac 100644 --- a/sql/wsrep_hton.cc +++ b/sql/wsrep_hton.cc @@ -497,7 +497,7 @@ wsrep_run_wsrep_commit(THD *thd, handlerton *hton, bool all) /* Override XID iff it was generated by mysql */ if (thd->transaction.xid_state.xid.get_my_xid()) { - wsrep_xid_init(&thd->transaction.xid_state.xid, + wsrep_xid_init(thd->transaction.xid_state.xid, thd->wsrep_trx_meta.gtid.uuid, thd->wsrep_trx_meta.gtid.seqno); } diff --git a/sql/wsrep_xid.cc b/sql/wsrep_xid.cc index 056da5748b9..2d168c97390 100644 --- a/sql/wsrep_xid.cc +++ b/sql/wsrep_xid.cc @@ -20,6 +20,44 @@ #include "sql_class.h" #include "wsrep_mysqld.h" // for logging macros +static inline wsrep_seqno_t +wsrep_seqno_byteswap(wsrep_seqno_t const seqno) +{ + union { wsrep_seqno_t s; uint8_t b[8]; } from, to; + + from.s = seqno; + + to.b[0] = from.b[7]; to.b[1] = from.b[6]; + to.b[2] = from.b[5]; to.b[3] = from.b[4]; + to.b[4] = from.b[3]; to.b[5] = from.b[2]; + to.b[6] = from.b[1]; to.b[7] = from.b[0]; + + return to.s; +} + +/* Since vast majority of existing installations are little-endian and + * for the general little-endian cause, canonical XID seqno representation + * is little-endian. */ +#ifdef WORDS_BIGENDIAN + #define host_to_xid_seqno(s) wsrep_seqno_byteswap(s) + static inline wsrep_seqno_t + xid_to_host_seqno(wsrep_seqno_t const seqno) + { + // a little trick to simplify migration for existing installations: + // it is highly inlikely that the current seqno in any big-endian + // production cluster exceeds 0x0000000fffffffffLL (64G). + // Hence any seqno read from XID that is bigger than that must have been + // written in BE format. This BE detection has failure probability of + // 1 in 256M. This must be removed after next release. + wsrep_seqno_t const ret(wsrep_seqno_byteswap(seqno)); + return (ret > 0x0000000fffffffffLL || ret < WSREP_SEQNO_UNDEFINED ? + seqno : ret); + } +#else + #define host_to_xid_seqno(s) (s) + #define xid_to_host_seqno(s) host_to_xid_seqno(s) +#endif + /* * WSREPXid */ @@ -30,15 +68,16 @@ #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) +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)); + seqno= host_to_xid_seqno(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) @@ -65,7 +104,7 @@ wsrep_seqno_t wsrep_xid_seqno(const XID& xid) { wsrep_seqno_t seqno; memcpy(&seqno, xid.data + WSREP_XID_SEQNO_OFFSET, sizeof(wsrep_seqno_t)); - return seqno; + return xid_to_host_seqno(seqno); } else { @@ -99,13 +138,13 @@ void wsrep_set_SE_checkpoint(XID& xid) void wsrep_set_SE_checkpoint(const wsrep_uuid_t& uuid, wsrep_seqno_t seqno) { XID xid; - wsrep_xid_init(&xid, uuid, seqno); + 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(arg); + XID* xid= static_cast(arg); handlerton* hton= plugin_data(plugin, handlerton *); if (hton->db_type == DB_TYPE_INNODB) diff --git a/sql/wsrep_xid.h b/sql/wsrep_xid.h index 04de2d35ed8..48d08105b45 100644 --- a/sql/wsrep_xid.h +++ b/sql/wsrep_xid.h @@ -17,12 +17,13 @@ #define WSREP_XID_H #include "../wsrep/wsrep_api.h" -#include "handler.h" // XID typedef -void wsrep_xid_init(xid_t*, const wsrep_uuid_t&, wsrep_seqno_t); +struct xid_t; + +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&); +const wsrep_uuid_t* wsrep_xid_uuid(const xid_t&); +wsrep_seqno_t wsrep_xid_seqno(const xid_t&); //void wsrep_get_SE_checkpoint(XID&); uncomment if needed void wsrep_get_SE_checkpoint(wsrep_uuid_t&, wsrep_seqno_t&); diff --git a/storage/innobase/trx/trx0sys.cc b/storage/innobase/trx/trx0sys.cc index 816de1ca511..6d0c04c0c54 100644 --- a/storage/innobase/trx/trx0sys.cc +++ b/storage/innobase/trx/trx0sys.cc @@ -317,22 +317,11 @@ trx_sys_print_mysql_binlog_offset(void) #ifdef WITH_WSREP +#include #ifdef UNIV_DEBUG static long long trx_sys_cur_xid_seqno = -1; static unsigned char trx_sys_cur_xid_uuid[16]; - -long long read_wsrep_xid_seqno(const XID* xid) -{ - long long seqno; - memcpy(&seqno, xid->data + 24, sizeof(long long)); - return seqno; -} - -void read_wsrep_xid_uuid(const XID* xid, unsigned char* buf) -{ - memcpy(buf, xid->data + 8, 16); -} - +static size_t const xid_len = sizeof(trx_sys_cur_xid_uuid); #endif /* UNIV_DEBUG */ void @@ -345,17 +334,17 @@ trx_sys_update_wsrep_checkpoint( #ifdef UNIV_DEBUG { /* Check that seqno is monotonically increasing */ - unsigned char xid_uuid[16]; - long long xid_seqno = read_wsrep_xid_seqno(xid); - read_wsrep_xid_uuid(xid, xid_uuid); - if (!memcmp(xid_uuid, trx_sys_cur_xid_uuid, 8)) + const wsrep_uuid_t* const xid_uuid = wsrep_xid_uuid(*xid); + wsrep_seqno_t const xid_seqno = wsrep_xid_seqno(*xid); + if (!memcmp(xid_uuid, trx_sys_cur_xid_uuid, xid_len)) { - ut_ad(xid_seqno > trx_sys_cur_xid_seqno); + ut_ad(xid_seqno > trx_sys_cur_xid_seqno || + trx_sys_cur_xid_seqno < 0); trx_sys_cur_xid_seqno = xid_seqno; } else { - memcpy(trx_sys_cur_xid_uuid, xid_uuid, 16); + memcpy(trx_sys_cur_xid_uuid, xid_uuid, xid_len); } trx_sys_cur_xid_seqno = xid_seqno; } @@ -409,8 +398,7 @@ trx_sys_read_wsrep_checkpoint(XID* xid) if ((magic = mach_read_from_4(sys_header + TRX_SYS_WSREP_XID_INFO + TRX_SYS_WSREP_XID_MAGIC_N_FLD)) != TRX_SYS_WSREP_XID_MAGIC_N) { - memset(xid, 0, sizeof(*xid)); - xid->formatID = -1; + wsrep_xid_init(*xid,WSREP_UUID_UNDEFINED,WSREP_SEQNO_UNDEFINED); trx_sys_update_wsrep_checkpoint(xid, sys_header, &mtr); mtr_commit(&mtr); return; From d1a262fa04b8ab37cc8ee28a55639221d284fb67 Mon Sep 17 00:00:00 2001 From: Alexey Yurchenko Date: Tue, 31 Mar 2015 16:15:55 +0300 Subject: [PATCH 3/3] Refs codership/mysql-wsrep#104 - fixed a questionable upgrade strategy to one using wsrep XID prefix as a version ID to distinguish which order XID seqno is stored in. --- sql/wsrep_xid.cc | 52 ++++++++++++++++++++++++++---------------------- 1 file changed, 28 insertions(+), 24 deletions(-) diff --git a/sql/wsrep_xid.cc b/sql/wsrep_xid.cc index 2d168c97390..98356127d56 100644 --- a/sql/wsrep_xid.cc +++ b/sql/wsrep_xid.cc @@ -39,30 +39,19 @@ wsrep_seqno_byteswap(wsrep_seqno_t const seqno) * for the general little-endian cause, canonical XID seqno representation * is little-endian. */ #ifdef WORDS_BIGENDIAN - #define host_to_xid_seqno(s) wsrep_seqno_byteswap(s) - static inline wsrep_seqno_t - xid_to_host_seqno(wsrep_seqno_t const seqno) - { - // a little trick to simplify migration for existing installations: - // it is highly inlikely that the current seqno in any big-endian - // production cluster exceeds 0x0000000fffffffffLL (64G). - // Hence any seqno read from XID that is bigger than that must have been - // written in BE format. This BE detection has failure probability of - // 1 in 256M. This must be removed after next release. - wsrep_seqno_t const ret(wsrep_seqno_byteswap(seqno)); - return (ret > 0x0000000fffffffffLL || ret < WSREP_SEQNO_UNDEFINED ? - seqno : ret); - } + #define HOST_TO_XID_SEQNO(s) wsrep_seqno_byteswap(s) #else - #define host_to_xid_seqno(s) (s) - #define xid_to_host_seqno(s) host_to_xid_seqno(s) + #define HOST_TO_XID_SEQNO(s) (s) #endif +#define XID_TO_HOST_SEQNO(s) HOST_TO_XID_SEQNO(s) /* * WSREPXid */ -#define WSREP_XID_PREFIX "WSREPXid" +#define WSREP_XID_PREFIX_1 "WSREPXid" // seqno in host order +#define WSREP_XID_PREFIX_2 "WS_XID_2" // seqno in little-endian order +#define WSREP_XID_PREFIX WSREP_XID_PREFIX_2 // current version #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)) @@ -70,7 +59,7 @@ wsrep_seqno_byteswap(wsrep_seqno_t const seqno) void wsrep_xid_init(XID& xid, const wsrep_uuid_t& uuid, wsrep_seqno_t seqno) { - seqno= host_to_xid_seqno(seqno); + seqno= HOST_TO_XID_SEQNO(seqno); xid.formatID= 1; xid.gtrid_length= WSREP_XID_GTRID_LEN; xid.bqual_length= 0; @@ -80,13 +69,22 @@ void wsrep_xid_init(XID& xid, const wsrep_uuid_t& uuid, wsrep_seqno_t seqno) memcpy(xid.data + WSREP_XID_SEQNO_OFFSET, &seqno, sizeof(wsrep_seqno_t)); } +// returns XID version, 0 if not a wsrep XID int 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)); + + if (xid->formatID == 1 && + xid->gtrid_length == WSREP_XID_GTRID_LEN && + xid->bqual_length == 0) + { + if (!memcmp(xid->data, WSREP_XID_PREFIX_2, WSREP_XID_PREFIX_LEN)) + return 2; + if (!memcmp(xid->data, WSREP_XID_PREFIX_1, WSREP_XID_PREFIX_LEN)) + return 1; + } + + return 0; } const wsrep_uuid_t* wsrep_xid_uuid(const XID& xid) @@ -100,11 +98,17 @@ const wsrep_uuid_t* wsrep_xid_uuid(const XID& xid) wsrep_seqno_t wsrep_xid_seqno(const XID& xid) { - if (wsrep_is_wsrep_xid(&xid)) + int const xid_ver = wsrep_is_wsrep_xid(&xid); + if (xid_ver) { wsrep_seqno_t seqno; memcpy(&seqno, xid.data + WSREP_XID_SEQNO_OFFSET, sizeof(wsrep_seqno_t)); - return xid_to_host_seqno(seqno); +#ifdef WORDS_BIGENDIAN + if (xid_ver >= 2) + return XID_TO_HOST_SEQNO(seqno); + else +#endif /* WORDS_BIGENDIAN */ + return seqno; // host and XID orders are the same } else {