diff options
author | Seppo Jaakola <seppo.jaakola@codership.com> | 2012-04-26 20:18:30 +0300 |
---|---|---|
committer | Seppo Jaakola <seppo.jaakola@codership.com> | 2012-04-26 20:18:30 +0300 |
commit | 609388fcfd912c9c2cb03a92251469a25a781893 (patch) | |
tree | 9135fdc6e31e1e784fbdbcc35ae63003d0600824 | |
parent | e0015163515d1fe5d3747c6f859461a30c2ecfd6 (diff) | |
download | mariadb-git-609388fcfd912c9c2cb03a92251469a25a781893.tar.gz |
Merged changes from lp:codership-mysql up to rev 3743
-r3725..3737
-r3738..3740
-r3741..3743
-rw-r--r-- | sql/log_event.cc | 25 | ||||
-rw-r--r-- | sql/sql_alter.cc | 7 | ||||
-rw-r--r-- | sql/sql_base.cc | 19 | ||||
-rw-r--r-- | sql/sql_connect.cc | 6 | ||||
-rw-r--r-- | sql/sql_parse.cc | 203 | ||||
-rw-r--r-- | sql/sql_truncate.cc | 2 | ||||
-rw-r--r-- | sql/sys_vars.cc | 3 | ||||
-rw-r--r-- | sql/transaction.cc | 2 | ||||
-rw-r--r-- | sql/wsrep_hton.cc | 20 | ||||
-rw-r--r-- | sql/wsrep_mysqld.cc | 166 | ||||
-rw-r--r-- | sql/wsrep_mysqld.h | 22 | ||||
-rw-r--r-- | sql/wsrep_utils.cc | 2 | ||||
-rw-r--r-- | storage/innobase/handler/ha_innodb.cc | 5 | ||||
-rw-r--r-- | storage/innobase/rem/rem0rec.c | 26 | ||||
-rw-r--r-- | storage/xtradb/handler/ha_innodb.cc | 5 | ||||
-rw-r--r-- | storage/xtradb/rem/rem0rec.c | 26 |
16 files changed, 349 insertions, 190 deletions
diff --git a/sql/log_event.cc b/sql/log_event.cc index e02cfc6d20c..1536d9e899b 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -8130,19 +8130,20 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli) thd->variables.option_bits&= ~OPTION_RELAXED_UNIQUE_CHECKS; /* A small test to verify that objects have consistent types */ DBUG_ASSERT(sizeof(thd->variables.option_bits) == sizeof(OPTION_RELAXED_UNIQUE_CHECKS)); - if (open_and_lock_tables(thd, rli->tables_to_lock, FALSE, 0)) { + uint actual_error= thd->stmt_da->sql_errno(); #ifdef WITH_WSREP - uint actual_error= ER_SERVER_SHUTDOWN; - if (WSREP(thd) && !thd->is_fatal_error) + if (WSREP(thd)) { - sql_print_information("WSREP, BF applier interrupted in log_event.cc"); + WSREP_WARN("BF applier failed to open_and_lock_tables: %u, fatal: %d " + "wsrep = (exec_mode: %d conflict_state: %d seqno: %lld)", + thd->stmt_da->sql_errno(), + thd->is_fatal_error, + thd->wsrep_exec_mode, + thd->wsrep_conflict_state, + (long long)thd->wsrep_trx_seqno); } - else - actual_error= thd->stmt_da->sql_errno(); -#else - uint actual_error= thd->stmt_da->sql_errno(); #endif if (thd->is_slave_error || thd->is_fatal_error) { @@ -10878,6 +10879,8 @@ Format_description_log_event *wsrep_format_desc; // TODO: free them at the end At the end (*buf) is shitfed to point to the following event or NULL and (*buf_len) will be changed to account just being read bytes of the 1st event. */ +#define WSREP_MAX_ALLOWED_PACKET 1024*1024*1024 // current protocol max + Log_event* wsrep_read_log_event( char **arg_buf, size_t *arg_buf_len, const Format_description_log_event *description_event) @@ -10889,12 +10892,8 @@ Log_event* wsrep_read_log_event( char *buf= (*arg_buf); const char *error= 0; Log_event *res= 0; -#ifndef max_allowed_packet - THD *thd=current_thd; - uint max_allowed_packet= thd ? thd->variables.max_allowed_packet : ~(ulong)0; -#endif - if (data_len > max_allowed_packet) + if (data_len > WSREP_MAX_ALLOWED_PACKET) { error = "Event too big"; goto err; diff --git a/sql/sql_alter.cc b/sql/sql_alter.cc index c4468ee8793..00691633aa8 100644 --- a/sql/sql_alter.cc +++ b/sql/sql_alter.cc @@ -100,11 +100,14 @@ bool Alter_table_statement::execute(THD *thd) thd->enable_slow_log= opt_log_slow_admin_statements; #ifdef WITH_WSREP -TABLE *find_temporary_table(THD *thd, const TABLE_LIST *tl); + TABLE *find_temporary_table(THD *thd, const TABLE_LIST *tl); if ((!thd->is_current_stmt_binlog_format_row() || !find_temporary_table(thd, first_table)) && - wsrep_to_isolation_begin(thd, first_table->db, first_table->table_name)) + wsrep_to_isolation_begin(thd, + lex->name.str ? select_lex->db : NULL, + lex->name.str ? lex->name.str : NULL, + first_table)) { WSREP_WARN("ALTER TABLE isolation failure"); DBUG_RETURN(TRUE); diff --git a/sql/sql_base.cc b/sql/sql_base.cc index d4aeedeb852..da93cfeb001 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -62,6 +62,7 @@ #ifdef WITH_WSREP #include "wsrep_mysqld.h" + #endif // WITH_WSREP bool @@ -5077,6 +5078,24 @@ restart: } } } +#ifdef WITH_WSREP +#define WSREP_TO_ISOLATION_BEGIN(db_, table_, table_list_) \ + if (WSREP(thd) && wsrep_to_isolation_begin(thd, db_, table_, table_list_)) goto err; + + if ((thd->lex->sql_command== SQLCOM_INSERT || + thd->lex->sql_command== SQLCOM_INSERT_SELECT || + thd->lex->sql_command== SQLCOM_REPLACE || + thd->lex->sql_command== SQLCOM_REPLACE_SELECT || + thd->lex->sql_command== SQLCOM_UPDATE || + thd->lex->sql_command== SQLCOM_UPDATE_MULTI || + thd->lex->sql_command== SQLCOM_LOAD || + thd->lex->sql_command== SQLCOM_DELETE) && + wsrep_replicate_myisam && + (*start)->table && (*start)->table->file->ht->db_type == DB_TYPE_MYISAM) + { + WSREP_TO_ISOLATION_BEGIN(NULL, NULL, (*start)); + } +#endif err: #ifdef WITH_WSREP diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc index 04e46bfa1e6..c0cdddeb561 100644 --- a/sql/sql_connect.cc +++ b/sql/sql_connect.cc @@ -100,9 +100,6 @@ int get_or_create_user_conn(THD *thd, const char *user, } thd->user_connect=uc; uc->connections++; -#ifdef WITH_WSREP - thd->wsrep_client_thread= 1; -#endif /* WITH_WSREP */ end: mysql_mutex_unlock(&LOCK_user_conn); return return_val; @@ -1203,6 +1200,9 @@ bool thd_prepare_connection(THD *thd) (char *) thd->security_ctx->host_or_ip); prepare_new_connection_state(thd); +#ifdef WITH_WSREP + thd->wsrep_client_thread= 1; +#endif /* WITH_WSREP */ return FALSE; } diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 51d81616c24..b4b7eb0b2cf 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -105,19 +105,20 @@ #ifdef WITH_WSREP #include "wsrep_mysqld.h" #include "rpl_rli.h" +static void wsrep_client_rollback(THD *thd); extern Format_description_log_event *wsrep_format_desc; #define WSREP_MYSQL_DB (char *)"mysql" -#define WSREP_TO_ISOLATION_BEGIN(db_, table_) \ - if (WSREP(thd) && wsrep_to_isolation_begin(thd, db_, table_)) goto error; +#define WSREP_TO_ISOLATION_BEGIN(db_, table_, table_list_) \ + if (WSREP(thd) && wsrep_to_isolation_begin(thd, db_, table_, table_list_)) goto error; #define WSREP_TO_ISOLATION_END \ if (WSREP(thd) || (thd && thd->wsrep_exec_mode==TOTAL_ORDER)) \ wsrep_to_isolation_end(thd); #else -#define WSREP_TO_ISOLATION_BEGIN(db_, table_) +#define WSREP_TO_ISOLATION_BEGIN(db_, table_, table_list_) #define WSREP_TO_ISOLATION_END #endif /* WITH_WSREP */ /** @@ -727,15 +728,7 @@ bool do_command(THD *thd) thd->wsrep_query_state= QUERY_IDLE; if (thd->wsrep_conflict_state==MUST_ABORT) { - thd->wsrep_conflict_state= ABORTING; - - mysql_mutex_unlock(&thd->LOCK_wsrep_thd); - trans_rollback(thd); - thd->locked_tables_list.unlock_locked_tables(thd); - /* Release transactional metadata locks. */ - thd->mdl_context.release_transactional_locks(); - mysql_mutex_lock(&thd->LOCK_wsrep_thd); - thd->wsrep_conflict_state= ABORTED; + wsrep_client_rollback(thd); } mysql_mutex_unlock(&thd->LOCK_wsrep_thd); } @@ -822,16 +815,7 @@ bool do_command(THD *thd) if (thd->wsrep_conflict_state == MUST_ABORT) { DBUG_PRINT("wsrep",("aborted for wsrep rollback: %lu", thd->real_id)); - thd->wsrep_conflict_state= ABORTING; - - mysql_mutex_unlock(&thd->LOCK_wsrep_thd); - trans_rollback(thd); - thd->locked_tables_list.unlock_locked_tables(thd); - /* Release transactional metadata locks. */ - thd->mdl_context.release_transactional_locks(); - - mysql_mutex_lock(&thd->LOCK_wsrep_thd); - thd->wsrep_conflict_state= ABORTED; + wsrep_client_rollback(thd); } mysql_mutex_unlock(&thd->LOCK_wsrep_thd); } @@ -1082,14 +1066,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, if (thd->wsrep_conflict_state== MUST_ABORT) { - thd->wsrep_conflict_state= ABORTING; - mysql_mutex_unlock(&thd->LOCK_wsrep_thd); - trans_rollback(thd); - thd->locked_tables_list.unlock_locked_tables(thd); - /* Release transactional metadata locks. */ - thd->mdl_context.release_transactional_locks(); - mysql_mutex_lock(&thd->LOCK_wsrep_thd); - thd->wsrep_conflict_state= ABORTED; + wsrep_client_rollback(thd); } if (thd->wsrep_conflict_state== ABORTED) { @@ -1641,43 +1618,11 @@ bool dispatch_command(enum enum_server_command command, THD *thd, /* wsrep BF abort in query exec phase */ mysql_mutex_lock(&thd->LOCK_wsrep_thd); if (thd->wsrep_conflict_state == MUST_ABORT) { - mysql_mutex_unlock(&thd->LOCK_wsrep_thd); - ha_rollback_trans(thd, 0); - thd->locked_tables_list.unlock_locked_tables(thd); - /* Release transactional metadata locks. */ - thd->mdl_context.release_transactional_locks(); - thd->transaction.stmt.reset(); - WSREP_DEBUG("abort in exec query state, avoiding autocommit"); - goto wsrep_must_abort; - } - mysql_mutex_unlock(&thd->LOCK_wsrep_thd); - } -#endif /* WITH_WSREP */ + wsrep_client_rollback(thd); -#ifdef WITH_WSREP - wsrep_must_abort: - if (WSREP(thd)) { - mysql_mutex_lock(&thd->LOCK_wsrep_thd); - if (thd->wsrep_conflict_state == MUST_ABORT) { - thd->wsrep_conflict_state= ABORTING; - mysql_mutex_unlock(&thd->LOCK_wsrep_thd); - - WSREP_DEBUG("in dispatch_command, aborting %s", - (thd->query()) ? thd->query() : "void"); - trans_rollback(thd); - thd->locked_tables_list.unlock_locked_tables(thd); - /* Release transactional metadata locks. */ - thd->mdl_context.release_transactional_locks(); - - if (thd->get_binlog_table_maps()) { - thd->clear_binlog_table_maps(); - } - mysql_mutex_lock(&thd->LOCK_wsrep_thd); - thd->wsrep_conflict_state= ABORTED; + WSREP_DEBUG("abort in exec query state, avoiding autocommit"); } - mysql_mutex_unlock(&thd->LOCK_wsrep_thd); - mysql_mutex_lock(&thd->LOCK_wsrep_thd); /* checking if BF trx must be replayed */ if (thd->wsrep_conflict_state== MUST_REPLAY) { if (thd->wsrep_exec_mode!= REPL_RECV) { @@ -1692,11 +1637,18 @@ bool dispatch_command(enum enum_server_command command, THD *thd, mysql_reset_thd_for_next_command(thd, opt_userstat_running); thd->killed= NOT_KILLED; close_thread_tables(thd); + if (thd->locked_tables_mode && thd->lock) + { + WSREP_DEBUG("releasing table lock for replaying (%ld)", thd->thread_id); + thd->locked_tables_list.unlock_locked_tables(thd); + thd->variables.option_bits&= ~(OPTION_TABLE_LOCK); + } + thd->mdl_context.release_transactional_locks(); thd_proc_info(thd, "wsrep replaying trx"); WSREP_DEBUG("replay trx: %s %lld", - thd->query() ? thd->query() : "void", - (long long)thd->wsrep_trx_seqno); + thd->query() ? thd->query() : "void", + (long long)thd->wsrep_trx_seqno); struct wsrep_thd_shadow shadow; wsrep_prepare_bf_thd(thd, &shadow); int rcode = wsrep->replay_trx(wsrep, @@ -2547,7 +2499,7 @@ mysql_execute_command(THD *thd) case SQLCOM_SHOW_STATUS_PROC: case SQLCOM_SHOW_STATUS_FUNC: #ifdef WITH_WSREP - if (WSREP(thd) && wsrep_causal_wait(thd)) goto error; + if (WSREP_CLIENT(thd) && wsrep_causal_wait(thd)) goto error; #endif /* WITH_WSREP */ if ((res= check_table_access(thd, SELECT_ACL, all_tables, FALSE, UINT_MAX, FALSE))) @@ -2557,7 +2509,7 @@ mysql_execute_command(THD *thd) case SQLCOM_SHOW_STATUS: { #ifdef WITH_WSREP - if (WSREP(thd) && wsrep_causal_wait(thd)) goto error; + if (WSREP_CLIENT(thd) && wsrep_causal_wait(thd)) goto error; #endif /* WITH_WSREP */ execute_show_status(thd, all_tables); break; @@ -2583,7 +2535,7 @@ mysql_execute_command(THD *thd) case SQLCOM_SHOW_INDEX_STATS: case SQLCOM_SELECT: #ifdef WITH_WSREP - if (WSREP(thd) && wsrep_causal_wait(thd)) goto error; + if (WSREP_CLIENT(thd) && wsrep_causal_wait(thd)) goto error; case SQLCOM_SHOW_VARIABLES: case SQLCOM_SHOW_CHARSETS: case SQLCOM_SHOW_COLLATIONS: @@ -3007,7 +2959,8 @@ case SQLCOM_PREPARE: #ifdef WITH_WSREP if (!thd->is_current_stmt_binlog_format_row() || !(create_info.options & HA_LEX_CREATE_TMP_TABLE)) - WSREP_TO_ISOLATION_BEGIN(create_table->db, create_table->table_name) + WSREP_TO_ISOLATION_BEGIN(create_table->db, create_table->table_name, + NULL) #endif /* WITH_WSREP */ if (create_info.options & HA_LEX_CREATE_TABLE_LIKE) { @@ -3050,7 +3003,7 @@ end_with_restore_list: DBUG_ASSERT(first_table == all_tables && first_table != 0); if (check_one_table_access(thd, INDEX_ACL, all_tables)) goto error; /* purecov: inspected */ - WSREP_TO_ISOLATION_BEGIN(first_table->db, first_table->table_name) + WSREP_TO_ISOLATION_BEGIN(first_table->db, first_table->table_name, NULL) /* Currently CREATE INDEX or DROP INDEX cause a full table rebuild and thus classify as slow administrative statements just like @@ -3108,7 +3061,7 @@ end_with_restore_list: case SQLCOM_RENAME_TABLE: { - WSREP_TO_ISOLATION_BEGIN(first_table->db, first_table->table_name) + WSREP_TO_ISOLATION_BEGIN(0, 0, first_table) if (execute_rename_table(thd, first_table, all_tables)) goto error; break; @@ -3137,7 +3090,7 @@ end_with_restore_list: #else { #ifdef WITH_WSREP - if (WSREP(thd) && wsrep_causal_wait(thd)) goto error; + if (WSREP_CLIENT(thd) && wsrep_causal_wait(thd)) goto error; #endif /* WITH_WSREP */ /* @@ -3196,7 +3149,7 @@ end_with_restore_list: { DBUG_ASSERT(first_table == all_tables && first_table != 0); #ifdef WITH_WSREP - if (WSREP(thd) && wsrep_causal_wait(thd)) goto error; + if (WSREP_CLIENT(thd) && wsrep_causal_wait(thd)) goto error; #endif /* WITH_WSREP */ if (check_table_access(thd, SELECT_ACL, all_tables, @@ -3397,7 +3350,7 @@ end_with_restore_list: if (lex->sql_command == SQLCOM_INSERT_SELECT && thd->wsrep_consistency_check) { - WSREP_TO_ISOLATION_BEGIN(first_table->db, first_table->table_name); + WSREP_TO_ISOLATION_BEGIN(first_table->db, first_table->table_name, NULL); } #endif @@ -3568,9 +3521,9 @@ end_with_restore_list: for (TABLE_LIST *table= all_tables; table; table= table->next_global) { if (!thd->is_current_stmt_binlog_format_row() || - !find_temporary_table(thd, table)) + !find_temporary_table(thd, table)) { - WSREP_TO_ISOLATION_BEGIN(table->db, table->table_name); + WSREP_TO_ISOLATION_BEGIN(NULL, NULL, all_tables); break; } } @@ -3760,7 +3713,7 @@ end_with_restore_list: #endif if (check_access(thd, CREATE_ACL, lex->name.str, NULL, NULL, 1, 0)) break; - WSREP_TO_ISOLATION_BEGIN(lex->name.str, NULL) + WSREP_TO_ISOLATION_BEGIN(lex->name.str, NULL, NULL) res= mysql_create_db(thd,(lower_case_table_names == 2 ? alias : lex->name.str), &create_info, 0); break; @@ -3790,7 +3743,7 @@ end_with_restore_list: #endif if (check_access(thd, DROP_ACL, lex->name.str, NULL, NULL, 1, 0)) break; - WSREP_TO_ISOLATION_BEGIN(lex->name.str, NULL) + WSREP_TO_ISOLATION_BEGIN(lex->name.str, NULL, NULL) res= mysql_rm_db(thd, lex->name.str, lex->drop_if_exists, 0); break; } @@ -3819,7 +3772,7 @@ end_with_restore_list: res= 1; break; } - WSREP_TO_ISOLATION_BEGIN(db->str, NULL) + WSREP_TO_ISOLATION_BEGIN(db->str, NULL, NULL) res= mysql_upgrade_db(thd, db); if (!res) my_ok(thd); @@ -3852,7 +3805,7 @@ end_with_restore_list: #endif if (check_access(thd, ALTER_ACL, db->str, NULL, NULL, 1, 0)) break; - WSREP_TO_ISOLATION_BEGIN(db->str, NULL) + WSREP_TO_ISOLATION_BEGIN(db->str, NULL, NULL) res= mysql_alter_db(thd, db->str, &create_info); break; } @@ -3885,7 +3838,7 @@ end_with_restore_list: if (res) break; - WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL) + WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL) switch (lex->sql_command) { case SQLCOM_CREATE_EVENT: { @@ -3920,7 +3873,7 @@ end_with_restore_list: lex->spname->m_name); break; case SQLCOM_DROP_EVENT: - WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL) + WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL) if (!(res= Events::drop_event(thd, lex->spname->m_db, lex->spname->m_name, lex->drop_if_exists))) @@ -3935,7 +3888,7 @@ end_with_restore_list: if (check_access(thd, INSERT_ACL, "mysql", NULL, NULL, 1, 0)) break; #ifdef HAVE_DLOPEN - WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL) + WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL) if (!(res = mysql_create_function(thd, &lex->udf))) my_ok(thd); #else @@ -3950,7 +3903,7 @@ end_with_restore_list: if (check_access(thd, INSERT_ACL, "mysql", NULL, NULL, 1, 1) && check_global_access(thd,CREATE_USER_ACL)) break; - WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL) + WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL) /* Conditionally writes to binlog */ if (!(res= mysql_create_user(thd, lex->users_list))) my_ok(thd); @@ -3962,7 +3915,7 @@ end_with_restore_list: check_global_access(thd,CREATE_USER_ACL)) break; /* Conditionally writes to binlog */ - WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL) + WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL) if (!(res= mysql_drop_user(thd, lex->users_list))) my_ok(thd); break; @@ -3973,7 +3926,7 @@ end_with_restore_list: check_global_access(thd,CREATE_USER_ACL)) break; /* Conditionally writes to binlog */ - WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL) + WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL) if (!(res= mysql_rename_user(thd, lex->users_list))) my_ok(thd); break; @@ -3988,7 +3941,7 @@ end_with_restore_list: thd->binlog_invoker(); /* Conditionally writes to binlog */ - WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL) + WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL) if (!(res = mysql_revoke_all(thd, lex->users_list))) my_ok(thd); break; @@ -4055,7 +4008,7 @@ end_with_restore_list: lex->type == TYPE_ENUM_PROCEDURE, 0)) goto error; /* Conditionally writes to binlog */ - WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL) + WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL) res= mysql_routine_grant(thd, all_tables, lex->type == TYPE_ENUM_PROCEDURE, lex->users_list, grants, @@ -4069,7 +4022,7 @@ end_with_restore_list: all_tables, FALSE, UINT_MAX, FALSE)) goto error; /* Conditionally writes to binlog */ - WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL) + WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL) res= mysql_table_grant(thd, all_tables, lex->users_list, lex->columns, lex->grant, lex->sql_command == SQLCOM_REVOKE); @@ -4085,7 +4038,7 @@ end_with_restore_list: } else { - WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL) + WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL) /* Conditionally writes to binlog */ res = mysql_grant(thd, select_lex->db, lex->users_list, lex->grant, lex->sql_command == SQLCOM_REVOKE, @@ -4383,7 +4336,7 @@ end_with_restore_list: if (sp_process_definer(thd)) goto create_sp_error; - WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL) + WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL) res= (sp_result= sp_create_routine(thd, lex->sphead->m_type, lex->sphead)); switch (sp_result) { case SP_OK: { @@ -4595,7 +4548,7 @@ create_sp_error: already puts on CREATE FUNCTION. */ /* Conditionally writes to binlog */ - WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL) + WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL) sp_result= sp_update_routine(thd, type, lex->spname, &lex->sp_chistics); switch (sp_result) { @@ -4667,7 +4620,7 @@ create_sp_error: if (check_routine_access(thd, ALTER_PROC_ACL, db, name, lex->sql_command == SQLCOM_DROP_PROCEDURE, 0)) goto error; - WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL) + WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL) /* Conditionally writes to binlog */ sp_result= sp_drop_routine(thd, type, lex->spname); @@ -4785,7 +4738,7 @@ create_sp_error: Note: SQLCOM_CREATE_VIEW also handles 'ALTER VIEW' commands as specified through the thd->lex->create_view_mode flag. */ - WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL) + WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL) res= mysql_create_view(thd, first_table, thd->lex->create_view_mode); break; } @@ -4794,14 +4747,14 @@ create_sp_error: if (check_table_access(thd, DROP_ACL, all_tables, FALSE, UINT_MAX, FALSE)) goto error; /* Conditionally writes to binlog. */ - WSREP_TO_ISOLATION_BEGIN(NULL, NULL) + WSREP_TO_ISOLATION_BEGIN(NULL, NULL, NULL) res= mysql_drop_view(thd, first_table, thd->lex->drop_mode); break; } case SQLCOM_CREATE_TRIGGER: { /* Conditionally writes to binlog. */ - WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL) + WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL) res= mysql_create_or_drop_trigger(thd, all_tables, 1); break; @@ -4809,7 +4762,7 @@ create_sp_error: case SQLCOM_DROP_TRIGGER: { /* Conditionally writes to binlog. */ - WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL) + WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL) res= mysql_create_or_drop_trigger(thd, all_tables, 0); break; } @@ -4860,13 +4813,13 @@ create_sp_error: my_ok(thd); break; case SQLCOM_INSTALL_PLUGIN: - WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL) + WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL) if (! (res= mysql_install_plugin(thd, &thd->lex->comment, &thd->lex->ident))) my_ok(thd); break; case SQLCOM_UNINSTALL_PLUGIN: - WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL) + WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL) if (! (res= mysql_uninstall_plugin(thd, &thd->lex->comment, &thd->lex->ident))) my_ok(thd); @@ -7905,6 +7858,41 @@ LEX_USER *create_definer(THD *thd, LEX_STRING *user_name, LEX_STRING *host_name) } #ifdef WITH_WSREP +/* must have (&thd->LOCK_wsrep_thd) */ +static void wsrep_client_rollback(THD *thd) +{ + WSREP_DEBUG("client rollback due to BF abort for (%ld), query: %s", + thd->thread_id, thd->query()); + + thd->wsrep_conflict_state= ABORTING; + mysql_mutex_unlock(&thd->LOCK_wsrep_thd); + trans_rollback(thd); + + if (thd->locked_tables_mode && thd->lock) + { + WSREP_DEBUG("unlocking tables for BF abort (%ld)", thd->thread_id); + thd->locked_tables_list.unlock_locked_tables(thd); + thd->variables.option_bits&= ~(OPTION_TABLE_LOCK); + } + + if (thd->global_read_lock.is_acquired()) + { + WSREP_DEBUG("unlocking GRL for BF abort (%ld)", thd->thread_id); + thd->global_read_lock.unlock_global_read_lock(thd); + } + + /* Release transactional metadata locks. */ + thd->mdl_context.release_transactional_locks(); + + if (thd->get_binlog_table_maps()) + { + WSREP_DEBUG("clearing binlog table map for BF abort (%ld)", thd->thread_id); + thd->clear_binlog_table_maps(); + } + mysql_mutex_lock(&thd->LOCK_wsrep_thd); + thd->wsrep_conflict_state= ABORTED; +} + static enum wsrep_status wsrep_apply_sql( THD *thd, const char *sql, size_t sql_len, time_t timeval, uint32 randseed) { @@ -8008,6 +7996,13 @@ static inline wsrep_status_t wsrep_apply_rbr( int error = 0; Log_event* ev= wsrep_read_log_event(&buf, &buf_len, wsrep_format_desc); + if (!ev) + { + WSREP_ERROR("applier could not read binlog event, seqno: %lld, len: %ld", + (long long)thd->wsrep_trx_seqno, buf_len); + rcode= 1; + goto error; + } switch (ev->get_type_code()) { case WRITE_ROWS_EVENT: case UPDATE_ROWS_EVENT: @@ -8378,16 +8373,12 @@ void wsrep_rollback_process(THD *thd) aborting->store_globals(); - trans_rollback(aborting); - aborting->locked_tables_list.unlock_locked_tables(thd); - /* Release transactional metadata locks. */ - aborting->mdl_context.release_transactional_locks(); - mysql_mutex_lock(&aborting->LOCK_wsrep_thd); - aborting->wsrep_conflict_state= ABORTED; + wsrep_client_rollback(aborting); WSREP_DEBUG("WSREP rollbacker aborted thd: %llu", (long long)aborting->real_id); mysql_mutex_unlock(&aborting->LOCK_wsrep_thd); + mysql_mutex_lock(&LOCK_wsrep_rollback); } } diff --git a/sql/sql_truncate.cc b/sql/sql_truncate.cc index a66b2377fcb..6745d461df5 100644 --- a/sql/sql_truncate.cc +++ b/sql/sql_truncate.cc @@ -521,7 +521,7 @@ bool Truncate_statement::execute(THD *thd) #ifdef WITH_WSREP if (WSREP(thd) && wsrep_to_isolation_begin(thd, first_table->db, - first_table->table_name)) + first_table->table_name, NULL)) DBUG_RETURN(TRUE); #endif /* WITH_WSREP */ if (! (res= truncate_table(thd, first_table))) diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index 8edfa8f2a6e..b8c21f9621e 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -3779,6 +3779,9 @@ static Sys_var_mybool Sys_wsrep_recover_datadir( READ_ONLY GLOBAL_VAR(wsrep_recovery), CMD_LINE(OPT_ARG, OPT_WSREP_RECOVER), DEFAULT(FALSE)); +static Sys_var_mybool Sys_wsrep_replicate_myisam( + "wsrep_replicate_myisam", "To enable myisam replication", + GLOBAL_VAR(wsrep_replicate_myisam), CMD_LINE(OPT_ARG), DEFAULT(FALSE)); #endif /* WITH_WSREP */ diff --git a/sql/transaction.cc b/sql/transaction.cc index d5f9436ae53..ef4383df0ea 100644 --- a/sql/transaction.cc +++ b/sql/transaction.cc @@ -158,7 +158,7 @@ bool trans_begin(THD *thd, uint flags) #ifdef WITH_WSREP thd->wsrep_PA_safe= true; - if (thd->wsrep_client_thread && wsrep_causal_wait(thd)) + if (WSREP_CLIENT(thd) && wsrep_causal_wait(thd)) DBUG_RETURN(TRUE); #endif /* WITH_WSREP */ diff --git a/sql/wsrep_hton.cc b/sql/wsrep_hton.cc index 9986d7c79cd..bb5faafc768 100644 --- a/sql/wsrep_hton.cc +++ b/sql/wsrep_hton.cc @@ -15,6 +15,7 @@ #include <mysqld.h> #include "sql_base.h" +#include "rpl_filter.h" #include <sql_class.h> #include "wsrep_mysqld.h" #include "wsrep_priv.h" @@ -174,6 +175,7 @@ int wsrep_commit(handlerton *hton, THD *thd, bool all) DBUG_RETURN(0); } +extern Rpl_filter* binlog_filter; extern my_bool opt_log_slave_updates; enum wsrep_trx_status wsrep_run_wsrep_commit( @@ -238,7 +240,8 @@ wsrep_run_wsrep_commit( while (wsrep_replaying > 0 && thd->wsrep_conflict_state == NO_CONFLICT && thd->killed == NOT_KILLED && - !shutdown_in_progress) { + !shutdown_in_progress) + { mysql_mutex_unlock(&LOCK_wsrep_replaying); mysql_mutex_unlock(&thd->LOCK_wsrep_thd); @@ -278,7 +281,8 @@ wsrep_run_wsrep_commit( WSREP_DEBUG("innobase_commit abort after replaying wait %s", (thd->query()) ? thd->query() : "void"); DBUG_RETURN(WSREP_TRX_ROLLBACK); - } thd->wsrep_query_state = QUERY_COMMITTING; + } + thd->wsrep_query_state = QUERY_COMMITTING; mysql_mutex_unlock(&thd->LOCK_wsrep_thd); cache = get_trans_log(thd); @@ -296,8 +300,18 @@ wsrep_run_wsrep_commit( { mysql_mutex_lock(&thd->LOCK_wsrep_thd); thd->wsrep_exec_mode = LOCAL_COMMIT; - WSREP_DEBUG("empty rbr buffer, query: %s", thd->query()); mysql_mutex_unlock(&thd->LOCK_wsrep_thd); + if (thd->stmt_da->is_ok() && + 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()); + } + else + { + WSREP_DEBUG("empty rbr buffer, query: %s", thd->query()); + } DBUG_RETURN(WSREP_TRX_OK); } if (!rcode) { diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc index 5a5250652b8..be2b8d7fa81 100644 --- a/sql/wsrep_mysqld.cc +++ b/sql/wsrep_mysqld.cc @@ -48,6 +48,7 @@ my_bool wsrep_certify_nonPK = 1; // certify, even when no primary key long wsrep_max_protocol_version = 1; // 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 /* * End configuration options @@ -456,9 +457,25 @@ int wsrep_init() } } + char node_addr[256] = {0, }; + if (!wsrep_node_address || !strcmp(wsrep_node_address, "")) + { + size_t node_addr_max= sizeof(node_addr); + size_t ret= default_ip(node_addr, node_addr_max); + if (!(ret > 0 && ret < node_addr_max)) + { + WSREP_WARN("Failed to autoguess base node address"); + node_addr[0]= 0; + } + } + else if (wsrep_node_address) + { + strncpy(node_addr, wsrep_node_address, sizeof(node_addr) - 1); + } + wsrep_args.data_dir = wsrep_data_home_dir; wsrep_args.node_name = (wsrep_node_name) ? wsrep_node_name : ""; - wsrep_args.node_address = (wsrep_node_address) ? wsrep_node_address : ""; + wsrep_args.node_address = node_addr; wsrep_args.node_incoming = wsrep_node_incoming_address; wsrep_args.options = (wsrep_provider_options) ? wsrep_provider_options : ""; @@ -629,7 +646,8 @@ bool wsrep_causal_wait (THD* thd) { if (thd->variables.wsrep_causal_reads && thd->variables.wsrep_on && - !thd->in_active_multi_stmt_transaction()) + !thd->in_active_multi_stmt_transaction() && + thd->wsrep_conflict_state != REPLAYING) { // This allows autocommit SELECTs and a first SELECT after SET AUTOCOMMIT=0 // TODO: modify to check if thd has locked any rows. @@ -667,10 +685,42 @@ wsrep_causal_wait (THD* thd) return false; } -bool wsrep_prepare_key_for_isolation(const char* db, - const char* table, - wsrep_key_part_t* key, - size_t* key_len) +/* + * Helpers to deal with TOI key arrays + */ +typedef struct wsrep_key_arr +{ + wsrep_key_t* keys; + size_t keys_len; +} wsrep_key_arr_t; + + +static void wsrep_keys_free(wsrep_key_arr_t* key_arr) +{ + for (size_t i= 0; i < key_arr->keys_len; ++i) + { + my_free((wsrep_key_part_t*)key_arr->keys[i].key_parts); + } + my_free(key_arr->keys); + key_arr->keys= 0; + key_arr->keys_len= 0; +} + + +/*! + * @param db Database string + * @param table Table string + * @param key Array of wsrep_key_t + * @param key_len In: number of elements in key array, Out: number of + * elements populated + * + * @return true if preparation was successful, otherwise false. + */ + +static bool wsrep_prepare_key_for_isolation(const char* db, + const char* table, + wsrep_key_part_t* key, + size_t* key_len) { if (*key_len < 2) return false; @@ -707,6 +757,89 @@ bool wsrep_prepare_key_for_isolation(const char* db, return true; } +/* Prepare key list from db/table and table_list */ +static bool wsrep_prepare_keys_for_isolation(THD* thd, + const char* db, + const char* table, + const TABLE_LIST* table_list, + wsrep_key_arr_t* ka) +{ + ka->keys= 0; + ka->keys_len= 0; + + extern TABLE* find_temporary_table(THD*, const TABLE_LIST*); + + if (db || table) + { + TABLE_LIST tmp_table; + bzero((char*) &tmp_table,sizeof(tmp_table)); + tmp_table.table_name= (char*)db; + tmp_table.db= (char*)table; + if (!table || !find_temporary_table(thd, &tmp_table)) + { + if (!(ka->keys= (wsrep_key_t*)my_malloc(sizeof(wsrep_key_t), MYF(0)))) + { + sql_print_error("Can't allocate memory for key_array"); + goto err; + } + ka->keys_len= 1; + if (!(ka->keys[0].key_parts= (wsrep_key_part_t*) + my_malloc(sizeof(wsrep_key_part_t)*2, MYF(0)))) + { + sql_print_error("Can't allocate memory for key_parts"); + goto err; + } + ka->keys[0].key_parts_len= 2; + if (!wsrep_prepare_key_for_isolation( + db, table, + (wsrep_key_part_t*)ka->keys[0].key_parts, + &ka->keys[0].key_parts_len)) + { + sql_print_error("Preparing keys for isolation failed"); + goto err; + } + } + } + + for (const TABLE_LIST* table= table_list; table; table= table->next_global) + { + if (!find_temporary_table(thd, table)) + { + wsrep_key_t* tmp; + tmp= (wsrep_key_t*)my_realloc( + ka->keys, (ka->keys_len + 1) * sizeof(wsrep_key_t), MYF(0)); + if (!tmp) + { + sql_print_error("Can't allocate memory for key_array"); + goto err; + } + ka->keys= tmp; + if (!(ka->keys[ka->keys_len].key_parts= (wsrep_key_part_t*) + my_malloc(sizeof(wsrep_key_part_t)*2, MYF(0)))) + { + sql_print_error("Can't allocate memory for key_parts"); + goto err; + } + ka->keys[ka->keys_len].key_parts_len= 2; + ++ka->keys_len; + if (!wsrep_prepare_key_for_isolation( + table->db, table->table_name, + (wsrep_key_part_t*)ka->keys[ka->keys_len - 1].key_parts, + &ka->keys[ka->keys_len - 1].key_parts_len)) + { + sql_print_error("Preparing keys for isolation failed"); + goto err; + } + } + } + return true; +err: + wsrep_keys_free(ka); + return false; +} + + + bool wsrep_prepare_key_for_innodb(const uchar* cache_key, size_t cache_key_len, const uchar* row_id, @@ -842,15 +975,14 @@ create_view_query(THD *thd, uchar** buf, uint* buf_len) return wsrep_to_buf_helper(thd, buff.ptr(), buff.length(), buf, buf_len); } -static int wsrep_TOI_begin(THD *thd, char *db_, char *table_) +static int wsrep_TOI_begin(THD *thd, char *db_, char *table_, + const TABLE_LIST* table_list) { wsrep_status_t ret(WSREP_WARNING); uchar* buf(0); uint buf_len(0); int buf_err; - wsrep_key_part_t wkey_part[2]; - wsrep_key_t wkey = {wkey_part, 2}; WSREP_DEBUG("TO BEGIN: %lld, %d : %s", (long long)thd->wsrep_trx_seqno, thd->wsrep_exec_mode, thd->query() ); switch (thd->lex->sql_command) @@ -874,17 +1006,18 @@ static int wsrep_TOI_begin(THD *thd, char *db_, char *table_) break; } + wsrep_key_arr_t key_arr= {0, 0}; if (!buf_err && - wsrep_prepare_key_for_isolation(db_, table_, wkey_part, - &wkey.key_parts_len) && + wsrep_prepare_keys_for_isolation(thd, db_, table_, table_list, &key_arr)&& WSREP_OK == (ret = wsrep->to_execute_start(wsrep, thd->thread_id, - &wkey, 1, + key_arr.keys, key_arr.keys_len, buf, buf_len, &thd->wsrep_trx_seqno))) { thd->wsrep_exec_mode= TOTAL_ORDER; wsrep_to_isolation++; if (buf) my_free(buf); + wsrep_keys_free(&key_arr); WSREP_DEBUG("TO BEGIN: %lld, %d",(long long)thd->wsrep_trx_seqno, thd->wsrep_exec_mode); } @@ -896,6 +1029,7 @@ static int wsrep_TOI_begin(THD *thd, char *db_, char *table_) my_error(ER_LOCK_DEADLOCK, MYF(0), "WSREP replication failed. Check " "your wsrep connection state and retry the query."); if (buf) my_free(buf); + wsrep_keys_free(&key_arr); return -1; } return 0; @@ -959,13 +1093,15 @@ static void wsrep_RSU_end(THD *thd) return; } -int wsrep_to_isolation_begin(THD *thd, char *db_, char *table_) +int wsrep_to_isolation_begin(THD *thd, char *db_, char *table_, + const TABLE_LIST* table_list) { int ret= 0; if (thd->variables.wsrep_on && thd->wsrep_exec_mode==LOCAL_STATE) { switch (wsrep_OSU_method_options) { - case WSREP_OSU_TOI: ret = wsrep_TOI_begin(thd, db_, table_); break; + case WSREP_OSU_TOI: ret = wsrep_TOI_begin(thd, db_, table_, + table_list); break; case WSREP_OSU_RSU: ret = wsrep_RSU_begin(thd, db_, table_); break; } if (!ret) @@ -1046,7 +1182,7 @@ wsrep_grant_mdl_exception(MDL_context *requestor_ctx, } else { - WSREP_MDL_LOG(INFO, "MDL conflict -> BF abort", request_thd, granted_thd); + WSREP_MDL_LOG(DEBUG, "MDL conflict-> BF abort", request_thd, granted_thd); mysql_mutex_unlock(&granted_thd->LOCK_wsrep_thd); wsrep_abort_thd((void*)request_thd, (void*)granted_thd, 1); return FALSE; diff --git a/sql/wsrep_mysqld.h b/sql/wsrep_mysqld.h index 90498c266ee..985431e74b9 100644 --- a/sql/wsrep_mysqld.h +++ b/sql/wsrep_mysqld.h @@ -60,6 +60,7 @@ extern long wsrep_protocol_version; extern ulong wsrep_forced_binlog_format; extern ulong wsrep_OSU_method_options; extern my_bool wsrep_recovery; +extern my_bool wsrep_replicate_myisam; enum enum_wsrep_OSU_method { WSREP_OSU_TOI, WSREP_OSU_RSU }; @@ -162,6 +163,9 @@ extern wsrep_seqno_t wsrep_locked_seqno; #define WSREP(thd) \ (WSREP_ON && (thd && thd->variables.wsrep_on)) +#define WSREP_CLIENT(thd) \ + (WSREP(thd) && thd->wsrep_client_thread) + #define WSREP_EMULATE_BINLOG(thd) \ (WSREP(thd) && wsrep_emulate_bin_log) @@ -206,20 +210,6 @@ class Ha_trx_info; struct THD_TRANS; void wsrep_register_hton(THD* thd, bool all); -/*! - * @param db Database string - * @param table Table string - * @param key Array of wsrep_key_t - * @param key_len In: number of elements in key array, Out: number of - * elements populated - * - * @return true if preparation was successful, otherwise false. - */ -bool wsrep_prepare_key_for_isolation(const char* db, - const char* table, - wsrep_key_part_t* key, - size_t *key_len); - void wsrep_replication_process(THD *thd); void wsrep_rollback_process(THD *thd); void wsrep_brute_force_killer(THD *thd); @@ -274,7 +264,9 @@ extern PSI_cond_key key_COND_wsrep_rollback; extern PSI_mutex_key key_LOCK_wsrep_replaying; extern PSI_cond_key key_COND_wsrep_replaying; -int wsrep_to_isolation_begin(THD *thd, char *db_, char *table_); +struct TABLE_LIST; +int wsrep_to_isolation_begin(THD *thd, char *db_, char *table_, + const TABLE_LIST* table_list); void wsrep_to_isolation_end(THD *thd); void wsrep_prepare_bf_thd(THD *thd, struct wsrep_thd_shadow*); diff --git a/sql/wsrep_utils.cc b/sql/wsrep_utils.cc index f39353eda44..a6d7dcdbfc8 100644 --- a/sql/wsrep_utils.cc +++ b/sql/wsrep_utils.cc @@ -332,7 +332,7 @@ size_t default_ip (char* buf, size_t buf_len) "awk '{ print $2 }' | awk -F : '{ print $2 }'"; #elif defined(__sun__) const char cmd[] = "/sbin/ifconfig -a | " - "grep -m1 -1 -E 'net[0-9]:' | tail -n 1 | awk '{ print $2 }'"; + "/usr/gnu/bin/grep -m1 -1 -E 'net[0-9]:' | tail -n 1 | awk '{ print $2 }'"; #else char *cmd; #error "OS not supported" diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index c9d4a28868d..050ebf7d505 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -6945,11 +6945,6 @@ wsrep_append_foreign_key( byte key[WSREP_MAX_SUPPORTED_KEY_LENGTH+1]; ulint len = WSREP_MAX_SUPPORTED_KEY_LENGTH; - if (!dict_index_is_clust(clust_index)) { - WSREP_ERROR("clustered index not passed for FK append"); - return DB_ERROR; - } - key[0] = '\0'; rcode = wsrep_rec_get_primary_key( &key[1], &len, clust_rec, clust_index); diff --git a/storage/innobase/rem/rem0rec.c b/storage/innobase/rem/rem0rec.c index 9ba1c646d9d..dbfc41881ce 100644 --- a/storage/innobase/rem/rem0rec.c +++ b/storage/innobase/rem/rem0rec.c @@ -1790,25 +1790,23 @@ wsrep_rec_get_primary_key( uint key_parts; mem_heap_t* heap = NULL; ulint offsets_[REC_OFFS_NORMAL_SIZE]; + const ulint* offsets; ut_ad(index); - key_parts = dict_index_get_n_unique_in_tree(index); - *offsets_ = (sizeof offsets_) / sizeof *offsets_; - rec_get_offsets(rec, index, offsets_, ULINT_UNDEFINED, &heap); - if (UNIV_LIKELY_NULL(heap)) { - mem_heap_free(heap); - } + rec_offs_init(offsets_); + offsets = rec_get_offsets(rec, index, offsets_, ULINT_UNDEFINED, &heap); - ut_ad(rec_offs_validate(rec, NULL, offsets_)); + ut_ad(rec_offs_validate(rec, NULL, offsets)); ut_ad(rec); + key_parts = dict_index_get_n_unique_in_tree(index); for (i = 0; i < key_parts; i++) { - dict_field_t* field = dict_index_get_nth_field(index, i); + dict_field_t* field = dict_index_get_nth_field(index, i); const dict_col_t* col = dict_field_get_col(field); - data = rec_get_nth_field(rec, offsets_, i, &len); + data = rec_get_nth_field(rec, offsets, i, &len); if (key_len + len > ((col->prtype & DATA_NOT_NULL) ? *buf_len : *buf_len - 1)) { fprintf (stderr, @@ -1836,11 +1834,19 @@ wsrep_rec_get_primary_key( } } - rec_validate(rec, offsets_); + rec_validate(rec, offsets); + + if (UNIV_LIKELY_NULL(heap)) { + mem_heap_free(heap); + } + *buf_len = key_len; return DB_SUCCESS; err_out: + if (UNIV_LIKELY_NULL(heap)) { + mem_heap_free(heap); + } return DB_ERROR; } #endif // WITH_WSREP diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc index 9e10cbc5d34..a1119fc3d47 100644 --- a/storage/xtradb/handler/ha_innodb.cc +++ b/storage/xtradb/handler/ha_innodb.cc @@ -7589,11 +7589,6 @@ wsrep_append_foreign_key( byte key[WSREP_MAX_SUPPORTED_KEY_LENGTH+1]; ulint len = WSREP_MAX_SUPPORTED_KEY_LENGTH; - if (!dict_index_is_clust(clust_index)) { - WSREP_ERROR("clustered index not passed for FK append"); - return DB_ERROR; - } - key[0] = '\0'; rcode = wsrep_rec_get_primary_key( &key[1], &len, clust_rec, clust_index); diff --git a/storage/xtradb/rem/rem0rec.c b/storage/xtradb/rem/rem0rec.c index 9ba1c646d9d..dbfc41881ce 100644 --- a/storage/xtradb/rem/rem0rec.c +++ b/storage/xtradb/rem/rem0rec.c @@ -1790,25 +1790,23 @@ wsrep_rec_get_primary_key( uint key_parts; mem_heap_t* heap = NULL; ulint offsets_[REC_OFFS_NORMAL_SIZE]; + const ulint* offsets; ut_ad(index); - key_parts = dict_index_get_n_unique_in_tree(index); - *offsets_ = (sizeof offsets_) / sizeof *offsets_; - rec_get_offsets(rec, index, offsets_, ULINT_UNDEFINED, &heap); - if (UNIV_LIKELY_NULL(heap)) { - mem_heap_free(heap); - } + rec_offs_init(offsets_); + offsets = rec_get_offsets(rec, index, offsets_, ULINT_UNDEFINED, &heap); - ut_ad(rec_offs_validate(rec, NULL, offsets_)); + ut_ad(rec_offs_validate(rec, NULL, offsets)); ut_ad(rec); + key_parts = dict_index_get_n_unique_in_tree(index); for (i = 0; i < key_parts; i++) { - dict_field_t* field = dict_index_get_nth_field(index, i); + dict_field_t* field = dict_index_get_nth_field(index, i); const dict_col_t* col = dict_field_get_col(field); - data = rec_get_nth_field(rec, offsets_, i, &len); + data = rec_get_nth_field(rec, offsets, i, &len); if (key_len + len > ((col->prtype & DATA_NOT_NULL) ? *buf_len : *buf_len - 1)) { fprintf (stderr, @@ -1836,11 +1834,19 @@ wsrep_rec_get_primary_key( } } - rec_validate(rec, offsets_); + rec_validate(rec, offsets); + + if (UNIV_LIKELY_NULL(heap)) { + mem_heap_free(heap); + } + *buf_len = key_len; return DB_SUCCESS; err_out: + if (UNIV_LIKELY_NULL(heap)) { + mem_heap_free(heap); + } return DB_ERROR; } #endif // WITH_WSREP |