diff options
Diffstat (limited to 'sql')
-rw-r--r-- | sql/filesort.cc | 1 | ||||
-rw-r--r-- | sql/log_event.h | 3 | ||||
-rw-r--r-- | sql/mysqld.cc | 4 | ||||
-rw-r--r-- | sql/slave.cc | 38 | ||||
-rw-r--r-- | sql/sql_select.cc | 2 | ||||
-rw-r--r-- | sql/wsrep_hton.cc | 20 | ||||
-rw-r--r-- | sql/wsrep_mysqld.cc | 34 |
7 files changed, 96 insertions, 6 deletions
diff --git a/sql/filesort.cc b/sql/filesort.cc index b847a5f61ec..c94bbd1e55d 100644 --- a/sql/filesort.cc +++ b/sql/filesort.cc @@ -315,6 +315,7 @@ SORT_INFO *filesort(THD *thd, TABLE *table, Filesort *filesort, param.max_keys_per_buffer=((param.max_keys_per_buffer * (param.rec_length + sizeof(char*))) / param.rec_length - 1); + set_if_bigger(param.max_keys_per_buffer, 1); maxbuffer--; // Offset from 0 if (merge_many_buff(¶m, (uchar*) sort->get_sort_keys(), diff --git a/sql/log_event.h b/sql/log_event.h index 20c09814464..3e838aff58c 100644 --- a/sql/log_event.h +++ b/sql/log_event.h @@ -5211,6 +5211,9 @@ bool event_that_should_be_ignored(const char *buf); bool event_checksum_test(uchar *buf, ulong event_len, enum_binlog_checksum_alg alg); enum enum_binlog_checksum_alg get_checksum_alg(const char* buf, ulong len); extern TYPELIB binlog_checksum_typelib; +#ifdef WITH_WSREP +enum Log_event_type wsrep_peak_event(rpl_group_info *rgi, ulonglong* event_size); +#endif /* WITH_WSREP */ /** @} (end of group Replication) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index fcb3390e0ff..8fe6e6b6d32 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -8907,8 +8907,8 @@ static void usage(void) "\nbecause execution stopped before plugins were initialized."); } - puts("\nTo see what values a running MySQL server is using, type" - "\n'mysqladmin variables' instead of 'mysqld --verbose --help'."); + puts("\nTo see what variables a running MySQL server is using, type" + "\n'mysqladmin variables' instead of 'mysqld --verbose --help'."); } DBUG_VOID_RETURN; } diff --git a/sql/slave.cc b/sql/slave.cc index 7d0ce253976..ff48ee92e98 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -481,6 +481,9 @@ handle_slave_background(void *arg __attribute__((unused))) thd->store_globals(); thd->security_ctx->skip_grants(); thd->set_command(COM_DAEMON); +#ifdef WITH_WSREP + thd->variables.wsrep_on= 0; +#endif thd_proc_info(thd, "Loading slave GTID position from table"); if (rpl_load_gtid_slave_state(thd)) @@ -4656,6 +4659,9 @@ pthread_handler_t handle_slave_io(void *arg) } +#ifdef WITH_WSREP + thd->variables.wsrep_on= 0; +#endif if (DBUG_EVALUATE_IF("failed_slave_start", 1, 0) || repl_semisync_slave.slave_start(mi)) { @@ -7844,7 +7850,39 @@ err: sql_print_error("Error reading relay log event: %s", errmsg); DBUG_RETURN(0); } +#ifdef WITH_WSREP +enum Log_event_type wsrep_peak_event(rpl_group_info *rgi, ulonglong* event_size) +{ + enum Log_event_type ev_type; + + mysql_mutex_lock(&rgi->rli->data_lock); + + unsigned long long event_pos= rgi->event_relay_log_pos; + unsigned long long orig_future_pos= rgi->future_event_relay_log_pos; + unsigned long long future_pos= rgi->future_event_relay_log_pos; + + /* scan the log to read next event and we skip + annotate events. */ + do { + my_b_seek(rgi->rli->cur_log, future_pos); + rgi->rli->event_relay_log_pos= future_pos; + rgi->event_relay_log_pos= future_pos; + Log_event* ev= next_event(rgi, event_size); + ev_type= (ev) ? ev->get_type_code() : UNKNOWN_EVENT; + delete ev; + future_pos+= *event_size; + } while (ev_type == ANNOTATE_ROWS_EVENT); + + /* scan the log back and re-set the positions to original values */ + rgi->rli->event_relay_log_pos= event_pos; + rgi->event_relay_log_pos= event_pos; + my_b_seek(rgi->rli->cur_log, orig_future_pos); + + mysql_mutex_unlock(&rgi->rli->data_lock); + return ev_type; +} +#endif /* WITH_WSREP */ /* Rotate a relay log (this is used only by FLUSH LOGS; the automatic rotation because of size is simpler because when we do it we already have all relevant diff --git a/sql/sql_select.cc b/sql/sql_select.cc index ce3ad4927ad..4c83c1d84e5 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -20586,7 +20586,7 @@ join_read_last(JOIN_TAB *tab) { TABLE *table=tab->table; int error= 0; - DBUG_ENTER("join_read_first"); + DBUG_ENTER("join_read_last"); DBUG_ASSERT(table->no_keyread || !table->covering_keys.is_set(tab->index) || diff --git a/sql/wsrep_hton.cc b/sql/wsrep_hton.cc index f84aa5b2e84..1feb46ecdaf 100644 --- a/sql/wsrep_hton.cc +++ b/sql/wsrep_hton.cc @@ -488,11 +488,27 @@ wsrep_run_wsrep_commit(THD *thd, bool all) if (WSREP_UNDEFINED_TRX_ID == thd->wsrep_ws_handle.trx_id) { - WSREP_WARN("SQL statement was ineffective thd: %lld buf: %zu\n" + /* + Async replication slave may have applied some non-innodb workload, + and then has written replication "meta data" into gtid_slave_pos + innodb table. Writes to gtid_slave_pos must not be replicated, + but this activity has caused that innodb hton is registered for this + transaction, but no wsrep keys have been appended. + We enter in this code path, because IO cache has events for non-innodb + tables. + => we should not treat it an error if trx is not introduced for provider + */ + if (thd->system_thread == SYSTEM_THREAD_SLAVE_SQL) + { + WSREP_DEBUG("skipping wsrep replication for async slave, error not raised"); + DBUG_RETURN(WSREP_TRX_OK); + } + + WSREP_WARN("SQL statement was ineffective thd: %llu buf: %zu\n" "schema: %s \n" "QUERY: %s\n" " => Skipping replication", - (longlong) thd->thread_id, data_len, + (ulonglong) thd->thread_id, data_len, thd->get_db(), thd->query()); rcode = WSREP_TRX_FAIL; } diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc index c639f3a0d58..895d7aac2c2 100644 --- a/sql/wsrep_mysqld.cc +++ b/sql/wsrep_mysqld.cc @@ -37,7 +37,6 @@ #include <cstdio> #include <cstdlib> #include "log_event.h" -#include <slave.h> wsrep_t *wsrep = NULL; /* @@ -1546,6 +1545,39 @@ static bool wsrep_can_run_in_toi(THD *thd, const char *db, const char *table, { return false; } + /* + If mariadb master has replicated a CTAS, we should not replicate the create table + part separately as TOI, but to replicate both create table and following inserts + as one write set. + Howver, if CTAS creates empty table, we should replicate the create table alone + as TOI. We have to do relay log event lookup to see if row events follow the + create table event. + */ + if (thd->slave_thread && !(thd->rgi_slave->gtid_ev_flags2 & Gtid_log_event::FL_STANDALONE)) + { + /* this is CTAS, either empty or populated table */ + ulonglong event_size = 0; + enum Log_event_type ev_type= wsrep_peak_event(thd->rgi_slave, &event_size); + switch (ev_type) + { + case QUERY_EVENT: + /* CTAS with empty table, we replicate create table as TOI */ + break; + + case TABLE_MAP_EVENT: + WSREP_DEBUG("replicating CTAS of empty table as TOI"); + // fall through + case WRITE_ROWS_EVENT: + /* CTAS with populated table, we replicate later at commit time */ + WSREP_DEBUG("skipping create table of CTAS replication"); + return false; + + default: + WSREP_WARN("unexpected async replication event: %d", ev_type); + } + return true; + } + /* no next async replication event */ return true; case SQLCOM_CREATE_VIEW: |