diff options
author | sjaakola <seppo.jaakola@iki.fi> | 2017-02-16 23:19:10 +0200 |
---|---|---|
committer | Jan Lindström <jan.lindstrom@mariadb.com> | 2017-08-11 13:23:51 +0300 |
commit | 7ef2d5aa5b5d0179d40bd42afea874235b8b60f8 (patch) | |
tree | fd6a5094243c31e603ef65c77f582d7867aba18a | |
parent | 364b15c090e7337eb752eec4bea239052f73b2ed (diff) | |
download | mariadb-git-7ef2d5aa5b5d0179d40bd42afea874235b8b60f8.tar.gz |
Refs: MW-360 * splitting DROP TABLE query in separate DROP commands for temporary and real tables * not replicating temporary table DROP command * using wsrep_sidno GTID group only for innodb table drop command part all this follows more or less the logic of how mysql wants to split drop table list
-rw-r--r-- | sql/sql_class.cc | 5 | ||||
-rw-r--r-- | sql/sql_class.h | 2 | ||||
-rw-r--r-- | sql/sql_parse.cc | 28 | ||||
-rw-r--r-- | sql/sql_parse.h | 26 | ||||
-rw-r--r-- | sql/sql_partition_admin.cc | 4 | ||||
-rw-r--r-- | sql/sql_table.cc | 100 | ||||
-rw-r--r-- | sql/sql_truncate.cc | 2 | ||||
-rw-r--r-- | sql/wsrep_hton.cc | 1 | ||||
-rw-r--r-- | sql/wsrep_mysqld.cc | 11 | ||||
-rw-r--r-- | sql/wsrep_mysqld.h | 26 |
10 files changed, 163 insertions, 42 deletions
diff --git a/sql/sql_class.cc b/sql/sql_class.cc index f0543becc0c..5964f4475a4 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -1213,6 +1213,8 @@ THD::THD() wsrep_TOI_pre_query_len = 0; wsrep_sync_wait_gtid = WSREP_GTID_UNDEFINED; wsrep_affected_rows = 0; + wsrep_replicate_GTID = false; + wsrep_skip_wsrep_GTID = false; #endif /* Call to init() below requires fully initialized Open_tables_state. */ reset_open_tables_state(this); @@ -1631,7 +1633,8 @@ void THD::init(void) wsrep_TOI_pre_query_len = 0; wsrep_sync_wait_gtid = WSREP_GTID_UNDEFINED; wsrep_affected_rows = 0; - + wsrep_replicate_GTID = false; + wsrep_skip_wsrep_GTID = false; /* @@wsrep_causal_reads is now being handled via wsrep_sync_wait, update it appropriately. diff --git a/sql/sql_class.h b/sql/sql_class.h index beef22a8140..8c9b8f92040 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -3867,6 +3867,8 @@ public: bool wsrep_skip_append_keys; wsrep_gtid_t wsrep_sync_wait_gtid; ulong wsrep_affected_rows; + bool wsrep_replicate_GTID; + bool wsrep_skip_wsrep_GTID; #endif /* WITH_WSREP */ }; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 9f0b6e25a5c..a4442653839 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -4031,16 +4031,24 @@ end_with_restore_list: thd->variables.option_bits|= OPTION_KEEP_LOG; } #ifdef WITH_WSREP - for (TABLE_LIST *table= all_tables; table; table= table->next_global) - { - if (!lex->drop_temporary && - (!thd->is_current_stmt_binlog_format_row() || - !find_temporary_table(thd, table))) - { - WSREP_TO_ISOLATION_BEGIN(NULL, NULL, all_tables); - break; - } - } + bool has_tmp_tables= false; + for (TABLE_LIST *table= all_tables; table; table= table->next_global) + { + if (lex->drop_temporary || find_temporary_table(thd, table)) + { + has_tmp_tables= true; + break; + } + } + if (has_tmp_tables) + { + wsrep_replicate_drop_query(thd, first_table, lex->check_exists, + lex->drop_temporary, false); + } + else + { + WSREP_TO_ISOLATION_BEGIN(NULL, NULL, all_tables); + } #endif /* WITH_WSREP */ /* If we are a slave, we should add IF EXISTS if the query executed diff --git a/sql/sql_parse.h b/sql/sql_parse.h index 368bba91c20..c2dbb950f2a 100644 --- a/sql/sql_parse.h +++ b/sql/sql_parse.h @@ -208,31 +208,13 @@ inline bool is_supported_parser_charset(CHARSET_INFO *cs) { return MY_TEST(cs->mbminlen == 1); } -#ifdef WITH_WSREP - -#define WSREP_MYSQL_DB (char *)"mysql" -#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); - -/* - Checks if lex->no_write_to_binlog is set for statements that use LOCAL or - NO_WRITE_TO_BINLOG. -*/ -#define WSREP_TO_ISOLATION_BEGIN_WRTCHK(db_, table_, table_list_) \ - if (WSREP(thd) && !thd->lex->no_write_to_binlog \ - && wsrep_to_isolation_begin(thd, db_, table_, table_list_)) goto error; - -#else +#ifndef WITH_WSREP #define WSREP_TO_ISOLATION_BEGIN(db_, table_, table_list_) +#define WSREP_TO_ISOLATION_BEGIN_QUERY(db_, query_, table_, table_list_) #define WSREP_TO_ISOLATION_END -#define WSREP_TO_ISOLATION_BEGIN_WRTCHK(db_, table_, table_list_) - -#endif /* WITH_WSREP */ +#define WSREP_TO_ISOLATION_BEGIN_WRTCHK(db_, query_, table_, table_list_) +#endif /* !WITH_WSREP */ #endif /* SQL_PARSE_INCLUDED */ diff --git a/sql/sql_partition_admin.cc b/sql/sql_partition_admin.cc index 2a76c8d6671..d50fe0379f3 100644 --- a/sql/sql_partition_admin.cc +++ b/sql/sql_partition_admin.cc @@ -537,7 +537,7 @@ bool Sql_cmd_alter_table_exchange_partition:: if ((!thd->is_current_stmt_binlog_format_row() || /* TODO: Do we really need to check for temp tables in this case? */ !find_temporary_table(thd, table_list)) && - wsrep_to_isolation_begin(thd, table_list->db, table_list->table_name, + wsrep_to_isolation_begin(thd, NULL, table_list->db, table_list->table_name, NULL)) { WSREP_WARN("ALTER TABLE EXCHANGE PARTITION isolation failure"); @@ -785,7 +785,7 @@ bool Sql_cmd_alter_table_truncate_partition::execute(THD *thd) if (WSREP(thd) && (!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, NULL) + thd, NULL, first_table->db, first_table->table_name, NULL) ) { WSREP_WARN("ALTER TABLE TRUNCATE PARTITION isolation failure"); diff --git a/sql/sql_table.cc b/sql/sql_table.cc index e591b8a1eb7..6a9107cb240 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -2156,7 +2156,95 @@ static uint32 comment_length(THD *thd, uint32 comment_pos, return 0; } +#ifdef WITH_WSREP +static void +wsrep_append_name(THD *thd, String *packet, const char *name, uint length, + const CHARSET_INFO *from_cs, const CHARSET_INFO *to_cs) +{ + const char *to_name= name; + size_t to_length= length; + String to_string(name,length, from_cs); + if (from_cs != NULL && to_cs != NULL && from_cs != to_cs) + thd->convert_string(&to_string, from_cs, to_cs); + + if (to_cs != NULL) + { + to_name= to_string.c_ptr(); + to_length= to_string.length(); + } + packet->append(to_name, to_length, packet->charset()); +} + +int wsrep_replicate_drop_query(THD *thd, TABLE_LIST *tables, bool if_exists, + bool drop_temporary, bool dont_log_query) +{ + TABLE_LIST *table; + int error= 0; + String built_query; + bool non_tmp_table_deleted= FALSE; + DBUG_ENTER("wsrep_build_drop_query"); + + if (!dont_log_query) + { + if (!drop_temporary) + { + built_query.set_charset(system_charset_info); + if (if_exists) + built_query.append("DROP TABLE IF EXISTS "); + else + built_query.append("DROP TABLE "); + } + } + + for (table= tables; table; table= table->next_local) + { + char *db=table->db; + int db_len= table->db_length; + + DBUG_PRINT("table", ("table_l: '%s'.'%s' table: 0x%lx s: 0x%lx", + table->db, table->table_name, (long) table->table, + table->table ? (long) table->table->s : (long) -1)); + + if (!find_temporary_table(thd, table)) + { + non_tmp_table_deleted= TRUE; + + if (thd->db == NULL || strcmp(db,thd->db) != 0) + { + wsrep_append_name(thd, &built_query, db, db_len, + system_charset_info, thd->charset()); + built_query.append("."); + } + + thd->variables.option_bits &= ~OPTION_QUOTE_SHOW_CREATE; + wsrep_append_name(thd, &built_query, table->table_name, + strlen(table->table_name), system_charset_info, + thd->charset()); + built_query.append(","); + } + } + +err: + if (non_tmp_table_deleted) + { + /* Chop of the last comma */ + built_query.chop(); + built_query.append(" /* generated by server */"); + WSREP_DEBUG("TOI for %s", built_query.ptr()); + if (WSREP_TO_ISOLATION_BEGIN_QUERY(built_query.ptr(), NULL, NULL, tables)) + { + WSREP_DEBUG("TOI failed for DROP TABLE: %s", WSREP_QUERY(thd)); + error= 1; + goto end; + } + } + +end: + DBUG_RETURN(error); +} + +#endif /* WITH_WSREP */ /** Execute the drop of a normal or temporary table. @@ -2591,6 +2679,9 @@ err: /* Chop of the last comma */ built_non_trans_tmp_query.chop(); built_non_trans_tmp_query.append(" /* generated by server */"); +#ifdef WITH_WSREP + thd->wsrep_skip_wsrep_GTID = true; +#endif /* WITH_WSREP */ error |= thd->binlog_query(THD::STMT_QUERY_TYPE, built_non_trans_tmp_query.ptr(), built_non_trans_tmp_query.length(), @@ -2603,6 +2694,9 @@ err: /* Chop of the last comma */ built_trans_tmp_query.chop(); built_trans_tmp_query.append(" /* generated by server */"); +#ifdef WITH_WSREP + thd->wsrep_skip_wsrep_GTID = true; +#endif /* WITH_WSREP */ error |= thd->binlog_query(THD::STMT_QUERY_TYPE, built_trans_tmp_query.ptr(), built_trans_tmp_query.length(), @@ -2617,6 +2711,9 @@ err: built_query.append(" /* generated by server */"); int error_code = non_tmp_error ? thd->get_stmt_da()->sql_errno() : 0; +#ifdef WITH_WSREP + thd->wsrep_skip_wsrep_GTID = false; +#endif /* WITH_WSREP */ error |= thd->binlog_query(THD::STMT_QUERY_TYPE, built_query.ptr(), built_query.length(), @@ -2665,6 +2762,9 @@ err: } end: +#ifdef WITH_WSREP + thd->wsrep_skip_wsrep_GTID = false; +#endif /* WITH_WSREP */ DBUG_RETURN(error); } diff --git a/sql/sql_truncate.cc b/sql/sql_truncate.cc index 16c2a5027e3..d047186b2cf 100644 --- a/sql/sql_truncate.cc +++ b/sql/sql_truncate.cc @@ -487,7 +487,7 @@ bool Sql_cmd_truncate_table::truncate_table(THD *thd, TABLE_LIST *table_ref) bool hton_can_recreate; #ifdef WITH_WSREP - if (WSREP(thd) && wsrep_to_isolation_begin(thd, + if (WSREP(thd) && wsrep_to_isolation_begin(thd, NULL, table_ref->db, table_ref->table_name, NULL)) DBUG_RETURN(TRUE); diff --git a/sql/wsrep_hton.cc b/sql/wsrep_hton.cc index 78d189fbd61..47697c34eb4 100644 --- a/sql/wsrep_hton.cc +++ b/sql/wsrep_hton.cc @@ -45,6 +45,7 @@ void wsrep_cleanup_transaction(THD *thd) thd->wsrep_trx_meta.depends_on= WSREP_SEQNO_UNDEFINED; thd->wsrep_exec_mode= LOCAL_STATE; thd->wsrep_affected_rows= 0; + thd->wsrep_skip_wsrep_GTID= false; return; } diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc index 353911dcfde..6d0c5e75592 100644 --- a/sql/wsrep_mysqld.cc +++ b/sql/wsrep_mysqld.cc @@ -1211,7 +1211,7 @@ create_view_query(THD *thd, uchar** buf, size_t* buf_len) 1: TOI replication was skipped -1: TOI replication failed */ -static int wsrep_TOI_begin(THD *thd, char *db_, char *table_, +static int wsrep_TOI_begin(THD *thd, const char *query, char *db_, char *table_, const TABLE_LIST* table_list) { wsrep_status_t ret(WSREP_WARNING); @@ -1247,8 +1247,9 @@ static int wsrep_TOI_begin(THD *thd, char *db_, char *table_, } /* fallthrough */ default: - buf_err= wsrep_to_buf_helper(thd, thd->query(), thd->query_length(), &buf, - &buf_len); + buf_err= wsrep_to_buf_helper(thd, (query) ? query : thd->query(), + (query) ? strlen(query) : thd->query_length(), + &buf, &buf_len); break; } @@ -1397,7 +1398,7 @@ static void wsrep_RSU_end(THD *thd) thd->variables.wsrep_on = 1; } -int wsrep_to_isolation_begin(THD *thd, char *db_, char *table_, +int wsrep_to_isolation_begin(THD *thd, const char *query, char *db_, char *table_, const TABLE_LIST* table_list) { @@ -1452,7 +1453,7 @@ int wsrep_to_isolation_begin(THD *thd, char *db_, char *table_, if (thd->variables.wsrep_on && thd->wsrep_exec_mode==LOCAL_STATE) { switch (thd->variables.wsrep_OSU_method) { - case WSREP_OSU_TOI: ret = wsrep_TOI_begin(thd, db_, table_, + case WSREP_OSU_TOI: ret = wsrep_TOI_begin(thd, query, db_, table_, table_list); break; case WSREP_OSU_RSU: ret = wsrep_RSU_begin(thd, db_, table_); break; default: diff --git a/sql/wsrep_mysqld.h b/sql/wsrep_mysqld.h index 5ec183f7186..fa069723021 100644 --- a/sql/wsrep_mysqld.h +++ b/sql/wsrep_mysqld.h @@ -254,6 +254,8 @@ extern wsrep_seqno_t wsrep_locked_seqno; #define WSREP_PROVIDER_EXISTS \ (wsrep_provider && strncasecmp(wsrep_provider, WSREP_NONE, FN_REFLEN)) +#define WSREP_QUERY(thd) (thd->query()) + extern void wsrep_ready_wait(); enum wsrep_trx_status { @@ -318,7 +320,7 @@ extern PSI_mutex_key key_LOCK_wsrep_slave_threads; extern PSI_mutex_key key_LOCK_wsrep_desync; #endif /* HAVE_PSI_INTERFACE */ struct TABLE_LIST; -int wsrep_to_isolation_begin(THD *thd, char *db_, char *table_, +int wsrep_to_isolation_begin(THD *thd, const char * query, char *db_, char *table_, const TABLE_LIST* table_list); void wsrep_to_isolation_end(THD *thd); void wsrep_cleanup_transaction(THD *thd); @@ -335,4 +337,26 @@ void wsrep_init_sidno(const wsrep_uuid_t&); bool wsrep_node_is_donor(); bool wsrep_node_is_synced(); +int wsrep_replicate_drop_query(THD *thd, TABLE_LIST *tables, bool if_exists, + bool drop_temporary, bool dont_log_query); + + +#define WSREP_MYSQL_DB (char *)"mysql" +#define WSREP_TO_ISOLATION_BEGIN(db_, table_, table_list_) \ + if (WSREP(thd) && wsrep_to_isolation_begin(thd, NULL, db_, table_, table_list_)) goto error; + +#define WSREP_TO_ISOLATION_BEGIN_QUERY(query, db_, table_, table_list_) \ + (WSREP(thd) && wsrep_to_isolation_begin(thd, query, db_, table_, table_list_)) + +#define WSREP_TO_ISOLATION_END \ + if (WSREP(thd) || (thd && thd->wsrep_exec_mode==TOTAL_ORDER)) \ + wsrep_to_isolation_end(thd); + +/* Checks if lex->no_write_to_binlog is set for statements that use + LOCAL or NO_WRITE_TO_BINLOG +*/ +#define WSREP_TO_ISOLATION_BEGIN_WRTCHK(db_, table_, table_list_) \ + if (WSREP(thd) && !thd->lex->no_write_to_binlog \ + && wsrep_to_isolation_begin(thd, NULL, db_, table_, table_list_)) goto error; + #endif /* WSREP_MYSQLD_H */ |