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:
@ -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.
|
||||
|
@ -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 */
|
||||
};
|
||||
|
||||
|
@ -4031,16 +4031,24 @@ end_with_restore_list:
|
||||
thd->variables.option_bits|= OPTION_KEEP_LOG;
|
||||
}
|
||||
#ifdef WITH_WSREP
|
||||
bool has_tmp_tables= false;
|
||||
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)))
|
||||
if (lex->drop_temporary || find_temporary_table(thd, table))
|
||||
{
|
||||
WSREP_TO_ISOLATION_BEGIN(NULL, NULL, all_tables);
|
||||
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
|
||||
|
@ -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 */
|
||||
|
@ -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");
|
||||
|
100
sql/sql_table.cc
100
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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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 */
|
||||
|
Reference in New Issue
Block a user