summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSeppo Jaakola <seppo.jaakola@codership.com>2012-06-12 10:55:11 +0300
committerSeppo Jaakola <seppo.jaakola@codership.com>2012-06-12 10:55:11 +0300
commit33ffe0dd29b6564e49dde8b1abda914da4b2f178 (patch)
treed4ed7e628eb0b8bdf7be707261de9d862655211a
parent609388fcfd912c9c2cb03a92251469a25a781893 (diff)
downloadmariadb-git-33ffe0dd29b6564e49dde8b1abda914da4b2f178.tar.gz
References lp:1011983
Merged from codership-mysql/5.5 changes revisions 3743-3756
-rw-r--r--cmake/wsrep.cmake2
-rw-r--r--scripts/mysqld_safe.sh39
-rw-r--r--sql/log_event.cc6
-rw-r--r--sql/mysqld.cc23
-rw-r--r--sql/sql_parse.cc8
-rw-r--r--sql/wsrep_hton.cc11
-rw-r--r--sql/wsrep_mysqld.cc12
-rw-r--r--sql/wsrep_mysqld.h4
-rw-r--r--sql/wsrep_sst.cc26
-rw-r--r--storage/innobase/handler/ha_innodb.cc30
-rw-r--r--storage/innobase/include/rem0rec.h3
-rw-r--r--storage/innobase/rem/rem0rec.c46
-rw-r--r--storage/xtradb/handler/ha_innodb.cc30
-rw-r--r--storage/xtradb/include/rem0rec.h3
-rw-r--r--storage/xtradb/rem/rem0rec.c46
15 files changed, 236 insertions, 53 deletions
diff --git a/cmake/wsrep.cmake b/cmake/wsrep.cmake
index 1fd747cddd6..3c10c5b3836 100644
--- a/cmake/wsrep.cmake
+++ b/cmake/wsrep.cmake
@@ -17,7 +17,7 @@
# so WSREP_VERSION is produced regardless
# Set the patch version
-SET(WSREP_PATCH_VERSION "5")
+SET(WSREP_PATCH_VERSION "6")
# Obtain patch revision number
SET(WSREP_PATCH_REVNO $ENV{WSREP_REV})
diff --git a/scripts/mysqld_safe.sh b/scripts/mysqld_safe.sh
index aaf1936afe1..5a390a32f26 100644
--- a/scripts/mysqld_safe.sh
+++ b/scripts/mysqld_safe.sh
@@ -63,6 +63,7 @@ Usage: $0 [OPTIONS]
--syslog Log messages to syslog with 'logger'
--skip-syslog Log messages to error log (default)
--syslog-tag=TAG Pass -t "mysqld-TAG" to 'logger'
+ --wsrep-urls=WSREP_URLS Comma-separated list of wsrep URLs
All other options are passed to the mysqld program.
@@ -161,6 +162,34 @@ shell_quote_string() {
echo "$1" | sed -e 's,\([^a-zA-Z0-9/_.=-]\),\\\1,g'
}
+wsrep_pick_url() {
+ [ $# -eq 0 ] && return 0
+
+ if ! which nc >/dev/null; then
+ log_error "ERROR: nc tool not found in PATH! Make sure you have it installed."
+ return 1
+ fi
+
+ local url
+ # Assuming URL in the form scheme://host:port
+ # If host and port are not NULL, the liveness of URL is assumed to be tested
+ # If port part is absent, the url is returned literally and unconditionally
+ # If every URL has port but none is reachable, nothing is returned
+ for url in `echo $@ | sed s/,/\ /g` 0; do
+ local host=`echo $url | cut -d \: -f 2 | sed s/^\\\/\\\///`
+ local port=`echo $url | cut -d \: -f 3`
+ [ -z "$port" ] && break
+ nc -z "$host" $port >/dev/null && break
+ done
+
+ if [ "$url" == "0" ]; then
+ log_error "ERROR: none of the URLs in '$@' is reachable."
+ return 1
+ fi
+
+ echo $url
+}
+
parse_arguments() {
# We only need to pass arguments through to the server if we don't
# handle them here. So, we collect unrecognized options (passed on
@@ -221,6 +250,7 @@ parse_arguments() {
--skip-syslog) want_syslog=0 ;;
--syslog-tag=*) syslog_tag="$val" ;;
--timezone=*) TZ="$val"; export TZ; ;;
+ --wsrep[-_]urls=*) wsrep_urls="$val"; ;;
--help) usage ;;
@@ -772,9 +802,16 @@ while true
do
rm -f $safe_mysql_unix_port "$pid_file" # Some extra safety
+ [ -n "$wsrep_urls" ] && url=`wsrep_pick_url $wsrep_urls` # check connect address
+
start_time=`date +%M%S`
- eval_log_error "$cmd"
+ if [ -z "$url" ]
+ then
+ eval_log_error "$cmd"
+ else
+ eval_log_error "$cmd --wsrep_cluster_address=$url"
+ fi
end_time=`date +%M%S`
diff --git a/sql/log_event.cc b/sql/log_event.cc
index 1536d9e899b..ccfa1ae73e2 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -9237,8 +9237,12 @@ check_table_map(Relay_log_info const *rli, RPL_TABLE_LIST *table_list)
{
DBUG_ENTER("check_table_map");
enum_tbl_map_status res= OK_TO_PROCESS;
-
+#ifdef WITH_WSREP
+ if ((rli->sql_thd->slave_thread /* filtering is for slave only */ ||
+ (WSREP(rli->sql_thd) && rli->sql_thd->wsrep_applier)) &&
+#else
if (rli->sql_thd->slave_thread /* filtering is for slave only */ &&
+#endif /* WITH_WSREP */
(!rpl_filter->db_ok(table_list->db) ||
(rpl_filter->is_on() && !rpl_filter->tables_ok("", table_list))))
res= FILTERED_OUT;
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index ec6219b978f..a88e76972e4 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -4857,6 +4857,17 @@ WSREP_WARN("applier has wsrep_exec_mode = %d", thd->wsrep_exec_mode);
#endif /* REMOVE */
}
+static inline bool is_replaying_connection(THD *thd)
+{
+ bool ret;
+
+ mysql_mutex_lock(&thd->LOCK_wsrep_thd);
+ ret= (thd->wsrep_conflict_state == REPLAYING) ? true : false;
+ mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
+
+ return ret;
+}
+
static bool have_client_connections()
{
THD *tmp;
@@ -4932,6 +4943,12 @@ void wsrep_close_client_connections(my_bool wait_to_end)
if (!is_client_connection(tmp))
continue;
+ if (is_replaying_connection(tmp))
+ {
+ tmp->killed= KILL_CONNECTION;
+ continue;
+ }
+
/* replicated transactions must be skipped */
if (abort_replicated(tmp))
continue;
@@ -4953,9 +4970,11 @@ void wsrep_close_client_connections(my_bool wait_to_end)
while ((tmp=it2++))
{
#ifndef __bsdi__ // Bug in BSDI kernel
- if (is_client_connection(tmp) && !abort_replicated(tmp))
+ if (is_client_connection(tmp) &&
+ !abort_replicated(tmp) &&
+ !is_replaying_connection(tmp))
{
- WSREP_INFO("SST kill local trx: %ld",tmp->thread_id);
+ WSREP_INFO("killing local connection: %ld",tmp->thread_id);
close_connection(tmp,0,0);
}
#endif
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index b4b7eb0b2cf..cce1aaf05d4 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -8304,14 +8304,6 @@ void wsrep_replication_process(THD *thd)
mysql_cond_broadcast(&COND_thread_count);
mysql_mutex_unlock(&LOCK_thread_count);
}
-
- if (thd->killed != KILL_CONNECTION)
- {
- mysql_mutex_lock(&LOCK_thread_count);
- wsrep_close_applier(thd);
- mysql_cond_broadcast(&COND_thread_count);
- mysql_mutex_unlock(&LOCK_thread_count);
- }
wsrep_return_from_bf_mode(thd, &shadow);
DBUG_VOID_RETURN;
}
diff --git a/sql/wsrep_hton.cc b/sql/wsrep_hton.cc
index bb5faafc768..49b3ea5c0bf 100644
--- a/sql/wsrep_hton.cc
+++ b/sql/wsrep_hton.cc
@@ -305,8 +305,15 @@ wsrep_run_wsrep_commit(
thd->stmt_da->affected_rows() > 0 &&
!binlog_filter->is_on())
{
- WSREP_WARN("empty rbr buffer, query: %s, affected rows: %llu",
- thd->query(), thd->stmt_da->affected_rows());
+ WSREP_DEBUG("empty rbr buffer, query: %s, "
+ "affected rows: %llu, "
+ "changed tables: %d, "
+ "sql_log_bin: %d, "
+ "wsrep status (%d %d %d)",
+ thd->query(), thd->stmt_da->affected_rows(),
+ stmt_has_updated_trans_table(thd), thd->variables.sql_log_bin,
+ thd->wsrep_exec_mode, thd->wsrep_query_state,
+ thd->wsrep_conflict_state);
}
else
{
diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc
index be2b8d7fa81..0bf0c2294d3 100644
--- a/sql/wsrep_mysqld.cc
+++ b/sql/wsrep_mysqld.cc
@@ -45,7 +45,7 @@ long long wsrep_max_ws_size = 1073741824LL; //max ws (RBR buffer) siz
long wsrep_max_ws_rows = 65536; // max number of rows in ws
int wsrep_to_isolation = 0; // # of active TO isolation threads
my_bool wsrep_certify_nonPK = 1; // certify, even when no primary key
-long wsrep_max_protocol_version = 1; // maximum protocol version to use
+long wsrep_max_protocol_version = 2; // maximum protocol version to use
ulong wsrep_forced_binlog_format = BINLOG_FORMAT_UNSPEC;
my_bool wsrep_recovery = 0; // recovery
my_bool wsrep_replicate_myisam = 0; // enable myisam replication
@@ -90,7 +90,7 @@ const char* wsrep_provider_vendor = provider_vendor;
wsrep_uuid_t local_uuid = WSREP_UUID_UNDEFINED;
wsrep_seqno_t local_seqno = WSREP_SEQNO_UNDEFINED;
wsp::node_status local_status;
-long wsrep_protocol_version = 1;
+long wsrep_protocol_version = 2;
// action execute callback
extern wsrep_status_t wsrep_apply_cb(void *ctx,
@@ -229,6 +229,7 @@ static void wsrep_view_handler_cb (void* app_ctx,
{
case 0:
case 1:
+ case 2:
// version change
if (view->proto_ver != wsrep_protocol_version)
{
@@ -278,9 +279,10 @@ static void wsrep_view_handler_cb (void* app_ctx,
{
/*
* NOTE: Initialize wsrep_group_uuid here only if it wasn't initialized
- * before.
+ * before - OR - it was reinitilized on startup (lp:992840)
*/
- if (!memcmp (&local_uuid, &WSREP_UUID_UNDEFINED, sizeof(wsrep_uuid_t)))
+ if (!memcmp (&local_uuid, &WSREP_UUID_UNDEFINED, sizeof(wsrep_uuid_t)) ||
+ 0 == wsrep_cluster_conf_id)
{
if (wsrep_init_first())
{
@@ -730,6 +732,7 @@ static bool wsrep_prepare_key_for_isolation(const char* db,
*key_len= 0;
break;
case 1:
+ case 2:
{
*key_len= 0;
if (db)
@@ -860,6 +863,7 @@ bool wsrep_prepare_key_for_innodb(const uchar* cache_key,
break;
}
case 1:
+ case 2:
{
key[*key_len].buf = cache_key;
key[*key_len].buf_len = strlen( (char*)cache_key );
diff --git a/sql/wsrep_mysqld.h b/sql/wsrep_mysqld.h
index 985431e74b9..ebea44c9151 100644
--- a/sql/wsrep_mysqld.h
+++ b/sql/wsrep_mysqld.h
@@ -1,4 +1,4 @@
-/* Copyright 2008 Codership Oy <http://www.codership.com>
+/* Copyright 2008-2012 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
@@ -131,7 +131,7 @@ extern bool wsrep_sst_donor_update UPDATE_ARGS;
extern bool wsrep_init_first(); // initialize wsrep before storage
- // engines or after
+ // engines (true) or after (false)
extern int wsrep_init();
extern void wsrep_deinit();
extern void wsrep_recover();
diff --git a/sql/wsrep_sst.cc b/sql/wsrep_sst.cc
index 4ce7fe84b0f..37779c4b96d 100644
--- a/sql/wsrep_sst.cc
+++ b/sql/wsrep_sst.cc
@@ -1,4 +1,4 @@
-/* Copyright 2008-2011 Codership Oy <http://www.codership.com>
+/* Copyright 2008-2012 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
@@ -25,10 +25,11 @@
extern const char wsrep_defaults_file[];
-#define WSREP_SST_MYSQLDUMP "mysqldump"
-#define WSREP_SST_DEFAULT WSREP_SST_MYSQLDUMP
+#define WSREP_SST_MYSQLDUMP "mysqldump"
+#define WSREP_SST_SKIP "skip"
+#define WSREP_SST_DEFAULT WSREP_SST_MYSQLDUMP
#define WSREP_SST_ADDRESS_AUTO "AUTO"
-#define WSREP_SST_AUTH_MASK "********"
+#define WSREP_SST_AUTH_MASK "********"
const char* wsrep_sst_method = WSREP_SST_DEFAULT;
const char* wsrep_sst_receive_address = WSREP_SST_ADDRESS_AUTO;
@@ -158,6 +159,7 @@ bool wsrep_init_first()
{
return (wsrep_provider != NULL
&& strcmp (wsrep_provider, WSREP_NONE)
+ && strcmp (wsrep_sst_method, WSREP_SST_SKIP)
&& strcmp (wsrep_sst_method, WSREP_SST_MYSQLDUMP));
}
@@ -439,8 +441,8 @@ static ssize_t sst_prepare_mysqldump (const char* addr_in,
ret= -ENOMEM;
}
- sql_print_error ("WSREP: Could not prepare state transfer request: "
- "adding default port failed: %zd.", ret);
+ WSREP_ERROR ("Could not prepare state transfer request: "
+ "adding default port failed: %zd.", ret);
}
else {
*addr_out= addr_in;
@@ -458,6 +460,18 @@ ssize_t wsrep_sst_prepare (void** msg)
const char* addr_in= NULL;
const char* addr_out= NULL;
+ if (!strcmp(wsrep_sst_method, WSREP_SST_SKIP))
+ {
+ ssize_t ret = strlen(WSREP_STATE_TRANSFER_TRIVIAL) + 1;
+ *msg = strdup(WSREP_STATE_TRANSFER_TRIVIAL);
+ if (!msg)
+ {
+ WSREP_ERROR("Could not allocate %zd bytes for state request", ret);
+ unireg_abort(1);
+ }
+ return ret;
+ }
+
// Figure out SST address. Common for all SST methods
if (wsrep_sst_receive_address &&
strcmp (wsrep_sst_receive_address, WSREP_SST_ADDRESS_AUTO))
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index 050ebf7d505..52df97e5eee 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -4751,14 +4751,17 @@ wsrep_store_key_val_for_row(
wsrep_innobase_mysql_sort(
mysql_type, cs->number, sorted, true_len);
- /* Note that we always reserve the maximum possible
+ if (wsrep_protocol_version > 1) {
+ memcpy(buff, sorted, true_len);
+ /* Note that we always reserve the maximum possible
length of the true VARCHAR in the key value, though
only len first bytes after the 2 length bytes contain
actual data. The rest of the space was reset to zero
in the bzero() call above. */
-
- buff += key_len;
-
+ buff += true_len;
+ } else {
+ buff += key_len;
+ }
} else if (mysql_type == MYSQL_TYPE_TINY_BLOB
|| mysql_type == MYSQL_TYPE_MEDIUM_BLOB
|| mysql_type == MYSQL_TYPE_BLOB
@@ -4825,8 +4828,11 @@ wsrep_store_key_val_for_row(
/* Note that we always reserve the maximum possible
length of the BLOB prefix in the key value. */
-
- buff += key_len;
+ if (wsrep_protocol_version > 1) {
+ buff += true_len;
+ } else {
+ buff += key_len;
+ }
} else {
/* Here we handle all other data types except the
true VARCHAR, BLOB and TEXT. Note that the column
@@ -6947,20 +6953,24 @@ wsrep_append_foreign_key(
key[0] = '\0';
rcode = wsrep_rec_get_primary_key(
- &key[1], &len, clust_rec, clust_index);
+ &key[1], &len, clust_rec, clust_index,
+ wsrep_protocol_version > 1);
if (rcode != DB_SUCCESS) {
WSREP_ERROR("FK key set failed: %lu", rcode);
return rcode;
}
#ifdef WSREP_DEBUG_PRINT
ulint i;
- fprintf(stderr, "FK parent key, len: %lu ", len+1);
+ fprintf(stderr, "FK parent key, table: %s shared: %d len: %lu ",
+ foreign->referenced_table_name, (int)shared, len+1);
for (i=0; i<len+1; i++) {
- fprintf(stderr, " (%X), ", key[i]);
+ fprintf(stderr, " %hhX, ", key[i]);
}
fprintf(stderr, "\n");
#endif
- strncpy(cache_key, foreign->foreign_table->name, 512);
+ strncpy(cache_key, (wsrep_protocol_version > 1) ?
+ foreign->referenced_table->name :
+ foreign->foreign_table->name, 512);
char *p = strchr(cache_key, '/');
if (p) {
*p = '\0';
diff --git a/storage/innobase/include/rem0rec.h b/storage/innobase/include/rem0rec.h
index ab390f4fb3a..30ef3048ff1 100644
--- a/storage/innobase/include/rem0rec.h
+++ b/storage/innobase/include/rem0rec.h
@@ -837,7 +837,8 @@ int wsrep_rec_get_primary_key(
byte *buf, /* out: extracted key */
ulint *buf_len, /* in/out: length of buf */
const rec_t* rec, /* in: physical record */
- dict_index_t* index); /* in: record descriptor */
+ dict_index_t* index, /* in: record descriptor */
+ ibool new_protocol); /* in: protocol > 1 */
#endif /* WITH_WSREP */
#ifndef UNIV_NONINL
#include "rem0rec.ic"
diff --git a/storage/innobase/rem/rem0rec.c b/storage/innobase/rem/rem0rec.c
index dbfc41881ce..15618a3fa02 100644
--- a/storage/innobase/rem/rem0rec.c
+++ b/storage/innobase/rem/rem0rec.c
@@ -1781,7 +1781,8 @@ wsrep_rec_get_primary_key(
byte *buf, /* out: extracted key */
ulint *buf_len, /* in/out: length of buf */
const rec_t* rec, /* in: physical record */
- dict_index_t* index) /* in: record descriptor */
+ dict_index_t* index, /* in: record descriptor */
+ ibool new_protocol) /* in: protocol > 1 */
{
const byte* data;
ulint len;
@@ -1819,7 +1820,7 @@ wsrep_rec_get_primary_key(
ut_a(!(col->prtype & DATA_NOT_NULL));
*buf++ = 1;
key_len++;
- } else {
+ } else if (!new_protocol) {
if (!(col->prtype & DATA_NOT_NULL)) {
*buf++ = 0;
key_len++;
@@ -1829,6 +1830,47 @@ wsrep_rec_get_primary_key(
(int)(col->prtype & DATA_MYSQL_TYPE_MASK),
(uint)dtype_get_charset_coll(col->prtype),
buf, len);
+ } else { /* new protocol */
+ if (!(col->prtype & DATA_NOT_NULL)) {
+ *buf++ = 0;
+ key_len++;
+ }
+ switch (col->mtype) {
+ case DATA_INT: {
+ byte* ptr = buf+len;
+ for (;;) {
+ ptr--;
+ *ptr = *data;
+ if (ptr == buf) {
+ break;
+ }
+ data++;
+ }
+
+ if (!(col->prtype & DATA_UNSIGNED)) {
+ buf[len-1] = (byte) (buf[len-1] ^ 128);
+ }
+
+ break;
+ }
+ case DATA_VARCHAR:
+ case DATA_VARMYSQL:
+ case DATA_BINARY:
+ /* Copy the actual data */
+ ut_memcpy(buf, data, len);
+ wsrep_innobase_mysql_sort(
+ (int)(col->prtype & DATA_MYSQL_TYPE_MASK),
+ (uint)dtype_get_charset_coll(col->prtype),
+ buf, len);
+ break;
+ case DATA_BLOB:
+ case DATA_MYSQL:
+ memcpy(buf, data, len);
+ break;
+ default:
+ break;
+ }
+
key_len += len;
buf += len;
}
diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc
index a1119fc3d47..4a869cf64b0 100644
--- a/storage/xtradb/handler/ha_innodb.cc
+++ b/storage/xtradb/handler/ha_innodb.cc
@@ -5131,14 +5131,17 @@ wsrep_store_key_val_for_row(
wsrep_innobase_mysql_sort(
mysql_type, cs->number, sorted, true_len);
- /* Note that we always reserve the maximum possible
+ if (wsrep_protocol_version > 1) {
+ memcpy(buff, sorted, true_len);
+ /* Note that we always reserve the maximum possible
length of the true VARCHAR in the key value, though
only len first bytes after the 2 length bytes contain
actual data. The rest of the space was reset to zero
in the bzero() call above. */
-
- buff += key_len;
-
+ buff += true_len;
+ } else {
+ buff += key_len;
+ }
} else if (mysql_type == MYSQL_TYPE_TINY_BLOB
|| mysql_type == MYSQL_TYPE_MEDIUM_BLOB
|| mysql_type == MYSQL_TYPE_BLOB
@@ -5205,8 +5208,11 @@ wsrep_store_key_val_for_row(
/* Note that we always reserve the maximum possible
length of the BLOB prefix in the key value. */
-
- buff += key_len;
+ if (wsrep_protocol_version > 1) {
+ buff += true_len;
+ } else {
+ buff += key_len;
+ }
} else {
/* Here we handle all other data types except the
true VARCHAR, BLOB and TEXT. Note that the column
@@ -7591,20 +7597,24 @@ wsrep_append_foreign_key(
key[0] = '\0';
rcode = wsrep_rec_get_primary_key(
- &key[1], &len, clust_rec, clust_index);
+ &key[1], &len, clust_rec, clust_index,
+ wsrep_protocol_version > 1);
if (rcode != DB_SUCCESS) {
WSREP_ERROR("FK key set failed: %lu", rcode);
return rcode;
}
#ifdef WSREP_DEBUG_PRINT
ulint i;
- fprintf(stderr, "FK parent key, len: %lu ", len+1);
+ fprintf(stderr, "FK parent key, table: %s shared: %d len: %lu ",
+ foreign->referenced_table_name, (int)shared, len+1);
for (i=0; i<len+1; i++) {
- fprintf(stderr, " (%X), ", key[i]);
+ fprintf(stderr, " %hhX, ", key[i]);
}
fprintf(stderr, "\n");
#endif
- strncpy(cache_key, foreign->foreign_table->name, 512);
+ strncpy(cache_key, (wsrep_protocol_version > 1) ?
+ foreign->referenced_table->name :
+ foreign->foreign_table->name, 512);
char *p = strchr(cache_key, '/');
if (p) {
*p = '\0';
diff --git a/storage/xtradb/include/rem0rec.h b/storage/xtradb/include/rem0rec.h
index ab390f4fb3a..30ef3048ff1 100644
--- a/storage/xtradb/include/rem0rec.h
+++ b/storage/xtradb/include/rem0rec.h
@@ -837,7 +837,8 @@ int wsrep_rec_get_primary_key(
byte *buf, /* out: extracted key */
ulint *buf_len, /* in/out: length of buf */
const rec_t* rec, /* in: physical record */
- dict_index_t* index); /* in: record descriptor */
+ dict_index_t* index, /* in: record descriptor */
+ ibool new_protocol); /* in: protocol > 1 */
#endif /* WITH_WSREP */
#ifndef UNIV_NONINL
#include "rem0rec.ic"
diff --git a/storage/xtradb/rem/rem0rec.c b/storage/xtradb/rem/rem0rec.c
index dbfc41881ce..15618a3fa02 100644
--- a/storage/xtradb/rem/rem0rec.c
+++ b/storage/xtradb/rem/rem0rec.c
@@ -1781,7 +1781,8 @@ wsrep_rec_get_primary_key(
byte *buf, /* out: extracted key */
ulint *buf_len, /* in/out: length of buf */
const rec_t* rec, /* in: physical record */
- dict_index_t* index) /* in: record descriptor */
+ dict_index_t* index, /* in: record descriptor */
+ ibool new_protocol) /* in: protocol > 1 */
{
const byte* data;
ulint len;
@@ -1819,7 +1820,7 @@ wsrep_rec_get_primary_key(
ut_a(!(col->prtype & DATA_NOT_NULL));
*buf++ = 1;
key_len++;
- } else {
+ } else if (!new_protocol) {
if (!(col->prtype & DATA_NOT_NULL)) {
*buf++ = 0;
key_len++;
@@ -1829,6 +1830,47 @@ wsrep_rec_get_primary_key(
(int)(col->prtype & DATA_MYSQL_TYPE_MASK),
(uint)dtype_get_charset_coll(col->prtype),
buf, len);
+ } else { /* new protocol */
+ if (!(col->prtype & DATA_NOT_NULL)) {
+ *buf++ = 0;
+ key_len++;
+ }
+ switch (col->mtype) {
+ case DATA_INT: {
+ byte* ptr = buf+len;
+ for (;;) {
+ ptr--;
+ *ptr = *data;
+ if (ptr == buf) {
+ break;
+ }
+ data++;
+ }
+
+ if (!(col->prtype & DATA_UNSIGNED)) {
+ buf[len-1] = (byte) (buf[len-1] ^ 128);
+ }
+
+ break;
+ }
+ case DATA_VARCHAR:
+ case DATA_VARMYSQL:
+ case DATA_BINARY:
+ /* Copy the actual data */
+ ut_memcpy(buf, data, len);
+ wsrep_innobase_mysql_sort(
+ (int)(col->prtype & DATA_MYSQL_TYPE_MASK),
+ (uint)dtype_get_charset_coll(col->prtype),
+ buf, len);
+ break;
+ case DATA_BLOB:
+ case DATA_MYSQL:
+ memcpy(buf, data, len);
+ break;
+ default:
+ break;
+ }
+
key_len += len;
buf += len;
}