1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-29 05:21:33 +03:00

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

This commit is contained in:
sjaakola
2017-02-16 23:19:10 +02:00
committed by Jan Lindström
parent 364b15c090
commit 7ef2d5aa5b
10 changed files with 163 additions and 42 deletions

View File

@ -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.

View File

@ -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 */
};

View File

@ -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

View File

@ -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 */

View File

@ -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");

View File

@ -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);
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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:

View File

@ -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 */