1
0
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:
Seppo Jaakola
2013-12-04 10:32:43 +02:00
4824 changed files with 2233124 additions and 118451 deletions

View File

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