summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNirbhay Choubey <nirbhay@skysql.com>2014-06-19 18:48:20 -0400
committerNirbhay Choubey <nirbhay@skysql.com>2014-06-19 18:48:20 -0400
commit97779a2ef05d2141d2ade2f72f0900dbd9960751 (patch)
tree1f2eb2c003247b77d602af4a035a7dd6f7e27aea
parenta76a6601ecb63d452c89202d8ca7f11bf2e0194f (diff)
downloadmariadb-git-97779a2ef05d2141d2ade2f72f0900dbd9960751.tar.gz
bzr merge -r4091..4101 codership/5.6/
-rw-r--r--cmake/wsrep.cmake2
-rw-r--r--sql/event_data_objects.cc13
-rw-r--r--sql/events.cc42
-rw-r--r--sql/sql_yacc.yy12
-rw-r--r--sql/sys_vars.cc12
-rw-r--r--sql/wsrep_applier.cc11
-rw-r--r--sql/wsrep_mysqld.cc20
-rw-r--r--sql/wsrep_mysqld.h3
-rw-r--r--sql/wsrep_thd.cc23
-rw-r--r--sql/wsrep_thd.h2
-rw-r--r--storage/innobase/handler/ha_innodb.cc75
-rw-r--r--storage/innobase/include/ha_prototypes.h7
-rw-r--r--storage/innobase/lock/lock0lock.cc11
-rw-r--r--storage/innobase/rem/rem0rec.cc8
-rw-r--r--storage/innobase/row/row0ins.cc4
-rw-r--r--storage/xtradb/handler/ha_innodb.cc75
-rw-r--r--storage/xtradb/include/ha_prototypes.h7
-rw-r--r--storage/xtradb/lock/lock0lock.cc11
-rw-r--r--storage/xtradb/rem/rem0rec.cc8
-rw-r--r--storage/xtradb/row/row0ins.cc4
20 files changed, 273 insertions, 77 deletions
diff --git a/cmake/wsrep.cmake b/cmake/wsrep.cmake
index 5057f14792b..0abc0b170a0 100644
--- a/cmake/wsrep.cmake
+++ b/cmake/wsrep.cmake
@@ -23,7 +23,7 @@ SET(WSREP_PATCH_VERSION "10")
# MariaDB addition: Revision number of the last revision merged from
# codership branch visible in @@visible_comment.
# Branch : codership-mysql/5.5
-SET(WSREP_PATCH_REVNO "3991") # Should be updated on every merge.
+SET(WSREP_PATCH_REVNO "4002") # Should be updated on every merge.
# MariaDB: Obtain patch revision number:
# Update WSREP_PATCH_REVNO if WSREP_REV environment variable is set.
diff --git a/sql/event_data_objects.cc b/sql/event_data_objects.cc
index d65180a60be..b91db2c3df4 100644
--- a/sql/event_data_objects.cc
+++ b/sql/event_data_objects.cc
@@ -1472,8 +1472,21 @@ end:
bool save_tx_read_only= thd->tx_read_only;
thd->tx_read_only= false;
+#ifdef WITH_WSREP
+ // sql_print_information("sizeof(LEX) = %d", sizeof(struct LEX));
+ // sizeof(LEX) = 4512, so it's relatively safe to allocate it on stack.
+ LEX lex;
+ lex.sql_command = SQLCOM_DROP_EVENT;
+ thd->lex = &lex;
+ WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL);
+#endif
+
ret= Events::drop_event(thd, dbname, name, FALSE);
+#ifdef WITH_WSREP
+ WSREP_TO_ISOLATION_END;
+ error:
+#endif
thd->tx_read_only= save_tx_read_only;
thd->security_ctx->master_access= saved_master_access;
}
diff --git a/sql/events.cc b/sql/events.cc
index e7631e33bf9..a14f1a6c384 100644
--- a/sql/events.cc
+++ b/sql/events.cc
@@ -1128,7 +1128,20 @@ Events::load_events_from_db(THD *thd)
delete et;
goto end;
}
-
+#ifdef WITH_WSREP
+ // when SST from master node who initials event, the event status is ENABLED
+ // this is problematic because there are two nodes with same events and both enabled.
+ if (et->originator != thd->variables.server_id)
+ {
+ store_record(table, record[1]);
+ table->field[ET_FIELD_STATUS]->
+ store((longlong) Event_parse_data::SLAVESIDE_DISABLED,
+ TRUE);
+ (void) table->file->ha_update_row(table->record[1], table->record[0]);
+ delete et;
+ continue;
+ }
+#endif
/**
Since the Event_queue_element object could be deleted inside
Event_queue::create_event we should save the value of dropped flag
@@ -1186,6 +1199,33 @@ int wsrep_create_event_query(THD *thd, uchar** buf, size_t* buf_len)
}
return wsrep_to_buf_helper(thd, log_query.ptr(), log_query.length(), buf, buf_len);
}
+static int
+wsrep_alter_query_string(THD *thd, String *buf)
+{
+ /* Append the "ALTER" part of the query */
+ if (buf->append(STRING_WITH_LEN("ALTER ")))
+ return 1;
+ /* Append definer */
+ append_definer(thd, buf, &(thd->lex->definer->user), &(thd->lex->definer->host));
+ /* Append the left part of thd->query after event name part */
+ if (buf->append(thd->lex->stmt_definition_begin,
+ thd->lex->stmt_definition_end -
+ thd->lex->stmt_definition_begin))
+ return 1;
+
+ return 0;
+}
+int wsrep_alter_event_query(THD *thd, uchar** buf, size_t* buf_len)
+{
+ String log_query;
+
+ if (wsrep_alter_query_string(thd, &log_query))
+ {
+ WSREP_WARN("events alter string failed: %s", thd->query());
+ return 1;
+ }
+ return wsrep_to_buf_helper(thd, log_query.ptr(), log_query.length(), buf, buf_len);
+}
#endif /* WITH_WSREP */
/**
@} (End of group Event_Scheduler)
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index d6b3fa41c78..a77d8478852 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -7153,7 +7153,7 @@ alter:
}
view_tail
{}
- | ALTER definer_opt EVENT_SYM sp_name
+ | ALTER definer_opt remember_name EVENT_SYM sp_name
{
/*
It is safe to use Lex->spname because
@@ -7165,9 +7165,12 @@ alter:
if (!(Lex->event_parse_data= Event_parse_data::new_instance(thd)))
MYSQL_YYABORT;
- Lex->event_parse_data->identifier= $4;
+ Lex->event_parse_data->identifier= $5;
Lex->sql_command= SQLCOM_ALTER_EVENT;
+#ifdef WITH_WSREP
+ Lex->stmt_definition_begin= $3;
+#endif
}
ev_alter_on_schedule_completion
opt_ev_rename_to
@@ -7175,7 +7178,7 @@ alter:
opt_ev_comment
opt_ev_sql_stmt
{
- if (!($6 || $7 || $8 || $9 || $10))
+ if (!($7 || $8 || $9 || $10 || $11))
{
my_parse_error(ER(ER_SYNTAX_ERROR));
MYSQL_YYABORT;
@@ -7185,6 +7188,9 @@ alter:
can overwrite it
*/
Lex->sql_command= SQLCOM_ALTER_EVENT;
+#ifdef WITH_WSREP
+ Lex->stmt_definition_end= (char*)YYLIP->get_cpp_ptr();
+#endif
}
| ALTER TABLESPACE alter_tablespace_info
{
diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc
index d5939473cf2..eca48bc6374 100644
--- a/sql/sys_vars.cc
+++ b/sql/sys_vars.cc
@@ -4712,6 +4712,18 @@ static Sys_var_mybool Sys_wsrep_load_data_splitting(
GLOBAL_VAR(wsrep_load_data_splitting),
CMD_LINE(OPT_ARG), DEFAULT(TRUE));
+static Sys_var_mybool Sys_wsrep_slave_FK_checks(
+ "wsrep_slave_FK_checks", "Should slave thread do "
+ "foreign key constraint checks",
+ GLOBAL_VAR(wsrep_slave_FK_checks),
+ CMD_LINE(OPT_ARG), DEFAULT(TRUE));
+
+static Sys_var_mybool Sys_wsrep_slave_UK_checks(
+ "wsrep_slave_UK_checks", "Should slave thread do "
+ "secondary index uniqueness chesks",
+ GLOBAL_VAR(wsrep_slave_UK_checks),
+ CMD_LINE(OPT_ARG), DEFAULT(FALSE));
+
static Sys_var_mybool Sys_wsrep_restart_slave(
"wsrep_restart_slave", "Should MySQL slave be restarted automatically, when node joins back to cluster",
GLOBAL_VAR(wsrep_restart_slave), CMD_LINE(OPT_ARG), DEFAULT(FALSE));
diff --git a/sql/wsrep_applier.cc b/sql/wsrep_applier.cc
index 05c32da580d..23687e98c32 100644
--- a/sql/wsrep_applier.cc
+++ b/sql/wsrep_applier.cc
@@ -227,6 +227,17 @@ wsrep_cb_status_t wsrep_apply_cb(void* const ctx,
thd_proc_info(thd, "applying write set");
#endif /* WSREP_PROC_INFO */
+ /* tune FK and UK checking policy */
+ if (wsrep_slave_UK_checks == FALSE)
+ thd->variables.option_bits|= OPTION_RELAXED_UNIQUE_CHECKS;
+ else
+ thd->variables.option_bits&= ~OPTION_RELAXED_UNIQUE_CHECKS;
+
+ if (wsrep_slave_FK_checks == FALSE)
+ thd->variables.option_bits|= OPTION_NO_FOREIGN_KEY_CHECKS;
+ else
+ thd->variables.option_bits&= ~OPTION_NO_FOREIGN_KEY_CHECKS;
+
if (flags & WSREP_FLAG_ISOLATION)
{
thd->wsrep_apply_toi= true;
diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc
index f979a9d1a42..353704930a5 100644
--- a/sql/wsrep_mysqld.cc
+++ b/sql/wsrep_mysqld.cc
@@ -55,7 +55,7 @@ ulong wsrep_max_ws_size = 1073741824UL;//max ws (RBR buffer) size
ulong 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 = 2; // maximum protocol version to use
+long wsrep_max_protocol_version = 3; // 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
@@ -68,6 +68,8 @@ my_bool wsrep_restart_slave = 0; // should mysql slave thread be
// restarted, if node joins back
my_bool wsrep_restart_slave_activated = 0; // node has dropped, and slave
// restart will be needed
+my_bool wsrep_slave_UK_checks = 0; // slave thread does UK checks
+my_bool wsrep_slave_FK_checks = 0; // slave thread does FK checks
/*
* End configuration options
*/
@@ -109,7 +111,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 = 2;
+long wsrep_protocol_version = 3;
// Boolean denoting if server is in initial startup phase. This is needed
// to make sure that main thread waiting in wsrep_sst_wait() is signaled
@@ -270,6 +272,7 @@ wsrep_view_handler_cb (void* app_ctx,
case 0:
case 1:
case 2:
+ case 3:
// version change
if (view->proto_ver != wsrep_protocol_version)
{
@@ -961,6 +964,7 @@ static bool wsrep_prepare_key_for_isolation(const char* db,
break;
case 1:
case 2:
+ case 3:
{
*key_len= 0;
if (db)
@@ -1100,6 +1104,7 @@ bool wsrep_prepare_key_for_innodb(const uchar* cache_key,
}
case 1:
case 2:
+ case 3:
{
key[0].ptr = cache_key;
key[0].len = strlen( (char*)cache_key );
@@ -1262,6 +1267,9 @@ static int wsrep_TOI_begin(THD *thd, char *db_, char *table_,
case SQLCOM_CREATE_EVENT:
buf_err= wsrep_create_event_query(thd, &buf, &buf_len);
break;
+ case SQLCOM_ALTER_EVENT:
+ buf_err= wsrep_alter_event_query(thd, &buf, &buf_len);
+ break;
default:
buf_err= wsrep_to_buf_helper(thd, thd->query(), thd->query_length(), &buf,
&buf_len);
@@ -1304,6 +1312,14 @@ static void wsrep_TOI_end(THD *thd) {
WSREP_DEBUG("TO END: %lld, %d : %s", (long long)wsrep_thd_trx_seqno(thd),
thd->wsrep_exec_mode, (thd->query()) ? thd->query() : "void");
+
+ XID xid;
+ wsrep_xid_init(&xid, &thd->wsrep_trx_meta.gtid.uuid,
+ thd->wsrep_trx_meta.gtid.seqno);
+ wsrep_set_SE_checkpoint(&xid);
+ WSREP_DEBUG("TO END: %lld, update seqno",
+ (long long)wsrep_thd_trx_seqno(thd));
+
if (WSREP_OK == (ret = wsrep->to_execute_end(wsrep, thd->thread_id))) {
WSREP_DEBUG("TO END: %lld", (long long)wsrep_thd_trx_seqno(thd));
}
diff --git a/sql/wsrep_mysqld.h b/sql/wsrep_mysqld.h
index 30264bf24c1..bd76abad14e 100644
--- a/sql/wsrep_mysqld.h
+++ b/sql/wsrep_mysqld.h
@@ -98,6 +98,8 @@ extern ulong wsrep_mysql_replication_bundle;
extern my_bool wsrep_load_data_splitting;
extern my_bool wsrep_restart_slave;
extern my_bool wsrep_restart_slave_activated;
+extern my_bool wsrep_slave_FK_checks;
+extern my_bool wsrep_slave_UK_checks;
enum enum_wsrep_OSU_method { WSREP_OSU_TOI, WSREP_OSU_RSU };
@@ -304,6 +306,7 @@ int wsrep_to_buf_helper(
int wsrep_create_sp(THD *thd, uchar** buf, size_t* buf_len);
int wsrep_create_trigger_query(THD *thd, uchar** buf, size_t* buf_len);
int wsrep_create_event_query(THD *thd, uchar** buf, size_t* buf_len);
+int wsrep_alter_event_query(THD *thd, uchar** buf, size_t* buf_len);
struct xid_t;
void wsrep_get_SE_checkpoint(xid_t*);
diff --git a/sql/wsrep_thd.cc b/sql/wsrep_thd.cc
index 7d61af8d84e..b485daa2a9c 100644
--- a/sql/wsrep_thd.cc
+++ b/sql/wsrep_thd.cc
@@ -480,6 +480,29 @@ void wsrep_create_rollbacker()
}
}
+void wsrep_thd_set_PA_safe(void *thd_ptr, my_bool safe)
+{
+ if (thd_ptr)
+ {
+ THD* thd = (THD*)thd_ptr;
+ thd->wsrep_PA_safe = safe;
+ }
+}
+
+int wsrep_thd_conflict_state(void *thd_ptr, my_bool sync)
+{
+ int state = -1;
+ if (thd_ptr)
+ {
+ THD* thd = (THD*)thd_ptr;
+ if (sync) mysql_mutex_lock(&thd->LOCK_wsrep_thd);
+
+ state = thd->wsrep_conflict_state;
+ if (sync) mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
+ }
+ return state;
+}
+
my_bool wsrep_thd_is_BF(void *thd_ptr, my_bool sync)
{
my_bool status = FALSE;
diff --git a/sql/wsrep_thd.h b/sql/wsrep_thd.h
index f719deae2b7..a7e34c35101 100644
--- a/sql/wsrep_thd.h
+++ b/sql/wsrep_thd.h
@@ -27,7 +27,9 @@ void wsrep_create_rollbacker();
int wsrep_abort_thd(void *bf_thd_ptr, void *victim_thd_ptr,
my_bool signal);
+extern void wsrep_thd_set_PA_safe(void *thd_ptr, my_bool safe);
extern my_bool wsrep_thd_is_BF(void *thd_ptr, my_bool sync);
+extern int wsrep_thd_conflict_state(void *thd_ptr, my_bool sync);
//extern "C" my_bool wsrep_thd_is_BF(void *thd_ptr, my_bool sync);
extern "C" my_bool wsrep_thd_is_BF_or_commit(void *thd_ptr, my_bool sync);
extern "C" my_bool wsrep_thd_is_local(void *thd_ptr, my_bool sync);
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index 6d120adf737..f0ef468ffcd 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -5598,18 +5598,21 @@ get_field_offset(
#ifdef WITH_WSREP
UNIV_INTERN
-void
+int
wsrep_innobase_mysql_sort(
/*===============*/
/* out: str contains sort string */
int mysql_type, /* in: MySQL type */
uint charset_number, /* in: number of the charset */
unsigned char* str, /* in: data field */
- unsigned int str_length) /* in: data field length,
+ unsigned int str_length, /* in: data field length,
not UNIV_SQL_NULL */
+ unsigned int buf_length) /* in: total str buffer length */
+
{
CHARSET_INFO* charset;
enum_field_types mysql_tp;
+ int ret_length = str_length;
DBUG_ASSERT(str_length != UNIV_SQL_NULL);
@@ -5653,14 +5656,26 @@ wsrep_innobase_mysql_sort(
ut_a(str_length <= tmp_length);
memcpy(tmp_str, str, str_length);
- //tmp_length = charset->coll->strnxfrm(charset, str, str_length,
- // tmp_str, str_length);
- /* Note: in MySQL 5.6:
- */
tmp_length = charset->coll->strnxfrm(charset, str, str_length,
- str_length, tmp_str, tmp_length, 0);
- /**/
+ str_length, tmp_str,
+ tmp_length, 0);
DBUG_ASSERT(tmp_length <= str_length);
+ if (wsrep_protocol_version < 3) {
+ tmp_length = charset->coll->strnxfrm(
+ charset, str, str_length,
+ str_length, tmp_str, tmp_length, 0);
+ DBUG_ASSERT(tmp_length <= str_length);
+ } else {
+ /* strnxfrm will expand the destination string,
+ protocols < 3 truncated the sorted sring
+ protocols > 3 gets full sorted sring
+ */
+ tmp_length = charset->coll->strnxfrm(
+ charset, str, buf_length,
+ str_length, tmp_str, tmp_length, 0);
+ DBUG_ASSERT(tmp_length <= buf_length);
+ ret_length = tmp_length;
+ }
break;
}
@@ -5688,7 +5703,7 @@ wsrep_innobase_mysql_sort(
break;
}
- return;
+ return ret_length;
}
#endif /* WITH_WSREP */
@@ -6246,6 +6261,7 @@ wsrep_store_key_val_for_row(
const byte* data;
ulint key_len;
ulint true_len;
+ ulint sort_len;
const CHARSET_INFO* cs;
int error=0;
@@ -6288,11 +6304,12 @@ wsrep_store_key_val_for_row(
}
memcpy(sorted, data, true_len);
- wsrep_innobase_mysql_sort(
- mysql_type, cs->number, sorted, true_len);
+ sort_len = wsrep_innobase_mysql_sort(
+ mysql_type, cs->number, sorted, true_len,
+ REC_VERSION_56_MAX_INDEX_COL_LEN);
if (wsrep_protocol_version > 1) {
- memcpy(buff, sorted, true_len);
+ memcpy(buff, sorted, sort_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
@@ -6313,6 +6330,7 @@ wsrep_store_key_val_for_row(
const CHARSET_INFO* cs;
ulint key_len;
ulint true_len;
+ ulint sort_len;
int error=0;
ulint blob_len;
const byte* blob_data;
@@ -6361,10 +6379,11 @@ wsrep_store_key_val_for_row(
}
memcpy(sorted, blob_data, true_len);
- wsrep_innobase_mysql_sort(
- mysql_type, cs->number, sorted, true_len);
+ sort_len = wsrep_innobase_mysql_sort(
+ mysql_type, cs->number, sorted, true_len,
+ REC_VERSION_56_MAX_INDEX_COL_LEN);
- memcpy(buff, sorted, true_len);
+ memcpy(buff, sorted, sort_len);
/* Note that we always reserve the maximum possible
length of the BLOB prefix in the key value. */
@@ -6381,6 +6400,7 @@ wsrep_store_key_val_for_row(
const CHARSET_INFO* cs = NULL;
ulint true_len;
+ ulint sort_len;
ulint key_len;
const uchar* src_start;
int error=0;
@@ -6425,9 +6445,11 @@ wsrep_store_key_val_for_row(
&error);
}
memcpy(sorted, src_start, true_len);
- wsrep_innobase_mysql_sort(
- mysql_type, cs->number, sorted, true_len);
- memcpy(buff, sorted, true_len);
+ sort_len = wsrep_innobase_mysql_sort(
+ mysql_type, cs->number, sorted, true_len,
+ REC_VERSION_56_MAX_INDEX_COL_LEN);
+
+ memcpy(buff, sorted, sort_len);
} else {
memcpy(buff, src_start, true_len);
}
@@ -9470,7 +9492,7 @@ wsrep_append_foreign_key(
wsrep_thd_query(thd) : "void");
return DB_ERROR;
}
- byte key[WSREP_MAX_SUPPORTED_KEY_LENGTH+1];
+ byte key[WSREP_MAX_SUPPORTED_KEY_LENGTH+1] = {'\0'};
ulint len = WSREP_MAX_SUPPORTED_KEY_LENGTH;
dict_index_t *idx_target = (referenced) ?
@@ -9665,10 +9687,15 @@ ha_innobase::wsrep_append_keys(
uint i;
bool hasPK= false;
- for (i=0; i<table->s->keys && !hasPK; ++i) {
- KEY* key_info = table->key_info + i;
- if (key_info->flags & HA_NOSAME) hasPK = true;
- }
+ for (i=0; i<table->s->keys; ++i) {
+ KEY* key_info = table->key_info + i;
+ if (key_info->flags & HA_NOSAME) {
+ hasPK = true;
+ if (i != table->s->primary_key) {
+ wsrep_thd_set_PA_safe(thd, FALSE);
+ }
+ }
+ }
for (i=0; i<table->s->keys; ++i) {
uint len;
@@ -9690,6 +9717,7 @@ ha_innobase::wsrep_append_keys(
table->s->table_name.str,
key_info->name);
}
+ /* !hasPK == table with no PK, must append all non-unique keys */
if (!hasPK || key_info->flags & HA_NOSAME ||
((tab &&
dict_table_get_referenced_constraint(tab, idx)) ||
@@ -17281,6 +17309,7 @@ static int innobase_wsrep_set_checkpoint(handlerton* hton, const XID* xid)
trx_sysf_t* sys_header = trx_sysf_get(&mtr);
trx_sys_update_wsrep_checkpoint(xid, sys_header, &mtr);
mtr_commit(&mtr);
+ innobase_flush_logs(hton);
return 0;
} else {
return 1;
diff --git a/storage/innobase/include/ha_prototypes.h b/storage/innobase/include/ha_prototypes.h
index a24a2b1d399..336ff92a619 100644
--- a/storage/innobase/include/ha_prototypes.h
+++ b/storage/innobase/include/ha_prototypes.h
@@ -291,10 +291,13 @@ UNIV_INTERN
int
wsrep_innobase_kill_one_trx(void *thd_ptr,
const trx_t *bf_trx, trx_t *victim_trx, ibool signal);
+my_bool wsrep_thd_set_PA_safe(void *thd_ptr, my_bool safe);
+int wsrep_thd_conflict_state(void *thd_ptr, my_bool sync);
my_bool wsrep_thd_is_BF(void *thd_ptr, my_bool sync);
int wsrep_trx_order_before(void *thd1, void *thd2);
-void wsrep_innobase_mysql_sort(int mysql_type, uint charset_number,
- unsigned char* str, unsigned int str_length);
+int wsrep_innobase_mysql_sort(int mysql_type, uint charset_number,
+ unsigned char* str, unsigned int str_length,
+ unsigned int buf_length);
int
wsrep_on(void *thd_ptr);
extern "C" int wsrep_is_wsrep_xid(const void*);
diff --git a/storage/innobase/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc
index a9556b49ac6..f99c34294cd 100644
--- a/storage/innobase/lock/lock0lock.cc
+++ b/storage/innobase/lock/lock0lock.cc
@@ -1041,7 +1041,12 @@ lock_rec_has_to_wait(
(lock2->type_mode & LOCK_MODE_MASK) == LOCK_X)
{
/* exclusive lock conflicts are not accepted */
- fprintf(stderr, "BF-BF X lock conflict\n");
+ fprintf(stderr, "BF-BF X lock conflict,"
+ "type_mode: %lu supremum: %lu\n",
+ type_mode, lock_is_on_supremum);
+ fprintf(stderr, "conflicts states: my %d locked %d\n",
+ wsrep_thd_conflict_state(trx->mysql_thd, FALSE),
+ wsrep_thd_conflict_state(lock2->trx->mysql_thd, FALSE) );
lock_rec_print(stderr, lock2);
abort();
} else {
@@ -1624,6 +1629,7 @@ wsrep_kill_victim(const trx_t * const trx, const lock_t *lock) {
ut_ad(trx_mutex_own(lock->trx));
my_bool bf_this = wsrep_thd_is_BF(trx->mysql_thd, FALSE);
my_bool bf_other = wsrep_thd_is_BF(lock->trx->mysql_thd, TRUE);
+
if ((bf_this && !bf_other) ||
(bf_this && bf_other && wsrep_trx_order_before(
trx->mysql_thd, lock->trx->mysql_thd))) {
@@ -4289,8 +4295,9 @@ lock_deadlock_check_and_resolve(
lock_deadlock_joining_trx_print(trx, lock);
}
#ifdef WITH_WSREP
- } else
+ } else {
/* BF processor */;
+ }
#endif /* WITH_WSREP */
MONITOR_INC(MONITOR_DEADLOCK);
diff --git a/storage/innobase/rem/rem0rec.cc b/storage/innobase/rem/rem0rec.cc
index 8bcb820553e..c1fee934fcd 100644
--- a/storage/innobase/rem/rem0rec.cc
+++ b/storage/innobase/rem/rem0rec.cc
@@ -2025,10 +2025,10 @@ wsrep_rec_get_foreign_key(
key_len++;
}
memcpy(buf, data, len);
- wsrep_innobase_mysql_sort(
+ *buf_len = wsrep_innobase_mysql_sort(
(int)(col_f->prtype & DATA_MYSQL_TYPE_MASK),
(uint)dtype_get_charset_coll(col_f->prtype),
- buf, len);
+ buf, len, *buf_len);
} else { /* new protocol */
if (!(col_r->prtype & DATA_NOT_NULL)) {
*buf++ = 0;
@@ -2058,12 +2058,12 @@ wsrep_rec_get_foreign_key(
case DATA_MYSQL:
/* Copy the actual data */
ut_memcpy(buf, data, len);
- wsrep_innobase_mysql_sort(
+ *buf_len = wsrep_innobase_mysql_sort(
(int)
(col_f->prtype & DATA_MYSQL_TYPE_MASK),
(uint)
dtype_get_charset_coll(col_f->prtype),
- buf, len);
+ buf, len, *buf_len);
break;
case DATA_BLOB:
case DATA_BINARY:
diff --git a/storage/innobase/row/row0ins.cc b/storage/innobase/row/row0ins.cc
index 928d3435eb9..e6487730a77 100644
--- a/storage/innobase/row/row0ins.cc
+++ b/storage/innobase/row/row0ins.cc
@@ -1937,10 +1937,6 @@ row_ins_scan_sec_index_for_duplicate(
#ifdef UNIV_SYNC_DEBUG
ut_ad(s_latch == rw_lock_own(&index->lock, RW_LOCK_SHARED));
#endif /* UNIV_SYNC_DEBUG */
-#ifdef WITH_WSREP
- /* appliers don't need dupkey checks */
- if (wsrep_thd_is_BF(thr_get_trx(thr)->mysql_thd, 0)) return(DB_SUCCESS);
-#endif /* WITH_WSREP */
n_unique = dict_index_get_n_unique(index);
diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc
index 70f5a0a64f7..12042d7c0a4 100644
--- a/storage/xtradb/handler/ha_innodb.cc
+++ b/storage/xtradb/handler/ha_innodb.cc
@@ -6045,18 +6045,21 @@ get_field_offset(
#ifdef WITH_WSREP
UNIV_INTERN
-void
+int
wsrep_innobase_mysql_sort(
/*===============*/
/* out: str contains sort string */
int mysql_type, /* in: MySQL type */
uint charset_number, /* in: number of the charset */
unsigned char* str, /* in: data field */
- unsigned int str_length) /* in: data field length,
+ unsigned int str_length, /* in: data field length,
not UNIV_SQL_NULL */
+ unsigned int buf_length) /* in: total str buffer length */
+
{
CHARSET_INFO* charset;
enum_field_types mysql_tp;
+ int ret_length = str_length;
DBUG_ASSERT(str_length != UNIV_SQL_NULL);
@@ -6100,14 +6103,26 @@ wsrep_innobase_mysql_sort(
ut_a(str_length <= tmp_length);
memcpy(tmp_str, str, str_length);
- //tmp_length = charset->coll->strnxfrm(charset, str, str_length,
- // tmp_str, str_length);
- /* Note: in MySQL 5.6:
- */
tmp_length = charset->coll->strnxfrm(charset, str, str_length,
- str_length, tmp_str, tmp_length, 0);
- /**/
+ str_length, tmp_str,
+ tmp_length, 0);
DBUG_ASSERT(tmp_length <= str_length);
+ if (wsrep_protocol_version < 3) {
+ tmp_length = charset->coll->strnxfrm(
+ charset, str, str_length,
+ str_length, tmp_str, tmp_length, 0);
+ DBUG_ASSERT(tmp_length <= str_length);
+ } else {
+ /* strnxfrm will expand the destination string,
+ protocols < 3 truncated the sorted sring
+ protocols > 3 gets full sorted sring
+ */
+ tmp_length = charset->coll->strnxfrm(
+ charset, str, buf_length,
+ str_length, tmp_str, tmp_length, 0);
+ DBUG_ASSERT(tmp_length <= buf_length);
+ ret_length = tmp_length;
+ }
break;
}
@@ -6135,7 +6150,7 @@ wsrep_innobase_mysql_sort(
break;
}
- return;
+ return ret_length;
}
#endif /* WITH_WSREP */
@@ -6693,6 +6708,7 @@ wsrep_store_key_val_for_row(
const byte* data;
ulint key_len;
ulint true_len;
+ ulint sort_len;
const CHARSET_INFO* cs;
int error=0;
@@ -6735,11 +6751,12 @@ wsrep_store_key_val_for_row(
}
memcpy(sorted, data, true_len);
- wsrep_innobase_mysql_sort(
- mysql_type, cs->number, sorted, true_len);
+ sort_len = wsrep_innobase_mysql_sort(
+ mysql_type, cs->number, sorted, true_len,
+ REC_VERSION_56_MAX_INDEX_COL_LEN);
if (wsrep_protocol_version > 1) {
- memcpy(buff, sorted, true_len);
+ memcpy(buff, sorted, sort_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
@@ -6760,6 +6777,7 @@ wsrep_store_key_val_for_row(
const CHARSET_INFO* cs;
ulint key_len;
ulint true_len;
+ ulint sort_len;
int error=0;
ulint blob_len;
const byte* blob_data;
@@ -6808,10 +6826,11 @@ wsrep_store_key_val_for_row(
}
memcpy(sorted, blob_data, true_len);
- wsrep_innobase_mysql_sort(
- mysql_type, cs->number, sorted, true_len);
+ sort_len = wsrep_innobase_mysql_sort(
+ mysql_type, cs->number, sorted, true_len,
+ REC_VERSION_56_MAX_INDEX_COL_LEN);
- memcpy(buff, sorted, true_len);
+ memcpy(buff, sorted, sort_len);
/* Note that we always reserve the maximum possible
length of the BLOB prefix in the key value. */
@@ -6828,6 +6847,7 @@ wsrep_store_key_val_for_row(
const CHARSET_INFO* cs = NULL;
ulint true_len;
+ ulint sort_len;
ulint key_len;
const uchar* src_start;
int error=0;
@@ -6872,9 +6892,11 @@ wsrep_store_key_val_for_row(
&error);
}
memcpy(sorted, src_start, true_len);
- wsrep_innobase_mysql_sort(
- mysql_type, cs->number, sorted, true_len);
- memcpy(buff, sorted, true_len);
+ sort_len = wsrep_innobase_mysql_sort(
+ mysql_type, cs->number, sorted, true_len,
+ REC_VERSION_56_MAX_INDEX_COL_LEN);
+
+ memcpy(buff, sorted, sort_len);
} else {
memcpy(buff, src_start, true_len);
}
@@ -9985,7 +10007,7 @@ wsrep_append_foreign_key(
wsrep_thd_query(thd) : "void");
return DB_ERROR;
}
- byte key[WSREP_MAX_SUPPORTED_KEY_LENGTH+1];
+ byte key[WSREP_MAX_SUPPORTED_KEY_LENGTH+1] = {'\0'};
ulint len = WSREP_MAX_SUPPORTED_KEY_LENGTH;
dict_index_t *idx_target = (referenced) ?
@@ -10180,10 +10202,15 @@ ha_innobase::wsrep_append_keys(
uint i;
bool hasPK= false;
- for (i=0; i<table->s->keys && !hasPK; ++i) {
- KEY* key_info = table->key_info + i;
- if (key_info->flags & HA_NOSAME) hasPK = true;
- }
+ for (i=0; i<table->s->keys; ++i) {
+ KEY* key_info = table->key_info + i;
+ if (key_info->flags & HA_NOSAME) {
+ hasPK = true;
+ if (i != table->s->primary_key) {
+ wsrep_thd_set_PA_safe(thd, FALSE);
+ }
+ }
+ }
for (i=0; i<table->s->keys; ++i) {
uint len;
@@ -10205,6 +10232,7 @@ ha_innobase::wsrep_append_keys(
table->s->table_name.str,
key_info->name);
}
+ /* !hasPK == table with no PK, must append all non-unique keys */
if (!hasPK || key_info->flags & HA_NOSAME ||
((tab &&
dict_table_get_referenced_constraint(tab, idx)) ||
@@ -18206,6 +18234,7 @@ static int innobase_wsrep_set_checkpoint(handlerton* hton, const XID* xid)
trx_sysf_t* sys_header = trx_sysf_get(&mtr);
trx_sys_update_wsrep_checkpoint(xid, sys_header, &mtr);
mtr_commit(&mtr);
+ innobase_flush_logs(hton);
return 0;
} else {
return 1;
diff --git a/storage/xtradb/include/ha_prototypes.h b/storage/xtradb/include/ha_prototypes.h
index 095ab484159..1dd109eb940 100644
--- a/storage/xtradb/include/ha_prototypes.h
+++ b/storage/xtradb/include/ha_prototypes.h
@@ -290,10 +290,13 @@ UNIV_INTERN
int
wsrep_innobase_kill_one_trx(void *thd_ptr,
const trx_t *bf_trx, trx_t *victim_trx, ibool signal);
+my_bool wsrep_thd_set_PA_safe(void *thd_ptr, my_bool safe);
+int wsrep_thd_conflict_state(void *thd_ptr, my_bool sync);
my_bool wsrep_thd_is_BF(void *thd_ptr, my_bool sync);
int wsrep_trx_order_before(void *thd1, void *thd2);
-void wsrep_innobase_mysql_sort(int mysql_type, uint charset_number,
- unsigned char* str, unsigned int str_length);
+int wsrep_innobase_mysql_sort(int mysql_type, uint charset_number,
+ unsigned char* str, unsigned int str_length,
+ unsigned int buf_length);
int
wsrep_on(void *thd_ptr);
extern "C" int wsrep_is_wsrep_xid(const void*);
diff --git a/storage/xtradb/lock/lock0lock.cc b/storage/xtradb/lock/lock0lock.cc
index a32509f7bdb..4a633c1bcd2 100644
--- a/storage/xtradb/lock/lock0lock.cc
+++ b/storage/xtradb/lock/lock0lock.cc
@@ -1042,7 +1042,12 @@ lock_rec_has_to_wait(
(lock2->type_mode & LOCK_MODE_MASK) == LOCK_X)
{
/* exclusive lock conflicts are not accepted */
- fprintf(stderr, "BF-BF X lock conflict\n");
+ fprintf(stderr, "BF-BF X lock conflict,"
+ "type_mode: %lu supremum: %lu\n",
+ type_mode, lock_is_on_supremum);
+ fprintf(stderr, "conflicts states: my %d locked %d\n",
+ wsrep_thd_conflict_state(trx->mysql_thd, FALSE),
+ wsrep_thd_conflict_state(lock2->trx->mysql_thd, FALSE) );
lock_rec_print(stderr, lock2);
abort();
} else {
@@ -1623,6 +1628,7 @@ wsrep_kill_victim(const trx_t * const trx, const lock_t *lock) {
ut_ad(trx_mutex_own(lock->trx));
my_bool bf_this = wsrep_thd_is_BF(trx->mysql_thd, FALSE);
my_bool bf_other = wsrep_thd_is_BF(lock->trx->mysql_thd, TRUE);
+
if ((bf_this && !bf_other) ||
(bf_this && bf_other && wsrep_trx_order_before(
trx->mysql_thd, lock->trx->mysql_thd))) {
@@ -4314,8 +4320,9 @@ lock_deadlock_check_and_resolve(
lock_deadlock_joining_trx_print(trx, lock);
}
#ifdef WITH_WSREP
- } else
+ } else {
/* BF processor */;
+ }
#endif /* WITH_WSREP */
MONITOR_INC(MONITOR_DEADLOCK);
diff --git a/storage/xtradb/rem/rem0rec.cc b/storage/xtradb/rem/rem0rec.cc
index 45874f464fd..79a542845a3 100644
--- a/storage/xtradb/rem/rem0rec.cc
+++ b/storage/xtradb/rem/rem0rec.cc
@@ -1983,10 +1983,10 @@ wsrep_rec_get_foreign_key(
key_len++;
}
memcpy(buf, data, len);
- wsrep_innobase_mysql_sort(
+ *buf_len = wsrep_innobase_mysql_sort(
(int)(col_f->prtype & DATA_MYSQL_TYPE_MASK),
(uint)dtype_get_charset_coll(col_f->prtype),
- buf, len);
+ buf, len, *buf_len);
} else { /* new protocol */
if (!(col_r->prtype & DATA_NOT_NULL)) {
*buf++ = 0;
@@ -2016,12 +2016,12 @@ wsrep_rec_get_foreign_key(
case DATA_MYSQL:
/* Copy the actual data */
ut_memcpy(buf, data, len);
- wsrep_innobase_mysql_sort(
+ *buf_len = wsrep_innobase_mysql_sort(
(int)
(col_f->prtype & DATA_MYSQL_TYPE_MASK),
(uint)
dtype_get_charset_coll(col_f->prtype),
- buf, len);
+ buf, len, *buf_len);
break;
case DATA_BLOB:
case DATA_BINARY:
diff --git a/storage/xtradb/row/row0ins.cc b/storage/xtradb/row/row0ins.cc
index 69ce31e1625..444fac87842 100644
--- a/storage/xtradb/row/row0ins.cc
+++ b/storage/xtradb/row/row0ins.cc
@@ -1949,10 +1949,6 @@ row_ins_scan_sec_index_for_duplicate(
#ifdef UNIV_SYNC_DEBUG
ut_ad(s_latch == rw_lock_own(&index->lock, RW_LOCK_SHARED));
#endif /* UNIV_SYNC_DEBUG */
-#ifdef WITH_WSREP
- /* appliers don't need dupkey checks */
- if (wsrep_thd_is_BF(thr_get_trx(thr)->mysql_thd, 0)) return(DB_SUCCESS);
-#endif /* WITH_WSREP */
n_unique = dict_index_get_n_unique(index);