summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsjaakola <seppo.jaakola@iki.fi>2017-02-16 23:19:10 +0200
committerJan Lindström <jan.lindstrom@mariadb.com>2017-08-11 13:23:51 +0300
commit7ef2d5aa5b5d0179d40bd42afea874235b8b60f8 (patch)
treefd6a5094243c31e603ef65c77f582d7867aba18a
parent364b15c090e7337eb752eec4bea239052f73b2ed (diff)
downloadmariadb-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.cc5
-rw-r--r--sql/sql_class.h2
-rw-r--r--sql/sql_parse.cc28
-rw-r--r--sql/sql_parse.h26
-rw-r--r--sql/sql_partition_admin.cc4
-rw-r--r--sql/sql_table.cc100
-rw-r--r--sql/sql_truncate.cc2
-rw-r--r--sql/wsrep_hton.cc1
-rw-r--r--sql/wsrep_mysqld.cc11
-rw-r--r--sql/wsrep_mysqld.h26
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 */