mirror of
https://github.com/MariaDB/server.git
synced 2026-01-06 05:22:24 +03:00
merge with MariaDB 5.6 bzr merge lp:maria --rtag:mariadb-10.0.6
and a number of fixes to make this buildable. Run also few short multi-master high conflict rate tests, with no issues
This commit is contained in:
258
sql/sql_class.h
258
sql/sql_class.h
@@ -71,6 +71,7 @@ struct wsrep_thd_shadow {
|
||||
#endif
|
||||
class Reprepare_observer;
|
||||
class Relay_log_info;
|
||||
struct rpl_group_info;
|
||||
class Rpl_filter;
|
||||
|
||||
class Query_log_event;
|
||||
@@ -468,7 +469,8 @@ extern int killed_errno(killed_state killed);
|
||||
enum killed_type
|
||||
{
|
||||
KILL_TYPE_ID,
|
||||
KILL_TYPE_USER
|
||||
KILL_TYPE_USER,
|
||||
KILL_TYPE_QUERY
|
||||
};
|
||||
|
||||
#include "sql_lex.h" /* Must be here */
|
||||
@@ -761,6 +763,35 @@ typedef struct system_status_var
|
||||
|
||||
void mark_transaction_to_rollback(THD *thd, bool all);
|
||||
|
||||
|
||||
/**
|
||||
Get collation by name, send error to client on failure.
|
||||
@param name Collation name
|
||||
@param name_cs Character set of the name string
|
||||
@return
|
||||
@retval NULL on error
|
||||
@retval Pointter to CHARSET_INFO with the given name on success
|
||||
*/
|
||||
inline CHARSET_INFO *
|
||||
mysqld_collation_get_by_name(const char *name,
|
||||
CHARSET_INFO *name_cs= system_charset_info)
|
||||
{
|
||||
CHARSET_INFO *cs;
|
||||
MY_CHARSET_LOADER loader;
|
||||
my_charset_loader_init_mysys(&loader);
|
||||
if (!(cs= my_collation_get_by_name(&loader, name, MYF(0))))
|
||||
{
|
||||
ErrConvString err(name, name_cs);
|
||||
my_error(ER_UNKNOWN_COLLATION, MYF(0), err.ptr());
|
||||
if (loader.error[0])
|
||||
push_warning_printf(current_thd,
|
||||
Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_UNKNOWN_COLLATION, "%s", loader.error);
|
||||
}
|
||||
return cs;
|
||||
}
|
||||
|
||||
|
||||
#ifdef MYSQL_SERVER
|
||||
|
||||
void free_tmp_table(THD *thd, TABLE *entry);
|
||||
@@ -1083,6 +1114,8 @@ public:
|
||||
char proxy_user[USERNAME_LENGTH + MAX_HOSTNAME + 5];
|
||||
/* The host privilege we are using */
|
||||
char priv_host[MAX_HOSTNAME];
|
||||
/* The role privilege we are using */
|
||||
char priv_role[USERNAME_LENGTH];
|
||||
/* The external user (if available) */
|
||||
char *external_user;
|
||||
/* points to host if host is available, otherwise points to ip */
|
||||
@@ -1596,6 +1629,120 @@ private:
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
Class to facilitate the commit of one transactions waiting for the commit of
|
||||
another transaction to complete first.
|
||||
|
||||
This is used during (parallel) replication, to allow different transactions
|
||||
to be applied in parallel, but still commit in order.
|
||||
|
||||
The transaction that wants to wait for a prior commit must first register
|
||||
to wait with register_wait_for_prior_commit(waitee). Such registration
|
||||
must be done holding the waitee->LOCK_wait_commit, to prevent the other
|
||||
THD from disappearing during the registration.
|
||||
|
||||
Then during commit, if a THD is registered to wait, it will call
|
||||
wait_for_prior_commit() as part of ha_commit_trans(). If no wait is
|
||||
registered, or if the waitee for has already completed commit, then
|
||||
wait_for_prior_commit() returns immediately.
|
||||
|
||||
And when a THD that may be waited for has completed commit (more precisely
|
||||
commit_ordered()), then it must call wakeup_subsequent_commits() to wake
|
||||
up any waiters. Note that this must be done at a point that is guaranteed
|
||||
to be later than any waiters registering themselves. It is safe to call
|
||||
wakeup_subsequent_commits() multiple times, as waiters are removed from
|
||||
registration as part of the wakeup.
|
||||
|
||||
The reason for separate register and wait calls is that this allows to
|
||||
register the wait early, at a point where the waited-for THD is known to
|
||||
exist. And then the actual wait can be done much later, where the
|
||||
waited-for THD may have been long gone. By registering early, the waitee
|
||||
can signal before disappearing.
|
||||
*/
|
||||
struct wait_for_commit
|
||||
{
|
||||
/*
|
||||
The LOCK_wait_commit protects the fields subsequent_commits_list and
|
||||
wakeup_subsequent_commits_running (for a waitee), and the flag
|
||||
waiting_for_commit and associated COND_wait_commit (for a waiter).
|
||||
*/
|
||||
mysql_mutex_t LOCK_wait_commit;
|
||||
mysql_cond_t COND_wait_commit;
|
||||
/* List of threads that did register_wait_for_prior_commit() on us. */
|
||||
wait_for_commit *subsequent_commits_list;
|
||||
/* Link field for entries in subsequent_commits_list. */
|
||||
wait_for_commit *next_subsequent_commit;
|
||||
/* Our waitee, if we did register_wait_for_prior_commit(), else NULL. */
|
||||
wait_for_commit *waitee;
|
||||
/*
|
||||
Generic pointer for use by the transaction coordinator to optimise the
|
||||
waiting for improved group commit.
|
||||
|
||||
Currently used by binlog TC to signal that a waiter is ready to commit, so
|
||||
that the waitee can grab it and group commit it directly. It is free to be
|
||||
used by another transaction coordinator for similar purposes.
|
||||
*/
|
||||
void *opaque_pointer;
|
||||
/*
|
||||
The waiting_for_commit flag is cleared when a waiter has been woken
|
||||
up. The COND_wait_commit condition is signalled when this has been
|
||||
cleared.
|
||||
*/
|
||||
bool waiting_for_commit;
|
||||
/* The wakeup error code from the waitee. 0 means no error. */
|
||||
int wakeup_error;
|
||||
/*
|
||||
Flag set when wakeup_subsequent_commits_running() is active, see comments
|
||||
on that function for details.
|
||||
*/
|
||||
bool wakeup_subsequent_commits_running;
|
||||
|
||||
void register_wait_for_prior_commit(wait_for_commit *waitee);
|
||||
int wait_for_prior_commit()
|
||||
{
|
||||
/*
|
||||
Quick inline check, to avoid function call and locking in the common case
|
||||
where no wakeup is registered, or a registered wait was already signalled.
|
||||
*/
|
||||
if (waiting_for_commit)
|
||||
return wait_for_prior_commit2();
|
||||
else
|
||||
return wakeup_error;
|
||||
}
|
||||
void wakeup_subsequent_commits(int wakeup_error)
|
||||
{
|
||||
/*
|
||||
Do the check inline, so only the wakeup case takes the cost of a function
|
||||
call for every commmit.
|
||||
|
||||
Note that the check is done without locking. It is the responsibility of
|
||||
the user of the wakeup facility to ensure that no waiters can register
|
||||
themselves after the last call to wakeup_subsequent_commits().
|
||||
|
||||
This avoids having to take another lock for every commit, which would be
|
||||
pointless anyway - even if we check under lock, there is nothing to
|
||||
prevent a waiter from arriving just after releasing the lock.
|
||||
*/
|
||||
if (subsequent_commits_list)
|
||||
wakeup_subsequent_commits2(wakeup_error);
|
||||
}
|
||||
void unregister_wait_for_prior_commit()
|
||||
{
|
||||
if (waiting_for_commit)
|
||||
unregister_wait_for_prior_commit2();
|
||||
}
|
||||
|
||||
void wakeup(int wakeup_error);
|
||||
|
||||
int wait_for_prior_commit2();
|
||||
void wakeup_subsequent_commits2(int wakeup_error);
|
||||
void unregister_wait_for_prior_commit2();
|
||||
|
||||
wait_for_commit();
|
||||
~wait_for_commit();
|
||||
};
|
||||
|
||||
|
||||
extern "C" void my_message_sql(uint error, const char *str, myf MyFlags);
|
||||
|
||||
class THD;
|
||||
@@ -1631,13 +1778,14 @@ public:
|
||||
|
||||
/* Used to execute base64 coded binlog events in MySQL server */
|
||||
Relay_log_info* rli_fake;
|
||||
rpl_group_info* rgi_fake;
|
||||
/* Slave applier execution context */
|
||||
Relay_log_info* rli_slave;
|
||||
rpl_group_info* rgi_slave;
|
||||
|
||||
/* Used to SLAVE SQL thread */
|
||||
Rpl_filter* rpl_filter;
|
||||
|
||||
void reset_for_next_command(bool calculate_userstat);
|
||||
void reset_for_next_command();
|
||||
/*
|
||||
Constant for THD::where initialization in the beginning of every query.
|
||||
|
||||
@@ -2549,6 +2697,7 @@ public:
|
||||
wsrep_trx_meta_t wsrep_trx_meta;
|
||||
uint32 wsrep_rand;
|
||||
Relay_log_info* wsrep_rli;
|
||||
rpl_group_info* wsrep_rgi;
|
||||
bool wsrep_converted_lock_session;
|
||||
wsrep_ws_handle_t wsrep_ws_handle;
|
||||
#ifdef WSREP_PROC_INFO
|
||||
@@ -2566,6 +2715,13 @@ public:
|
||||
const char* wsrep_TOI_pre_query; /* a query to apply before
|
||||
the actual TOI query */
|
||||
size_t wsrep_TOI_pre_query_len;
|
||||
wsrep_po_handle_t wsrep_po_handle;
|
||||
size_t wsrep_po_cnt;
|
||||
my_bool wsrep_po_in_trans;
|
||||
#ifdef GTID_SUPPORT
|
||||
rpl_sid wsrep_po_sid;
|
||||
#endif /* GTID_SUPPORT */
|
||||
void* wsrep_apply_format;
|
||||
bool wsrep_apply_toi; /* applier processing in TOI */
|
||||
#endif /* WITH_WSREP */
|
||||
/**
|
||||
@@ -3415,9 +3571,11 @@ public:
|
||||
}
|
||||
void leave_locked_tables_mode();
|
||||
int decide_logging_format(TABLE_LIST *tables);
|
||||
void binlog_invoker() { m_binlog_invoker= TRUE; }
|
||||
bool need_binlog_invoker() { return m_binlog_invoker; }
|
||||
void get_definer(LEX_USER *definer);
|
||||
|
||||
enum need_invoker { INVOKER_NONE=0, INVOKER_USER, INVOKER_ROLE};
|
||||
void binlog_invoker(bool role) { m_binlog_invoker= role ? INVOKER_ROLE : INVOKER_USER; }
|
||||
enum need_invoker need_binlog_invoker() { return m_binlog_invoker; }
|
||||
void get_definer(LEX_USER *definer, bool role);
|
||||
void set_invoker(const LEX_STRING *user, const LEX_STRING *host)
|
||||
{
|
||||
invoker_user= *user;
|
||||
@@ -3467,6 +3625,25 @@ public:
|
||||
void wait_for_wakeup_ready();
|
||||
/* Wake this thread up from wait_for_wakeup_ready(). */
|
||||
void signal_wakeup_ready();
|
||||
|
||||
wait_for_commit *wait_for_commit_ptr;
|
||||
int wait_for_prior_commit()
|
||||
{
|
||||
if (wait_for_commit_ptr)
|
||||
{
|
||||
int err= wait_for_commit_ptr->wait_for_prior_commit();
|
||||
if (err)
|
||||
my_error(ER_PRIOR_COMMIT_FAILED, MYF(0));
|
||||
return err;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
void wakeup_subsequent_commits(int wakeup_error)
|
||||
{
|
||||
if (wait_for_commit_ptr)
|
||||
wait_for_commit_ptr->wakeup_subsequent_commits(wakeup_error);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
/** The current internal error handler for this thread, or NULL. */
|
||||
@@ -3492,14 +3669,15 @@ private:
|
||||
Diagnostics_area *m_stmt_da;
|
||||
|
||||
/**
|
||||
It will be set TURE if CURRENT_USER() is called in account management
|
||||
statements or default definer is set in CREATE/ALTER SP, SF, Event,
|
||||
TRIGGER or VIEW statements.
|
||||
It will be set if CURRENT_USER() or CURRENT_ROLE() is called in account
|
||||
management statements or default definer is set in CREATE/ALTER SP, SF,
|
||||
Event, TRIGGER or VIEW statements.
|
||||
|
||||
Current user will be binlogged into Query_log_event if m_binlog_invoker
|
||||
is TRUE; It will be stored into invoker_host and invoker_user by SQL thread.
|
||||
Current user or role will be binlogged into Query_log_event if
|
||||
m_binlog_invoker is not NONE; It will be stored into invoker_host and
|
||||
invoker_user by SQL thread.
|
||||
*/
|
||||
bool m_binlog_invoker;
|
||||
enum need_invoker m_binlog_invoker;
|
||||
|
||||
/**
|
||||
It points to the invoker in the Query_log_event.
|
||||
@@ -3519,6 +3697,27 @@ private:
|
||||
bool wakeup_ready;
|
||||
mysql_mutex_t LOCK_wakeup_ready;
|
||||
mysql_cond_t COND_wakeup_ready;
|
||||
|
||||
/* Protect against add/delete of temporary tables in parallel replication */
|
||||
void rgi_lock_temporary_tables();
|
||||
void rgi_unlock_temporary_tables();
|
||||
bool rgi_have_temporary_tables();
|
||||
public:
|
||||
inline void lock_temporary_tables()
|
||||
{
|
||||
if (rgi_slave)
|
||||
rgi_lock_temporary_tables();
|
||||
}
|
||||
inline void unlock_temporary_tables()
|
||||
{
|
||||
if (rgi_slave)
|
||||
rgi_unlock_temporary_tables();
|
||||
}
|
||||
inline bool have_temporary_tables()
|
||||
{
|
||||
return (temporary_tables ||
|
||||
(rgi_slave && rgi_have_temporary_tables()));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -3659,6 +3858,11 @@ public:
|
||||
void begin_dataset() {}
|
||||
#endif
|
||||
virtual void update_used_tables() {}
|
||||
|
||||
void reset_offset_limit()
|
||||
{
|
||||
unit->offset_limit_cnt= 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -3687,6 +3891,26 @@ public:
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
This is a select_result_sink which stores the data in text form.
|
||||
*/
|
||||
|
||||
class select_result_text_buffer : public select_result_sink
|
||||
{
|
||||
public:
|
||||
select_result_text_buffer(THD *thd_arg) : thd(thd_arg) {}
|
||||
int send_data(List<Item> &items);
|
||||
bool send_result_set_metadata(List<Item> &fields, uint flag);
|
||||
|
||||
void save_to(String *res);
|
||||
private:
|
||||
int append_row(List<Item> &items, bool send_names);
|
||||
|
||||
THD *thd;
|
||||
List<char*> rows;
|
||||
int n_columns;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
Base class for select_result descendands which intercept and
|
||||
@@ -3999,7 +4223,8 @@ public:
|
||||
bool is_distinct, ulonglong options,
|
||||
const char *alias,
|
||||
bool bit_fields_as_long,
|
||||
bool create_table);
|
||||
bool create_table,
|
||||
bool keep_row_order= FALSE);
|
||||
TMP_TABLE_PARAM *get_tmp_table_param() { return &tmp_table_param; }
|
||||
};
|
||||
|
||||
@@ -4069,7 +4294,8 @@ public:
|
||||
bool is_distinct, ulonglong options,
|
||||
const char *alias,
|
||||
bool bit_fields_as_long,
|
||||
bool create_table);
|
||||
bool create_table,
|
||||
bool keep_row_order= FALSE);
|
||||
bool init_result_table(ulonglong select_options);
|
||||
int send_data(List<Item> &items);
|
||||
void cleanup();
|
||||
@@ -4412,7 +4638,9 @@ class multi_update :public select_result_interceptor
|
||||
so that afterward send_error() needs to find out that.
|
||||
*/
|
||||
bool error_handled;
|
||||
|
||||
|
||||
/* Need this to protect against multiple prepare() calls */
|
||||
bool prepared;
|
||||
public:
|
||||
multi_update(TABLE_LIST *ut, List<TABLE_LIST> *leaves_list,
|
||||
List<Item> *fields, List<Item> *values,
|
||||
|
||||
Reference in New Issue
Block a user