diff options
author | Nirbhay Choubey <nirbhay@skysql.com> | 2014-06-19 18:48:20 -0400 |
---|---|---|
committer | Nirbhay Choubey <nirbhay@skysql.com> | 2014-06-19 18:48:20 -0400 |
commit | 97779a2ef05d2141d2ade2f72f0900dbd9960751 (patch) | |
tree | 1f2eb2c003247b77d602af4a035a7dd6f7e27aea | |
parent | a76a6601ecb63d452c89202d8ca7f11bf2e0194f (diff) | |
download | mariadb-git-97779a2ef05d2141d2ade2f72f0900dbd9960751.tar.gz |
bzr merge -r4091..4101 codership/5.6/
-rw-r--r-- | cmake/wsrep.cmake | 2 | ||||
-rw-r--r-- | sql/event_data_objects.cc | 13 | ||||
-rw-r--r-- | sql/events.cc | 42 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 12 | ||||
-rw-r--r-- | sql/sys_vars.cc | 12 | ||||
-rw-r--r-- | sql/wsrep_applier.cc | 11 | ||||
-rw-r--r-- | sql/wsrep_mysqld.cc | 20 | ||||
-rw-r--r-- | sql/wsrep_mysqld.h | 3 | ||||
-rw-r--r-- | sql/wsrep_thd.cc | 23 | ||||
-rw-r--r-- | sql/wsrep_thd.h | 2 | ||||
-rw-r--r-- | storage/innobase/handler/ha_innodb.cc | 75 | ||||
-rw-r--r-- | storage/innobase/include/ha_prototypes.h | 7 | ||||
-rw-r--r-- | storage/innobase/lock/lock0lock.cc | 11 | ||||
-rw-r--r-- | storage/innobase/rem/rem0rec.cc | 8 | ||||
-rw-r--r-- | storage/innobase/row/row0ins.cc | 4 | ||||
-rw-r--r-- | storage/xtradb/handler/ha_innodb.cc | 75 | ||||
-rw-r--r-- | storage/xtradb/include/ha_prototypes.h | 7 | ||||
-rw-r--r-- | storage/xtradb/lock/lock0lock.cc | 11 | ||||
-rw-r--r-- | storage/xtradb/rem/rem0rec.cc | 8 | ||||
-rw-r--r-- | storage/xtradb/row/row0ins.cc | 4 |
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); |