mirror of
https://github.com/MariaDB/server.git
synced 2026-04-25 09:45:31 +02:00
Review fixes.
This commit is contained in:
parent
5ebb396638
commit
21b4dec072
62 changed files with 1805 additions and 1998 deletions
|
|
@ -20,16 +20,6 @@
|
|||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#ifdef WITH_WSREP
|
||||
#include <my_sys.h>
|
||||
typedef my_bool (* wsrep_thd_is_brute_force_fun)(void *, my_bool);
|
||||
typedef int (* wsrep_abort_thd_fun)(void *, void *, my_bool);
|
||||
typedef int (* wsrep_on_fun)(void *);
|
||||
void wsrep_thr_lock_init(
|
||||
wsrep_thd_is_brute_force_fun bf_fun, wsrep_abort_thd_fun abort_fun,
|
||||
my_bool debug, my_bool convert_LOCK_to_trx, wsrep_on_fun on_fun);
|
||||
#endif
|
||||
|
||||
#include <my_pthread.h>
|
||||
#include <my_list.h>
|
||||
|
||||
|
|
@ -104,10 +94,7 @@ typedef struct st_thr_lock_info
|
|||
{
|
||||
pthread_t thread;
|
||||
my_thread_id thread_id;
|
||||
#ifdef WITH_WSREP
|
||||
void *mysql_thd; // THD pointer
|
||||
my_bool in_lock_tables; // true, if inside locking session
|
||||
#endif
|
||||
} THR_LOCK_INFO;
|
||||
|
||||
|
||||
|
|
@ -177,6 +164,17 @@ my_bool thr_reschedule_write_lock(THR_LOCK_DATA *data,
|
|||
ulong lock_wait_timeout);
|
||||
void thr_set_lock_wait_callback(void (*before_wait)(void),
|
||||
void (*after_wait)(void));
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
#include <my_sys.h>
|
||||
typedef my_bool (* wsrep_thd_is_brute_force_fun)(void *, my_bool);
|
||||
typedef int (* wsrep_abort_thd_fun)(void *, void *, my_bool);
|
||||
typedef int (* wsrep_on_fun)(void *);
|
||||
void wsrep_thr_lock_init(
|
||||
wsrep_thd_is_brute_force_fun bf_fun, wsrep_abort_thd_fun abort_fun,
|
||||
my_bool debug, my_bool convert_LOCK_to_trx, wsrep_on_fun on_fun);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
58
include/wsrep.h
Normal file
58
include/wsrep.h
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
/* Copyright 2014 Codership Oy <http://www.codership.com> & SkySQL Ab
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#ifndef WSREP_INCLUDED
|
||||
#define WSERP_INCLUDED
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
#define IF_WSREP(A,B) A
|
||||
#define DBUG_ASSERT_IF_WSREP(A) DBUG_ASSERT(A)
|
||||
|
||||
#if !defined(EMBEDDED_LIBRARY)
|
||||
#define WSREP_FORMAT(my_format) \
|
||||
((wsrep_forced_binlog_format != BINLOG_FORMAT_UNSPEC) ? \
|
||||
wsrep_forced_binlog_format : my_format)
|
||||
#else
|
||||
#define WSREP_FORMAT(my_format) my_format
|
||||
#endif /* && !EMBEDDED_LIBRARY */
|
||||
|
||||
#define WSREP_MYSQL_DB (char *)"mysql"
|
||||
#define WSREP_TO_ISOLATION_BEGIN(db_, table_, table_list_) \
|
||||
if (WSREP_ON && WSREP(thd) && wsrep_to_isolation_begin(thd, db_, table_, table_list_)) \
|
||||
goto error;
|
||||
|
||||
#define WSREP_TO_ISOLATION_END \
|
||||
if (WSREP_ON && (WSREP(thd) || (thd && thd->wsrep_exec_mode==TOTAL_ORDER))) \
|
||||
wsrep_to_isolation_end(thd);
|
||||
|
||||
#define WSREP_DEBUG(...) \
|
||||
if (wsrep_debug) WSREP_LOG(sql_print_information, ##__VA_ARGS__)
|
||||
#define WSREP_INFO(...) WSREP_LOG(sql_print_information, ##__VA_ARGS__)
|
||||
#define WSREP_WARN(...) WSREP_LOG(sql_print_warning, ##__VA_ARGS__)
|
||||
#define WSREP_ERROR(...) WSREP_LOG(sql_print_error, ##__VA_ARGS__)
|
||||
|
||||
#else
|
||||
#define IF_WSREP(A,B) B
|
||||
#define DBUG_ASSERT_IF_WSREP(A)
|
||||
#define WSREP_DEBUG(...)
|
||||
#define WSREP_INFO(...)
|
||||
#define WSREP_WARN(...)
|
||||
#define WSREP_ERROR(...)
|
||||
#define WSREP_FORMAT(my_format) my_format
|
||||
#define WSREP_TO_ISOLATION_BEGIN(db_, table_, table_list_)
|
||||
#define WSREP_TO_ISOLATION_END
|
||||
#endif
|
||||
|
||||
#endif /* WSERP_INCLUDED */
|
||||
|
|
@ -813,7 +813,7 @@ static int search_default_file_with_ext(Process_option_func opt_handler,
|
|||
#ifdef WITH_WSREP
|
||||
/* make sure we do this only once - for top-level file */
|
||||
if ('\0' == wsrep_defaults_file[0])
|
||||
strncpy(wsrep_defaults_file, name, sizeof(wsrep_defaults_file) - 1);
|
||||
strmake(wsrep_defaults_file, name, sizeof(wsrep_defaults_file) - 1);
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
while (mysql_file_fgets(buff, sizeof(buff) - 1, fp))
|
||||
|
|
|
|||
|
|
@ -68,6 +68,10 @@ uint my_large_page_size= 0;
|
|||
int volatile my_have_got_alarm=0; /* declare variable to reset */
|
||||
ulong my_time_to_wait_for_lock=2; /* In seconds */
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
my_bool mysys_wsrep= 0;
|
||||
#endif
|
||||
|
||||
/* from errors.c */
|
||||
#ifdef SHARED_LIBRARY
|
||||
const char *globerrs[GLOBERRS]; /* my_error_messages is here */
|
||||
|
|
|
|||
|
|
@ -62,6 +62,8 @@ extern mysql_mutex_t THR_LOCK_malloc, THR_LOCK_open, THR_LOCK_keycache;
|
|||
extern mysql_mutex_t THR_LOCK_lock, THR_LOCK_net;
|
||||
extern mysql_mutex_t THR_LOCK_charset;
|
||||
|
||||
extern my_bool mysys_wsrep;
|
||||
|
||||
#include <mysql/psi/mysql_file.h>
|
||||
|
||||
#ifdef HAVE_PSI_INTERFACE
|
||||
|
|
|
|||
|
|
@ -683,10 +683,10 @@ wait_for_lock(struct st_lock_list *wait, THR_LOCK_DATA *data,
|
|||
* This needs an condition to check for bf locks first.
|
||||
* TODO: we still have a debug fprintf, this should be removed
|
||||
*/
|
||||
static inline my_bool
|
||||
static my_bool
|
||||
wsrep_break_lock(
|
||||
THR_LOCK_DATA *data, struct st_lock_list *lock_queue1,
|
||||
struct st_lock_list *lock_queue2, struct st_lock_list *wait_queue)
|
||||
struct st_lock_list *wait_queue)
|
||||
{
|
||||
if (wsrep_on(data->owner->mysql_thd) &&
|
||||
wsrep_thd_is_brute_force &&
|
||||
|
|
@ -698,7 +698,7 @@ wsrep_break_lock(
|
|||
we know that this conflicting lock must be read lock and furthermore,
|
||||
lock holder is read-only. It is safe to wait for him.
|
||||
*/
|
||||
#ifdef TODO
|
||||
#ifdef TODO_WHEN_LOCK_TABLES_IS_A_TRANSACTION
|
||||
if (wsrep_convert_LOCK_to_trx &&
|
||||
(THD*)(data->owner->mysql_thd)->in_lock_tables)
|
||||
{
|
||||
|
|
@ -727,22 +727,6 @@ wsrep_break_lock(
|
|||
return FALSE;
|
||||
}
|
||||
}
|
||||
for (holder=(lock_queue2) ? lock_queue2->data : NULL;
|
||||
holder;
|
||||
holder=holder->next)
|
||||
{
|
||||
if (!wsrep_thd_is_brute_force(holder->owner->mysql_thd, TRUE))
|
||||
{
|
||||
wsrep_abort_thd(data->owner->mysql_thd,
|
||||
holder->owner->mysql_thd, FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (wsrep_debug)
|
||||
fprintf(stderr,"WSREP wsrep_break_lock skipping BF lock conflict\n");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Add our lock to the head of the wait queue */
|
||||
if (*(wait_queue->last)==wait_queue->data)
|
||||
|
|
@ -846,14 +830,6 @@ thr_lock(THR_LOCK_DATA *data, THR_LOCK_INFO *owner, ulong lock_wait_timeout)
|
|||
}
|
||||
if (lock->write.data->type == TL_WRITE_ONLY)
|
||||
{
|
||||
#ifdef WITH_WSREP
|
||||
if (wsrep_break_lock(data, &lock->write, NULL, &lock->read_wait))
|
||||
{
|
||||
wsrep_lock_inserted= TRUE;
|
||||
goto wsrep_read_wait;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* We are not allowed to get a READ lock in this case */
|
||||
data->type=TL_UNLOCK;
|
||||
result= THR_LOCK_ABORTED; /* Can't wait for this one */
|
||||
|
|
@ -882,7 +858,7 @@ thr_lock(THR_LOCK_DATA *data, THR_LOCK_INFO *owner, ulong lock_wait_timeout)
|
|||
In the latter case we should yield the lock to the writer.
|
||||
*/
|
||||
#ifdef WITH_WSREP
|
||||
if (wsrep_break_lock(data, &lock->write, NULL, &lock->read_wait))
|
||||
if (mysys_wsrep && wsrep_break_lock(data, &lock->write, &lock->read_wait))
|
||||
{
|
||||
wsrep_lock_inserted= TRUE;
|
||||
}
|
||||
|
|
@ -897,25 +873,12 @@ thr_lock(THR_LOCK_DATA *data, THR_LOCK_INFO *owner, ulong lock_wait_timeout)
|
|||
{
|
||||
if (lock->write.data && lock->write.data->type == TL_WRITE_ONLY)
|
||||
{
|
||||
#ifdef WITH_WSREP
|
||||
if (wsrep_break_lock(data, &lock->write, NULL, &lock->write_wait))
|
||||
{
|
||||
wsrep_lock_inserted=TRUE;
|
||||
goto wsrep_write_wait;
|
||||
}
|
||||
#endif
|
||||
data->type=TL_UNLOCK;
|
||||
result= THR_LOCK_ABORTED; /* Can't wait for this one */
|
||||
goto end;
|
||||
}
|
||||
if (lock->write.data || lock->read.data)
|
||||
{
|
||||
#ifdef WITH_WSREP
|
||||
if (wsrep_break_lock(data, &lock->write, NULL, &lock->write_wait))
|
||||
{
|
||||
goto end;
|
||||
}
|
||||
#endif
|
||||
/* Add delayed write lock to write_wait queue, and return at once */
|
||||
(*lock->write_wait.last)=data;
|
||||
data->prev=lock->write_wait.last;
|
||||
|
|
@ -940,13 +903,6 @@ thr_lock(THR_LOCK_DATA *data, THR_LOCK_INFO *owner, ulong lock_wait_timeout)
|
|||
/* Allow lock owner to bypass TL_WRITE_ONLY. */
|
||||
if (!thr_lock_owner_equal(data->owner, lock->write.data->owner))
|
||||
{
|
||||
#ifdef WITH_WSREP
|
||||
if (wsrep_break_lock(data, &lock->write, NULL, &lock->write_wait))
|
||||
{
|
||||
wsrep_lock_inserted=TRUE;
|
||||
goto wsrep_write_wait;
|
||||
}
|
||||
#endif
|
||||
/* We are not allowed to get a lock in this case */
|
||||
data->type=TL_UNLOCK;
|
||||
result= THR_LOCK_ABORTED; /* Can't wait for this one */
|
||||
|
|
@ -1051,7 +1007,7 @@ thr_lock(THR_LOCK_DATA *data, THR_LOCK_INFO *owner, ulong lock_wait_timeout)
|
|||
lock->read.data->owner->thread_id, data->type));
|
||||
}
|
||||
#ifdef WITH_WSREP
|
||||
if (wsrep_break_lock(data, &lock->write, NULL, &lock->write_wait))
|
||||
if (mysys_wsrep && wsrep_break_lock(data, &lock->write, &lock->write_wait))
|
||||
{
|
||||
wsrep_lock_inserted= TRUE;
|
||||
}
|
||||
|
|
@ -1063,7 +1019,7 @@ thr_lock(THR_LOCK_DATA *data, THR_LOCK_INFO *owner, ulong lock_wait_timeout)
|
|||
}
|
||||
/* Can't get lock yet; Wait for it */
|
||||
#ifdef WITH_WSREP
|
||||
if (wsrep_on(data->owner->mysql_thd) && wsrep_lock_inserted)
|
||||
if (mysys_wsrep && wsrep_lock_inserted && wsrep_on(data->owner->mysql_thd))
|
||||
DBUG_RETURN(wait_for_lock(wait_queue, data, 1, lock_wait_timeout));
|
||||
#endif
|
||||
result= wait_for_lock(wait_queue, data, 0, lock_wait_timeout);
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ done
|
|||
readonly WSREP_SST_OPT_BYPASS
|
||||
readonly WSREP_SST_OPT_BINLOG
|
||||
|
||||
# For Bug:1200727
|
||||
# State Snapshot Transfer authentication password was displayed in the ps output. Bug fixed #1200727.
|
||||
if my_print_defaults -c $WSREP_SST_OPT_CONF sst | grep -q "wsrep_sst_auth";then
|
||||
if [ -z "$WSREP_SST_OPT_AUTH" -o "$WSREP_SST_OPT_AUTH" = "(null)" ];then
|
||||
WSREP_SST_OPT_AUTH=$(my_print_defaults -c $WSREP_SST_OPT_CONF sst | grep -- "--wsrep_sst_auth" | cut -d= -f2)
|
||||
|
|
@ -114,7 +114,7 @@ wsrep_log()
|
|||
# echo everything to stderr so that it gets into common error log
|
||||
# deliberately made to look different from the rest of the log
|
||||
local readonly tst="$(date +%Y%m%d\ %H:%M:%S.%N | cut -b -21)"
|
||||
echo "WSREP_SST: $* ($tst)" >&2
|
||||
echo "$tst WSREP_SST: " >&2
|
||||
}
|
||||
|
||||
wsrep_log_error()
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ done
|
|||
readonly WSREP_SST_OPT_BYPASS
|
||||
readonly WSREP_SST_OPT_BINLOG
|
||||
|
||||
# For Bug:1200727
|
||||
# State Snapshot Transfer authentication password was displayed in the ps output. Bug fixed #1200727.
|
||||
if my_print_defaults -c $WSREP_SST_OPT_CONF sst | grep -q "wsrep_sst_auth";then
|
||||
if [ -z "$WSREP_SST_OPT_AUTH" -o "$WSREP_SST_OPT_AUTH" = "(null)" ];then
|
||||
WSREP_SST_OPT_AUTH=$(my_print_defaults -c $WSREP_SST_OPT_CONF sst | grep -- "--wsrep_sst_auth" | cut -d= -f2)
|
||||
|
|
@ -114,7 +114,7 @@ wsrep_log()
|
|||
# echo everything to stderr so that it gets into common error log
|
||||
# deliberately made to look different from the rest of the log
|
||||
local readonly tst="$(date +%Y%m%d\ %H:%M:%S.%N | cut -b -21)"
|
||||
echo "WSREP_SST: $* ($tst)" >&2
|
||||
echo "$tst WSREP_SST: " >&2
|
||||
}
|
||||
|
||||
wsrep_log_error()
|
||||
|
|
|
|||
|
|
@ -24,11 +24,10 @@ WSREP_SST_OPT_CONF=""
|
|||
. $(dirname $0)/wsrep_sst_common
|
||||
|
||||
EINVAL=22
|
||||
PATH=$PATH:/usr/sbin:/usr/bin:/sbin:/bin
|
||||
|
||||
local_ip()
|
||||
{
|
||||
PATH=$PATH:/usr/sbin:/usr/bin:/sbin:/bin
|
||||
|
||||
[ "$1" = "127.0.0.1" ] && return 0
|
||||
[ "$1" = "localhost" ] && return 0
|
||||
[ "$1" = "$(hostname -s)" ] && return 0
|
||||
|
|
@ -58,10 +57,10 @@ then
|
|||
fi
|
||||
|
||||
# Check client version
|
||||
if ! mysql --version | grep 'Distrib 10.0' >/dev/null
|
||||
if ! mysql --version | grep 'Distrib 10' >/dev/null
|
||||
then
|
||||
mysql --version >&2
|
||||
wsrep_log_error "this operation requires MySQL client version 10.0.x"
|
||||
wsrep_log_error "this operation requires MySQL client version 10 or newer"
|
||||
exit $EINVAL
|
||||
fi
|
||||
|
||||
|
|
|
|||
|
|
@ -24,11 +24,10 @@ WSREP_SST_OPT_CONF=""
|
|||
. $(dirname $0)/wsrep_sst_common
|
||||
|
||||
EINVAL=22
|
||||
PATH=$PATH:/usr/sbin:/usr/bin:/sbin:/bin
|
||||
|
||||
local_ip()
|
||||
{
|
||||
PATH=$PATH:/usr/sbin:/usr/bin:/sbin:/bin
|
||||
|
||||
[ "$1" = "127.0.0.1" ] && return 0
|
||||
[ "$1" = "localhost" ] && return 0
|
||||
[ "$1" = "$(hostname -s)" ] && return 0
|
||||
|
|
@ -58,10 +57,10 @@ then
|
|||
fi
|
||||
|
||||
# Check client version
|
||||
if ! mysql --version | grep 'Distrib 10.0' >/dev/null
|
||||
if ! mysql --version | grep 'Distrib 10' >/dev/null
|
||||
then
|
||||
mysql --version >&2
|
||||
wsrep_log_error "this operation requires MySQL client version 10.0.x"
|
||||
wsrep_log_error "this operation requires MySQL client version 10 or newer"
|
||||
exit $EINVAL
|
||||
fi
|
||||
|
||||
|
|
|
|||
|
|
@ -1190,7 +1190,8 @@ end:
|
|||
#ifdef WITH_WSREP
|
||||
int wsrep_create_event_query(THD *thd, uchar** buf, size_t* buf_len)
|
||||
{
|
||||
String log_query;
|
||||
char buffer[1024];
|
||||
String log_query(buffer, sizeof(buffer), &my_charset_bin);
|
||||
|
||||
if (create_query_string(thd, &log_query))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -386,14 +386,17 @@ const char *ha_partition::table_type() const
|
|||
// we can do this since we only support a single engine type
|
||||
return m_file[0]->table_type();
|
||||
}
|
||||
|
||||
|
||||
#if defined(WITH_WSREP) && !defined(EMBEDDED_LIBRARY)
|
||||
int ha_partition::wsrep_db_type() const
|
||||
{
|
||||
// we can do this since we only support a single engine type
|
||||
return ha_legacy_type(m_file[0]->ht);
|
||||
return partition_ht()->db_type;
|
||||
}
|
||||
#endif /* WITH_WSREP && !EMBEDDED_LIBRARY */
|
||||
|
||||
|
||||
/*
|
||||
Destructor method
|
||||
|
||||
|
|
|
|||
142
sql/handler.cc
142
sql/handler.cc
|
|
@ -50,9 +50,9 @@
|
|||
#include "../storage/maria/ha_maria.h"
|
||||
#endif
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
#include "wsrep_mysqld.h"
|
||||
#endif
|
||||
#include "wsrep.h"
|
||||
|
||||
/*
|
||||
While we have legacy_db_type, we have this array to
|
||||
check for dups and to find handlerton from legacy_db_type.
|
||||
|
|
@ -1169,26 +1169,24 @@ int ha_prepare(THD *thd)
|
|||
if ((err= ht->prepare(ht, thd, all)))
|
||||
{
|
||||
#ifdef WITH_WSREP
|
||||
if (WSREP(thd) && ht->db_type== DB_TYPE_WSREP)
|
||||
if (ht == wsrep_hton)
|
||||
{
|
||||
error= 1;
|
||||
/* avoid sending error, if we need to replay */
|
||||
error= 1;
|
||||
/* avoid sending error, if we need to replay */
|
||||
if (thd->wsrep_conflict_state!= MUST_REPLAY)
|
||||
{
|
||||
my_error(ER_LOCK_DEADLOCK, MYF(0), err);
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
/* not wsrep hton, bail to native mysql behavior */
|
||||
#endif
|
||||
my_error(ER_ERROR_DURING_COMMIT, MYF(0), err);
|
||||
ha_rollback_trans(thd, all);
|
||||
error=1;
|
||||
break;
|
||||
#ifdef WITH_WSREP
|
||||
my_error(ER_ERROR_DURING_COMMIT, MYF(0), err);
|
||||
ha_rollback_trans(thd, all);
|
||||
error=1;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -1386,13 +1384,9 @@ int ha_commit_trans(THD *thd, bool all)
|
|||
mdl_request.init(MDL_key::COMMIT, "", "", MDL_INTENTION_EXCLUSIVE,
|
||||
MDL_EXPLICIT);
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
if (!WSREP(thd) &&
|
||||
if (IF_WSREP(!WSREP(thd),1) &&
|
||||
thd->mdl_context.acquire_lock(&mdl_request,
|
||||
#else
|
||||
if (thd->mdl_context.acquire_lock(&mdl_request,
|
||||
#endif /* WITH_WSREP */
|
||||
thd->variables.lock_wait_timeout))
|
||||
thd->variables.lock_wait_timeout))
|
||||
{
|
||||
ha_rollback_trans(thd, all);
|
||||
thd->wakeup_subsequent_commits(1);
|
||||
|
|
@ -1439,15 +1433,13 @@ int ha_commit_trans(THD *thd, bool all)
|
|||
err= ht->prepare(ht, thd, all);
|
||||
status_var_increment(thd->status_var.ha_prepare_count);
|
||||
if (err)
|
||||
#ifdef WITH_WSREP
|
||||
{
|
||||
if (WSREP(thd) && ht->db_type== DB_TYPE_WSREP)
|
||||
#ifdef WITH_WSREP
|
||||
if (ht == wsrep_hton)
|
||||
{
|
||||
error= 1;
|
||||
switch (err)
|
||||
{
|
||||
switch (err) {
|
||||
case WSREP_TRX_SIZE_EXCEEDED:
|
||||
/* give user size exeeded erro from wsrep_api.h */
|
||||
/* give user size exeeded error from wsrep_api.h */
|
||||
my_error(ER_ERROR_DURING_COMMIT, MYF(0), WSREP_SIZE_EXCEEDED);
|
||||
break;
|
||||
case WSREP_TRX_CERT_FAIL:
|
||||
|
|
@ -1458,15 +1450,11 @@ int ha_commit_trans(THD *thd, bool all)
|
|||
my_error(ER_LOCK_DEADLOCK, MYF(0), err);
|
||||
}
|
||||
}
|
||||
goto err;
|
||||
}
|
||||
else
|
||||
/* not wsrep hton, bail to native mysql behavior */
|
||||
#endif /* WITH_WSREP */
|
||||
my_error(ER_ERROR_DURING_COMMIT, MYF(0), err);
|
||||
#ifdef WITH_WSREP
|
||||
}
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
if (err)
|
||||
goto err;
|
||||
|
||||
|
|
@ -1477,12 +1465,13 @@ int ha_commit_trans(THD *thd, bool all)
|
|||
DBUG_EXECUTE_IF("crash_commit_after_prepare", DBUG_SUICIDE(););
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
if (!error && wsrep_is_wsrep_xid(&thd->transaction.xid_state.xid))
|
||||
if (!error && WSREP_ON && wsrep_is_wsrep_xid(&thd->transaction.xid_state.xid))
|
||||
{
|
||||
// xid was rewritten by wsrep
|
||||
xid= wsrep_xid_seqno(&thd->transaction.xid_state.xid);
|
||||
}
|
||||
#endif // WITH_WSREP
|
||||
|
||||
if (!is_real_trans)
|
||||
{
|
||||
error= commit_one_phase_2(thd, all, trans, is_real_trans);
|
||||
|
|
@ -1859,13 +1848,10 @@ static my_bool xarecover_handlerton(THD *unused, plugin_ref plugin,
|
|||
got, hton_name(hton)->str);
|
||||
for (int i=0; i < got; i ++)
|
||||
{
|
||||
#ifdef WITH_WSREP
|
||||
my_xid x=(wsrep_is_wsrep_xid(&info->list[i]) ?
|
||||
wsrep_xid_seqno(&info->list[i]) :
|
||||
info->list[i].get_my_xid());
|
||||
#else
|
||||
my_xid x=info->list[i].get_my_xid();
|
||||
#endif /* WITH_WSREP */
|
||||
my_xid x= IF_WSREP(WSREP_ON && wsrep_is_wsrep_xid(&info->list[i]) ?
|
||||
wsrep_xid_seqno(&info->list[i]) :
|
||||
info->list[i].get_my_xid(),
|
||||
info->list[i].get_my_xid());
|
||||
if (!x) // not "mine" - that is generated by external TM
|
||||
{
|
||||
#ifndef DBUG_OFF
|
||||
|
|
@ -3150,15 +3136,12 @@ int handler::update_auto_increment()
|
|||
variables->auto_increment_increment);
|
||||
auto_inc_intervals_count++;
|
||||
/* Row-based replication does not need to store intervals in binlog */
|
||||
#ifdef WITH_WSREP
|
||||
if (((WSREP(thd) && wsrep_emulate_bin_log) || mysql_bin_log.is_open()) &&
|
||||
!thd->is_current_stmt_binlog_format_row())
|
||||
#else
|
||||
if (mysql_bin_log.is_open() && !thd->is_current_stmt_binlog_format_row())
|
||||
#endif /* WITH_WSREP */
|
||||
thd->auto_inc_intervals_in_cur_stmt_for_binlog.append(auto_inc_interval_for_cur_row.minimum(),
|
||||
auto_inc_interval_for_cur_row.values(),
|
||||
variables->auto_increment_increment);
|
||||
if (IF_WSREP((WSREP(thd) && (wsrep_emulate_bin_log || mysql_bin_log.is_open())), mysql_bin_log.is_open())
|
||||
&& !thd->is_current_stmt_binlog_format_row())
|
||||
thd->auto_inc_intervals_in_cur_stmt_for_binlog.
|
||||
append(auto_inc_interval_for_cur_row.minimum(),
|
||||
auto_inc_interval_for_cur_row.values(),
|
||||
variables->auto_increment_increment);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -5776,13 +5759,9 @@ static bool check_table_binlog_row_based(THD *thd, TABLE *table)
|
|||
return (thd->is_current_stmt_binlog_format_row() &&
|
||||
table->s->cached_row_logging_check &&
|
||||
(thd->variables.option_bits & OPTION_BIN_LOG) &&
|
||||
#ifdef WITH_WSREP
|
||||
/* applier and replayer should not binlog */
|
||||
((WSREP_EMULATE_BINLOG(thd) && (thd->wsrep_exec_mode != REPL_RECV)) ||
|
||||
(IF_WSREP((WSREP_EMULATE_BINLOG(thd) && (thd->wsrep_exec_mode != REPL_RECV)),0) ||
|
||||
mysql_bin_log.is_open()));
|
||||
#else
|
||||
mysql_bin_log.is_open());
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -5884,14 +5863,9 @@ static int binlog_log_row(TABLE* table,
|
|||
|
||||
#ifdef WITH_WSREP
|
||||
/* only InnoDB tables will be replicated through binlog emulation */
|
||||
if (WSREP_EMULATE_BINLOG(thd) &&
|
||||
table->file->ht->db_type != DB_TYPE_INNODB &&
|
||||
!(table->file->ht->db_type == DB_TYPE_PARTITION_DB &&
|
||||
(((ha_partition*)(table->file))->wsrep_db_type() == DB_TYPE_INNODB)))
|
||||
// !strcmp(table->file->table_type(), "InnoDB"))
|
||||
{
|
||||
if (WSREP_ON && WSREP_EMULATE_BINLOG(thd) &&
|
||||
table->file->partition_ht()->db_type != DB_TYPE_INNODB)
|
||||
return 0;
|
||||
}
|
||||
#endif /* WITH_WSREP */
|
||||
if (check_table_binlog_row_based(thd, table))
|
||||
{
|
||||
|
|
@ -6240,46 +6214,58 @@ void handler::set_lock_type(enum thr_lock_type lock)
|
|||
int ha_wsrep_abort_transaction(THD *bf_thd, THD *victim_thd, my_bool signal)
|
||||
{
|
||||
DBUG_ENTER("ha_wsrep_abort_transaction");
|
||||
if (!WSREP(bf_thd) &&
|
||||
if (!WSREP(bf_thd) &&
|
||||
!(wsrep_OSU_method_options == WSREP_OSU_RSU &&
|
||||
bf_thd->wsrep_exec_mode == TOTAL_ORDER)) {
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
handlerton *hton= installed_htons[DB_TYPE_INNODB];
|
||||
if (hton && hton->wsrep_abort_transaction)
|
||||
{
|
||||
hton->wsrep_abort_transaction(hton, bf_thd, victim_thd, signal);
|
||||
}
|
||||
else
|
||||
{
|
||||
WSREP_WARN("cannot abort InnoDB transaction");
|
||||
}
|
||||
THD_TRANS *trans= &victim_thd->transaction.all;
|
||||
Ha_trx_info *ha_info= trans->ha_list, *ha_info_next;
|
||||
|
||||
for (; ha_info; ha_info= ha_info_next)
|
||||
{
|
||||
handlerton *hton= ha_info->ht();
|
||||
if (!hton->wsrep_abort_transaction)
|
||||
{
|
||||
WSREP_WARN("cannot abort WRESP transaction");
|
||||
}
|
||||
else
|
||||
hton->wsrep_abort_transaction(hton, bf_thd, victim_thd, signal);
|
||||
ha_info_next= ha_info->next();
|
||||
ha_info->reset(); /* keep it conveniently zero-filled */
|
||||
}
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
void ha_wsrep_fake_trx_id(THD *thd)
|
||||
{
|
||||
DBUG_ENTER("ha_wsrep_fake_trx_id");
|
||||
if (!WSREP(thd))
|
||||
if (!WSREP(thd))
|
||||
{
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
handlerton *hton= installed_htons[DB_TYPE_INNODB];
|
||||
if (hton && hton->wsrep_fake_trx_id)
|
||||
{
|
||||
hton->wsrep_fake_trx_id(hton, thd);
|
||||
}
|
||||
else
|
||||
{
|
||||
WSREP_WARN("cannot get fake InnoDB transaction ID");
|
||||
}
|
||||
THD_TRANS *trans= &thd->transaction.all;
|
||||
Ha_trx_info *ha_info= trans->ha_list, *ha_info_next;
|
||||
|
||||
for (; ha_info; ha_info= ha_info_next)
|
||||
{
|
||||
handlerton *hton= ha_info->ht();
|
||||
if (!hton->wsrep_fake_trx_id)
|
||||
{
|
||||
WSREP_WARN("cannot get fake InnoDB transaction ID");
|
||||
}
|
||||
else
|
||||
hton->wsrep_fake_trx_id(hton, thd);
|
||||
ha_info_next= ha_info->next();
|
||||
ha_info->reset(); /* keep it conveniently zero-filled */
|
||||
}
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
|
||||
#ifdef TRANS_LOG_MGM_EXAMPLE_CODE
|
||||
/*
|
||||
Example of transaction log management functions based on assumption that logs
|
||||
|
|
|
|||
|
|
@ -439,7 +439,6 @@ enum legacy_db_type
|
|||
DB_TYPE_BINLOG=21,
|
||||
DB_TYPE_PBXT=23,
|
||||
DB_TYPE_PERFORMANCE_SCHEMA=28,
|
||||
DB_TYPE_WSREP=41,
|
||||
DB_TYPE_ARIA=42,
|
||||
DB_TYPE_TOKUDB=43,
|
||||
DB_TYPE_FIRST_DYNAMIC=44,
|
||||
|
|
|
|||
|
|
@ -2769,7 +2769,19 @@ void Item_func_rand::seed_random(Item *arg)
|
|||
TODO: do not do reinit 'rand' for every execute of PS/SP if
|
||||
args[0] is a constant.
|
||||
*/
|
||||
uint32 tmp= (uint32) arg->val_int();
|
||||
uint32 tmp;
|
||||
#ifdef WITH_WSREP
|
||||
if (WSREP(current_thd))
|
||||
{
|
||||
if (current_thd->wsrep_exec_mode==REPL_RECV)
|
||||
tmp= current_thd->wsrep_rand;
|
||||
else
|
||||
tmp= current_thd->wsrep_rand= (uint32) arg->val_int();
|
||||
}
|
||||
else
|
||||
#endif /* WITH_WSREP */
|
||||
tmp= (uint32) arg->val_int();
|
||||
|
||||
my_rnd_init(rand, (uint32) (tmp*0x10001L+55555555L),
|
||||
(uint32) (tmp*0x10000001L));
|
||||
}
|
||||
|
|
|
|||
60
sql/lock.cc
60
sql/lock.cc
|
|
@ -83,10 +83,7 @@
|
|||
#include "sql_acl.h" // SUPER_ACL
|
||||
#include <hash.h>
|
||||
#include <assert.h>
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
#include "wsrep_mysqld.h"
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
/**
|
||||
@defgroup Locking Locking
|
||||
|
|
@ -318,9 +315,6 @@ bool mysql_lock_tables(THD *thd, MYSQL_LOCK *sql_lock, uint flags)
|
|||
/* Copy the lock data array. thr_multi_lock() reorders its contents. */
|
||||
memmove(sql_lock->locks + sql_lock->lock_count, sql_lock->locks,
|
||||
sql_lock->lock_count * sizeof(*sql_lock->locks));
|
||||
#ifdef WITH_WSREP
|
||||
thd->lock_info.in_lock_tables= thd->in_lock_tables;
|
||||
#endif
|
||||
|
||||
/* Lock on the copied half of the lock data array. */
|
||||
rc= thr_lock_errno_to_mysql[(int) thr_multi_lock(sql_lock->locks +
|
||||
|
|
@ -332,26 +326,21 @@ bool mysql_lock_tables(THD *thd, MYSQL_LOCK *sql_lock, uint flags)
|
|||
|
||||
end:
|
||||
THD_STAGE_INFO(thd, stage_after_table_lock);
|
||||
#ifdef WITH_WSREP
|
||||
thd_proc_info(thd, "mysql_lock_tables(): unlocking tables II");
|
||||
#else /* WITH_WSREP */
|
||||
thd_proc_info(thd, 0);
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
if (thd->killed)
|
||||
{
|
||||
thd->send_kill_message();
|
||||
if (!rc)
|
||||
{
|
||||
mysql_unlock_tables(thd, sql_lock, 0);
|
||||
THD_STAGE_INFO(thd, stage_after_table_lock);
|
||||
}
|
||||
rc= 1;
|
||||
}
|
||||
else if (rc > 1)
|
||||
my_error(rc, MYF(0));
|
||||
|
||||
thd->set_time_after_lock();
|
||||
#ifdef WITH_WSREP
|
||||
thd_proc_info(thd, "exit mysqld_lock_tables()");
|
||||
#endif /* WITH_WSREP */
|
||||
DBUG_RETURN(rc);
|
||||
}
|
||||
|
||||
|
|
@ -396,6 +385,8 @@ static int lock_external(THD *thd, TABLE **tables, uint count)
|
|||
void mysql_unlock_tables(THD *thd, MYSQL_LOCK *sql_lock, bool free_lock)
|
||||
{
|
||||
DBUG_ENTER("mysql_unlock_tables");
|
||||
THD_STAGE_INFO(thd, stage_unlocking_tables);
|
||||
|
||||
if (sql_lock->table_count)
|
||||
unlock_external(thd, sql_lock->table, sql_lock->table_count);
|
||||
if (sql_lock->lock_count)
|
||||
|
|
@ -1069,8 +1060,11 @@ void Global_read_lock::unlock_global_read_lock(THD *thd)
|
|||
thd->mdl_context.release_lock(m_mdl_blocks_commits_lock);
|
||||
m_mdl_blocks_commits_lock= NULL;
|
||||
#ifdef WITH_WSREP
|
||||
wsrep_locked_seqno= WSREP_SEQNO_UNDEFINED;
|
||||
wsrep->resume(wsrep);
|
||||
if (WSREP_ON)
|
||||
{
|
||||
wsrep_locked_seqno= WSREP_SEQNO_UNDEFINED;
|
||||
wsrep->resume(wsrep);
|
||||
}
|
||||
#endif /* WITH_WSREP */
|
||||
}
|
||||
thd->mdl_context.release_lock(m_mdl_global_shared_lock);
|
||||
|
|
@ -1105,8 +1099,11 @@ bool Global_read_lock::make_global_read_lock_block_commit(THD *thd)
|
|||
make_global_read_lock_block_commit(), do nothing.
|
||||
*/
|
||||
|
||||
if (m_state != GRL_ACQUIRED)
|
||||
DBUG_RETURN(0);
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
if (m_mdl_blocks_commits_lock)
|
||||
if (WSREP_ON && m_mdl_blocks_commits_lock)
|
||||
{
|
||||
WSREP_DEBUG("GRL was in block commit mode when entering "
|
||||
"make_global_read_lock_block_commit");
|
||||
|
|
@ -1114,13 +1111,9 @@ bool Global_read_lock::make_global_read_lock_block_commit(THD *thd)
|
|||
m_mdl_blocks_commits_lock= NULL;
|
||||
wsrep_locked_seqno= WSREP_SEQNO_UNDEFINED;
|
||||
wsrep->resume(wsrep);
|
||||
m_state= GRL_ACQUIRED;
|
||||
}
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
if (m_state != GRL_ACQUIRED)
|
||||
DBUG_RETURN(0);
|
||||
|
||||
mdl_request.init(MDL_key::COMMIT, "", "", MDL_SHARED, MDL_EXPLICIT);
|
||||
|
||||
if (thd->mdl_context.acquire_lock(&mdl_request,
|
||||
|
|
@ -1131,19 +1124,22 @@ bool Global_read_lock::make_global_read_lock_block_commit(THD *thd)
|
|||
m_state= GRL_ACQUIRED_AND_BLOCKS_COMMIT;
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
long long ret = wsrep->pause(wsrep);
|
||||
if (ret >= 0)
|
||||
if (WSREP_ON)
|
||||
{
|
||||
wsrep_locked_seqno= ret;
|
||||
}
|
||||
else if (ret != -ENOSYS) /* -ENOSYS - no provider */
|
||||
{
|
||||
WSREP_ERROR("Failed to pause provider: %lld (%s)", -ret, strerror(-ret));
|
||||
long long ret = wsrep->pause(wsrep);
|
||||
if (ret >= 0)
|
||||
{
|
||||
wsrep_locked_seqno= ret;
|
||||
}
|
||||
else if (ret != -ENOSYS) /* -ENOSYS - no provider */
|
||||
{
|
||||
WSREP_ERROR("Failed to pause provider: %lld (%s)", -ret, strerror(-ret));
|
||||
|
||||
/* m_mdl_blocks_commits_lock is always NULL here */
|
||||
wsrep_locked_seqno= WSREP_SEQNO_UNDEFINED;
|
||||
my_error(ER_LOCK_DEADLOCK, MYF(0));
|
||||
DBUG_RETURN(TRUE);
|
||||
DBUG_ASSERT(m_mdl_blocks_commits_lock == NULL);
|
||||
wsrep_locked_seqno= WSREP_SEQNO_UNDEFINED;
|
||||
my_error(ER_LOCK_DEADLOCK, MYF(0));
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
}
|
||||
#endif /* WITH_WSREP */
|
||||
DBUG_RETURN(FALSE);
|
||||
|
|
|
|||
290
sql/log.cc
290
sql/log.cc
|
|
@ -52,12 +52,11 @@
|
|||
|
||||
#include "sql_plugin.h"
|
||||
#include "rpl_handler.h"
|
||||
#ifdef WITH_WSREP
|
||||
#include "wsrep_mysqld.h"
|
||||
#endif /* WITH_WSREP */
|
||||
#include "debug_sync.h"
|
||||
#include "sql_show.h"
|
||||
#include "my_pthread.h"
|
||||
#include "wsrep_mysqld.h"
|
||||
|
||||
/* max size of the log message */
|
||||
#define MAX_LOG_BUFFER_SIZE 1024
|
||||
|
|
@ -66,6 +65,7 @@
|
|||
|
||||
#define FLAGSTR(V,F) ((V)&(F)?#F" ":"")
|
||||
|
||||
handlerton *binlog_hton;
|
||||
LOGGER logger;
|
||||
|
||||
MYSQL_BIN_LOG mysql_bin_log(&sync_binlog_period);
|
||||
|
|
@ -514,11 +514,6 @@ private:
|
|||
binlog_cache_mngr(const binlog_cache_mngr& info);
|
||||
};
|
||||
|
||||
handlerton *binlog_hton;
|
||||
#ifdef WITH_WSREP
|
||||
extern handlerton *wsrep_hton;
|
||||
#endif
|
||||
|
||||
bool LOGGER::is_log_table_enabled(uint log_table_type)
|
||||
{
|
||||
switch (log_table_type) {
|
||||
|
|
@ -532,129 +527,6 @@ bool LOGGER::is_log_table_enabled(uint log_table_type)
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
IO_CACHE * get_trans_log(THD * thd)
|
||||
{
|
||||
binlog_cache_mngr *cache_mngr = (binlog_cache_mngr*)
|
||||
thd_get_ha_data(thd, binlog_hton);
|
||||
if (cache_mngr)
|
||||
{
|
||||
return cache_mngr->get_binlog_cache_log(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
WSREP_DEBUG("binlog cache not initialized, conn :%ld", thd->thread_id);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool wsrep_trans_cache_is_empty(THD *thd)
|
||||
{
|
||||
binlog_cache_mngr *const cache_mngr=
|
||||
(binlog_cache_mngr*) thd_get_ha_data(thd, binlog_hton);
|
||||
return (!cache_mngr || cache_mngr->trx_cache.empty());
|
||||
}
|
||||
|
||||
void thd_binlog_flush_pending_rows_event(THD *thd, bool stmt_end)
|
||||
{
|
||||
thd->binlog_flush_pending_rows_event(stmt_end);
|
||||
}
|
||||
void thd_binlog_trx_reset(THD * thd)
|
||||
{
|
||||
/*
|
||||
todo: fix autocommit select to not call the caller
|
||||
*/
|
||||
if (thd_get_ha_data(thd, binlog_hton) != NULL)
|
||||
{
|
||||
binlog_cache_mngr *const cache_mngr=
|
||||
(binlog_cache_mngr*) thd_get_ha_data(thd, binlog_hton);
|
||||
if (cache_mngr) cache_mngr->reset(false, true);
|
||||
}
|
||||
thd->clear_binlog_table_maps();
|
||||
}
|
||||
|
||||
void thd_binlog_rollback_stmt(THD * thd)
|
||||
{
|
||||
WSREP_DEBUG("thd_binlog_rollback_stmt :%ld", thd->thread_id);
|
||||
binlog_cache_mngr *const cache_mngr=
|
||||
(binlog_cache_mngr*) thd_get_ha_data(thd, binlog_hton);
|
||||
if (cache_mngr) cache_mngr->trx_cache.set_prev_position(MY_OFF_T_UNDEF);
|
||||
}
|
||||
|
||||
#ifdef REMOVED
|
||||
/*
|
||||
Write the contents of a cache to memory buffer.
|
||||
|
||||
This function quite the same as MYSQL_BIN_LOG::write_cache(),
|
||||
with the exception that here we write in buffer instead of log file.
|
||||
*/
|
||||
|
||||
int wsrep_write_cache(IO_CACHE *cache, uchar **buf, int *buf_len)
|
||||
{
|
||||
|
||||
if (reinit_io_cache(cache, READ_CACHE, 0, 0, 0))
|
||||
return ER_ERROR_ON_WRITE;
|
||||
uint length= my_b_bytes_in_cache(cache);
|
||||
long long total_length = 0;
|
||||
uchar *buf_ptr = NULL;
|
||||
|
||||
do
|
||||
{
|
||||
/* bail out if buffer grows too large
|
||||
This is a temporary fix to avoid flooding replication
|
||||
TODO: remove this check for 0.7.4 release
|
||||
*/
|
||||
if (total_length > wsrep_max_ws_size)
|
||||
{
|
||||
WSREP_WARN("transaction size limit (%lld) exceeded: %lld",
|
||||
wsrep_max_ws_size, total_length);
|
||||
if (reinit_io_cache(cache, WRITE_CACHE, 0, 0, 0))
|
||||
{
|
||||
WSREP_WARN("failed to initialize io-cache");
|
||||
}
|
||||
if (buf_ptr) my_free(*buf);
|
||||
*buf_len = 0;
|
||||
return ER_ERROR_ON_WRITE;
|
||||
}
|
||||
if (total_length > 0)
|
||||
{
|
||||
*buf_len += length;
|
||||
*buf = (uchar *)my_realloc(*buf, total_length+length,
|
||||
MYF(MY_ALLOW_ZERO_PTR));
|
||||
if (!*buf)
|
||||
{
|
||||
WSREP_ERROR("io cache write problem: %d %d", *buf_len, length);
|
||||
return ER_ERROR_ON_WRITE;
|
||||
}
|
||||
buf_ptr = *buf+total_length;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (buf_ptr != NULL)
|
||||
{
|
||||
WSREP_ERROR("io cache alloc error: %d %d", *buf_len, length);
|
||||
my_free(*buf);
|
||||
}
|
||||
if (length > 0)
|
||||
{
|
||||
*buf = (uchar *) my_malloc(length, MYF(0));
|
||||
buf_ptr = *buf;
|
||||
*buf_len = length;
|
||||
}
|
||||
}
|
||||
total_length += length;
|
||||
|
||||
memcpy(buf_ptr, cache->read_pos, length);
|
||||
cache->read_pos=cache->read_end;
|
||||
} while ((cache->file >= 0) && (length= my_b_fill(cache)));
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* REMOVED */
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
Check if a given table is opened log table
|
||||
|
||||
|
|
@ -1705,11 +1577,8 @@ binlog_trans_log_savepos(THD *thd, my_off_t *pos)
|
|||
DBUG_ENTER("binlog_trans_log_savepos");
|
||||
DBUG_ASSERT(pos != NULL);
|
||||
binlog_cache_mngr *const cache_mngr= thd->binlog_setup_trx_data();
|
||||
#ifdef WITH_WSREP
|
||||
DBUG_ASSERT((WSREP(thd) && wsrep_emulate_bin_log) || mysql_bin_log.is_open());
|
||||
#else
|
||||
DBUG_ASSERT(mysql_bin_log.is_open());
|
||||
#endif
|
||||
DBUG_ASSERT_IF_WSREP(((WSREP(thd) && wsrep_emulate_bin_log)) || mysql_bin_log.is_open());
|
||||
DBUG_ASSERT(IF_WSREP(1, mysql_bin_log.is_open()));
|
||||
*pos= cache_mngr->trx_cache.get_byte_position();
|
||||
DBUG_PRINT("return", ("*pos: %lu", (ulong) *pos));
|
||||
DBUG_VOID_RETURN;
|
||||
|
|
@ -1757,16 +1626,8 @@ binlog_trans_log_truncate(THD *thd, my_off_t pos)
|
|||
int binlog_init(void *p)
|
||||
{
|
||||
binlog_hton= (handlerton *)p;
|
||||
#ifdef WITH_WSREP
|
||||
if (WSREP_ON)
|
||||
binlog_hton->state= SHOW_OPTION_YES;
|
||||
else
|
||||
{
|
||||
#endif /* WITH_WSREP */
|
||||
binlog_hton->state=opt_bin_log ? SHOW_OPTION_YES : SHOW_OPTION_NO;
|
||||
#ifdef WITH_WSREP
|
||||
}
|
||||
#endif /* WITH_WSREP */
|
||||
binlog_hton->state=IF_WSREP(WSREP_ON || opt_bin_log, opt_bin_log) ?
|
||||
SHOW_OPTION_YES : SHOW_OPTION_NO;
|
||||
binlog_hton->db_type=DB_TYPE_BINLOG;
|
||||
binlog_hton->savepoint_offset= sizeof(my_off_t);
|
||||
binlog_hton->close_connection= binlog_close_connection;
|
||||
|
|
@ -1889,7 +1750,9 @@ binlog_commit_flush_stmt_cache(THD *thd, bool all,
|
|||
#ifdef WITH_WSREP
|
||||
if (thd->wsrep_mysql_replicated > 0)
|
||||
{
|
||||
WSREP_DEBUG("avoiding binlog_commit_flush_trx_cache: %d", thd->wsrep_mysql_replicated);
|
||||
DBUG_ASSERT(WSREP_ON);
|
||||
WSREP_DEBUG("avoiding binlog_commit_flush_trx_cache: %d",
|
||||
thd->wsrep_mysql_replicated);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
|
@ -2077,7 +1940,11 @@ static int binlog_commit(handlerton *hton, THD *thd, bool all)
|
|||
binlog_cache_mngr *const cache_mngr=
|
||||
(binlog_cache_mngr*) thd_get_ha_data(thd, binlog_hton);
|
||||
#ifdef WITH_WSREP
|
||||
if (!cache_mngr) DBUG_RETURN(0);
|
||||
if (!cache_mngr)
|
||||
{
|
||||
DBUG_ASSERT(WSREP(thd));
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
DBUG_PRINT("debug",
|
||||
|
|
@ -2136,7 +2003,12 @@ static int binlog_rollback(handlerton *hton, THD *thd, bool all)
|
|||
binlog_cache_mngr *const cache_mngr=
|
||||
(binlog_cache_mngr*) thd_get_ha_data(thd, binlog_hton);
|
||||
#ifdef WITH_WSREP
|
||||
if (!cache_mngr) DBUG_RETURN(0);
|
||||
if (!cache_mngr)
|
||||
{
|
||||
DBUG_ASSERT(WSREP(thd));
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
DBUG_PRINT("debug", ("all: %s, all.modified_non_trans_table: %s, stmt.modified_non_trans_table: %s",
|
||||
|
|
@ -2166,12 +2038,8 @@ static int binlog_rollback(handlerton *hton, THD *thd, bool all)
|
|||
cache_mngr->reset(false, true);
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
#ifdef WITH_WSREP
|
||||
if (!wsrep_emulate_bin_log &&
|
||||
if (IF_WSREP(!wsrep_emulate_bin_log,1) &&
|
||||
mysql_bin_log.check_write_error(thd))
|
||||
#else
|
||||
if (mysql_bin_log.check_write_error(thd))
|
||||
#endif
|
||||
{
|
||||
/*
|
||||
"all == true" means that a "rollback statement" triggered the error and
|
||||
|
|
@ -2309,13 +2177,15 @@ bool MYSQL_BIN_LOG::check_write_error(THD *thd)
|
|||
|
||||
static int binlog_savepoint_set(handlerton *hton, THD *thd, void *sv)
|
||||
{
|
||||
DBUG_ENTER("binlog_savepoint_set");
|
||||
int error= 1;
|
||||
DBUG_ENTER("binlog_savepoint_set");
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
if (wsrep_emulate_bin_log)
|
||||
DBUG_RETURN(0);
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
char buf[1024];
|
||||
#ifdef WITH_WSREP
|
||||
if (wsrep_emulate_bin_log) DBUG_RETURN(0);
|
||||
#endif /* WITH_WSREP */
|
||||
String log_query(buf, sizeof(buf), &my_charset_bin);
|
||||
if (log_query.copy(STRING_WITH_LEN("SAVEPOINT "), &my_charset_bin) ||
|
||||
append_identifier(thd, &log_query,
|
||||
|
|
@ -2352,14 +2222,9 @@ static int binlog_savepoint_rollback(handlerton *hton, THD *thd, void *sv)
|
|||
non-transactional table. Otherwise, truncate the binlog cache starting
|
||||
from the SAVEPOINT command.
|
||||
*/
|
||||
#ifdef WITH_WSREP
|
||||
if (!wsrep_emulate_bin_log &&
|
||||
if (IF_WSREP(!wsrep_emulate_bin_log, 1) &&
|
||||
unlikely(trans_has_updated_non_trans_table(thd) ||
|
||||
(thd->variables.option_bits & OPTION_KEEP_LOG)))
|
||||
#else
|
||||
if (unlikely(trans_has_updated_non_trans_table(thd) ||
|
||||
(thd->variables.option_bits & OPTION_KEEP_LOG)))
|
||||
#endif
|
||||
{
|
||||
char buf[1024];
|
||||
String log_query(buf, sizeof(buf), &my_charset_bin);
|
||||
|
|
@ -2373,10 +2238,8 @@ static int binlog_savepoint_rollback(handlerton *hton, THD *thd, void *sv)
|
|||
DBUG_RETURN(mysql_bin_log.write(&qinfo));
|
||||
}
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
if (!wsrep_emulate_bin_log)
|
||||
#endif
|
||||
binlog_trans_log_truncate(thd, *(my_off_t*)sv);
|
||||
if (IF_WSREP(!wsrep_emulate_bin_log, 1))
|
||||
binlog_trans_log_truncate(thd, *(my_off_t*)sv);
|
||||
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
|
@ -5505,12 +5368,8 @@ int THD::binlog_write_table_map(TABLE *table, bool is_transactional,
|
|||
is_transactional= 1;
|
||||
|
||||
/* Pre-conditions */
|
||||
#ifdef WITH_WSREP
|
||||
DBUG_ASSERT(is_current_stmt_binlog_format_row() &&
|
||||
(WSREP_EMULATE_BINLOG(this) || mysql_bin_log.is_open()));
|
||||
#else
|
||||
DBUG_ASSERT(is_current_stmt_binlog_format_row() && mysql_bin_log.is_open());
|
||||
#endif
|
||||
DBUG_ASSERT(is_current_stmt_binlog_format_row());
|
||||
DBUG_ASSERT(IF_WSREP(WSREP_EMULATE_BINLOG(this), 0) || mysql_bin_log.is_open());
|
||||
DBUG_ASSERT(table->s->table_map_id != ULONG_MAX);
|
||||
|
||||
Table_map_log_event
|
||||
|
|
@ -5643,11 +5502,7 @@ MYSQL_BIN_LOG::flush_and_set_pending_rows_event(THD *thd,
|
|||
bool is_transactional)
|
||||
{
|
||||
DBUG_ENTER("MYSQL_BIN_LOG::flush_and_set_pending_rows_event(event)");
|
||||
#ifdef WITH_WSREP
|
||||
DBUG_ASSERT(WSREP_EMULATE_BINLOG(thd) || mysql_bin_log.is_open());
|
||||
#else
|
||||
DBUG_ASSERT(mysql_bin_log.is_open());
|
||||
#endif
|
||||
DBUG_ASSERT(IF_WSREP(WSREP_EMULATE_BINLOG(thd),0) || mysql_bin_log.is_open());
|
||||
DBUG_PRINT("enter", ("event: 0x%lx", (long) event));
|
||||
|
||||
int error= 0;
|
||||
|
|
@ -5973,13 +5828,9 @@ bool MYSQL_BIN_LOG::write(Log_event *event_info, my_bool *with_annotate)
|
|||
mostly called if is_open() *was* true a few instructions before, but it
|
||||
could have changed since.
|
||||
*/
|
||||
#ifdef WITH_WSREP
|
||||
/* applier and replayer can skip writing binlog events */
|
||||
if ((WSREP_EMULATE_BINLOG(thd) && (thd->wsrep_exec_mode != REPL_RECV)) ||
|
||||
is_open())
|
||||
#else
|
||||
if (likely(is_open()))
|
||||
#endif
|
||||
if (IF_WSREP((WSREP_EMULATE_BINLOG(thd) && (thd->wsrep_exec_mode != REPL_RECV)), 0) ||
|
||||
likely(is_open()))
|
||||
{
|
||||
my_off_t UNINIT_VAR(my_org_b_tell);
|
||||
#ifdef HAVE_REPLICATION
|
||||
|
|
@ -6317,14 +6168,16 @@ int MYSQL_BIN_LOG::rotate(bool force_rotate, bool* check_purge)
|
|||
{
|
||||
int error= 0;
|
||||
DBUG_ENTER("MYSQL_BIN_LOG::rotate");
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
if (WSREP_ON && wsrep_to_isolation)
|
||||
{
|
||||
*check_purge= false;
|
||||
WSREP_DEBUG("avoiding binlog rotate due to TO isolation: %d",
|
||||
wsrep_to_isolation);
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
if (wsrep_to_isolation)
|
||||
{
|
||||
DBUG_ASSERT(WSREP_ON);
|
||||
*check_purge= false;
|
||||
WSREP_DEBUG("avoiding binlog rotate due to TO isolation: %d",
|
||||
wsrep_to_isolation);
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
//todo: fix the macro def and restore safe_mutex_assert_owner(&LOCK_log);
|
||||
|
|
@ -6873,8 +6726,10 @@ MYSQL_BIN_LOG::write_transaction_to_binlog(THD *thd,
|
|||
DBUG_ENTER("MYSQL_BIN_LOG::write_transaction_to_binlog");
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
if (wsrep_emulate_bin_log) DBUG_RETURN(0);
|
||||
if (wsrep_emulate_bin_log)
|
||||
DBUG_RETURN(0);
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
entry.thd= thd;
|
||||
entry.cache_mngr= cache_mngr;
|
||||
entry.error= 0;
|
||||
|
|
@ -9020,14 +8875,10 @@ TC_LOG_BINLOG::log_and_order(THD *thd, my_xid xid, bool all,
|
|||
|
||||
binlog_cache_mngr *cache_mngr= thd->binlog_setup_trx_data();
|
||||
if (!cache_mngr)
|
||||
#ifdef WITH_WSREP
|
||||
{
|
||||
WSREP_DEBUG("Skipping empty log_xid: %s", thd->query());
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
#else
|
||||
DBUG_RETURN(0);
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
cache_mngr->using_xa= TRUE;
|
||||
cache_mngr->xa_xid= xid;
|
||||
|
|
@ -9857,3 +9708,50 @@ maria_declare_plugin(binlog)
|
|||
MariaDB_PLUGIN_MATURITY_STABLE /* maturity */
|
||||
}
|
||||
maria_declare_plugin_end;
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
IO_CACHE * get_trans_log(THD * thd)
|
||||
{
|
||||
binlog_cache_mngr *cache_mngr = (binlog_cache_mngr*)
|
||||
thd_get_ha_data(thd, binlog_hton);
|
||||
if (cache_mngr)
|
||||
return cache_mngr->get_binlog_cache_log(true);
|
||||
|
||||
WSREP_DEBUG("binlog cache not initialized, conn :%ld", thd->thread_id);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
bool wsrep_trans_cache_is_empty(THD *thd)
|
||||
{
|
||||
binlog_cache_mngr *const cache_mngr=
|
||||
(binlog_cache_mngr*) thd_get_ha_data(thd, binlog_hton);
|
||||
return (!cache_mngr || cache_mngr->trx_cache.empty());
|
||||
}
|
||||
|
||||
|
||||
void thd_binlog_trx_reset(THD * thd)
|
||||
{
|
||||
/*
|
||||
todo: fix autocommit select to not call the caller
|
||||
*/
|
||||
if (thd_get_ha_data(thd, binlog_hton) != NULL)
|
||||
{
|
||||
binlog_cache_mngr *const cache_mngr=
|
||||
(binlog_cache_mngr*) thd_get_ha_data(thd, binlog_hton);
|
||||
if (cache_mngr)
|
||||
cache_mngr->reset(false, true);
|
||||
}
|
||||
thd->clear_binlog_table_maps();
|
||||
}
|
||||
|
||||
|
||||
void thd_binlog_rollback_stmt(THD * thd)
|
||||
{
|
||||
WSREP_DEBUG("thd_binlog_rollback_stmt :%ld", thd->thread_id);
|
||||
binlog_cache_mngr *const cache_mngr=
|
||||
(binlog_cache_mngr*) thd_get_ha_data(thd, binlog_hton);
|
||||
if (cache_mngr)
|
||||
cache_mngr->trx_cache.set_prev_position(MY_OFF_T_UNDEF);
|
||||
}
|
||||
#endif /* WITH_WSREP */
|
||||
|
|
|
|||
27
sql/log.h
27
sql/log.h
|
|
@ -19,6 +19,8 @@
|
|||
|
||||
#include "unireg.h" // REQUIRED: for other includes
|
||||
#include "handler.h" /* my_xid */
|
||||
#include "wsrep.h"
|
||||
#include "wsrep_mysqld.h"
|
||||
|
||||
class Relay_log_info;
|
||||
|
||||
|
|
@ -106,10 +108,11 @@ public:
|
|||
int log_and_order(THD *thd, my_xid xid, bool all,
|
||||
bool need_prepare_ordered, bool need_commit_ordered)
|
||||
{
|
||||
#ifndef WITH_WSREP
|
||||
DBUG_ASSERT(0 /* Internal error - TC_LOG_DUMMY::log_and_order() called
|
||||
*/);
|
||||
#endif
|
||||
/*
|
||||
If we are not using WSREP this is an Internal error
|
||||
- TC_LOG_DUMMY::log_and_order() called
|
||||
*/
|
||||
DBUG_ASSERT(IF_WSREP(1,0));
|
||||
return 1;
|
||||
}
|
||||
int unlog(ulong cookie, my_xid xid) { return 0; }
|
||||
|
|
@ -984,22 +987,6 @@ enum enum_binlog_format {
|
|||
BINLOG_FORMAT_UNSPEC=3 ///< thd_binlog_format() returns it when binlog is closed
|
||||
};
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
IO_CACHE * get_trans_log(THD * thd);
|
||||
bool wsrep_trans_cache_is_empty(THD *thd);
|
||||
void thd_binlog_flush_pending_rows_event(THD *thd, bool stmt_end);
|
||||
void thd_binlog_trx_reset(THD * thd);
|
||||
void thd_binlog_rollback_stmt(THD * thd);
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
#if defined(WITH_WSREP) && !defined(EMBEDDED_LIBRARY)
|
||||
#define WSREP_FORMAT(my_format) \
|
||||
((wsrep_forced_binlog_format != BINLOG_FORMAT_UNSPEC) ? \
|
||||
wsrep_forced_binlog_format : my_format)
|
||||
#else
|
||||
#define WSREP_FORMAT(my_format) my_format
|
||||
#endif /* WITH_WSREP && !EMBEDDED_LIBRARY */
|
||||
|
||||
int query_error_code(THD *thd, bool not_killed);
|
||||
uint purge_log_get_error_code(int res);
|
||||
|
||||
|
|
|
|||
171
sql/log_event.cc
171
sql/log_event.cc
|
|
@ -44,10 +44,7 @@
|
|||
#include <mysql/psi/mysql_statement.h>
|
||||
#include <strfunc.h>
|
||||
#include "compat56.h"
|
||||
|
||||
#if WITH_WSREP
|
||||
#include "wsrep_mysqld.h"
|
||||
#endif
|
||||
#endif /* MYSQL_CLIENT */
|
||||
|
||||
#include <base64.h>
|
||||
|
|
@ -3094,14 +3091,16 @@ Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg,
|
|||
master_data_written(0)
|
||||
{
|
||||
time_t end_time;
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
/*
|
||||
If Query_log_event will contain non trans keyword (not BEGIN, COMMIT,
|
||||
SAVEPOINT or ROLLBACK) we disable PA for this transaction.
|
||||
*/
|
||||
if (!is_trans_keyword())
|
||||
if (WSREP_ON && !is_trans_keyword())
|
||||
thd->wsrep_PA_safe= false;
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
memset(&user, 0, sizeof(user));
|
||||
memset(&host, 0, sizeof(host));
|
||||
|
||||
|
|
@ -4055,11 +4054,7 @@ int Query_log_event::do_apply_event(rpl_group_info *rgi,
|
|||
uint64 sub_id= 0;
|
||||
rpl_gtid gtid;
|
||||
Relay_log_info const *rli= rgi->rli;
|
||||
#ifdef WITH_WSREP
|
||||
Rpl_filter *rpl_filter= (rli->mi) ? rli->mi->rpl_filter: NULL;
|
||||
#else
|
||||
Rpl_filter *rpl_filter= rli->mi->rpl_filter;
|
||||
#endif /* WITH_WSREP */
|
||||
bool current_stmt_is_commit;
|
||||
DBUG_ENTER("Query_log_event::do_apply_event");
|
||||
|
||||
|
|
@ -4534,8 +4529,9 @@ Query_log_event::do_shall_skip(rpl_group_info *rgi)
|
|||
}
|
||||
}
|
||||
#ifdef WITH_WSREP
|
||||
else if (wsrep_mysql_replication_bundle && WSREP_ON && thd->wsrep_mysql_replicated > 0 &&
|
||||
(!strncasecmp(query , "BEGIN", 5) || !strncasecmp(query , "COMMIT", 6)))
|
||||
else if (WSREP_ON && wsrep_mysql_replication_bundle && opt_slave_domain_parallel_threads == 0 &&
|
||||
thd->wsrep_mysql_replicated > 0 &&
|
||||
(is_begin() || is_commit()))
|
||||
{
|
||||
if (++thd->wsrep_mysql_replicated < (int)wsrep_mysql_replication_bundle)
|
||||
{
|
||||
|
|
@ -7378,7 +7374,8 @@ Xid_log_event::do_shall_skip(rpl_group_info *rgi)
|
|||
DBUG_RETURN(Log_event::EVENT_SKIP_COUNT);
|
||||
}
|
||||
#ifdef WITH_WSREP
|
||||
else if (wsrep_mysql_replication_bundle && WSREP_ON)
|
||||
else if (wsrep_mysql_replication_bundle && WSREP_ON &&
|
||||
opt_slave_domain_parallel_threads == 0)
|
||||
{
|
||||
if (++thd->wsrep_mysql_replicated < (int)wsrep_mysql_replication_bundle)
|
||||
{
|
||||
|
|
@ -8413,14 +8410,6 @@ err:
|
|||
end_io_cache(&file);
|
||||
if (fd >= 0)
|
||||
mysql_file_close(fd, MYF(0));
|
||||
#ifdef WITH_WSREP
|
||||
if (WSREP(thd))
|
||||
thd_proc_info(thd, "exit Create_file_log_event::do_apply_event()");
|
||||
else
|
||||
thd_proc_info(thd, 0);
|
||||
#else /* WITH_WSREP */
|
||||
thd_proc_info(thd, 0);
|
||||
#endif /* WITH_WSREP */
|
||||
return error != 0;
|
||||
}
|
||||
#endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
|
||||
|
|
@ -8592,14 +8581,6 @@ int Append_block_log_event::do_apply_event(rpl_group_info *rgi)
|
|||
err:
|
||||
if (fd >= 0)
|
||||
mysql_file_close(fd, MYF(0));
|
||||
#ifdef WITH_WSREP
|
||||
if (WSREP(thd))
|
||||
thd_proc_info(thd, "exit Append_block_log_event::do_apply_event()");
|
||||
else
|
||||
thd_proc_info(thd, 0);
|
||||
#else /* WITH_WSREP */
|
||||
thd_proc_info(thd, 0);
|
||||
#endif /* WITH_WSREP */
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
#endif
|
||||
|
|
@ -9694,7 +9675,7 @@ int Rows_log_event::do_apply_event(rpl_group_info *rgi)
|
|||
thd->wsrep_exec_mode,
|
||||
thd->wsrep_conflict_state,
|
||||
(long long)wsrep_thd_trx_seqno(thd));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (thd->is_slave_error || thd->is_fatal_error)
|
||||
{
|
||||
|
|
@ -10842,13 +10823,8 @@ check_table_map(rpl_group_info *rgi, RPL_TABLE_LIST *table_list)
|
|||
DBUG_ENTER("check_table_map");
|
||||
enum_tbl_map_status res= OK_TO_PROCESS;
|
||||
Relay_log_info *rli= rgi->rli;
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
if ((rgi->thd->slave_thread /* filtering is for slave only */ ||
|
||||
(WSREP(rgi->thd) && rgi->thd->wsrep_applier)) &&
|
||||
#else
|
||||
if (rgi->thd->slave_thread /* filtering is for slave only */ &&
|
||||
#endif /* WITH_WSREP */
|
||||
if ((rgi->thd->slave_thread /* filtering is for slave only */ ||
|
||||
IF_WSREP((WSREP(rgi->thd) && rgi->thd->wsrep_applier), 0)) &&
|
||||
(!rli->mi->rpl_filter->db_ok(table_list->db) ||
|
||||
(rli->mi->rpl_filter->is_on() && !rli->mi->rpl_filter->tables_ok("", table_list))))
|
||||
res= FILTERED_OUT;
|
||||
|
|
@ -11596,23 +11572,20 @@ int
|
|||
Write_rows_log_event::do_exec_row(rpl_group_info *rgi)
|
||||
{
|
||||
DBUG_ASSERT(m_table != NULL);
|
||||
#ifdef WITH_WSREP
|
||||
#ifdef WSREP_PROC_INFO
|
||||
char info[64];
|
||||
info[sizeof(info) - 1] = '\0';
|
||||
snprintf(info, sizeof(info) - 1, "Write_rows_log_event::write_row(%lld)",
|
||||
(long long) wsrep_thd_trx_seqno(thd));
|
||||
const char* tmp = (WSREP(thd)) ? thd_proc_info(thd, info) : NULL;
|
||||
#else
|
||||
const char* tmp = (WSREP(thd)) ?
|
||||
thd_proc_info(thd,"Write_rows_log_event::write_row()") : NULL;
|
||||
#endif /* WSREP_PROC_INFO */
|
||||
#endif /* WITH_WSREP */
|
||||
int error= write_row(rgi, slave_exec_mode == SLAVE_EXEC_MODE_IDEMPOTENT);
|
||||
const char *tmp= thd->get_proc_info();
|
||||
const char *message= "Write_rows_log_event::write_row()";
|
||||
|
||||
#ifdef WSREP_PROC_INFO
|
||||
my_snprintf(thd->wsrep_info, sizeof(thd->wsrep_info) - 1,
|
||||
"Write_rows_log_event::write_row(%lld)",
|
||||
(long long) wsrep_thd_trx_seqno(thd));
|
||||
message= thd->wsrep_info;
|
||||
#endif /* WSREP_PROC_INFO */
|
||||
|
||||
thd_proc_info(thd, message);
|
||||
int error= write_row(rgi, slave_exec_mode == SLAVE_EXEC_MODE_IDEMPOTENT);
|
||||
thd_proc_info(thd, tmp);
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
if (WSREP(thd)) thd_proc_info(thd, tmp);
|
||||
#endif /* WITH_WSREP */
|
||||
if (error && !thd->is_error())
|
||||
{
|
||||
DBUG_ASSERT(0);
|
||||
|
|
@ -12289,37 +12262,34 @@ Delete_rows_log_event::do_after_row_operations(const Slave_reporting_capability
|
|||
int Delete_rows_log_event::do_exec_row(rpl_group_info *rgi)
|
||||
{
|
||||
int error;
|
||||
const char *tmp= thd->get_proc_info();
|
||||
const char *message= "Delete_rows_log_event::find_row()";
|
||||
const bool invoke_triggers=
|
||||
slave_run_triggers_for_rbr && !master_had_triggers && m_table->triggers;
|
||||
DBUG_ASSERT(m_table != NULL);
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
#ifdef WSREP_PROC_INFO
|
||||
char info[64];
|
||||
info[sizeof(info) - 1] = '\0';
|
||||
snprintf(info, sizeof(info) - 1, "Delete_rows_log_event::find_row(%lld)",
|
||||
(long long) wsrep_thd_trx_seqno(thd));
|
||||
const char* tmp = (WSREP(thd)) ? thd_proc_info(thd, info) : NULL;
|
||||
#else
|
||||
const char* tmp = (WSREP(thd)) ?
|
||||
thd_proc_info(thd,"Delete_rows_log_event::find_row()") : NULL;
|
||||
my_snprintf(thd->wsrep_info, sizeof(thd->wsrep_info) - 1,
|
||||
"Delete_rows_log_event::find_row(%lld)",
|
||||
(long long) wsrep_thd_trx_seqno(thd));
|
||||
message= thd->wsrep_info;
|
||||
#endif /* WSREP_PROC_INFO */
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
thd_proc_info(thd, message);
|
||||
if (!(error= find_row(rgi)))
|
||||
{
|
||||
/*
|
||||
Delete the record found, located in record[0]
|
||||
*/
|
||||
#ifdef WITH_WSREP
|
||||
message= "Delete_rows_log_event::ha_delete_row()";
|
||||
#ifdef WSREP_PROC_INFO
|
||||
snprintf(info, sizeof(info) - 1,
|
||||
snprintf(thd->wsrep_info, sizeof(thd->wsrep_info) - 1,
|
||||
"Delete_rows_log_event::ha_delete_row(%lld)",
|
||||
(long long) wsrep_thd_trx_seqno(thd));
|
||||
if (WSREP(thd)) thd_proc_info(thd, info);
|
||||
#else
|
||||
if (WSREP(thd)) thd_proc_info(thd,"Delete_rows_log_event::ha_delete_row()");
|
||||
#endif /* WSREP_PROC_INFO */
|
||||
#endif /* WITH_WSREP */
|
||||
message= thd->wsrep_info;
|
||||
#endif
|
||||
thd_proc_info(thd, message);
|
||||
|
||||
if (invoke_triggers &&
|
||||
process_triggers(TRG_EVENT_DELETE, TRG_ACTION_BEFORE, FALSE))
|
||||
error= HA_ERR_GENERIC; // in case if error is not set yet
|
||||
|
|
@ -12330,9 +12300,7 @@ int Delete_rows_log_event::do_exec_row(rpl_group_info *rgi)
|
|||
error= HA_ERR_GENERIC; // in case if error is not set yet
|
||||
m_table->file->ha_index_or_rnd_end();
|
||||
}
|
||||
#ifdef WITH_WSREP
|
||||
if (WSREP(thd)) thd_proc_info(thd, tmp);
|
||||
#endif /* WITH_WSREP */
|
||||
thd_proc_info(thd, tmp);
|
||||
return error;
|
||||
}
|
||||
|
||||
|
|
@ -12460,20 +12428,18 @@ Update_rows_log_event::do_exec_row(rpl_group_info *rgi)
|
|||
{
|
||||
const bool invoke_triggers=
|
||||
slave_run_triggers_for_rbr && !master_had_triggers && m_table->triggers;
|
||||
const char *tmp= thd->get_proc_info();
|
||||
const char *message= "Update_rows_log_event::find_row()";
|
||||
DBUG_ASSERT(m_table != NULL);
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
#ifdef WSREP_PROC_INFO
|
||||
char info[64];
|
||||
info[sizeof(info) - 1] = '\0';
|
||||
snprintf(info, sizeof(info) - 1, "Update_rows_log_event::find_row(%lld)",
|
||||
(long long) wsrep_thd_trx_seqno(thd));
|
||||
const char* tmp = (WSREP(thd)) ? thd_proc_info(thd, info) : NULL;
|
||||
#else
|
||||
const char* tmp = (WSREP(thd)) ?
|
||||
thd_proc_info(thd,"Update_rows_log_event::find_row()") : NULL;
|
||||
my_snprintf(thd->wsrep_info, sizeof(thd->wsrep_info) - 1,
|
||||
"Update_rows_log_event::find_row(%lld)",
|
||||
(long long) wsrep_thd_trx_seqno(thd));
|
||||
message= thd->wsrep_info;
|
||||
#endif /* WSREP_PROC_INFO */
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
thd_proc_info(thd, message);
|
||||
int error= find_row(rgi);
|
||||
if (error)
|
||||
{
|
||||
|
|
@ -12483,6 +12449,7 @@ Update_rows_log_event::do_exec_row(rpl_group_info *rgi)
|
|||
*/
|
||||
m_curr_row= m_curr_row_end;
|
||||
unpack_current_row(rgi);
|
||||
thd_proc_info(thd, tmp);
|
||||
return error;
|
||||
}
|
||||
|
||||
|
|
@ -12500,18 +12467,16 @@ Update_rows_log_event::do_exec_row(rpl_group_info *rgi)
|
|||
store_record(m_table,record[1]);
|
||||
|
||||
m_curr_row= m_curr_row_end;
|
||||
#ifdef WITH_WSREP
|
||||
message= "Update_rows_log_event::unpack_current_row()";
|
||||
#ifdef WSREP_PROC_INFO
|
||||
snprintf(info, sizeof(info) - 1,
|
||||
"Update_rows_log_event::unpack_current_row(%lld)",
|
||||
(long long) wsrep_thd_trx_seqno(thd));
|
||||
if (WSREP(thd)) thd_proc_info(thd, info);
|
||||
#else
|
||||
if (WSREP(thd))
|
||||
thd_proc_info(thd,"Update_rows_log_event::unpack_current_row()");
|
||||
my_snprintf(thd->wsrep_info, sizeof(thd->wsrep_info) - 1,
|
||||
"Update_rows_log_event::unpack_current_row(%lld)",
|
||||
(long long) wsrep_thd_trx_seqno(thd));
|
||||
message= thd->wsrep_info;
|
||||
#endif /* WSREP_PROC_INFO */
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
/* this also updates m_curr_row_end */
|
||||
thd_proc_info(thd, message);
|
||||
if ((error= unpack_current_row(rgi)))
|
||||
goto err;
|
||||
|
||||
|
|
@ -12529,17 +12494,15 @@ Update_rows_log_event::do_exec_row(rpl_group_info *rgi)
|
|||
DBUG_DUMP("new values", m_table->record[0], m_table->s->reclength);
|
||||
#endif
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
message= "Update_rows_log_event::ha_update_row()";
|
||||
#ifdef WSREP_PROC_INFO
|
||||
snprintf(info, sizeof(info) - 1,
|
||||
"Update_rows_log_event::ha_update_row(%lld)",
|
||||
(long long) wsrep_thd_trx_seqno(thd));
|
||||
if (WSREP(thd)) thd_proc_info(thd, info);
|
||||
#else
|
||||
if (WSREP(thd)) thd_proc_info(thd,"Update_rows_log_event::ha_update_row()");
|
||||
my_snprintf(thd->wsrep_info, sizeof(thd->wsrep_info) - 1,
|
||||
"Update_rows_log_event::ha_update_row(%lld)",
|
||||
(long long) wsrep_thd_trx_seqno(thd));
|
||||
message= thd->wsrep_info;
|
||||
#endif /* WSREP_PROC_INFO */
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
thd_proc_info(thd, message);
|
||||
if (invoke_triggers &&
|
||||
process_triggers(TRG_EVENT_UPDATE, TRG_ACTION_BEFORE, TRUE))
|
||||
{
|
||||
|
|
@ -12555,9 +12518,8 @@ Update_rows_log_event::do_exec_row(rpl_group_info *rgi)
|
|||
process_triggers(TRG_EVENT_UPDATE, TRG_ACTION_AFTER, TRUE))
|
||||
error= HA_ERR_GENERIC; // in case if error is not set yet
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
if (WSREP(thd)) thd_proc_info(thd, tmp);
|
||||
#endif /* WITH_WSREP */
|
||||
thd_proc_info(thd, tmp);
|
||||
|
||||
err:
|
||||
m_table->file->ha_index_or_rnd_end();
|
||||
return error;
|
||||
|
|
@ -12647,7 +12609,9 @@ void Incident_log_event::pack_info(THD *thd, Protocol *protocol)
|
|||
m_incident, description(), m_message.str);
|
||||
protocol->store(buf, bytes, &my_charset_bin);
|
||||
}
|
||||
#endif
|
||||
#endif /* MYSQL_CLIENT */
|
||||
|
||||
|
||||
#if WITH_WSREP && !defined(MYSQL_CLIENT)
|
||||
Format_description_log_event *wsrep_format_desc; // TODO: free them at the end
|
||||
/*
|
||||
|
|
@ -12661,13 +12625,12 @@ Log_event* wsrep_read_log_event(
|
|||
char **arg_buf, size_t *arg_buf_len,
|
||||
const Format_description_log_event *description_event)
|
||||
{
|
||||
DBUG_ENTER("wsrep_read_log_event");
|
||||
char *head= (*arg_buf);
|
||||
|
||||
uint data_len = uint4korr(head + EVENT_LEN_OFFSET);
|
||||
char *buf= (*arg_buf);
|
||||
const char *error= 0;
|
||||
Log_event *res= 0;
|
||||
DBUG_ENTER("wsrep_read_log_event");
|
||||
|
||||
if (data_len > WSREP_MAX_ALLOWED_PACKET)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1340,7 +1340,12 @@ public:
|
|||
*/
|
||||
int apply_event(rpl_group_info *rgi)
|
||||
{
|
||||
return do_apply_event(rgi);
|
||||
int res;
|
||||
THD_STAGE_INFO(thd, stage_apply_event);
|
||||
res= do_apply_event(rgi);
|
||||
THD_STAGE_INFO(thd, stage_after_apply_event);
|
||||
res= 0;
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
93
sql/mdl.cc
93
sql/mdl.cc
|
|
@ -22,19 +22,9 @@
|
|||
#include <mysql/plugin.h>
|
||||
#include <mysql/service_thd_wait.h>
|
||||
#include <mysql/psi/mysql_stage.h>
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
#include "wsrep_mysqld.h"
|
||||
#include "wsrep_thd.h"
|
||||
extern "C" my_thread_id wsrep_thd_thread_id(THD *thd);
|
||||
extern "C" char *wsrep_thd_query(THD *thd);
|
||||
void sql_print_information(const char *format, ...)
|
||||
ATTRIBUTE_FORMAT(printf, 1, 2);
|
||||
|
||||
extern bool
|
||||
wsrep_grant_mdl_exception(MDL_context *requestor_ctx,
|
||||
MDL_ticket *ticket);
|
||||
#endif /* WITH_WSREP */
|
||||
#ifdef HAVE_PSI_INTERFACE
|
||||
static PSI_mutex_key key_MDL_map_mutex;
|
||||
static PSI_mutex_key key_MDL_wait_LOCK_wait_status;
|
||||
|
|
@ -1511,22 +1501,23 @@ void MDL_lock::Ticket_list::add_ticket(MDL_ticket *ticket)
|
|||
DBUG_ASSERT(ticket->get_lock());
|
||||
#ifdef WITH_WSREP
|
||||
if ((this == &(ticket->get_lock()->m_waiting)) &&
|
||||
wsrep_thd_is_BF((void *)(ticket->get_ctx()->wsrep_get_thd()), false))
|
||||
wsrep_thd_is_BF((void *)(ticket->get_ctx()->get_thd()), false))
|
||||
{
|
||||
Ticket_iterator itw(ticket->get_lock()->m_waiting);
|
||||
Ticket_iterator itg(ticket->get_lock()->m_granted);
|
||||
|
||||
DBUG_ASSERT(WSREP_ON);
|
||||
MDL_ticket *waiting, *granted;
|
||||
MDL_ticket *prev=NULL;
|
||||
bool added= false;
|
||||
|
||||
while ((waiting= itw++) && !added)
|
||||
{
|
||||
if (!wsrep_thd_is_BF((void *)(waiting->get_ctx()->wsrep_get_thd()), true))
|
||||
if (!wsrep_thd_is_BF((void *)(waiting->get_ctx()->get_thd()), true))
|
||||
{
|
||||
WSREP_DEBUG("MDL add_ticket inserted before: %lu %s",
|
||||
wsrep_thd_thread_id(waiting->get_ctx()->wsrep_get_thd()),
|
||||
wsrep_thd_query(waiting->get_ctx()->wsrep_get_thd()));
|
||||
wsrep_thd_thread_id(waiting->get_ctx()->get_thd()),
|
||||
wsrep_thd_query(waiting->get_ctx()->get_thd()));
|
||||
m_list.insert_after(prev, ticket);
|
||||
added= true;
|
||||
}
|
||||
|
|
@ -1547,16 +1538,14 @@ void MDL_lock::Ticket_list::add_ticket(MDL_ticket *ticket)
|
|||
}
|
||||
}
|
||||
else
|
||||
#endif /* WITH_WSREP */
|
||||
{
|
||||
#endif /* WITH_WSREP */
|
||||
/*
|
||||
Add ticket to the *back* of the queue to ensure fairness
|
||||
among requests with the same priority.
|
||||
*/
|
||||
m_list.push_back(ticket);
|
||||
#ifdef WITH_WSREP
|
||||
/*
|
||||
Add ticket to the *back* of the queue to ensure fairness
|
||||
among requests with the same priority.
|
||||
*/
|
||||
m_list.push_back(ticket);
|
||||
}
|
||||
#endif /* WITH_WSREP */
|
||||
m_bitmap|= MDL_BIT(ticket->get_type());
|
||||
}
|
||||
|
||||
|
|
@ -1897,9 +1886,7 @@ MDL_lock::can_grant_lock(enum_mdl_type type_arg,
|
|||
bool can_grant= FALSE;
|
||||
bitmap_t waiting_incompat_map= incompatible_waiting_types_bitmap()[type_arg];
|
||||
bitmap_t granted_incompat_map= incompatible_granted_types_bitmap()[type_arg];
|
||||
#ifdef WITH_WSREP
|
||||
bool wsrep_can_grant= TRUE;
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
/*
|
||||
New lock request can be satisfied iff:
|
||||
|
|
@ -1922,55 +1909,49 @@ MDL_lock::can_grant_lock(enum_mdl_type type_arg,
|
|||
{
|
||||
if (ticket->get_ctx() != requestor_ctx &&
|
||||
ticket->is_incompatible_when_granted(type_arg))
|
||||
#ifdef WITH_WSREP
|
||||
{
|
||||
if (wsrep_thd_is_BF((void *)(requestor_ctx->wsrep_get_thd()),false) &&
|
||||
if (IF_WSREP(!WSREP_ON, 0))
|
||||
break;
|
||||
#ifdef WITH_WSREP
|
||||
if (wsrep_thd_is_BF((void *)(requestor_ctx->get_thd()),false) &&
|
||||
key.mdl_namespace() == MDL_key::GLOBAL)
|
||||
{
|
||||
WSREP_DEBUG("global lock granted for BF: %lu %s",
|
||||
wsrep_thd_thread_id(requestor_ctx->wsrep_get_thd()),
|
||||
wsrep_thd_query(requestor_ctx->wsrep_get_thd()));
|
||||
wsrep_thd_thread_id(requestor_ctx->get_thd()),
|
||||
wsrep_thd_query(requestor_ctx->get_thd()));
|
||||
can_grant = true;
|
||||
}
|
||||
else if (!wsrep_grant_mdl_exception(requestor_ctx, ticket))
|
||||
{
|
||||
wsrep_can_grant= FALSE;
|
||||
if (wsrep_log_conflicts)
|
||||
{
|
||||
MDL_lock * lock = ticket->get_lock();
|
||||
WSREP_INFO(
|
||||
"MDL conflict db=%s table=%s ticket=%d solved by %s",
|
||||
lock->key.db_name(), lock->key.name(), ticket->get_type(), "abort"
|
||||
);
|
||||
if (wsrep_log_conflicts)
|
||||
{
|
||||
MDL_lock * lock = ticket->get_lock();
|
||||
WSREP_INFO(
|
||||
"MDL conflict db=%s table=%s ticket=%d solved by %s",
|
||||
lock->key.db_name(), lock->key.name(), ticket->get_type(),
|
||||
"abort" );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
can_grant= TRUE;
|
||||
}
|
||||
/* Continue loop */
|
||||
}
|
||||
#else
|
||||
break;
|
||||
#endif /* WITH_WSREP */
|
||||
}
|
||||
#ifdef WITH_WSREP
|
||||
if ((ticket == NULL) && wsrep_can_grant)
|
||||
#else
|
||||
if (ticket == NULL) /* Incompatible locks are our own. */
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
if ((ticket == NULL) && IF_WSREP(wsrep_can_grant, 1))
|
||||
can_grant= TRUE;
|
||||
}
|
||||
}
|
||||
#ifdef WITH_WSREP
|
||||
else
|
||||
{
|
||||
if (wsrep_thd_is_BF((void *)(requestor_ctx->wsrep_get_thd()), false) &&
|
||||
if (wsrep_thd_is_BF((void *)(requestor_ctx->get_thd()), false) &&
|
||||
key.mdl_namespace() == MDL_key::GLOBAL)
|
||||
{
|
||||
WSREP_DEBUG("global lock granted for BF (waiting queue): %lu %s",
|
||||
wsrep_thd_thread_id(requestor_ctx->wsrep_get_thd()),
|
||||
wsrep_thd_query(requestor_ctx->wsrep_get_thd()));
|
||||
wsrep_thd_thread_id(requestor_ctx->get_thd()),
|
||||
wsrep_thd_query(requestor_ctx->get_thd()));
|
||||
can_grant = true;
|
||||
}
|
||||
}
|
||||
|
|
@ -3019,12 +3000,7 @@ void MDL_context::release_locks_stored_before(enum_mdl_duration duration,
|
|||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
void MDL_context::release_explicit_locks()
|
||||
{
|
||||
release_locks_stored_before(MDL_EXPLICIT, NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
Release all explicit locks in the context which correspond to the
|
||||
same name/object as this lock request.
|
||||
|
|
@ -3332,7 +3308,16 @@ void MDL_context::set_transaction_duration_for_all_locks()
|
|||
ticket->m_duration= MDL_TRANSACTION;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
|
||||
void MDL_context::release_explicit_locks()
|
||||
{
|
||||
release_locks_stored_before(MDL_EXPLICIT, NULL);
|
||||
}
|
||||
|
||||
|
||||
void MDL_ticket::wsrep_report(bool debug)
|
||||
{
|
||||
if (debug)
|
||||
|
|
|
|||
|
|
@ -776,13 +776,10 @@ public:
|
|||
m_tickets[MDL_TRANSACTION].is_empty() &&
|
||||
m_tickets[MDL_EXPLICIT].is_empty());
|
||||
}
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
inline bool has_transactional_locks() const
|
||||
{
|
||||
return !m_tickets[MDL_TRANSACTION].is_empty();
|
||||
}
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
MDL_savepoint mdl_savepoint()
|
||||
{
|
||||
|
|
@ -923,7 +920,6 @@ private:
|
|||
*/
|
||||
MDL_wait_for_subgraph *m_waiting_for;
|
||||
private:
|
||||
THD *get_thd() const { return m_owner->get_thd(); }
|
||||
MDL_ticket *find_ticket(MDL_request *mdl_req,
|
||||
enum_mdl_duration *duration);
|
||||
void release_locks_stored_before(enum_mdl_duration duration, MDL_ticket *sentinel);
|
||||
|
|
@ -932,9 +928,7 @@ private:
|
|||
MDL_ticket **out_ticket);
|
||||
|
||||
public:
|
||||
#ifdef WITH_WSREP
|
||||
THD *wsrep_get_thd() const { return get_thd(); }
|
||||
#endif
|
||||
THD *get_thd() const { return m_owner->get_thd(); }
|
||||
void find_deadlock();
|
||||
|
||||
ulong get_thread_id() const { return thd_get_thread_id(get_thd()); }
|
||||
|
|
|
|||
641
sql/mysqld.cc
641
sql/mysqld.cc
|
|
@ -71,13 +71,11 @@
|
|||
#include "scheduler.h"
|
||||
#include <waiting_threads.h>
|
||||
#include "debug_sync.h"
|
||||
#ifdef WITH_WSREP
|
||||
#include "wsrep_mysqld.h"
|
||||
#include "wsrep_var.h"
|
||||
#include "wsrep_thd.h"
|
||||
#include "wsrep_sst.h"
|
||||
ulong wsrep_running_threads = 0; // # of currently running wsrep threads
|
||||
#endif
|
||||
|
||||
#include "sql_callback.h"
|
||||
#include "threadpool.h"
|
||||
|
||||
|
|
@ -359,7 +357,8 @@ static bool volatile select_thread_in_use, signal_thread_in_use;
|
|||
static volatile bool ready_to_exit;
|
||||
static my_bool opt_debugging= 0, opt_external_locking= 0, opt_console= 0;
|
||||
static my_bool opt_short_log_format= 0;
|
||||
static uint kill_cached_threads, wake_thread;
|
||||
uint kill_cached_threads;
|
||||
static uint wake_thread;
|
||||
ulong max_used_connections;
|
||||
static volatile ulong cached_thread_count= 0;
|
||||
static char *mysqld_user, *mysqld_chroot;
|
||||
|
|
@ -367,25 +366,19 @@ static char *default_character_set_name;
|
|||
static char *character_set_filesystem_name;
|
||||
static char *lc_messages;
|
||||
static char *lc_time_names_name;
|
||||
#ifndef WITH_WSREP
|
||||
static char *my_bind_addr_str;
|
||||
#else
|
||||
char *my_bind_addr_str;
|
||||
#endif /* WITH_WSREP */
|
||||
static char *default_collation_name;
|
||||
char *default_storage_engine, *default_tmp_storage_engine;
|
||||
static char compiled_default_collation_name[]= MYSQL_DEFAULT_COLLATION_NAME;
|
||||
static I_List<THD> thread_cache;
|
||||
static bool binlog_format_used= false;
|
||||
LEX_STRING opt_init_connect, opt_init_slave;
|
||||
static mysql_cond_t COND_thread_cache, COND_flush_thread_cache;
|
||||
mysql_cond_t COND_thread_cache;
|
||||
static mysql_cond_t COND_flush_thread_cache;
|
||||
static DYNAMIC_ARRAY all_options;
|
||||
|
||||
/* Global variables */
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
ulong my_bind_addr;
|
||||
#endif /* WITH_WSREP */
|
||||
bool opt_bin_log, opt_bin_log_used=0, opt_ignore_builtin_innodb= 0;
|
||||
my_bool opt_log, opt_slow_log, debug_assert_if_crashed_table= 0, opt_help= 0;
|
||||
static my_bool opt_abort;
|
||||
|
|
@ -479,10 +472,6 @@ ulong opt_binlog_rows_event_max_size;
|
|||
my_bool opt_master_verify_checksum= 0;
|
||||
my_bool opt_slave_sql_verify_checksum= 1;
|
||||
const char *binlog_format_names[]= {"MIXED", "STATEMENT", "ROW", NullS};
|
||||
#ifdef WITH_WSREP
|
||||
const char *wsrep_binlog_format_names[]=
|
||||
{"MIXED", "STATEMENT", "ROW", "NONE", NullS};
|
||||
#endif /*WITH_WSREP */
|
||||
#ifdef HAVE_INITGROUPS
|
||||
volatile sig_atomic_t calling_initgroups= 0; /**< Used in SIGSEGV handler. */
|
||||
#endif
|
||||
|
|
@ -748,6 +737,7 @@ mysql_cond_t COND_server_started;
|
|||
|
||||
int mysqld_server_started=0, mysqld_server_initialized= 0;
|
||||
File_parser_dummy_hook file_parser_dummy_hook;
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
mysql_mutex_t LOCK_wsrep_ready;
|
||||
mysql_cond_t COND_wsrep_ready;
|
||||
|
|
@ -763,7 +753,10 @@ mysql_cond_t COND_wsrep_replaying;
|
|||
mysql_mutex_t LOCK_wsrep_slave_threads;
|
||||
mysql_mutex_t LOCK_wsrep_desync;
|
||||
int wsrep_replaying= 0;
|
||||
static void wsrep_close_threads(THD* thd);
|
||||
ulong wsrep_running_threads = 0; // # of currently running wsrep threads
|
||||
ulong my_bind_addr;
|
||||
const char *wsrep_binlog_format_names[]=
|
||||
{"MIXED", "STATEMENT", "ROW", "NONE", NullS};
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
/* replication parameters, if master_host is not NULL, we are a slave */
|
||||
|
|
@ -1465,7 +1458,7 @@ bool mysqld_embedded=0;
|
|||
bool mysqld_embedded=1;
|
||||
#endif
|
||||
|
||||
static my_bool plugins_are_initialized= FALSE;
|
||||
my_bool plugins_are_initialized= FALSE;
|
||||
|
||||
#ifndef DBUG_OFF
|
||||
static const char* default_dbug_option;
|
||||
|
|
@ -1772,7 +1765,8 @@ static void close_connections(void)
|
|||
#endif
|
||||
#ifdef WITH_WSREP
|
||||
/*
|
||||
* TODO: this code block may turn out redundant. wsrep->disconnect()
|
||||
* WSREP_TODO:
|
||||
* this code block may turn out redundant. wsrep->disconnect()
|
||||
* should terminate slave threads gracefully, and we don't need
|
||||
* to signal them here.
|
||||
* The code here makes sure mysqld will not hang during shutdown
|
||||
|
|
@ -1950,15 +1944,19 @@ static void __cdecl kill_server(int sig_ptr)
|
|||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
if (WSREP_ON) wsrep_stop_replication(NULL);
|
||||
if (WSREP_ON)
|
||||
wsrep_stop_replication(NULL);
|
||||
#endif
|
||||
|
||||
close_connections();
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
if (wsrep_inited == 1)
|
||||
if (WSREP_ON && wsrep_inited == 1)
|
||||
wsrep_deinit(true);
|
||||
#endif
|
||||
|
||||
if (sig != MYSQL_KILL_SIGNAL &&
|
||||
sig != 0)
|
||||
unireg_abort(1); /* purecov: inspected */
|
||||
|
|
@ -2053,14 +2051,18 @@ extern "C" void unireg_abort(int exit_code)
|
|||
usage();
|
||||
if (exit_code)
|
||||
sql_print_error("Aborting\n");
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
/* Check if wsrep class is used. If yes, then cleanup wsrep */
|
||||
if (wsrep)
|
||||
{
|
||||
/* This is an abort situation, we cannot expect to gracefully close all
|
||||
* wsrep threads here, we can only diconnect from service */
|
||||
/*
|
||||
This is an abort situation, we cannot expect to gracefully close all
|
||||
wsrep threads here, we can only diconnect from service
|
||||
*/
|
||||
wsrep_close_client_connections(FALSE);
|
||||
shutdown_in_progress= 1;
|
||||
THD* thd(0);
|
||||
THD *thd(0);
|
||||
wsrep->disconnect(wsrep);
|
||||
WSREP_INFO("Service disconnected.");
|
||||
wsrep_close_threads(thd); /* this won't close all threads */
|
||||
|
|
@ -2072,6 +2074,7 @@ extern "C" void unireg_abort(int exit_code)
|
|||
wsrep_deinit(true);
|
||||
}
|
||||
#endif // WITH_WSREP
|
||||
|
||||
clean_up(!opt_abort && (exit_code || !opt_bootstrap)); /* purecov: inspected */
|
||||
DBUG_PRINT("quit",("done with cleanup in unireg_abort"));
|
||||
mysqld_exit(exit_code);
|
||||
|
|
@ -2621,6 +2624,7 @@ static MYSQL_SOCKET activate_tcp_port(uint port)
|
|||
unireg_abort(1);
|
||||
}
|
||||
#if defined(WITH_WSREP) && defined(HAVE_FCNTL) && defined(FD_CLOEXEC)
|
||||
if (WSREP_ON)
|
||||
(void) fcntl(mysql_socket_getfd(ip_sock), F_SETFD, FD_CLOEXEC);
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
|
|
@ -2751,7 +2755,8 @@ static void network_init(void)
|
|||
sql_print_warning("listen() on Unix socket failed with error %d",
|
||||
socket_errno);
|
||||
#if defined(WITH_WSREP) && defined(HAVE_FCNTL)
|
||||
(void) fcntl(mysql_socket_getfd(unix_sock), F_SETFD, FD_CLOEXEC);
|
||||
if (WSREP_ON)
|
||||
(void) fcntl(mysql_socket_getfd(unix_sock), F_SETFD, FD_CLOEXEC);
|
||||
#endif /* WITH_WSREP */
|
||||
}
|
||||
#endif
|
||||
|
|
@ -2833,15 +2838,16 @@ void dec_connection_count(THD *thd)
|
|||
applier as well as rollbacker threads.
|
||||
*/
|
||||
if (!thd->wsrep_applier)
|
||||
return;
|
||||
#endif /* WITH_WSREP */
|
||||
{
|
||||
DBUG_ASSERT(*thd->scheduler->connection_count > 0);
|
||||
mysql_mutex_lock(&LOCK_connection_count);
|
||||
(*thd->scheduler->connection_count)--;
|
||||
mysql_mutex_unlock(&LOCK_connection_count);
|
||||
}
|
||||
|
||||
DBUG_ASSERT(*thd->scheduler->connection_count > 0);
|
||||
mysql_mutex_lock(&LOCK_connection_count);
|
||||
(*thd->scheduler->connection_count)--;
|
||||
mysql_mutex_unlock(&LOCK_connection_count);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Delete THD and decrement thread counters, including thread_running
|
||||
*/
|
||||
|
|
@ -3014,11 +3020,7 @@ bool one_thread_per_connection_end(THD *thd, bool put_in_cache)
|
|||
/* Mark that current_thd is not valid anymore */
|
||||
set_current_thd(0);
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
if (put_in_cache && cache_thread() && !wsrep_applier)
|
||||
#else
|
||||
if (put_in_cache && cache_thread())
|
||||
#endif /* WITH_WSREP */
|
||||
if (put_in_cache && cache_thread() && IF_WSREP(!wsrep_applier, 1))
|
||||
DBUG_RETURN(0); // Thread is reused
|
||||
|
||||
/*
|
||||
|
|
@ -4139,6 +4141,7 @@ static int init_common_variables()
|
|||
}
|
||||
else
|
||||
opt_log_basename= glob_hostname;
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
if (0 == wsrep_node_name || 0 == wsrep_node_name[0])
|
||||
{
|
||||
|
|
@ -4146,6 +4149,7 @@ static int init_common_variables()
|
|||
wsrep_node_name= my_strdup(glob_hostname, MYF(MY_WME));
|
||||
}
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
if (!*pidfile_name)
|
||||
{
|
||||
strmake(pidfile_name, opt_log_basename, sizeof(pidfile_name)-5);
|
||||
|
|
@ -4205,11 +4209,16 @@ static int init_common_variables()
|
|||
compile_time_assert(sizeof(com_status_vars)/sizeof(com_status_vars[0]) - 1 ==
|
||||
SQLCOM_END + 8);
|
||||
#endif
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
/* This is a protection against mutually incompatible option values. */
|
||||
/*
|
||||
This is a protection against mutually incompatible option values.
|
||||
Note WSREP_ON == global_system_variables.wsrep_on
|
||||
*/
|
||||
if (WSREP_ON && wsrep_check_opts (remaining_argc, remaining_argv))
|
||||
global_system_variables.wsrep_on= 0;
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
if (get_options(&remaining_argc, &remaining_argv))
|
||||
return 1;
|
||||
set_server_version();
|
||||
|
|
@ -4923,18 +4932,10 @@ static int init_server_components()
|
|||
/* need to configure logging before initializing storage engines */
|
||||
if (!opt_bin_log_used)
|
||||
{
|
||||
#ifdef WITH_WSREP
|
||||
if (!WSREP_ON && opt_log_slave_updates)
|
||||
#else
|
||||
if (opt_log_slave_updates)
|
||||
#endif
|
||||
if (IF_WSREP(!WSREP_ON,1) && opt_log_slave_updates)
|
||||
sql_print_warning("You need to use --log-bin to make "
|
||||
"--log-slave-updates work.");
|
||||
#ifdef WITH_WSREP
|
||||
if (!WSREP_ON && binlog_format_used)
|
||||
#else
|
||||
if (binlog_format_used)
|
||||
#endif
|
||||
if (IF_WSREP(!WSREP_ON, 1) && binlog_format_used)
|
||||
sql_print_warning("You need to use --log-bin to make "
|
||||
"--binlog-format work.");
|
||||
}
|
||||
|
|
@ -5018,7 +5019,7 @@ a file name for --log-bin-index option", opt_binlog_index_name);
|
|||
after SST has happened
|
||||
*/
|
||||
}
|
||||
if (!wsrep_recovery)
|
||||
if (WSREP_ON && !wsrep_recovery)
|
||||
{
|
||||
if (opt_bootstrap) // bootsrap option given - disable wsrep functionality
|
||||
{
|
||||
|
|
@ -5192,23 +5193,34 @@ a file name for --log-bin-index option", opt_binlog_index_name);
|
|||
#endif
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
if (!opt_bin_log)
|
||||
if (WSREP_ON && !opt_bin_log)
|
||||
{
|
||||
wsrep_emulate_bin_log= 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* if total_ha_2pc <= 1
|
||||
tc_log = tc_log_dummy
|
||||
else
|
||||
if opt_bin_log == true
|
||||
tc_log = mysql_bin_log
|
||||
else
|
||||
if WITH_WSREP
|
||||
if WSREP_ON
|
||||
tc_log = tc_log_dummy
|
||||
else
|
||||
tc_log = tc_log_mmap
|
||||
else
|
||||
tc_log=tc_log_mmap
|
||||
*/
|
||||
tc_log= (total_ha_2pc > 1 ? (opt_bin_log ?
|
||||
(TC_LOG *) &mysql_bin_log :
|
||||
IF_WSREP((WSREP_ON ? (TC_LOG *) &tc_log_dummy :
|
||||
(TC_LOG *) &tc_log_mmap), (TC_LOG *) &tc_log_mmap)) :
|
||||
(TC_LOG *) &tc_log_dummy);
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
(WSREP_ON ?
|
||||
(TC_LOG *) &tc_log_dummy :
|
||||
(TC_LOG *) &tc_log_mmap)) :
|
||||
#else
|
||||
(TC_LOG *) &tc_log_mmap) :
|
||||
#endif
|
||||
(TC_LOG *) &tc_log_dummy);
|
||||
#ifdef WITH_WSREP
|
||||
WSREP_DEBUG("Initial TC log open: %s",
|
||||
WSREP_DEBUG("Initial TC log open: %s",
|
||||
(tc_log == &mysql_bin_log) ? "binlog" :
|
||||
(tc_log == &tc_log_mmap) ? "mmap" :
|
||||
(tc_log == &tc_log_dummy) ? "dummy" : "unknown"
|
||||
|
|
@ -5296,468 +5308,6 @@ static void create_shutdown_thread()
|
|||
|
||||
#endif /* EMBEDDED_LIBRARY */
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
typedef void (*wsrep_thd_processor_fun)(THD *);
|
||||
|
||||
pthread_handler_t start_wsrep_THD(void *arg)
|
||||
{
|
||||
THD *thd;
|
||||
rpl_sql_thread_info sql_info(NULL);
|
||||
wsrep_thd_processor_fun processor= (wsrep_thd_processor_fun)arg;
|
||||
|
||||
if (my_thread_init())
|
||||
{
|
||||
WSREP_ERROR("Could not initialize thread");
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
if (!(thd= new THD(true)))
|
||||
{
|
||||
return(NULL);
|
||||
}
|
||||
mysql_mutex_lock(&LOCK_thread_count);
|
||||
thd->thread_id=thread_id++;
|
||||
|
||||
thd->real_id=pthread_self(); // Keep purify happy
|
||||
thread_count++;
|
||||
thread_created++;
|
||||
threads.append(thd);
|
||||
|
||||
my_net_init(&thd->net,(st_vio*) 0, MYF(0));
|
||||
|
||||
DBUG_PRINT("wsrep",(("creating thread %lld"), (long long)thd->thread_id));
|
||||
thd->prior_thr_create_utime= thd->start_utime= microsecond_interval_timer();
|
||||
(void) mysql_mutex_unlock(&LOCK_thread_count);
|
||||
|
||||
/* from bootstrap()... */
|
||||
thd->bootstrap=1;
|
||||
thd->max_client_packet_length= thd->net.max_packet;
|
||||
thd->security_ctx->master_access= ~(ulong)0;
|
||||
thd->system_thread_info.rpl_sql_info= &sql_info;
|
||||
|
||||
/* from handle_one_connection... */
|
||||
pthread_detach_this_thread();
|
||||
|
||||
mysql_thread_set_psi_id(thd->thread_id);
|
||||
thd->thr_create_utime= microsecond_interval_timer();
|
||||
if (MYSQL_CALLBACK_ELSE(thread_scheduler, init_new_connection_thread, (), 0))
|
||||
{
|
||||
close_connection(thd, ER_OUT_OF_RESOURCES);
|
||||
statistic_increment(aborted_connects,&LOCK_status);
|
||||
MYSQL_CALLBACK(thread_scheduler, end_thread, (thd, 0));
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
// </5.1.17>
|
||||
/*
|
||||
handle_one_connection() is normally the only way a thread would
|
||||
start and would always be on the very high end of the stack ,
|
||||
therefore, the thread stack always starts at the address of the
|
||||
first local variable of handle_one_connection, which is thd. We
|
||||
need to know the start of the stack so that we could check for
|
||||
stack overruns.
|
||||
*/
|
||||
DBUG_PRINT("wsrep", ("handle_one_connection called by thread %lld\n",
|
||||
(long long)thd->thread_id));
|
||||
/* now that we've called my_thread_init(), it is safe to call DBUG_* */
|
||||
|
||||
thd->thread_stack= (char*) &thd;
|
||||
if (thd->store_globals())
|
||||
{
|
||||
close_connection(thd, ER_OUT_OF_RESOURCES);
|
||||
statistic_increment(aborted_connects,&LOCK_status);
|
||||
MYSQL_CALLBACK(thread_scheduler, end_thread, (thd, 0));
|
||||
delete thd;
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
thd->system_thread= SYSTEM_THREAD_SLAVE_SQL;
|
||||
thd->security_ctx->skip_grants();
|
||||
|
||||
/* handle_one_connection() again... */
|
||||
//thd->version= refresh_version;
|
||||
thd->proc_info= 0;
|
||||
thd->set_command(COM_SLEEP);
|
||||
thd->set_time();
|
||||
thd->init_for_queries();
|
||||
|
||||
mysql_mutex_lock(&LOCK_thread_count);
|
||||
wsrep_running_threads++;
|
||||
mysql_cond_broadcast(&COND_thread_count);
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
|
||||
processor(thd);
|
||||
|
||||
close_connection(thd, 0);
|
||||
|
||||
mysql_mutex_lock(&LOCK_thread_count);
|
||||
wsrep_running_threads--;
|
||||
WSREP_DEBUG("wsrep running threads now: %lu", wsrep_running_threads);
|
||||
mysql_cond_broadcast(&COND_thread_count);
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
|
||||
// Note: We can't call THD destructor without crashing
|
||||
// if plugins have not been initialized. However, in most of the
|
||||
// cases this means that pre SE initialization SST failed and
|
||||
// we are going to exit anyway.
|
||||
if (plugins_are_initialized)
|
||||
{
|
||||
net_end(&thd->net);
|
||||
MYSQL_CALLBACK(thread_scheduler, end_thread, (thd, 1));
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: lightweight cleanup to get rid of:
|
||||
// 'Error in my_thread_global_end(): 2 threads didn't exit'
|
||||
// at server shutdown
|
||||
}
|
||||
|
||||
my_thread_end();
|
||||
if (thread_handling > SCHEDULER_ONE_THREAD_PER_CONNECTION)
|
||||
{
|
||||
mysql_mutex_lock(&LOCK_thread_count);
|
||||
delete thd;
|
||||
thread_count--;
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
}
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
/**/
|
||||
static bool abort_replicated(THD *thd)
|
||||
{
|
||||
bool ret_code= false;
|
||||
if (thd->wsrep_query_state== QUERY_COMMITTING)
|
||||
{
|
||||
if (wsrep_debug) WSREP_INFO("aborting replicated trx: %lu", thd->real_id);
|
||||
|
||||
(void)wsrep_abort_thd(thd, thd, TRUE);
|
||||
ret_code= true;
|
||||
}
|
||||
return ret_code;
|
||||
}
|
||||
/**/
|
||||
static inline bool is_client_connection(THD *thd)
|
||||
{
|
||||
#if REMOVE
|
||||
// REMOVE THIS LATER (lp:777201). Below we had to add an explicit check for
|
||||
// wsrep_applier since wsrep_exec_mode didn't seem to always work
|
||||
if (thd->wsrep_applier && thd->wsrep_exec_mode != REPL_RECV)
|
||||
WSREP_WARN("applier has wsrep_exec_mode = %d", thd->wsrep_exec_mode);
|
||||
|
||||
if ( thd->slave_thread || /* declared as mysql slave */
|
||||
thd->system_thread || /* declared as system thread */
|
||||
!thd->vio_ok() || /* server internal thread */
|
||||
thd->wsrep_exec_mode==REPL_RECV || /* applier or replaying thread */
|
||||
thd->wsrep_applier || /* wsrep slave applier */
|
||||
!thd->variables.wsrep_on) /* client, but fenced outside wsrep */
|
||||
return false;
|
||||
|
||||
return true;
|
||||
#else
|
||||
return (thd->wsrep_client_thread && thd->variables.wsrep_on);
|
||||
#endif /* REMOVE */
|
||||
}
|
||||
|
||||
static inline bool is_replaying_connection(THD *thd)
|
||||
{
|
||||
bool ret;
|
||||
|
||||
mysql_mutex_lock(&thd->LOCK_wsrep_thd);
|
||||
ret= (thd->wsrep_conflict_state == REPLAYING) ? true : false;
|
||||
mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline bool is_committing_connection(THD *thd)
|
||||
{
|
||||
bool ret;
|
||||
|
||||
mysql_mutex_lock(&thd->LOCK_wsrep_thd);
|
||||
ret= (thd->wsrep_query_state == QUERY_COMMITTING) ? true : false;
|
||||
mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool have_client_connections()
|
||||
{
|
||||
THD *tmp;
|
||||
|
||||
I_List_iterator<THD> it(threads);
|
||||
while ((tmp=it++))
|
||||
{
|
||||
DBUG_PRINT("quit",("Informing thread %ld that it's time to die",
|
||||
tmp->thread_id));
|
||||
if (is_client_connection(tmp) && tmp->killed == KILL_CONNECTION)
|
||||
{
|
||||
(void)abort_replicated(tmp);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
returns the number of wsrep appliers running.
|
||||
However, the caller (thd parameter) is not taken in account
|
||||
*/
|
||||
static int have_wsrep_appliers(THD *thd)
|
||||
{
|
||||
int ret= 0;
|
||||
THD *tmp;
|
||||
|
||||
I_List_iterator<THD> it(threads);
|
||||
while ((tmp=it++))
|
||||
{
|
||||
ret+= (tmp != thd && tmp->wsrep_applier);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void wsrep_close_thread(THD *thd)
|
||||
{
|
||||
thd->killed= KILL_CONNECTION;
|
||||
MYSQL_CALLBACK(thread_scheduler, post_kill_notification, (thd));
|
||||
if (thd->mysys_var)
|
||||
{
|
||||
thd->mysys_var->abort=1;
|
||||
mysql_mutex_lock(&thd->mysys_var->mutex);
|
||||
if (thd->mysys_var->current_cond)
|
||||
{
|
||||
mysql_mutex_lock(thd->mysys_var->current_mutex);
|
||||
mysql_cond_broadcast(thd->mysys_var->current_cond);
|
||||
mysql_mutex_unlock(thd->mysys_var->current_mutex);
|
||||
}
|
||||
mysql_mutex_unlock(&thd->mysys_var->mutex);
|
||||
}
|
||||
}
|
||||
|
||||
static my_bool have_committing_connections()
|
||||
{
|
||||
THD *tmp;
|
||||
mysql_mutex_lock(&LOCK_thread_count); // For unlink from list
|
||||
|
||||
I_List_iterator<THD> it(threads);
|
||||
while ((tmp=it++))
|
||||
{
|
||||
if (!is_client_connection(tmp))
|
||||
continue;
|
||||
|
||||
if (is_committing_connection(tmp))
|
||||
{
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
int wsrep_wait_committing_connections_close(int wait_time)
|
||||
{
|
||||
int sleep_time= 100;
|
||||
|
||||
while (have_committing_connections() && wait_time > 0)
|
||||
{
|
||||
WSREP_DEBUG("wait for committing transaction to close: %d", wait_time);
|
||||
my_sleep(sleep_time);
|
||||
wait_time -= sleep_time;
|
||||
}
|
||||
if (have_committing_connections())
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void wsrep_close_client_connections(my_bool wait_to_end)
|
||||
{
|
||||
/*
|
||||
First signal all threads that it's time to die
|
||||
*/
|
||||
|
||||
THD *tmp;
|
||||
mysql_mutex_lock(&LOCK_thread_count); // For unlink from list
|
||||
|
||||
bool kill_cached_threads_saved= kill_cached_threads;
|
||||
kill_cached_threads= true; // prevent future threads caching
|
||||
mysql_cond_broadcast(&COND_thread_cache); // tell cached threads to die
|
||||
|
||||
I_List_iterator<THD> it(threads);
|
||||
while ((tmp=it++))
|
||||
{
|
||||
DBUG_PRINT("quit",("Informing thread %ld that it's time to die",
|
||||
tmp->thread_id));
|
||||
/* We skip slave threads & scheduler on this first loop through. */
|
||||
if (!is_client_connection(tmp))
|
||||
continue;
|
||||
|
||||
if (is_replaying_connection(tmp))
|
||||
{
|
||||
tmp->killed= KILL_CONNECTION;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* replicated transactions must be skipped */
|
||||
if (abort_replicated(tmp))
|
||||
continue;
|
||||
|
||||
WSREP_DEBUG("closing connection %ld", tmp->thread_id);
|
||||
wsrep_close_thread(tmp);
|
||||
}
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
|
||||
if (thread_count)
|
||||
sleep(2); // Give threads time to die
|
||||
|
||||
mysql_mutex_lock(&LOCK_thread_count);
|
||||
/*
|
||||
Force remaining threads to die by closing the connection to the client
|
||||
*/
|
||||
|
||||
I_List_iterator<THD> it2(threads);
|
||||
while ((tmp=it2++))
|
||||
{
|
||||
#ifndef __bsdi__ // Bug in BSDI kernel
|
||||
if (is_client_connection(tmp) &&
|
||||
!abort_replicated(tmp) &&
|
||||
!is_replaying_connection(tmp))
|
||||
{
|
||||
WSREP_INFO("killing local connection: %ld",tmp->thread_id);
|
||||
close_connection(tmp,0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
DBUG_PRINT("quit",("Waiting for threads to die (count=%u)",thread_count));
|
||||
if (wsrep_debug)
|
||||
WSREP_INFO("waiting for client connections to close: %u", thread_count);
|
||||
|
||||
while (wait_to_end && have_client_connections())
|
||||
{
|
||||
mysql_cond_wait(&COND_thread_count, &LOCK_thread_count);
|
||||
DBUG_PRINT("quit",("One thread died (count=%u)", thread_count));
|
||||
}
|
||||
|
||||
kill_cached_threads= kill_cached_threads_saved;
|
||||
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
|
||||
/* All client connection threads have now been aborted */
|
||||
}
|
||||
|
||||
void wsrep_close_applier(THD *thd)
|
||||
{
|
||||
WSREP_DEBUG("closing applier %ld", thd->thread_id);
|
||||
wsrep_close_thread(thd);
|
||||
}
|
||||
|
||||
static void wsrep_close_threads(THD *thd)
|
||||
{
|
||||
THD *tmp;
|
||||
mysql_mutex_lock(&LOCK_thread_count); // For unlink from list
|
||||
|
||||
I_List_iterator<THD> it(threads);
|
||||
while ((tmp=it++))
|
||||
{
|
||||
DBUG_PRINT("quit",("Informing thread %ld that it's time to die",
|
||||
tmp->thread_id));
|
||||
/* We skip slave threads & scheduler on this first loop through. */
|
||||
if (tmp->wsrep_applier && tmp != thd)
|
||||
{
|
||||
WSREP_DEBUG("closing wsrep thread %ld", tmp->thread_id);
|
||||
wsrep_close_thread (tmp);
|
||||
}
|
||||
}
|
||||
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
}
|
||||
|
||||
void wsrep_close_applier_threads(int count)
|
||||
{
|
||||
THD *tmp;
|
||||
mysql_mutex_lock(&LOCK_thread_count); // For unlink from list
|
||||
|
||||
I_List_iterator<THD> it(threads);
|
||||
while ((tmp=it++) && count)
|
||||
{
|
||||
DBUG_PRINT("quit",("Informing thread %ld that it's time to die",
|
||||
tmp->thread_id));
|
||||
/* We skip slave threads & scheduler on this first loop through. */
|
||||
if (tmp->wsrep_applier)
|
||||
{
|
||||
WSREP_DEBUG("closing wsrep applier thread %ld", tmp->thread_id);
|
||||
tmp->wsrep_applier_closing= TRUE;
|
||||
count--;
|
||||
}
|
||||
}
|
||||
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
}
|
||||
|
||||
void wsrep_wait_appliers_close(THD *thd)
|
||||
{
|
||||
/* Wait for wsrep appliers to gracefully exit */
|
||||
mysql_mutex_lock(&LOCK_thread_count);
|
||||
while (have_wsrep_appliers(thd) > 1)
|
||||
// 1 is for rollbacker thread which needs to be killed explicitly.
|
||||
// This gotta be fixed in a more elegant manner if we gonna have arbitrary
|
||||
// number of non-applier wsrep threads.
|
||||
{
|
||||
if (thread_handling > SCHEDULER_ONE_THREAD_PER_CONNECTION)
|
||||
{
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
my_sleep(100);
|
||||
mysql_mutex_lock(&LOCK_thread_count);
|
||||
}
|
||||
else
|
||||
mysql_cond_wait(&COND_thread_count,&LOCK_thread_count);
|
||||
DBUG_PRINT("quit",("One applier died (count=%u)",thread_count));
|
||||
}
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
/* Now kill remaining wsrep threads: rollbacker */
|
||||
wsrep_close_threads (thd);
|
||||
/* and wait for them to die */
|
||||
mysql_mutex_lock(&LOCK_thread_count);
|
||||
while (have_wsrep_appliers(thd) > 0)
|
||||
{
|
||||
if (thread_handling > SCHEDULER_ONE_THREAD_PER_CONNECTION)
|
||||
{
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
my_sleep(100);
|
||||
mysql_mutex_lock(&LOCK_thread_count);
|
||||
}
|
||||
else
|
||||
mysql_cond_wait(&COND_thread_count,&LOCK_thread_count);
|
||||
DBUG_PRINT("quit",("One thread died (count=%u)",thread_count));
|
||||
}
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
|
||||
/* All wsrep applier threads have now been aborted. However, if this thread
|
||||
is also applier, we are still running...
|
||||
*/
|
||||
}
|
||||
|
||||
void wsrep_kill_mysql(THD *thd)
|
||||
{
|
||||
if (mysqld_server_started)
|
||||
{
|
||||
if (!shutdown_in_progress)
|
||||
{
|
||||
WSREP_INFO("starting shutdown");
|
||||
kill_mysql();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
unireg_abort(1);
|
||||
}
|
||||
}
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
#if (defined(_WIN32) || defined(HAVE_SMEM)) && !defined(EMBEDDED_LIBRARY)
|
||||
static void handle_connections_methods()
|
||||
|
|
@ -5935,7 +5485,8 @@ int mysqld_main(int argc, char **argv)
|
|||
}
|
||||
#endif
|
||||
#ifdef WITH_WSREP
|
||||
wsrep_filter_new_cluster (&argc, argv);
|
||||
if (WSREP_ON)
|
||||
wsrep_filter_new_cluster (&argc, argv);
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
orig_argc= argc;
|
||||
|
|
@ -6154,7 +5705,7 @@ int mysqld_main(int argc, char **argv)
|
|||
#endif
|
||||
|
||||
#ifdef WITH_WSREP /* WSREP AFTER SE */
|
||||
if (wsrep_recovery)
|
||||
if (WSREP_ON && wsrep_recovery)
|
||||
{
|
||||
select_thread_in_use= 0;
|
||||
wsrep_recover();
|
||||
|
|
@ -6219,28 +5770,31 @@ int mysqld_main(int argc, char **argv)
|
|||
unireg_abort(1);
|
||||
|
||||
#ifdef WITH_WSREP /* WSREP AFTER SE */
|
||||
if (opt_bootstrap)
|
||||
if (WSREP_ON)
|
||||
{
|
||||
/*! bootstrap wsrep init was taken care of above */
|
||||
}
|
||||
else
|
||||
{
|
||||
wsrep_SE_initialized();
|
||||
|
||||
if (wsrep_before_SE())
|
||||
if (opt_bootstrap)
|
||||
{
|
||||
/*! in case of no SST wsrep waits in view handler callback */
|
||||
wsrep_SE_init_grab();
|
||||
wsrep_SE_init_done();
|
||||
/*! in case of SST wsrep waits for wsrep->sst_received */
|
||||
wsrep_sst_continue();
|
||||
/*! bootstrap wsrep init was taken care of above */
|
||||
}
|
||||
else
|
||||
{
|
||||
wsrep_init_startup (false);
|
||||
}
|
||||
wsrep_SE_initialized();
|
||||
|
||||
wsrep_create_appliers(wsrep_slave_threads - 1);
|
||||
if (wsrep_before_SE())
|
||||
{
|
||||
/*! in case of no SST wsrep waits in view handler callback */
|
||||
wsrep_SE_init_grab();
|
||||
wsrep_SE_init_done();
|
||||
/*! in case of SST wsrep waits for wsrep->sst_received */
|
||||
wsrep_sst_continue();
|
||||
}
|
||||
else
|
||||
{
|
||||
wsrep_init_startup (false);
|
||||
}
|
||||
|
||||
wsrep_create_appliers(wsrep_slave_threads - 1);
|
||||
}
|
||||
}
|
||||
#endif /* WITH_WSREP */
|
||||
if (opt_bootstrap)
|
||||
|
|
@ -6311,9 +5865,7 @@ int mysqld_main(int argc, char **argv)
|
|||
#ifdef EXTRA_DEBUG2
|
||||
sql_print_error("Before Lock_thread_count");
|
||||
#endif
|
||||
#ifdef WITH_WSREP
|
||||
WSREP_DEBUG("Before Lock_thread_count");
|
||||
#endif
|
||||
mysql_mutex_lock(&LOCK_thread_count);
|
||||
DBUG_PRINT("quit", ("Got thread_count mutex"));
|
||||
select_thread_in_use=0; // For close_connections
|
||||
|
|
@ -10140,7 +9692,8 @@ void refresh_status(THD *thd)
|
|||
/* Reset some global variables */
|
||||
reset_status_vars();
|
||||
#ifdef WITH_WSREP
|
||||
wsrep->stats_reset(wsrep);
|
||||
if (WSREP_ON)
|
||||
wsrep->stats_reset(wsrep);
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
/* Reset the counters of all key caches (default and named). */
|
||||
|
|
@ -10193,6 +9746,7 @@ static PSI_file_info all_server_files[]=
|
|||
};
|
||||
#endif /* HAVE_PSI_INTERFACE */
|
||||
|
||||
PSI_stage_info stage_after_apply_event= { 0, "after apply log event", 0};
|
||||
PSI_stage_info stage_after_create= { 0, "After create", 0};
|
||||
PSI_stage_info stage_after_opening_tables= { 0, "After opening tables", 0};
|
||||
PSI_stage_info stage_after_table_lock= { 0, "After table lock", 0};
|
||||
|
|
@ -10200,6 +9754,7 @@ PSI_stage_info stage_allocating_local_table= { 0, "allocating local table", 0};
|
|||
PSI_stage_info stage_alter_inplace_prepare= { 0, "preparing for alter table", 0};
|
||||
PSI_stage_info stage_alter_inplace= { 0, "altering table", 0};
|
||||
PSI_stage_info stage_alter_inplace_commit= { 0, "committing alter table to storage engine", 0};
|
||||
PSI_stage_info stage_apply_event= { 0, "apply log event", 0};
|
||||
PSI_stage_info stage_changing_master= { 0, "Changing master", 0};
|
||||
PSI_stage_info stage_checking_master_version= { 0, "Checking master version", 0};
|
||||
PSI_stage_info stage_checking_permissions= { 0, "checking permissions", 0};
|
||||
|
|
@ -10273,6 +9828,7 @@ PSI_stage_info stage_sql_thd_waiting_until_delay= { 0, "Waiting until MASTER_DEL
|
|||
PSI_stage_info stage_storing_result_in_query_cache= { 0, "storing result in query cache", 0};
|
||||
PSI_stage_info stage_storing_row_into_queue= { 0, "storing row into queue", 0};
|
||||
PSI_stage_info stage_system_lock= { 0, "System lock", 0};
|
||||
PSI_stage_info stage_unlocking_tables= { 0, "Unlocking tables", 0};
|
||||
PSI_stage_info stage_update= { 0, "update", 0};
|
||||
PSI_stage_info stage_updating= { 0, "updating", 0};
|
||||
PSI_stage_info stage_updating_main_table= { 0, "updating main table", 0};
|
||||
|
|
@ -10317,6 +9873,7 @@ PSI_stage_info stage_gtid_wait_other_connection= { 0, "Waiting for other master
|
|||
|
||||
PSI_stage_info *all_server_stages[]=
|
||||
{
|
||||
& stage_after_apply_event,
|
||||
& stage_after_create,
|
||||
& stage_after_opening_tables,
|
||||
& stage_after_table_lock,
|
||||
|
|
@ -10324,6 +9881,7 @@ PSI_stage_info *all_server_stages[]=
|
|||
& stage_alter_inplace,
|
||||
& stage_alter_inplace_commit,
|
||||
& stage_alter_inplace_prepare,
|
||||
& stage_apply_event,
|
||||
& stage_binlog_processing_checkpoint_notify,
|
||||
& stage_binlog_stopping_background_thread,
|
||||
& stage_binlog_waiting_background_tasks,
|
||||
|
|
@ -10405,6 +9963,7 @@ PSI_stage_info *all_server_stages[]=
|
|||
& stage_storing_result_in_query_cache,
|
||||
& stage_storing_row_into_queue,
|
||||
& stage_system_lock,
|
||||
& stage_unlocking_tables,
|
||||
& stage_update,
|
||||
& stage_updating,
|
||||
& stage_updating_main_table,
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
#include "sql_list.h" /* I_List */
|
||||
#include "sql_cmd.h"
|
||||
#include <my_rnd.h>
|
||||
#include "my_pthread.h"
|
||||
|
||||
class THD;
|
||||
struct handlerton;
|
||||
|
|
@ -333,6 +334,7 @@ void init_server_psi_keys();
|
|||
MAINTAINER: Please keep this list in order, to limit merge collisions.
|
||||
Hint: grep PSI_stage_info | sort -u
|
||||
*/
|
||||
extern PSI_stage_info stage_apply_event;
|
||||
extern PSI_stage_info stage_after_create;
|
||||
extern PSI_stage_info stage_after_opening_tables;
|
||||
extern PSI_stage_info stage_after_table_lock;
|
||||
|
|
@ -340,6 +342,7 @@ extern PSI_stage_info stage_allocating_local_table;
|
|||
extern PSI_stage_info stage_alter_inplace_prepare;
|
||||
extern PSI_stage_info stage_alter_inplace;
|
||||
extern PSI_stage_info stage_alter_inplace_commit;
|
||||
extern PSI_stage_info stage_after_apply_event;
|
||||
extern PSI_stage_info stage_changing_master;
|
||||
extern PSI_stage_info stage_checking_master_version;
|
||||
extern PSI_stage_info stage_checking_permissions;
|
||||
|
|
@ -413,6 +416,7 @@ extern PSI_stage_info stage_statistics;
|
|||
extern PSI_stage_info stage_storing_result_in_query_cache;
|
||||
extern PSI_stage_info stage_storing_row_into_queue;
|
||||
extern PSI_stage_info stage_system_lock;
|
||||
extern PSI_stage_info stage_unlocking_tables;
|
||||
extern PSI_stage_info stage_update;
|
||||
extern PSI_stage_info stage_updating;
|
||||
extern PSI_stage_info stage_updating_main_table;
|
||||
|
|
@ -766,9 +770,4 @@ extern uint internal_tmp_table_max_key_segments;
|
|||
extern uint volatile global_disable_checkpoint;
|
||||
extern my_bool opt_help;
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
#include "my_pthread.h"
|
||||
pthread_handler_t start_wsrep_THD(void*);
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
#endif /* MYSQLD_INCLUDED */
|
||||
|
|
|
|||
|
|
@ -488,14 +488,8 @@ static uchar *net_store_length_fast(uchar *packet, uint length)
|
|||
|
||||
void Protocol::end_statement()
|
||||
{
|
||||
#ifdef WITH_WSREP
|
||||
/*sanity check, can be removed before 1.0 release */
|
||||
if (WSREP(thd) && thd->wsrep_conflict_state== REPLAYING)
|
||||
{
|
||||
WSREP_ERROR("attempting net_end_statement while replaying");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
/* sanity check*/
|
||||
DBUG_ASSERT_IF_WSREP(!(WSREP_ON && WSREP(thd) && thd->wsrep_conflict_state == REPLAYING));
|
||||
DBUG_ENTER("Protocol::end_statement");
|
||||
DBUG_ASSERT(! thd->get_stmt_da()->is_sent());
|
||||
bool error= FALSE;
|
||||
|
|
|
|||
|
|
@ -305,13 +305,8 @@ unpack_row(rpl_group_info *rgi,
|
|||
normal unpack operation.
|
||||
*/
|
||||
uint16 const metadata= tabledef->field_metadata(i);
|
||||
#ifndef DBUG_OFF
|
||||
uchar const *const old_pack_ptr= pack_ptr;
|
||||
#else
|
||||
#ifdef WITH_WSREP
|
||||
uchar const *const old_pack_ptr= pack_ptr;
|
||||
#endif /* WITH_WSREP */
|
||||
#endif /* !DBUF_OFF */
|
||||
|
||||
pack_ptr= f->unpack(f->ptr, pack_ptr, row_end, metadata);
|
||||
DBUG_PRINT("debug", ("field: %s; metadata: 0x%x;"
|
||||
" pack_ptr: 0x%lx; pack_ptr': 0x%lx; bytes: %d",
|
||||
|
|
@ -321,17 +316,21 @@ unpack_row(rpl_group_info *rgi,
|
|||
if (!pack_ptr)
|
||||
{
|
||||
#ifdef WITH_WSREP
|
||||
/*
|
||||
Debug message to troubleshoot bug:
|
||||
https://mariadb.atlassian.net/browse/MDEV-4404
|
||||
*/
|
||||
WSREP_WARN("ROW event unpack field: %s metadata: 0x%x;"
|
||||
" pack_ptr: 0x%lx; conv_table %p conv_field %p table %s"
|
||||
" row_end: 0x%lx",
|
||||
f->field_name, metadata,
|
||||
(ulong) old_pack_ptr, conv_table, conv_field,
|
||||
(table_found) ? "found" : "not found", (ulong)row_end
|
||||
);
|
||||
if (WSREP_ON)
|
||||
{
|
||||
/*
|
||||
Debug message to troubleshoot bug:
|
||||
https://mariadb.atlassian.net/browse/MDEV-4404
|
||||
Galera Node throws "Could not read field" error and drops out of cluster
|
||||
*/
|
||||
WSREP_WARN("ROW event unpack field: %s metadata: 0x%x;"
|
||||
" pack_ptr: 0x%lx; conv_table %p conv_field %p table %s"
|
||||
" row_end: 0x%lx",
|
||||
f->field_name, metadata,
|
||||
(ulong) old_pack_ptr, conv_table, conv_field,
|
||||
(table_found) ? "found" : "not found", (ulong)row_end
|
||||
);
|
||||
}
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
rgi->rli->report(ERROR_LEVEL, ER_SLAVE_CORRUPT_EVENT,
|
||||
|
|
|
|||
19
sql/slave.cc
19
sql/slave.cc
|
|
@ -52,10 +52,8 @@
|
|||
#include "log_event.h" // Rotate_log_event,
|
||||
// Create_file_log_event,
|
||||
// Format_description_log_event
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
#include "wsrep_mysqld.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_REPLICATION
|
||||
|
||||
#include "rpl_tblmap.h"
|
||||
|
|
@ -4370,9 +4368,7 @@ pthread_handler_t handle_slave_sql(void *arg)
|
|||
my_off_t saved_skip= 0;
|
||||
Master_info *mi= ((Master_info*)arg);
|
||||
Relay_log_info* rli = &mi->rli;
|
||||
#ifdef WITH_WSREP
|
||||
my_bool wsrep_node_dropped= FALSE;
|
||||
#endif /* WITH_WSREP */
|
||||
const char *errmsg;
|
||||
rpl_group_info *serial_rgi;
|
||||
rpl_sql_thread_info sql_info(mi->rpl_filter);
|
||||
|
|
@ -4380,9 +4376,8 @@ pthread_handler_t handle_slave_sql(void *arg)
|
|||
// needs to call my_thread_init(), otherwise we get a coredump in DBUG_ stuff
|
||||
my_thread_init();
|
||||
DBUG_ENTER("handle_slave_sql");
|
||||
#ifdef WITH_WSREP
|
||||
|
||||
wsrep_restart_point:
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
LINT_INIT(saved_master_log_pos);
|
||||
LINT_INIT(saved_log_pos);
|
||||
|
|
@ -4515,7 +4510,8 @@ pthread_handler_t handle_slave_sql(void *arg)
|
|||
#ifdef WITH_WSREP
|
||||
thd->wsrep_exec_mode= LOCAL_STATE;
|
||||
/* synchronize with wsrep replication */
|
||||
if (WSREP_ON) wsrep_ready_wait();
|
||||
if (WSREP_ON)
|
||||
wsrep_ready_wait();
|
||||
#endif
|
||||
DBUG_PRINT("master_info",("log_file_name: %s position: %s",
|
||||
rli->group_master_log_name,
|
||||
|
|
@ -4617,7 +4613,7 @@ log '%s' at position %s, relay log '%s' position: %s%s", RPL_LOG_NAME,
|
|||
rli->group_master_log_name, (ulong) rli->group_master_log_pos);
|
||||
saved_skip= 0;
|
||||
}
|
||||
|
||||
|
||||
if (exec_relay_log_event(thd, rli, serial_rgi))
|
||||
{
|
||||
DBUG_PRINT("info", ("exec_relay_log_event() failed"));
|
||||
|
|
@ -4626,8 +4622,7 @@ log '%s' at position %s, relay log '%s' position: %s%s", RPL_LOG_NAME,
|
|||
{
|
||||
slave_output_error_info(rli, thd);
|
||||
#ifdef WITH_WSREP
|
||||
uint32 const last_errno= rli->last_error().number;
|
||||
if (WSREP_ON && last_errno == ER_UNKNOWN_COM_ERROR)
|
||||
if (WSREP_ON && rli->last_error().number == ER_UNKNOWN_COM_ERROR)
|
||||
{
|
||||
wsrep_node_dropped= TRUE;
|
||||
}
|
||||
|
|
@ -4721,7 +4716,7 @@ err_during_init:
|
|||
/* if slave stopped due to node going non primary, we set global flag to
|
||||
trigger automatic restart of slave when node joins back to cluster
|
||||
*/
|
||||
if (wsrep_node_dropped && wsrep_restart_slave)
|
||||
if (WSREP_ON && wsrep_node_dropped && wsrep_restart_slave)
|
||||
{
|
||||
if (wsrep_ready)
|
||||
{
|
||||
|
|
|
|||
39
sql/sp.cc
39
sql/sp.cc
|
|
@ -32,7 +32,7 @@
|
|||
|
||||
#include <my_user.h>
|
||||
|
||||
static bool
|
||||
bool
|
||||
create_string(THD *thd, String *buf,
|
||||
stored_procedure_type sp_type,
|
||||
const char *db, ulong dblen,
|
||||
|
|
@ -924,7 +924,7 @@ end:
|
|||
}
|
||||
|
||||
|
||||
static void
|
||||
void
|
||||
sp_returns_type(THD *thd, String &result, sp_head *sp)
|
||||
{
|
||||
TABLE table;
|
||||
|
|
@ -2126,7 +2126,7 @@ int sp_cache_routine(THD *thd, enum stored_procedure_type type, sp_name *name,
|
|||
@return
|
||||
Returns TRUE on success, FALSE on (alloc) failure.
|
||||
*/
|
||||
static bool
|
||||
bool
|
||||
create_string(THD *thd, String *buf,
|
||||
stored_procedure_type type,
|
||||
const char *db, ulong dblen,
|
||||
|
|
@ -2271,37 +2271,4 @@ sp_load_for_information_schema(THD *thd, TABLE *proc_table, String *db,
|
|||
thd->lex= old_lex;
|
||||
return sp;
|
||||
}
|
||||
#ifdef WITH_WSREP
|
||||
int wsrep_create_sp(THD *thd, uchar** buf, size_t* buf_len)
|
||||
{
|
||||
String log_query;
|
||||
sp_head *sp = thd->lex->sphead;
|
||||
ulong saved_mode= thd->variables.sql_mode;
|
||||
String retstr(64);
|
||||
retstr.set_charset(system_charset_info);
|
||||
|
||||
log_query.set_charset(system_charset_info);
|
||||
|
||||
if (sp->m_type == TYPE_ENUM_FUNCTION)
|
||||
{
|
||||
sp_returns_type(thd, retstr, sp);
|
||||
}
|
||||
|
||||
if (!create_string(thd, &log_query,
|
||||
sp->m_type,
|
||||
(sp->m_explicit_name ? sp->m_db.str : NULL),
|
||||
(sp->m_explicit_name ? sp->m_db.length : 0),
|
||||
sp->m_name.str, sp->m_name.length,
|
||||
sp->m_params.str, sp->m_params.length,
|
||||
retstr.c_ptr(), retstr.length(),
|
||||
sp->m_body.str, sp->m_body.length,
|
||||
sp->m_chistics, &(thd->lex->definer->user),
|
||||
&(thd->lex->definer->host),
|
||||
saved_mode))
|
||||
{
|
||||
WSREP_WARN("SP create string failed: %s", thd->query());
|
||||
return 1;
|
||||
}
|
||||
return wsrep_to_buf_helper(thd, log_query.ptr(), log_query.length(), buf, buf_len);
|
||||
}
|
||||
#endif /* WITH_WSREP */
|
||||
|
|
|
|||
15
sql/sp.h
15
sql/sp.h
|
|
@ -214,4 +214,19 @@ bool load_collation(MEM_ROOT *mem_root,
|
|||
CHARSET_INFO *dflt_cl,
|
||||
CHARSET_INFO **cl);
|
||||
|
||||
void sp_returns_type(THD *thd,
|
||||
String &result,
|
||||
sp_head *sp);
|
||||
|
||||
bool create_string(THD *thd, String *buf,
|
||||
stored_procedure_type type,
|
||||
const char *db, ulong dblen,
|
||||
const char *name, ulong namelen,
|
||||
const char *params, ulong paramslen,
|
||||
const char *returns, ulong returnslen,
|
||||
const char *body, ulong bodylen,
|
||||
st_sp_chistics *chistics,
|
||||
const LEX_STRING *definer_user,
|
||||
const LEX_STRING *definer_host,
|
||||
ulonglong sql_mode);
|
||||
#endif /* _SP_H_ */
|
||||
|
|
|
|||
|
|
@ -2560,12 +2560,8 @@ int check_alter_user(THD *thd, const char *host, const char *user)
|
|||
goto end;
|
||||
}
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
if ((!WSREP(thd) || !thd->wsrep_applier) &&
|
||||
if (IF_WSREP((!WSREP(thd) || !thd->wsrep_applier), 1) &&
|
||||
!thd->slave_thread && !thd->security_ctx->priv_user[0])
|
||||
#else
|
||||
if (!thd->slave_thread && !thd->security_ctx->priv_user[0])
|
||||
#endif /* WITH_WSREP */
|
||||
{
|
||||
my_message(ER_PASSWORD_ANONYMOUS_USER, ER(ER_PASSWORD_ANONYMOUS_USER),
|
||||
MYF(0));
|
||||
|
|
@ -2576,10 +2572,9 @@ int check_alter_user(THD *thd, const char *host, const char *user)
|
|||
my_error(ER_PASSWORD_NO_MATCH, MYF(0));
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!thd->slave_thread &&
|
||||
#ifdef WITH_WSREP
|
||||
(!WSREP(thd) || !thd->wsrep_applier) &&
|
||||
#endif /* WITH_WSREP */
|
||||
IF_WSREP((!WSREP(thd) || !thd->wsrep_applier),1) &&
|
||||
(strcmp(thd->security_ctx->priv_user, user) ||
|
||||
my_strcasecmp(system_charset_info, host,
|
||||
thd->security_ctx->priv_host)))
|
||||
|
|
@ -2648,9 +2643,8 @@ bool change_password(THD *thd, const char *host, const char *user,
|
|||
enum_binlog_format save_binlog_format;
|
||||
uint new_password_len= (uint) strlen(new_password);
|
||||
int result=0;
|
||||
#ifdef WITH_WSREP
|
||||
const CSET_STRING query_save = thd->query_string;
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
DBUG_ENTER("change_password");
|
||||
DBUG_PRINT("enter",("host: '%s' user: '%s' new_password: '%s'",
|
||||
host,user,new_password));
|
||||
|
|
@ -2658,10 +2652,11 @@ bool change_password(THD *thd, const char *host, const char *user,
|
|||
|
||||
if (check_change_password(thd, host, user, new_password, new_password_len))
|
||||
DBUG_RETURN(1);
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
if (WSREP(thd) && !thd->wsrep_applier)
|
||||
{
|
||||
query_length= sprintf(buff, "SET PASSWORD FOR '%-.120s'@'%-.120s'='%-.120s'",
|
||||
query_length= sprintf(buff, "SET PASSWORD FOR '%-.120s'@'%-.120s'='%-.120s'",
|
||||
user ? user : "",
|
||||
host ? host : "",
|
||||
new_password);
|
||||
|
|
@ -2736,11 +2731,10 @@ end:
|
|||
|
||||
DBUG_RETURN(result);
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
error:
|
||||
WSREP_ERROR("Replication of SET PASSWORD failed: %s", buff);
|
||||
error:
|
||||
WSREP_ERROR("Repliation of SET PASSWORD failed: %s", buff);
|
||||
DBUG_RETURN(result);
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
}
|
||||
|
||||
int acl_check_set_default_role(THD *thd, const char *host, const char *user)
|
||||
|
|
@ -2759,9 +2753,7 @@ int acl_set_default_role(THD *thd, const char *host, const char *user,
|
|||
bool clear_role= FALSE;
|
||||
char buff[512];
|
||||
enum_binlog_format save_binlog_format;
|
||||
#ifdef WITH_WSREP
|
||||
const CSET_STRING query_save = thd->query_string;
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
DBUG_ENTER("acl_set_default_role");
|
||||
DBUG_PRINT("enter",("host: '%s' user: '%s' rolename: '%s'",
|
||||
|
|
@ -2867,6 +2859,7 @@ int acl_set_default_role(THD *thd, const char *host, const char *user,
|
|||
}
|
||||
end:
|
||||
close_mysql_tables(thd);
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
if (WSREP(thd) && !thd->wsrep_applier)
|
||||
{
|
||||
|
|
@ -2876,14 +2869,10 @@ end:
|
|||
thd->wsrep_exec_mode = LOCAL_STATE;
|
||||
}
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
thd->restore_stmt_binlog_format(save_binlog_format);
|
||||
|
||||
DBUG_RETURN(result);
|
||||
#ifdef WITH_WSREP
|
||||
error:
|
||||
WSREP_ERROR("Replication of SET PASSWORD failed: %s", buff);
|
||||
DBUG_RETURN(result);
|
||||
#endif /* WITH_WSREP */
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1143,9 +1143,8 @@ bool Sql_cmd_analyze_table::execute(THD *thd)
|
|||
FALSE, UINT_MAX, FALSE))
|
||||
goto error;
|
||||
thd->enable_slow_log= opt_log_slow_admin_statements;
|
||||
#ifdef WITH_WSREP
|
||||
WSREP_TO_ISOLATION_BEGIN(first_table->db, first_table->table_name, NULL);
|
||||
#endif
|
||||
|
||||
res= mysql_admin_table(thd, first_table, &m_lex->check_opt,
|
||||
"analyze", lock_type, 1, 0, 0, 0,
|
||||
&handler::ha_analyze, 0);
|
||||
|
|
|
|||
|
|
@ -18,9 +18,8 @@
|
|||
// mysql_exchange_partition
|
||||
#include "sql_base.h" // open_temporary_tables
|
||||
#include "sql_alter.h"
|
||||
#ifdef WITH_WSREP
|
||||
#include "wsrep_mysqld.h"
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
Alter_info::Alter_info(const Alter_info &rhs, MEM_ROOT *mem_root)
|
||||
:drop_list(rhs.drop_list, mem_root),
|
||||
alter_list(rhs.alter_list, mem_root),
|
||||
|
|
@ -320,6 +319,7 @@ bool Sql_cmd_alter_table::execute(THD *thd)
|
|||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
result= mysql_alter_table(thd, select_lex->db, lex->name.str,
|
||||
&create_info,
|
||||
first_table,
|
||||
|
|
@ -328,8 +328,6 @@ bool Sql_cmd_alter_table::execute(THD *thd)
|
|||
select_lex->order_list.first,
|
||||
lex->ignore);
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
#endif /* WITH_WSREP */
|
||||
DBUG_RETURN(result);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -61,11 +61,8 @@
|
|||
#ifdef __WIN__
|
||||
#include <io.h>
|
||||
#endif
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
#include "wsrep_mysqld.h"
|
||||
#include "wsrep_thd.h"
|
||||
#endif // WITH_WSREP
|
||||
|
||||
bool
|
||||
No_such_table_error_handler::handle_condition(THD *,
|
||||
|
|
@ -4588,8 +4585,10 @@ restart:
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
if ((thd->lex->sql_command== SQLCOM_INSERT ||
|
||||
if (WSREP_ON &&
|
||||
(thd->lex->sql_command== SQLCOM_INSERT ||
|
||||
thd->lex->sql_command== SQLCOM_INSERT_SELECT ||
|
||||
thd->lex->sql_command== SQLCOM_REPLACE ||
|
||||
thd->lex->sql_command== SQLCOM_REPLACE_SELECT ||
|
||||
|
|
@ -4608,15 +4607,7 @@ restart:
|
|||
|
||||
err:
|
||||
THD_STAGE_INFO(thd, stage_after_opening_tables);
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
if (WSREP(thd))
|
||||
thd_proc_info(thd, "exit open_tables()");
|
||||
else
|
||||
thd_proc_info(thd, 0);
|
||||
#else /* WITH_WSREP */
|
||||
thd_proc_info(thd, 0);
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
free_root(&new_frm_mem, MYF(0)); // Free pre-alloced block
|
||||
|
||||
|
|
@ -5072,15 +5063,7 @@ end:
|
|||
}
|
||||
THD_STAGE_INFO(thd, stage_after_opening_tables);
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
if (WSREP(thd))
|
||||
thd_proc_info(thd, "End opening table");
|
||||
else
|
||||
thd_proc_info(thd, 0);
|
||||
#else /* WITH_WSREP */
|
||||
thd_proc_info(thd, 0);
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
DBUG_RETURN(table);
|
||||
}
|
||||
|
||||
|
|
@ -9034,19 +9017,17 @@ bool mysql_notify_thread_having_shared_lock(THD *thd, THD *in_use,
|
|||
(e.g. see partitioning code).
|
||||
*/
|
||||
if (!thd_table->needs_reopen())
|
||||
#ifdef WITH_WSREP
|
||||
{
|
||||
signalled|= mysql_lock_abort_for_thread(thd, thd_table);
|
||||
if (thd && WSREP(thd) && wsrep_thd_is_BF((void *)thd, true))
|
||||
#ifdef WITH_WSREP
|
||||
if (thd && WSREP(thd) && wsrep_thd_is_BF((void *)thd, true))
|
||||
{
|
||||
WSREP_DEBUG("remove_table_from_cache: %llu",
|
||||
(unsigned long long) thd->real_id);
|
||||
wsrep_abort_thd((void *)thd, (void *)in_use, FALSE);
|
||||
}
|
||||
}
|
||||
#else
|
||||
signalled|= mysql_lock_abort_for_thread(thd, thd_table);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
mysql_mutex_unlock(&in_use->LOCK_thd_data);
|
||||
}
|
||||
|
|
|
|||
279
sql/sql_class.cc
279
sql/sql_class.cc
|
|
@ -64,10 +64,8 @@
|
|||
#include "sql_parse.h" // is_update_query
|
||||
#include "sql_callback.h"
|
||||
#include "lock.h"
|
||||
#ifdef WITH_WSREP
|
||||
#include "wsrep_mysqld.h"
|
||||
#include "wsrep_thd.h"
|
||||
#endif
|
||||
#include "sql_connect.h"
|
||||
|
||||
/*
|
||||
|
|
@ -820,176 +818,6 @@ char *thd_get_error_context_description(THD *thd, char *buffer,
|
|||
return buffer;
|
||||
}
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
extern int wsrep_on(void *thd)
|
||||
{
|
||||
return (int)(WSREP(((THD*)thd)));
|
||||
}
|
||||
extern "C" bool wsrep_thd_is_wsrep_on(THD *thd)
|
||||
{
|
||||
return thd->variables.wsrep_on;
|
||||
}
|
||||
|
||||
extern "C" bool wsrep_consistency_check(void *thd)
|
||||
{
|
||||
return ((THD*)thd)->wsrep_consistency_check == CONSISTENCY_CHECK_RUNNING;
|
||||
}
|
||||
|
||||
extern "C" void wsrep_thd_set_exec_mode(THD *thd, enum wsrep_exec_mode mode)
|
||||
{
|
||||
thd->wsrep_exec_mode= mode;
|
||||
}
|
||||
extern "C" void wsrep_thd_set_query_state(
|
||||
THD *thd, enum wsrep_query_state state)
|
||||
{
|
||||
thd->wsrep_query_state= state;
|
||||
}
|
||||
extern "C" void wsrep_thd_set_conflict_state(
|
||||
THD *thd, enum wsrep_conflict_state state)
|
||||
{
|
||||
thd->wsrep_conflict_state= state;
|
||||
}
|
||||
|
||||
|
||||
extern "C" enum wsrep_exec_mode wsrep_thd_exec_mode(THD *thd)
|
||||
{
|
||||
return thd->wsrep_exec_mode;
|
||||
}
|
||||
|
||||
extern "C" const char *wsrep_thd_exec_mode_str(THD *thd)
|
||||
{
|
||||
return
|
||||
(!thd) ? "void" :
|
||||
(thd->wsrep_exec_mode == LOCAL_STATE) ? "local" :
|
||||
(thd->wsrep_exec_mode == REPL_RECV) ? "applier" :
|
||||
(thd->wsrep_exec_mode == TOTAL_ORDER) ? "total order" :
|
||||
(thd->wsrep_exec_mode == LOCAL_COMMIT) ? "local commit" : "void";
|
||||
}
|
||||
|
||||
extern "C" enum wsrep_query_state wsrep_thd_query_state(THD *thd)
|
||||
{
|
||||
return thd->wsrep_query_state;
|
||||
}
|
||||
|
||||
extern "C" const char *wsrep_thd_query_state_str(THD *thd)
|
||||
{
|
||||
return
|
||||
(!thd) ? "void" :
|
||||
(thd->wsrep_query_state == QUERY_IDLE) ? "idle" :
|
||||
(thd->wsrep_query_state == QUERY_EXEC) ? "executing" :
|
||||
(thd->wsrep_query_state == QUERY_COMMITTING) ? "committing" :
|
||||
(thd->wsrep_query_state == QUERY_EXITING) ? "exiting" :
|
||||
(thd->wsrep_query_state == QUERY_ROLLINGBACK) ? "rolling back" : "void";
|
||||
}
|
||||
|
||||
extern "C" enum wsrep_conflict_state wsrep_thd_conflict_state(THD *thd)
|
||||
{
|
||||
return thd->wsrep_conflict_state;
|
||||
}
|
||||
extern "C" const char *wsrep_thd_conflict_state_str(THD *thd)
|
||||
{
|
||||
return
|
||||
(!thd) ? "void" :
|
||||
(thd->wsrep_conflict_state == NO_CONFLICT) ? "no conflict" :
|
||||
(thd->wsrep_conflict_state == MUST_ABORT) ? "must abort" :
|
||||
(thd->wsrep_conflict_state == ABORTING) ? "aborting" :
|
||||
(thd->wsrep_conflict_state == MUST_REPLAY) ? "must replay" :
|
||||
(thd->wsrep_conflict_state == REPLAYING) ? "replaying" :
|
||||
(thd->wsrep_conflict_state == RETRY_AUTOCOMMIT) ? "retrying" :
|
||||
(thd->wsrep_conflict_state == CERT_FAILURE) ? "cert failure" : "void";
|
||||
}
|
||||
|
||||
extern "C" wsrep_ws_handle_t* wsrep_thd_ws_handle(THD *thd)
|
||||
{
|
||||
return &thd->wsrep_ws_handle;
|
||||
}
|
||||
|
||||
extern "C" void wsrep_thd_LOCK(THD *thd)
|
||||
{
|
||||
mysql_mutex_lock(&thd->LOCK_wsrep_thd);
|
||||
}
|
||||
extern "C" void wsrep_thd_UNLOCK(THD *thd)
|
||||
{
|
||||
mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
|
||||
}
|
||||
extern "C" time_t wsrep_thd_query_start(THD *thd)
|
||||
{
|
||||
return thd->query_start();
|
||||
}
|
||||
extern "C" uint32 wsrep_thd_wsrep_rand(THD *thd)
|
||||
{
|
||||
return thd->wsrep_rand;
|
||||
}
|
||||
extern "C" my_thread_id wsrep_thd_thread_id(THD *thd)
|
||||
{
|
||||
return thd->thread_id;
|
||||
}
|
||||
extern "C" wsrep_seqno_t wsrep_thd_trx_seqno(THD *thd)
|
||||
{
|
||||
return (thd) ? thd->wsrep_trx_meta.gtid.seqno : WSREP_SEQNO_UNDEFINED;
|
||||
}
|
||||
extern "C" query_id_t wsrep_thd_query_id(THD *thd)
|
||||
{
|
||||
return thd->query_id;
|
||||
}
|
||||
extern "C" char *wsrep_thd_query(THD *thd)
|
||||
{
|
||||
return (thd) ? thd->query() : NULL;
|
||||
}
|
||||
extern "C" query_id_t wsrep_thd_wsrep_last_query_id(THD *thd)
|
||||
{
|
||||
return thd->wsrep_last_query_id;
|
||||
}
|
||||
extern "C" void wsrep_thd_set_wsrep_last_query_id(THD *thd, query_id_t id)
|
||||
{
|
||||
thd->wsrep_last_query_id= id;
|
||||
}
|
||||
extern "C" void wsrep_thd_awake(THD *thd, my_bool signal)
|
||||
{
|
||||
if (signal)
|
||||
{
|
||||
mysql_mutex_lock(&thd->LOCK_thd_data);
|
||||
thd->awake(KILL_QUERY);
|
||||
mysql_mutex_unlock(&thd->LOCK_thd_data);
|
||||
}
|
||||
else
|
||||
{
|
||||
mysql_mutex_lock(&LOCK_wsrep_replaying);
|
||||
mysql_cond_broadcast(&COND_wsrep_replaying);
|
||||
mysql_mutex_unlock(&LOCK_wsrep_replaying);
|
||||
}
|
||||
}
|
||||
extern "C" int wsrep_thd_retry_counter(THD *thd)
|
||||
{
|
||||
return(thd->wsrep_retry_counter);
|
||||
}
|
||||
|
||||
extern int
|
||||
wsrep_trx_order_before(void *thd1, void *thd2)
|
||||
{
|
||||
if (wsrep_thd_trx_seqno((THD*)thd1) < wsrep_thd_trx_seqno((THD*)thd2)) {
|
||||
WSREP_DEBUG("BF conflict, order: %lld %lld\n",
|
||||
(long long)wsrep_thd_trx_seqno((THD*)thd1),
|
||||
(long long)wsrep_thd_trx_seqno((THD*)thd2));
|
||||
return 1;
|
||||
}
|
||||
WSREP_DEBUG("waiting for BF, trx order: %lld %lld\n",
|
||||
(long long)wsrep_thd_trx_seqno((THD*)thd1),
|
||||
(long long)wsrep_thd_trx_seqno((THD*)thd2));
|
||||
return 0;
|
||||
}
|
||||
extern "C" int
|
||||
wsrep_trx_is_aborting(void *thd_ptr)
|
||||
{
|
||||
if (thd_ptr) {
|
||||
if ((((THD *)thd_ptr)->wsrep_conflict_state == MUST_ABORT) ||
|
||||
(((THD *)thd_ptr)->wsrep_conflict_state == ABORTING)) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if MARIA_PLUGIN_INTERFACE_VERSION < 0x0200
|
||||
/**
|
||||
|
|
@ -1069,7 +897,7 @@ THD::THD(bool is_applier)
|
|||
wsrep_client_thread(false),
|
||||
wsrep_po_handle(WSREP_PO_INITIALIZER),
|
||||
wsrep_po_cnt(0),
|
||||
wsrep_po_in_trans(false),
|
||||
// wsrep_po_in_trans(false),
|
||||
wsrep_apply_format(0),
|
||||
wsrep_apply_toi(false),
|
||||
#endif
|
||||
|
|
@ -1243,13 +1071,9 @@ THD::THD(bool is_applier)
|
|||
my_rnd_init(&rand, tmp + (ulong) &rand, tmp + (ulong) ::global_query_id);
|
||||
substitute_null_with_insert_id = FALSE;
|
||||
thr_lock_info_init(&lock_info); /* safety: will be reset after start */
|
||||
#ifdef WITH_WSREP
|
||||
lock_info.mysql_thd= (void *)this;
|
||||
lock_info.in_lock_tables= false;
|
||||
#ifdef WSREP_PROC_INFO
|
||||
|
||||
wsrep_info[sizeof(wsrep_info) - 1] = '\0'; /* make sure it is 0-terminated */
|
||||
#endif /* WSREP_PROC_INFO */
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
m_internal_handler= NULL;
|
||||
m_binlog_invoker= INVOKER_NONE;
|
||||
|
|
@ -1992,9 +1816,6 @@ void THD::awake(killed_state state_to_set)
|
|||
|
||||
/* Interrupt target waiting inside a storage engine. */
|
||||
if (state_to_set != NOT_KILLED)
|
||||
#ifdef WITH_WSREP
|
||||
/* TODO: prevent applier close here */
|
||||
#endif /* WITH_WSREP */
|
||||
ha_kill_query(this, thd_kill_level(this));
|
||||
|
||||
/* Broadcast a condition to kick the target if it is waiting on it. */
|
||||
|
|
@ -2127,19 +1948,17 @@ bool THD::notify_shared_lock(MDL_context_owner *ctx_in_use,
|
|||
(e.g. see partitioning code).
|
||||
*/
|
||||
if (!thd_table->needs_reopen())
|
||||
#ifdef WITH_WSREP
|
||||
{
|
||||
signalled|= mysql_lock_abort_for_thread(this, thd_table);
|
||||
if (this && WSREP(this) && wsrep_thd_is_BF((void *)this, FALSE))
|
||||
#if WITH_WSREP
|
||||
if (WSREP_ON && this && WSREP(this) && wsrep_thd_is_BF((void *)this, FALSE))
|
||||
{
|
||||
WSREP_DEBUG("remove_table_from_cache: %llu",
|
||||
(unsigned long long) this->real_id);
|
||||
wsrep_abort_thd((void *)this, (void *)in_use, FALSE);
|
||||
}
|
||||
#endif /* WITH_WSREP */
|
||||
}
|
||||
#else
|
||||
signalled|= mysql_lock_abort_for_thread(this, thd_table);
|
||||
#endif
|
||||
}
|
||||
mysql_mutex_unlock(&in_use->LOCK_thd_data);
|
||||
}
|
||||
|
|
@ -2322,11 +2141,10 @@ void THD::cleanup_after_query()
|
|||
table_map_for_update= 0;
|
||||
m_binlog_invoker= INVOKER_NONE;
|
||||
#ifdef WITH_WSREP
|
||||
if (TOTAL_ORDER == wsrep_exec_mode)
|
||||
{
|
||||
wsrep_exec_mode = LOCAL_STATE;
|
||||
}
|
||||
//wsrep_trx_seqno = 0;
|
||||
if (WSREP_ON && TOTAL_ORDER == wsrep_exec_mode)
|
||||
{
|
||||
wsrep_exec_mode = LOCAL_STATE;
|
||||
}
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
|
|
@ -2751,7 +2569,7 @@ bool select_send::send_result_set_metadata(List<Item> &list, uint flags)
|
|||
{
|
||||
bool res;
|
||||
#ifdef WITH_WSREP
|
||||
if (WSREP(thd) && thd->wsrep_retry_query)
|
||||
if (WSREP_ON && WSREP(thd) && thd->wsrep_retry_query)
|
||||
{
|
||||
WSREP_DEBUG("skipping select metadata");
|
||||
return FALSE;
|
||||
|
|
@ -4502,12 +4320,9 @@ extern "C" int thd_non_transactional_update(const MYSQL_THD thd)
|
|||
|
||||
extern "C" int thd_binlog_format(const MYSQL_THD thd)
|
||||
{
|
||||
#ifdef WITH_WSREP
|
||||
if (((WSREP(thd) && wsrep_emulate_bin_log) || mysql_bin_log.is_open()) &&
|
||||
(thd->variables.option_bits & OPTION_BIN_LOG))
|
||||
#else
|
||||
if (mysql_bin_log.is_open() && (thd->variables.option_bits & OPTION_BIN_LOG))
|
||||
#endif
|
||||
if (IF_WSREP(((WSREP(thd) && wsrep_emulate_bin_log) || mysql_bin_log.is_open()),
|
||||
mysql_bin_log.is_open()) &&
|
||||
thd->variables.option_bits & OPTION_BIN_LOG)
|
||||
return (int) WSREP_FORMAT(thd->variables.binlog_format);
|
||||
else
|
||||
return BINLOG_FORMAT_UNSPEC;
|
||||
|
|
@ -5494,14 +5309,10 @@ int THD::decide_logging_format(TABLE_LIST *tables)
|
|||
5. Error: Cannot modify table that uses a storage engine
|
||||
limited to row-logging when binlog_format = STATEMENT
|
||||
*/
|
||||
#ifdef WITH_WSREP
|
||||
if (!WSREP(this) || wsrep_exec_mode == LOCAL_STATE)
|
||||
if (IF_WSREP(WSREP_ON && (!WSREP(this) || wsrep_exec_mode == LOCAL_STATE),1))
|
||||
{
|
||||
#endif /* WITH_WSREP */
|
||||
my_error((error= ER_BINLOG_STMT_MODE_AND_ROW_ENGINE), MYF(0), "");
|
||||
#ifdef WITH_WSREP
|
||||
my_error((error= ER_BINLOG_STMT_MODE_AND_ROW_ENGINE), MYF(0), "");
|
||||
}
|
||||
#endif /* WITH_WSREP */
|
||||
}
|
||||
else if (is_write && (unsafe_flags= lex->get_stmt_unsafe_flags()) != 0)
|
||||
{
|
||||
|
|
@ -5849,15 +5660,11 @@ CPP_UNNAMED_NS_END
|
|||
int THD::binlog_write_row(TABLE* table, bool is_trans,
|
||||
MY_BITMAP const* cols, size_t colcnt,
|
||||
uchar const *record)
|
||||
{
|
||||
#ifdef WITH_WSREP
|
||||
DBUG_ASSERT(is_current_stmt_binlog_format_row() &&
|
||||
((WSREP(this) && wsrep_emulate_bin_log) ||
|
||||
mysql_bin_log.is_open()));
|
||||
#else
|
||||
DBUG_ASSERT(is_current_stmt_binlog_format_row() && mysql_bin_log.is_open());
|
||||
#endif
|
||||
{
|
||||
|
||||
DBUG_ASSERT(is_current_stmt_binlog_format_row() &&
|
||||
IF_WSREP(((WSREP_ON && WSREP(this) && wsrep_emulate_bin_log) || mysql_bin_log.is_open()),
|
||||
mysql_bin_log.is_open()));
|
||||
/*
|
||||
Pack records into format for transfer. We are allocating more
|
||||
memory than needed, but that doesn't matter.
|
||||
|
|
@ -5889,14 +5696,10 @@ int THD::binlog_update_row(TABLE* table, bool is_trans,
|
|||
MY_BITMAP const* cols, size_t colcnt,
|
||||
const uchar *before_record,
|
||||
const uchar *after_record)
|
||||
{
|
||||
#ifdef WITH_WSREP
|
||||
DBUG_ASSERT(is_current_stmt_binlog_format_row() &&
|
||||
((WSREP(this) && wsrep_emulate_bin_log)
|
||||
|| mysql_bin_log.is_open()));
|
||||
#else
|
||||
DBUG_ASSERT(is_current_stmt_binlog_format_row() && mysql_bin_log.is_open());
|
||||
#endif
|
||||
{
|
||||
DBUG_ASSERT(is_current_stmt_binlog_format_row() &&
|
||||
IF_WSREP(((WSREP_ON && WSREP(this) && wsrep_emulate_bin_log) || mysql_bin_log.is_open()),
|
||||
mysql_bin_log.is_open()));
|
||||
|
||||
size_t const before_maxlen = max_row_length(table, before_record);
|
||||
size_t const after_maxlen = max_row_length(table, after_record);
|
||||
|
|
@ -5944,14 +5747,10 @@ int THD::binlog_update_row(TABLE* table, bool is_trans,
|
|||
int THD::binlog_delete_row(TABLE* table, bool is_trans,
|
||||
MY_BITMAP const* cols, size_t colcnt,
|
||||
uchar const *record)
|
||||
{
|
||||
#ifdef WITH_WSREP
|
||||
DBUG_ASSERT(is_current_stmt_binlog_format_row() &&
|
||||
((WSREP(this) && wsrep_emulate_bin_log)
|
||||
|| mysql_bin_log.is_open()));
|
||||
#else
|
||||
DBUG_ASSERT(is_current_stmt_binlog_format_row() && mysql_bin_log.is_open());
|
||||
#endif
|
||||
{
|
||||
DBUG_ASSERT(is_current_stmt_binlog_format_row() &&
|
||||
IF_WSREP(((WSREP_ON && WSREP(this) && wsrep_emulate_bin_log) || mysql_bin_log.is_open()),
|
||||
mysql_bin_log.is_open()));
|
||||
|
||||
/*
|
||||
Pack records into format for transfer. We are allocating more
|
||||
|
|
@ -5986,11 +5785,8 @@ int THD::binlog_remove_pending_rows_event(bool clear_maps,
|
|||
{
|
||||
DBUG_ENTER("THD::binlog_remove_pending_rows_event");
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
if (!(WSREP_EMULATE_BINLOG(this) || mysql_bin_log.is_open()))
|
||||
#else
|
||||
if (!mysql_bin_log.is_open())
|
||||
#endif
|
||||
IF_WSREP(WSREP_ON && !(WSREP_EMULATE_BINLOG(this) || mysql_bin_log.is_open()),
|
||||
!mysql_bin_log.is_open());
|
||||
DBUG_RETURN(0);
|
||||
|
||||
/* Ensure that all events in a GTID group are in the same cache */
|
||||
|
|
@ -6013,11 +5809,8 @@ int THD::binlog_flush_pending_rows_event(bool stmt_end, bool is_transactional)
|
|||
mode: it might be the case that we left row-based mode before
|
||||
flushing anything (e.g., if we have explicitly locked tables).
|
||||
*/
|
||||
#ifdef WITH_WSREP
|
||||
if (!(WSREP_EMULATE_BINLOG(this) || mysql_bin_log.is_open()))
|
||||
#else
|
||||
if (!mysql_bin_log.is_open())
|
||||
#endif
|
||||
IF_WSREP(WSREP_ON && !(WSREP_EMULATE_BINLOG(this) || mysql_bin_log.is_open()),
|
||||
!mysql_bin_log.is_open());
|
||||
DBUG_RETURN(0);
|
||||
|
||||
/* Ensure that all events in a GTID group are in the same cache */
|
||||
|
|
@ -6269,12 +6062,10 @@ int THD::binlog_query(THD::enum_binlog_query_type qtype, char const *query_arg,
|
|||
DBUG_ENTER("THD::binlog_query");
|
||||
DBUG_PRINT("enter", ("qtype: %s query: '%-.*s'",
|
||||
show_query_type(qtype), (int) query_len, query_arg));
|
||||
#ifdef WITH_WSREP
|
||||
DBUG_ASSERT(query_arg && (WSREP_EMULATE_BINLOG(this)
|
||||
|| mysql_bin_log.is_open()));
|
||||
#else
|
||||
DBUG_ASSERT(query_arg && mysql_bin_log.is_open());
|
||||
#endif
|
||||
|
||||
DBUG_ASSERT(query_arg &&
|
||||
IF_WSREP(WSREP_ON && (WSREP_EMULATE_BINLOG(this) || mysql_bin_log.is_open()),
|
||||
mysql_bin_log.is_open()));
|
||||
|
||||
/* If this is withing a BEGIN ... COMMIT group, don't log it */
|
||||
if (variables.option_bits & OPTION_GTID_BEGIN)
|
||||
|
|
|
|||
|
|
@ -50,25 +50,14 @@ void set_thd_stage_info(void *thd,
|
|||
const char *calling_func,
|
||||
const char *calling_file,
|
||||
const unsigned int calling_line);
|
||||
|
||||
|
||||
#define THD_STAGE_INFO(thd, stage) \
|
||||
(thd)->enter_stage(& stage, NULL, __func__, __FILE__, __LINE__)
|
||||
|
||||
#include "my_apc.h"
|
||||
#include "rpl_gtid.h"
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
#include "wsrep_mysqld.h"
|
||||
struct wsrep_thd_shadow {
|
||||
ulonglong options;
|
||||
uint server_status;
|
||||
enum wsrep_exec_mode wsrep_exec_mode;
|
||||
Vio *vio;
|
||||
ulong tx_isolation;
|
||||
char *db;
|
||||
size_t db_length;
|
||||
};
|
||||
#endif
|
||||
|
||||
class Reprepare_observer;
|
||||
class Relay_log_info;
|
||||
struct rpl_group_info;
|
||||
|
|
@ -2746,6 +2735,9 @@ public:
|
|||
const bool wsrep_applier; /* dedicated slave applier thread */
|
||||
bool wsrep_applier_closing; /* applier marked to close */
|
||||
bool wsrep_client_thread; /* to identify client threads*/
|
||||
bool wsrep_PA_safe;
|
||||
bool wsrep_converted_lock_session;
|
||||
bool wsrep_apply_toi; /* applier processing in TOI */
|
||||
enum wsrep_exec_mode wsrep_exec_mode;
|
||||
query_id_t wsrep_last_query_id;
|
||||
enum wsrep_query_state wsrep_query_state;
|
||||
|
|
@ -2758,17 +2750,13 @@ public:
|
|||
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
|
||||
char wsrep_info[128]; /* string for dynamic proc info */
|
||||
#endif /* WSREP_PROC_INFO */
|
||||
ulong wsrep_retry_counter; // of autocommit
|
||||
bool wsrep_PA_safe;
|
||||
char* wsrep_retry_query;
|
||||
size_t wsrep_retry_query_len;
|
||||
enum enum_server_command wsrep_retry_command;
|
||||
enum wsrep_consistency_check_mode
|
||||
enum wsrep_consistency_check_mode
|
||||
wsrep_consistency_check;
|
||||
wsrep_stats_var* wsrep_status_vars;
|
||||
int wsrep_mysql_replicated;
|
||||
|
|
@ -2777,12 +2765,10 @@ public:
|
|||
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 */
|
||||
/**
|
||||
Internal parser state.
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@
|
|||
// reset_host_errors
|
||||
#include "sql_acl.h" // acl_getroot, NO_ACCESS, SUPER_ACL
|
||||
#include "sql_callback.h"
|
||||
#include "wsrep_mysqld.h"
|
||||
|
||||
HASH global_user_stats, global_client_stats, global_table_stats;
|
||||
HASH global_index_stats;
|
||||
|
|
@ -44,9 +45,6 @@ HASH global_index_stats;
|
|||
extern mysql_mutex_t LOCK_global_user_client_stats;
|
||||
extern mysql_mutex_t LOCK_global_table_stats;
|
||||
extern mysql_mutex_t LOCK_global_index_stats;
|
||||
#ifdef WITH_WSREP
|
||||
#include "wsrep_mysqld.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
Get structure for logging connection data for the current user
|
||||
|
|
@ -1397,7 +1395,7 @@ void do_handle_one_connection(THD *thd_arg)
|
|||
break;
|
||||
}
|
||||
end_connection(thd);
|
||||
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
if (WSREP(thd))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -642,22 +642,19 @@ cleanup:
|
|||
if (!transactional_table && deleted > 0)
|
||||
thd->transaction.stmt.modified_non_trans_table=
|
||||
thd->transaction.all.modified_non_trans_table= TRUE;
|
||||
|
||||
|
||||
/* See similar binlogging code in sql_update.cc, for comments */
|
||||
if ((error < 0) || thd->transaction.stmt.modified_non_trans_table)
|
||||
{
|
||||
#ifdef WITH_WSREP
|
||||
if ((WSREP_EMULATE_BINLOG(thd) || mysql_bin_log.is_open()))
|
||||
#else
|
||||
if (mysql_bin_log.is_open())
|
||||
#endif
|
||||
if(IF_WSREP((WSREP_EMULATE_BINLOG(thd) || mysql_bin_log.is_open()),
|
||||
mysql_bin_log.is_open()))
|
||||
{
|
||||
int errcode= 0;
|
||||
if (error < 0)
|
||||
thd->clear_error();
|
||||
else
|
||||
errcode= query_error_code(thd, killed_status == NOT_KILLED);
|
||||
|
||||
|
||||
/*
|
||||
[binlog]: If 'handler::delete_all_rows()' was called and the
|
||||
storage engine does not inject the rows itself, we replicate
|
||||
|
|
@ -1111,17 +1108,14 @@ void multi_delete::abort_result_set()
|
|||
DBUG_ASSERT(error_handled);
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
|
||||
if (thd->transaction.stmt.modified_non_trans_table)
|
||||
{
|
||||
/*
|
||||
/*
|
||||
there is only side effects; to binlog with the error
|
||||
*/
|
||||
#ifdef WITH_WSREP
|
||||
if (WSREP_EMULATE_BINLOG(thd) || mysql_bin_log.is_open())
|
||||
#else
|
||||
if (mysql_bin_log.is_open())
|
||||
#endif
|
||||
if (IF_WSREP((WSREP_EMULATE_BINLOG(thd) || mysql_bin_log.is_open()),
|
||||
mysql_bin_log.is_open()))
|
||||
{
|
||||
int errcode= query_error_code(thd, thd->killed == NOT_KILLED);
|
||||
/* possible error of writing binary log is ignored deliberately */
|
||||
|
|
@ -1297,11 +1291,8 @@ bool multi_delete::send_eof()
|
|||
}
|
||||
if ((local_error == 0) || thd->transaction.stmt.modified_non_trans_table)
|
||||
{
|
||||
#ifdef WITH_WSREP
|
||||
if (WSREP_EMULATE_BINLOG(thd) || mysql_bin_log.is_open())
|
||||
#else
|
||||
if (mysql_bin_log.is_open())
|
||||
#endif
|
||||
if(IF_WSREP((WSREP_EMULATE_BINLOG(thd) || mysql_bin_log.is_open()),
|
||||
mysql_bin_log.is_open()))
|
||||
{
|
||||
int errcode= 0;
|
||||
if (local_error == 0)
|
||||
|
|
|
|||
|
|
@ -1014,11 +1014,8 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
|
|||
thd->transaction.stmt.modified_non_trans_table ||
|
||||
was_insert_delayed)
|
||||
{
|
||||
#ifdef WITH_WSREP
|
||||
if (WSREP_EMULATE_BINLOG(thd) || mysql_bin_log.is_open())
|
||||
#else
|
||||
if (mysql_bin_log.is_open())
|
||||
#endif
|
||||
if(IF_WSREP((WSREP_EMULATE_BINLOG(thd) || mysql_bin_log.is_open()),
|
||||
mysql_bin_log.is_open()))
|
||||
{
|
||||
int errcode= 0;
|
||||
if (error <= 0)
|
||||
|
|
@ -3199,6 +3196,7 @@ bool Delayed_insert::handle_inserts(void)
|
|||
mysql_cond_broadcast(&cond_client); // If waiting clients
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
if (WSREP((&thd)))
|
||||
thd_proc_info(&thd, "insert done");
|
||||
|
|
@ -3657,15 +3655,11 @@ bool select_insert::send_eof()
|
|||
DBUG_PRINT("enter", ("trans_table=%d, table_type='%s'",
|
||||
trans_table, table->file->table_type()));
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
error= (thd->wsrep_conflict_state == MUST_ABORT ||
|
||||
thd->wsrep_conflict_state == CERT_FAILURE) ? -1 :
|
||||
(thd->locked_tables_mode <= LTM_LOCK_TABLES ?
|
||||
table->file->ha_end_bulk_insert() : 0);
|
||||
#else
|
||||
error= (thd->locked_tables_mode <= LTM_LOCK_TABLES ?
|
||||
table->file->ha_end_bulk_insert() : 0);
|
||||
#endif /* WITH_WSREP */
|
||||
error = IF_WSREP((thd->wsrep_conflict_state == MUST_ABORT ||
|
||||
thd->wsrep_conflict_state == CERT_FAILURE) ? -1 :, )
|
||||
(thd->locked_tables_mode <= LTM_LOCK_TABLES ?
|
||||
table->file->ha_end_bulk_insert() : 0);
|
||||
|
||||
if (!error && thd->is_error())
|
||||
error= thd->get_stmt_da()->sql_errno();
|
||||
|
||||
|
|
@ -3693,13 +3687,9 @@ bool select_insert::send_eof()
|
|||
events are in the transaction cache and will be written when
|
||||
ha_autocommit_or_rollback() is issued below.
|
||||
*/
|
||||
#ifdef WITH_WSREP
|
||||
if ((WSREP_EMULATE_BINLOG(thd) || mysql_bin_log.is_open()) &&
|
||||
(!error || thd->transaction.stmt.modified_non_trans_table))
|
||||
#else
|
||||
if (mysql_bin_log.is_open() &&
|
||||
(!error || thd->transaction.stmt.modified_non_trans_table))
|
||||
#endif
|
||||
if(IF_WSREP((WSREP_EMULATE_BINLOG(thd) || mysql_bin_log.is_open()),
|
||||
mysql_bin_log.is_open()) &&
|
||||
(!error || thd->transaction.stmt.modified_non_trans_table))
|
||||
{
|
||||
int errcode= 0;
|
||||
if (!error)
|
||||
|
|
@ -3783,11 +3773,8 @@ void select_insert::abort_result_set() {
|
|||
if (!can_rollback_data())
|
||||
thd->transaction.all.modified_non_trans_table= TRUE;
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
if (WSREP_EMULATE_BINLOG(thd) || mysql_bin_log.is_open())
|
||||
#else
|
||||
if (mysql_bin_log.is_open())
|
||||
#endif
|
||||
if(IF_WSREP((WSREP_EMULATE_BINLOG(thd) || mysql_bin_log.is_open()),
|
||||
mysql_bin_log.is_open()))
|
||||
{
|
||||
int errcode= query_error_code(thd, thd->killed == NOT_KILLED);
|
||||
/* error of writing binary log is ignored */
|
||||
|
|
@ -4195,11 +4182,8 @@ select_create::binlog_show_create_table(TABLE **tables, uint count)
|
|||
create_info->table_was_deleted);
|
||||
DBUG_ASSERT(result == 0); /* store_create_info() always return 0 */
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
if (WSREP_EMULATE_BINLOG(thd) || mysql_bin_log.is_open())
|
||||
#else
|
||||
if (mysql_bin_log.is_open())
|
||||
#endif /* WITH_WSREP */
|
||||
if(IF_WSREP((WSREP_EMULATE_BINLOG(thd) || mysql_bin_log.is_open()),
|
||||
mysql_bin_log.is_open()))
|
||||
{
|
||||
int errcode= query_error_code(thd, thd->killed == NOT_KILLED);
|
||||
result= thd->binlog_query(THD::STMT_QUERY_TYPE,
|
||||
|
|
@ -4209,9 +4193,9 @@ select_create::binlog_show_create_table(TABLE **tables, uint count)
|
|||
/* suppress_use */ FALSE,
|
||||
errcode);
|
||||
}
|
||||
#ifdef WITH_WSREP
|
||||
ha_wsrep_fake_trx_id(thd);
|
||||
#endif
|
||||
|
||||
IF_WSREP(ha_wsrep_fake_trx_id(thd), );
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -4242,16 +4226,19 @@ bool select_create::send_eof()
|
|||
if (!(thd->variables.option_bits & OPTION_GTID_BEGIN))
|
||||
trans_commit_implicit(thd);
|
||||
#ifdef WITH_WSREP
|
||||
if (WSREP_ON)
|
||||
{
|
||||
mysql_mutex_lock(&thd->LOCK_wsrep_thd);
|
||||
if (thd->wsrep_conflict_state != NO_CONFLICT)
|
||||
{
|
||||
WSREP_DEBUG("select_create commit failed, thd: %lu err: %d %s",
|
||||
WSREP_DEBUG("select_create commit failed, thd: %lu err: %d %s",
|
||||
thd->thread_id, thd->wsrep_conflict_state, thd->query());
|
||||
mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
|
||||
abort_result_set();
|
||||
return TRUE;
|
||||
}
|
||||
mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
|
||||
}
|
||||
#endif /* WITH_WSREP */
|
||||
}
|
||||
else if (!thd->is_current_stmt_binlog_format_row())
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/* Copyright (c) 2000, 2013, Oracle and/or its affiliates.
|
||||
Copyright (c) 2009, 2013, Monty Program Ab.
|
||||
Copyright (c) 2009, 2014, Monty Program Ab.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -1580,7 +1580,7 @@ int lex_one_token(void *arg, THD *thd)
|
|||
else
|
||||
{
|
||||
#ifdef WITH_WSREP
|
||||
if (version == 99997 && thd->wsrep_exec_mode == LOCAL_STATE)
|
||||
if (WSREP(thd) && version == 99997 && thd->wsrep_exec_mode == LOCAL_STATE)
|
||||
{
|
||||
WSREP_DEBUG("consistency check: %s", thd->query());
|
||||
thd->wsrep_consistency_check= CONSISTENCY_CHECK_DECLARED;
|
||||
|
|
|
|||
253
sql/sql_parse.cc
253
sql/sql_parse.cc
|
|
@ -1,5 +1,5 @@
|
|||
/* Copyright (c) 2000, 2013, Oracle and/or its affiliates.
|
||||
Copyright (c) 2008, 2013, Monty Program Ab
|
||||
Copyright (c) 2008, 2014, Monty Program Ab
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -103,12 +103,14 @@
|
|||
#include "../storage/maria/ha_maria.h"
|
||||
#endif
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
#include "wsrep_mysqld.h"
|
||||
#include "wsrep_thd.h"
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
static void wsrep_mysql_parse(THD *thd, char *rawbuf, uint length,
|
||||
Parser_state *parser_state);
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
/**
|
||||
@defgroup Runtime_Environment Runtime Environment
|
||||
@{
|
||||
|
|
@ -895,18 +897,20 @@ bool do_command(THD *thd)
|
|||
NET *net= &thd->net;
|
||||
enum enum_server_command command;
|
||||
DBUG_ENTER("do_command");
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
if (WSREP(thd))
|
||||
{
|
||||
mysql_mutex_lock(&thd->LOCK_wsrep_thd);
|
||||
thd->wsrep_query_state= QUERY_IDLE;
|
||||
if (thd->wsrep_conflict_state==MUST_ABORT)
|
||||
if (thd->wsrep_conflict_state==MUST_ABORT)
|
||||
{
|
||||
wsrep_client_rollback(thd);
|
||||
}
|
||||
mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
|
||||
}
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
/*
|
||||
indicator of uninitialized lex => normal flow of errors handling
|
||||
(see my_message_sql)
|
||||
|
|
@ -976,19 +980,17 @@ bool do_command(THD *thd)
|
|||
thd->wsrep_query_state= QUERY_EXEC;
|
||||
mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
|
||||
}
|
||||
|
||||
if ((WSREP(thd) && packet_length == packet_error) ||
|
||||
(!WSREP(thd) && (packet_length == packet_error)))
|
||||
#else
|
||||
if (packet_length == packet_error)
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
if (packet_length == packet_error)
|
||||
{
|
||||
DBUG_PRINT("info",("Got error %d reading command from socket %s",
|
||||
net->error,
|
||||
vio_description(net->vio)));
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
if (WSREP(thd)) {
|
||||
if (WSREP(thd))
|
||||
{
|
||||
mysql_mutex_lock(&thd->LOCK_wsrep_thd);
|
||||
if (thd->wsrep_conflict_state == MUST_ABORT)
|
||||
{
|
||||
|
|
@ -998,6 +1000,7 @@ bool do_command(THD *thd)
|
|||
mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
|
||||
}
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
/* Instrument this broken statement as "statement/com/error" */
|
||||
thd->m_statement_psi= MYSQL_REFINE_STATEMENT(thd->m_statement_psi,
|
||||
com_statement_info[COM_END].
|
||||
|
|
@ -1053,7 +1056,8 @@ bool do_command(THD *thd)
|
|||
command_name[command].str));
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
if (WSREP(thd)) {
|
||||
if (WSREP(thd))
|
||||
{
|
||||
/*
|
||||
* bail out if DB snapshot has not been installed. We however,
|
||||
* allow queries "SET" and "SHOW", they are trapped later in execute_command
|
||||
|
|
@ -1087,7 +1091,8 @@ bool do_command(THD *thd)
|
|||
DBUG_ASSERT(!thd->apc_target.is_enabled());
|
||||
return_value= dispatch_command(command, thd, packet+1, (uint) (packet_length-1));
|
||||
#ifdef WITH_WSREP
|
||||
if (WSREP(thd)) {
|
||||
if (WSREP(thd))
|
||||
{
|
||||
while (thd->wsrep_conflict_state== RETRY_AUTOCOMMIT)
|
||||
{
|
||||
WSREP_DEBUG("Retry autocommit for: %s\n", thd->wsrep_retry_query);
|
||||
|
|
@ -1105,13 +1110,14 @@ bool do_command(THD *thd)
|
|||
thd->wsrep_retry_query_len);
|
||||
thd->variables.character_set_client = current_charset;
|
||||
}
|
||||
}
|
||||
if (thd->wsrep_retry_query && thd->wsrep_conflict_state != REPLAYING)
|
||||
{
|
||||
my_free(thd->wsrep_retry_query);
|
||||
thd->wsrep_retry_query = NULL;
|
||||
thd->wsrep_retry_query_len = 0;
|
||||
thd->wsrep_retry_command = COM_CONNECT;
|
||||
|
||||
if (thd->wsrep_retry_query && thd->wsrep_conflict_state != REPLAYING)
|
||||
{
|
||||
my_free(thd->wsrep_retry_query);
|
||||
thd->wsrep_retry_query = NULL;
|
||||
thd->wsrep_retry_query_len = 0;
|
||||
thd->wsrep_retry_command = COM_CONNECT;
|
||||
}
|
||||
}
|
||||
#endif /* WITH_WSREP */
|
||||
DBUG_ASSERT(!thd->apc_target.is_enabled());
|
||||
|
|
@ -1137,7 +1143,7 @@ out:
|
|||
@retval FALSE The statement isn't updating any relevant tables.
|
||||
*/
|
||||
|
||||
static my_bool deny_updates_if_read_only_option(THD *thd,
|
||||
my_bool deny_updates_if_read_only_option(THD *thd,
|
||||
TABLE_LIST *all_tables)
|
||||
{
|
||||
DBUG_ENTER("deny_updates_if_read_only_option");
|
||||
|
|
@ -1191,33 +1197,7 @@ static my_bool deny_updates_if_read_only_option(THD *thd,
|
|||
DBUG_RETURN(FALSE);
|
||||
}
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
static my_bool wsrep_read_only_option(THD *thd, TABLE_LIST *all_tables)
|
||||
{
|
||||
int opt_readonly_saved = opt_readonly;
|
||||
ulong flag_saved = (ulong)(thd->security_ctx->master_access & SUPER_ACL);
|
||||
|
||||
opt_readonly = 0;
|
||||
thd->security_ctx->master_access &= ~SUPER_ACL;
|
||||
|
||||
my_bool ret = !deny_updates_if_read_only_option(thd, all_tables);
|
||||
|
||||
opt_readonly = opt_readonly_saved;
|
||||
thd->security_ctx->master_access |= flag_saved;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void wsrep_copy_query(THD *thd)
|
||||
{
|
||||
thd->wsrep_retry_command = thd->get_command();
|
||||
thd->wsrep_retry_query_len = thd->query_length();
|
||||
thd->wsrep_retry_query = (char *)my_malloc(
|
||||
thd->wsrep_retry_query_len + 1, MYF(0));
|
||||
strncpy(thd->wsrep_retry_query, thd->query(), thd->wsrep_retry_query_len);
|
||||
thd->wsrep_retry_query[thd->wsrep_retry_query_len] = '\0';
|
||||
}
|
||||
#endif /* WITH_WSREP */
|
||||
/**
|
||||
Perform one connection-level (COM_XXXX) command.
|
||||
|
||||
|
|
@ -1248,7 +1228,8 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
|
|||
DBUG_PRINT("info", ("command: %d", command));
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
if (WSREP(thd)) {
|
||||
if (WSREP(thd))
|
||||
{
|
||||
if (!thd->in_multi_stmt_transaction_mode())
|
||||
{
|
||||
thd->wsrep_PA_safe= true;
|
||||
|
|
@ -1480,10 +1461,11 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
|
|||
break;
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
wsrep_mysql_parse(thd, thd->query(), thd->query_length(), &parser_state);
|
||||
#else
|
||||
mysql_parse(thd, thd->query(), thd->query_length(), &parser_state);
|
||||
if (WSREP_ON)
|
||||
wsrep_mysql_parse(thd, thd->query(), thd->query_length(), &parser_state);
|
||||
else
|
||||
#endif /* WITH_WSREP */
|
||||
mysql_parse(thd, thd->query(), thd->query_length(), &parser_state);
|
||||
|
||||
while (!thd->killed && (parser_state.m_lip.found_semicolon != NULL) &&
|
||||
! thd->is_error())
|
||||
|
|
@ -1557,19 +1539,20 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
|
|||
Count each statement from the client.
|
||||
*/
|
||||
statistic_increment(thd->status_var.questions, &LOCK_status);
|
||||
#ifdef WITH_WSREP
|
||||
if (!WSREP(thd))
|
||||
|
||||
if(IF_WSREP(!WSREP(thd), 1))
|
||||
thd->set_time(); /* Reset the query start time. */
|
||||
#else
|
||||
thd->set_time(); /* Reset the query start time. */
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
parser_state.reset(beginning_of_next_stmt, length);
|
||||
/* TODO: set thd->lex->sql_command to SQLCOM_END here */
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
wsrep_mysql_parse(thd, beginning_of_next_stmt, length, &parser_state);
|
||||
#else
|
||||
mysql_parse(thd, beginning_of_next_stmt, length, &parser_state);
|
||||
if (WSREP_ON)
|
||||
wsrep_mysql_parse(thd, beginning_of_next_stmt, length, &parser_state);
|
||||
else
|
||||
#endif /* WITH_WSREP */
|
||||
mysql_parse(thd, beginning_of_next_stmt, length, &parser_state);
|
||||
|
||||
}
|
||||
|
||||
DBUG_PRINT("info",("query ready"));
|
||||
|
|
@ -1909,7 +1892,8 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
|
|||
#ifdef WITH_WSREP
|
||||
dispatch_end:
|
||||
|
||||
if (WSREP(thd)) {
|
||||
if (WSREP(thd))
|
||||
{
|
||||
/* wsrep BF abort in query exec phase */
|
||||
mysql_mutex_lock(&thd->LOCK_wsrep_thd);
|
||||
if ((thd->wsrep_conflict_state != REPLAYING) &&
|
||||
|
|
@ -1919,25 +1903,25 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
|
|||
thd->update_server_status();
|
||||
thd->protocol->end_statement();
|
||||
query_cache_end_of_result(thd);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
|
||||
}
|
||||
} else { /* if (WSREP(thd))... */
|
||||
}
|
||||
else
|
||||
#endif /* WITH_WSREP */
|
||||
DBUG_ASSERT(thd->derived_tables == NULL &&
|
||||
(thd->open_tables == NULL ||
|
||||
{
|
||||
DBUG_ASSERT(thd->derived_tables == NULL &&
|
||||
(thd->open_tables == NULL ||
|
||||
(thd->locked_tables_mode == LTM_LOCK_TABLES)));
|
||||
|
||||
thd_proc_info(thd, "updating status");
|
||||
/* Finalize server status flags after executing a command. */
|
||||
thd->update_server_status();
|
||||
thd->protocol->end_statement();
|
||||
query_cache_end_of_result(thd);
|
||||
#ifdef WITH_WSREP
|
||||
thd_proc_info(thd, "updating status");
|
||||
/* Finalize server status flags after executing a command. */
|
||||
thd->update_server_status();
|
||||
thd->protocol->end_statement();
|
||||
query_cache_end_of_result(thd);
|
||||
}
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
if (!thd->is_error() && !thd->killed_errno())
|
||||
mysql_audit_general(thd, MYSQL_AUDIT_GENERAL_RESULT, 0, 0);
|
||||
|
|
@ -2389,13 +2373,6 @@ err:
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
static bool wsrep_is_show_query(enum enum_sql_command command)
|
||||
{
|
||||
DBUG_ASSERT(command >= 0 && command <= SQLCOM_END);
|
||||
return (sql_command_flags[command] & CF_STATUS_COMMAND) != 0;
|
||||
}
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
/**
|
||||
Execute command saved in thd and lex->sql_command.
|
||||
|
|
@ -2598,7 +2575,8 @@ mysql_execute_command(THD *thd)
|
|||
} /* endif unlikely slave */
|
||||
#endif
|
||||
#ifdef WITH_WSREP
|
||||
if (WSREP(thd)) {
|
||||
if (WSREP(thd))
|
||||
{
|
||||
/*
|
||||
change LOCK TABLE WRITE to transaction
|
||||
*/
|
||||
|
|
@ -2630,31 +2608,10 @@ mysql_execute_command(THD *thd)
|
|||
lex->sql_command != SQLCOM_SET_OPTION &&
|
||||
!wsrep_is_show_query(lex->sql_command))
|
||||
{
|
||||
#if DIRTY_HACK
|
||||
/* Dirty hack for lp:1002714 - trying to recognize mysqldump connection
|
||||
* and allow it to continue. Actuall mysqldump_magic_str may be longer
|
||||
* and is obviously version dependent and may be issued by any client
|
||||
* connection after which connection becomes non-replicating. */
|
||||
static char const mysqldump_magic_str[]=
|
||||
"SELECT LOGFILE_GROUP_NAME, FILE_NAME, TOTAL_EXTENTS, INITIAL_SIZE, ENGINE, EXTRA FROM INFORMATION_SCHEMA.FILES WHERE FILE_TYPE = 'UNDO LOG' AND FILE_NAME IS NOT NULL";
|
||||
static const size_t mysqldump_magic_str_len= sizeof(mysqldump_magic_str) -1;
|
||||
if (SQLCOM_SELECT != lex->sql_command ||
|
||||
thd->query_length() < mysqldump_magic_str_len ||
|
||||
strncmp(thd->query(), mysqldump_magic_str, mysqldump_magic_str_len))
|
||||
{
|
||||
#endif /* DIRTY_HACK */
|
||||
my_message(ER_UNKNOWN_COM_ERROR,
|
||||
"WSREP has not yet prepared node for application use",
|
||||
MYF(0));
|
||||
goto error;
|
||||
#if DIRTY_HACK
|
||||
}
|
||||
else
|
||||
{
|
||||
/* mysqldump connection, allow all further queries to pass */
|
||||
thd->variables.wsrep_on= FALSE;
|
||||
}
|
||||
#endif /* DIRTY_HACK */
|
||||
}
|
||||
}
|
||||
#endif /* WITH_WSREP */
|
||||
|
|
@ -2701,16 +2658,14 @@ mysql_execute_command(THD *thd)
|
|||
if (trans_commit_implicit(thd))
|
||||
{
|
||||
thd->mdl_context.release_transactional_locks();
|
||||
#ifdef WITH_WSREP
|
||||
WSREP_DEBUG("implicit commit failed, MDL released: %lu", thd->thread_id);
|
||||
#endif /* WITH_WSREP */
|
||||
goto error;
|
||||
}
|
||||
/* Release metadata locks acquired in this transaction. */
|
||||
thd->mdl_context.release_transactional_locks();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifndef DBUG_OFF
|
||||
if (lex->sql_command != SQLCOM_SET_OPTION)
|
||||
DEBUG_SYNC(thd,"before_execute_sql_command");
|
||||
|
|
@ -2764,7 +2719,8 @@ mysql_execute_command(THD *thd)
|
|||
case SQLCOM_SHOW_STATUS:
|
||||
{
|
||||
#ifdef WITH_WSREP
|
||||
if (WSREP_CLIENT(thd) && wsrep_causal_wait(thd)) goto error;
|
||||
if (WSREP_CLIENT(thd) && wsrep_causal_wait(thd))
|
||||
goto error;
|
||||
#endif /* WITH_WSREP */
|
||||
execute_show_status(thd, all_tables);
|
||||
break;
|
||||
|
|
@ -2799,7 +2755,8 @@ mysql_execute_command(THD *thd)
|
|||
case SQLCOM_SHOW_STATUS_PROC:
|
||||
case SQLCOM_SHOW_STATUS_FUNC:
|
||||
#ifdef WITH_WSREP
|
||||
if (WSREP_CLIENT(thd) && wsrep_causal_wait(thd)) goto error;
|
||||
if (WSREP_CLIENT(thd) && wsrep_causal_wait(thd))
|
||||
goto error;
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
case SQLCOM_SHOW_DATABASES:
|
||||
|
|
@ -2823,7 +2780,8 @@ mysql_execute_command(THD *thd)
|
|||
case SQLCOM_SHOW_INDEX_STATS:
|
||||
case SQLCOM_SELECT:
|
||||
#ifdef WITH_WSREP
|
||||
if (WSREP_CLIENT(thd) && wsrep_causal_wait(thd)) goto error;
|
||||
if (WSREP_CLIENT(thd) && wsrep_causal_wait(thd))
|
||||
goto error;
|
||||
case SQLCOM_SHOW_VARIABLES:
|
||||
case SQLCOM_SHOW_CHARSETS:
|
||||
case SQLCOM_SHOW_COLLATIONS:
|
||||
|
|
@ -3187,7 +3145,7 @@ case SQLCOM_PREPARE:
|
|||
*/
|
||||
if(lex->ignore)
|
||||
lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_CREATE_IGNORE_SELECT);
|
||||
|
||||
|
||||
if(lex->duplicates == DUP_REPLACE)
|
||||
lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_CREATE_REPLACE_SELECT);
|
||||
|
||||
|
|
@ -3199,7 +3157,7 @@ case SQLCOM_PREPARE:
|
|||
raise a warning, as it may cause problems
|
||||
(see 'NAME_CONST issues' in 'Binary Logging of Stored Programs')
|
||||
*/
|
||||
if (thd->query_name_consts &&
|
||||
if (thd->query_name_consts &&
|
||||
mysql_bin_log.is_open() &&
|
||||
WSREP_FORMAT(thd->variables.binlog_format) == BINLOG_FORMAT_STMT &&
|
||||
!mysql_bin_log.is_query_in_union(thd, thd->query_id))
|
||||
|
|
@ -3320,8 +3278,8 @@ case SQLCOM_PREPARE:
|
|||
/* in STATEMENT format, we probably have to replicate also temporary
|
||||
tables, like mysql replication does
|
||||
*/
|
||||
if (!thd->is_current_stmt_binlog_format_row() ||
|
||||
!(create_info.options & HA_LEX_CREATE_TMP_TABLE))
|
||||
if (WSREP_ON && (!thd->is_current_stmt_binlog_format_row() ||
|
||||
!(create_info.options & HA_LEX_CREATE_TMP_TABLE)))
|
||||
WSREP_TO_ISOLATION_BEGIN(create_table->db, create_table->table_name,
|
||||
NULL)
|
||||
#endif /* WITH_WSREP */
|
||||
|
|
@ -3510,7 +3468,8 @@ end_with_restore_list:
|
|||
#else
|
||||
{
|
||||
#ifdef WITH_WSREP
|
||||
if (WSREP_CLIENT(thd) && wsrep_causal_wait(thd)) goto error;
|
||||
if (WSREP_CLIENT(thd) && wsrep_causal_wait(thd))
|
||||
goto error;
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
/*
|
||||
|
|
@ -3576,7 +3535,8 @@ end_with_restore_list:
|
|||
{
|
||||
DBUG_ASSERT(first_table == all_tables && first_table != 0);
|
||||
#ifdef WITH_WSREP
|
||||
if (WSREP_CLIENT(thd) && wsrep_causal_wait(thd)) goto error;
|
||||
if (WSREP_CLIENT(thd) && wsrep_causal_wait(thd))
|
||||
goto error;
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
if (check_table_access(thd, SELECT_ACL, all_tables,
|
||||
|
|
@ -3790,14 +3750,14 @@ end_with_restore_list:
|
|||
if ((res= insert_precheck(thd, all_tables)))
|
||||
break;
|
||||
#ifdef WITH_WSREP
|
||||
if (lex->sql_command == SQLCOM_INSERT_SELECT &&
|
||||
if (WSREP_ON && lex->sql_command == SQLCOM_INSERT_SELECT &&
|
||||
thd->wsrep_consistency_check == CONSISTENCY_CHECK_DECLARED)
|
||||
{
|
||||
thd->wsrep_consistency_check = CONSISTENCY_CHECK_RUNNING;
|
||||
WSREP_TO_ISOLATION_BEGIN(first_table->db, first_table->table_name, NULL);
|
||||
}
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
#endif
|
||||
/*
|
||||
INSERT...SELECT...ON DUPLICATE KEY UPDATE/REPLACE SELECT/
|
||||
INSERT...IGNORE...SELECT can be unsafe, unless ORDER BY PRIMARY KEY
|
||||
|
|
@ -4015,14 +3975,17 @@ 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 (WSREP_ON)
|
||||
{
|
||||
if (!lex->drop_temporary &&
|
||||
(!thd->is_current_stmt_binlog_format_row() ||
|
||||
!find_temporary_table(thd, table)))
|
||||
for (TABLE_LIST *table= all_tables; table; table= table->next_global)
|
||||
{
|
||||
WSREP_TO_ISOLATION_BEGIN(NULL, NULL, all_tables);
|
||||
break;
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* WITH_WSREP */
|
||||
|
|
@ -4755,17 +4718,10 @@ end_with_restore_list:
|
|||
able to open it (with SQLCOM_HA_OPEN) in the first place.
|
||||
*/
|
||||
unit->set_limit(select_lex);
|
||||
#ifdef WITH_WSREP
|
||||
{ char* tmp_info= NULL;
|
||||
if (WSREP(thd)) tmp_info = (char *)thd_proc_info(thd, "mysql_ha_read()");
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
res= mysql_ha_read(thd, first_table, lex->ha_read_mode, lex->ident.str,
|
||||
lex->insert_list, lex->ha_rkey_mode, select_lex->where,
|
||||
unit->select_limit_cnt, unit->offset_limit_cnt);
|
||||
#ifdef WITH_WSREP
|
||||
if (WSREP(thd)) thd_proc_info(thd, tmp_info);
|
||||
}
|
||||
#endif /* WITH_WSREP */
|
||||
break;
|
||||
|
||||
case SQLCOM_BEGIN:
|
||||
|
|
@ -4773,9 +4729,7 @@ end_with_restore_list:
|
|||
if (trans_begin(thd, lex->start_transaction_opt))
|
||||
{
|
||||
thd->mdl_context.release_transactional_locks();
|
||||
#ifdef WITH_WSREP
|
||||
WSREP_DEBUG("BEGIN failed, MDL released: %lu", thd->thread_id);
|
||||
#endif /* WITH_WSREP */
|
||||
goto error;
|
||||
}
|
||||
my_ok(thd);
|
||||
|
|
@ -4793,9 +4747,7 @@ end_with_restore_list:
|
|||
if (trans_commit(thd))
|
||||
{
|
||||
thd->mdl_context.release_transactional_locks();
|
||||
#ifdef WITH_WSREP
|
||||
WSREP_DEBUG("COMMIT failed, MDL released: %lu", thd->thread_id);
|
||||
#endif /* WITH_WSREP */
|
||||
goto error;
|
||||
}
|
||||
thd->mdl_context.release_transactional_locks();
|
||||
|
|
@ -4818,19 +4770,16 @@ end_with_restore_list:
|
|||
thd->print_aborted_warning(3, "RELEASE");
|
||||
}
|
||||
#ifdef WITH_WSREP
|
||||
if (WSREP(thd)) {
|
||||
|
||||
if (WSREP(thd))
|
||||
{
|
||||
if (thd->wsrep_conflict_state == NO_CONFLICT ||
|
||||
thd->wsrep_conflict_state == REPLAYING)
|
||||
{
|
||||
my_ok(thd);
|
||||
}
|
||||
} else {
|
||||
#endif /* WITH_WSREP */
|
||||
my_ok(thd);
|
||||
#ifdef WITH_WSREP
|
||||
}
|
||||
} else
|
||||
#endif /* WITH_WSREP */
|
||||
my_ok(thd);
|
||||
break;
|
||||
}
|
||||
case SQLCOM_ROLLBACK:
|
||||
|
|
@ -4847,9 +4796,7 @@ end_with_restore_list:
|
|||
if (trans_rollback(thd))
|
||||
{
|
||||
thd->mdl_context.release_transactional_locks();
|
||||
#ifdef WITH_WSREP
|
||||
WSREP_DEBUG("rollback failed, MDL released: %lu", thd->thread_id);
|
||||
#endif /* WITH_WSREP */
|
||||
goto error;
|
||||
}
|
||||
thd->mdl_context.release_transactional_locks();
|
||||
|
|
@ -4869,16 +4816,15 @@ end_with_restore_list:
|
|||
if (tx_release)
|
||||
thd->killed= KILL_CONNECTION;
|
||||
#ifdef WITH_WSREP
|
||||
if (WSREP(thd)) {
|
||||
if (WSREP(thd))
|
||||
{
|
||||
if (thd->wsrep_conflict_state == NO_CONFLICT) {
|
||||
my_ok(thd);
|
||||
}
|
||||
} else {
|
||||
#endif /* WITH_WSREP */
|
||||
my_ok(thd);
|
||||
#ifdef WITH_WSREP
|
||||
}
|
||||
else
|
||||
#endif /* WITH_WSREP */
|
||||
my_ok(thd);
|
||||
break;
|
||||
}
|
||||
case SQLCOM_RELEASE_SAVEPOINT:
|
||||
|
|
@ -5394,9 +5340,7 @@ create_sp_error:
|
|||
if (trans_xa_commit(thd))
|
||||
{
|
||||
thd->mdl_context.release_transactional_locks();
|
||||
#ifdef WITH_WSREP
|
||||
WSREP_DEBUG("XA commit failed, MDL released: %lu", thd->thread_id);
|
||||
#endif /* WITH_WSREP */
|
||||
goto error;
|
||||
}
|
||||
thd->mdl_context.release_transactional_locks();
|
||||
|
|
@ -5412,9 +5356,7 @@ create_sp_error:
|
|||
if (trans_xa_rollback(thd))
|
||||
{
|
||||
thd->mdl_context.release_transactional_locks();
|
||||
#ifdef WITH_WSREP
|
||||
WSREP_DEBUG("XA rollback failed, MDL released: %lu", thd->thread_id);
|
||||
#endif /* WITH_WSREP */
|
||||
goto error;
|
||||
}
|
||||
thd->mdl_context.release_transactional_locks();
|
||||
|
|
@ -5764,7 +5706,8 @@ static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables)
|
|||
else
|
||||
status_var_add(thd->status_var.rows_sent, thd->get_sent_row_count());
|
||||
#ifdef WITH_WSREP
|
||||
if (lex->sql_command == SQLCOM_SHOW_STATUS) wsrep_free_status(thd);
|
||||
if (WSREP_ON && lex->sql_command == SQLCOM_SHOW_STATUS)
|
||||
wsrep_free_status(thd);
|
||||
#endif /* WITH_WSREP */
|
||||
return res;
|
||||
}
|
||||
|
|
@ -6610,7 +6553,8 @@ void THD::reset_for_next_command()
|
|||
transactions. Appliers and replayers are either processing ROW
|
||||
events or get autoinc variable values from Query_log_event.
|
||||
*/
|
||||
if (WSREP(thd) && thd->wsrep_exec_mode == LOCAL_STATE) {
|
||||
if (WSREP(thd) && thd->wsrep_exec_mode == LOCAL_STATE)
|
||||
{
|
||||
if (wsrep_auto_increment_control)
|
||||
{
|
||||
if (thd->variables.auto_increment_offset !=
|
||||
|
|
@ -6831,7 +6775,7 @@ void mysql_init_multi_delete(LEX *lex)
|
|||
static void wsrep_mysql_parse(THD *thd, char *rawbuf, uint length,
|
||||
Parser_state *parser_state)
|
||||
{
|
||||
bool is_autocommit=
|
||||
bool is_autocommit=
|
||||
!thd->in_multi_stmt_transaction_mode() &&
|
||||
thd->wsrep_conflict_state == NO_CONFLICT &&
|
||||
!thd->wsrep_applier &&
|
||||
|
|
@ -7959,14 +7903,9 @@ kill_one_thread(THD *thd, longlong id, killed_state kill_signal, killed_type typ
|
|||
faster and do a harder kill than KILL_SYSTEM_THREAD;
|
||||
*/
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
if (((thd->security_ctx->master_access & SUPER_ACL) ||
|
||||
thd->security_ctx->user_matches(tmp->security_ctx)) &&
|
||||
!wsrep_thd_is_BF((void *)tmp, true))
|
||||
#else
|
||||
if ((thd->security_ctx->master_access & SUPER_ACL) ||
|
||||
thd->security_ctx->user_matches(tmp->security_ctx))
|
||||
#endif /* WITH_WSREP */
|
||||
IF_WSREP(!wsrep_thd_is_BF((void *)tmp, true), 1))
|
||||
{
|
||||
tmp->awake(kill_signal);
|
||||
error=0;
|
||||
|
|
|
|||
|
|
@ -202,22 +202,5 @@ 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);
|
||||
|
||||
#else
|
||||
|
||||
#define WSREP_TO_ISOLATION_BEGIN(db_, table_, table_list_)
|
||||
#define WSREP_TO_ISOLATION_END
|
||||
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
|
||||
#endif /* SQL_PARSE_INCLUDED */
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
/* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
Copyright (c) 2014, SkySQL Ab.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -764,18 +765,22 @@ bool Sql_cmd_alter_table_truncate_partition::execute(THD *thd)
|
|||
DBUG_RETURN(TRUE);
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
TABLE *find_temporary_table(THD *thd, const TABLE_LIST *tl);
|
||||
|
||||
if ((!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)
|
||||
)
|
||||
if (WSREP_ON)
|
||||
{
|
||||
WSREP_WARN("ALTER TABLE isolation failure");
|
||||
DBUG_RETURN(TRUE);
|
||||
TABLE *find_temporary_table(THD *thd, const TABLE_LIST *tl);
|
||||
|
||||
if ((!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)
|
||||
)
|
||||
{
|
||||
WSREP_WARN("ALTER TABLE isolation failure");
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
}
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
if (open_tables(thd, &first_table, &table_counter, 0))
|
||||
DBUG_RETURN(true);
|
||||
|
||||
|
|
|
|||
|
|
@ -3087,21 +3087,19 @@ void plugin_thdvar_init(THD *thd)
|
|||
thd->variables.dynamic_variables_size= 0;
|
||||
thd->variables.dynamic_variables_ptr= 0;
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
if (!WSREP(thd) || !thd->wsrep_applier) {
|
||||
#endif
|
||||
mysql_mutex_lock(&LOCK_plugin);
|
||||
thd->variables.table_plugin=
|
||||
if (IF_WSREP((!WSREP(thd) || !thd->wsrep_applier),1))
|
||||
{
|
||||
mysql_mutex_lock(&LOCK_plugin);
|
||||
thd->variables.table_plugin=
|
||||
intern_plugin_lock(NULL, global_system_variables.table_plugin);
|
||||
if (global_system_variables.tmp_table_plugin)
|
||||
thd->variables.tmp_table_plugin=
|
||||
if (global_system_variables.tmp_table_plugin)
|
||||
thd->variables.tmp_table_plugin=
|
||||
intern_plugin_lock(NULL, global_system_variables.tmp_table_plugin);
|
||||
intern_plugin_unlock(NULL, old_table_plugin);
|
||||
intern_plugin_unlock(NULL, old_tmp_table_plugin);
|
||||
mysql_mutex_unlock(&LOCK_plugin);
|
||||
#ifdef WITH_WSREP
|
||||
intern_plugin_unlock(NULL, old_table_plugin);
|
||||
intern_plugin_unlock(NULL, old_tmp_table_plugin);
|
||||
mysql_mutex_unlock(&LOCK_plugin);
|
||||
}
|
||||
#endif
|
||||
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/* Copyright (c) 2002, 2013, Oracle and/or its affiliates.
|
||||
Copyright (c) 2008, 2013, Monty Program Ab
|
||||
Copyright (c) 2008, 2014, Monty Program Ab
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -117,6 +117,7 @@ When one supplies long data for a placeholder:
|
|||
#include "lock.h" // MYSQL_OPEN_FORCE_SHARED_MDL
|
||||
#include "sql_handler.h"
|
||||
#include "transaction.h" // trans_rollback_implicit
|
||||
#include "wsrep_mysqld.h"
|
||||
|
||||
/**
|
||||
A result class used to send cursor rows using the binary protocol.
|
||||
|
|
@ -3547,9 +3548,7 @@ Prepared_statement::set_parameters(String *expanded_query,
|
|||
return res;
|
||||
}
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
void wsrep_replay_transaction(THD *thd);
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
/**
|
||||
Execute a prepared statement. Re-prepare it a limited number
|
||||
of times if necessary.
|
||||
|
|
@ -3629,20 +3628,25 @@ reexecute:
|
|||
|
||||
thd->m_reprepare_observer= NULL;
|
||||
#ifdef WITH_WSREP
|
||||
mysql_mutex_lock(&thd->LOCK_wsrep_thd);
|
||||
switch (thd->wsrep_conflict_state)
|
||||
{
|
||||
case CERT_FAILURE:
|
||||
WSREP_DEBUG("PS execute fail for CERT_FAILURE: thd: %ld err: %d",
|
||||
thd->thread_id, thd->get_stmt_da()->sql_errno() );
|
||||
thd->wsrep_conflict_state = NO_CONFLICT;
|
||||
break;
|
||||
|
||||
case MUST_REPLAY:
|
||||
(void)wsrep_replay_transaction(thd);
|
||||
default: break;
|
||||
if (WSREP_ON)
|
||||
{
|
||||
mysql_mutex_lock(&thd->LOCK_wsrep_thd);
|
||||
switch (thd->wsrep_conflict_state)
|
||||
{
|
||||
case CERT_FAILURE:
|
||||
WSREP_DEBUG("PS execute fail for CERT_FAILURE: thd: %ld err: %d",
|
||||
thd->thread_id, thd->get_stmt_da()->sql_errno() );
|
||||
thd->wsrep_conflict_state = NO_CONFLICT;
|
||||
break;
|
||||
|
||||
case MUST_REPLAY:
|
||||
(void)wsrep_replay_transaction(thd);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
|
||||
}
|
||||
mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
if ((sql_command_flags[lex->sql_command] & CF_REEXECUTION_FRAGILE) &&
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/* Copyright (c) 2000, 2013, Oracle and/or its affiliates.
|
||||
Copyright (c) 2008, 2013, Monty Program Ab
|
||||
Copyright (c) 2008, 2014, Monty Program Ab
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -2946,15 +2946,7 @@ int start_slave(THD* thd , Master_info* mi, bool net_report)
|
|||
|
||||
err:
|
||||
unlock_slave_threads(mi);
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
if (WSREP(thd))
|
||||
thd_proc_info(thd, "exit stop_slave()");
|
||||
else
|
||||
thd_proc_info(thd, 0);
|
||||
#else /* WITH_WSREP */
|
||||
thd_proc_info(thd, 0);
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
if (slave_errno)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -2972,13 +2972,9 @@ static bool show_status_array(THD *thd, const char *wild,
|
|||
DBUG_ASSERT(name_buffer[0] >= 'a');
|
||||
DBUG_ASSERT(name_buffer[0] <= 'z');
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
// TODO: remove once lp:1306875 has been addressed.
|
||||
if (status_var && (is_wsrep_var == FALSE))
|
||||
#else
|
||||
/* traditionally status variables have a first letter uppercased */
|
||||
if (status_var)
|
||||
#endif /* WITH_WSREP */
|
||||
// WSREP_TODO: remove once lp:1306875 has been addressed.
|
||||
if (IF_WSREP(WSREP_ON && is_wsrep_var == FALSE, 1) &&
|
||||
status_var)
|
||||
name_buffer[0]-= 'a' - 'A';
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5265,58 +5265,9 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table,
|
|||
DBUG_ENTER("mysql_create_like_table");
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
if (WSREP(thd) && !thd->wsrep_applier)
|
||||
{
|
||||
TABLE *tmp_table;
|
||||
bool is_tmp_table= FALSE;
|
||||
|
||||
for (tmp_table= thd->temporary_tables; tmp_table; tmp_table=tmp_table->next)
|
||||
{
|
||||
if (!strcmp(src_table->db, tmp_table->s->db.str) &&
|
||||
!strcmp(src_table->table_name, tmp_table->s->table_name.str))
|
||||
{
|
||||
is_tmp_table= TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
|
||||
{
|
||||
/* CREATE TEMPORARY TABLE LIKE must be skipped from replication */
|
||||
WSREP_DEBUG("CREATE TEMPORARY TABLE LIKE... skipped replication\n %s",
|
||||
thd->query());
|
||||
}
|
||||
else if (!is_tmp_table)
|
||||
{
|
||||
/* this is straight CREATE TABLE LIKE... eith no tmp tables */
|
||||
WSREP_TO_ISOLATION_BEGIN(table->db, table->table_name, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* here we have CREATE TABLE LIKE <temporary table>
|
||||
the temporary table definition will be needed in slaves to
|
||||
enable the create to succeed
|
||||
*/
|
||||
TABLE_LIST tbl;
|
||||
bzero((void*) &tbl, sizeof(tbl));
|
||||
tbl.db= src_table->db;
|
||||
tbl.table_name= tbl.alias= src_table->table_name;
|
||||
tbl.table= tmp_table;
|
||||
char buf[2048];
|
||||
String query(buf, sizeof(buf), system_charset_info);
|
||||
query.length(0); // Have to zero it since constructor doesn't
|
||||
|
||||
(void) store_create_info(thd, &tbl, &query, NULL, TRUE, FALSE);
|
||||
WSREP_DEBUG("TMP TABLE: %s", query.ptr());
|
||||
|
||||
thd->wsrep_TOI_pre_query= query.ptr();
|
||||
thd->wsrep_TOI_pre_query_len= query.length();
|
||||
|
||||
WSREP_TO_ISOLATION_BEGIN(table->db, table->table_name, NULL);
|
||||
|
||||
thd->wsrep_TOI_pre_query= NULL;
|
||||
thd->wsrep_TOI_pre_query_len= 0;
|
||||
}
|
||||
}
|
||||
if (WSREP_ON && !thd->wsrep_applier &&
|
||||
wsrep_create_like_table(thd, table, src_table, create_info))
|
||||
goto end;
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
@ -5580,14 +5531,9 @@ err:
|
|||
thd->query_length(), is_trans))
|
||||
res= 1;
|
||||
}
|
||||
|
||||
end:
|
||||
DBUG_RETURN(res);
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
error:
|
||||
thd->wsrep_TOI_pre_query= NULL;
|
||||
DBUG_RETURN(TRUE);
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -8119,10 +8065,6 @@ simple_rename_or_index_change(THD *thd, TABLE_LIST *table_list,
|
|||
: HA_EXTRA_FORCE_REOPEN;
|
||||
DBUG_ENTER("simple_rename_or_index_change");
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
bool do_log_write(true);
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
if (keys_onoff != Alter_info::LEAVE_AS_IS)
|
||||
{
|
||||
if (wait_while_table_is_used(thd, table, extra_func))
|
||||
|
|
@ -8182,13 +8124,7 @@ simple_rename_or_index_change(THD *thd, TABLE_LIST *table_list,
|
|||
|
||||
if (!error)
|
||||
{
|
||||
#ifdef WITH_WSREP
|
||||
if (!WSREP(thd) || do_log_write) {
|
||||
#endif /* WITH_WSREP */
|
||||
error= write_bin_log(thd, TRUE, thd->query(), thd->query_length());
|
||||
#ifdef WITH_WSREP
|
||||
}
|
||||
#endif /* !WITH_WSREP */
|
||||
error= write_bin_log(thd, TRUE, thd->query(), thd->query_length());
|
||||
|
||||
if (!error)
|
||||
my_ok(thd);
|
||||
|
|
|
|||
|
|
@ -434,14 +434,9 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create)
|
|||
binlogged, so they share the same danger, so trust_function_creators
|
||||
applies to them too.
|
||||
*/
|
||||
#ifdef WITH_WSREP
|
||||
if (!trust_function_creators &&
|
||||
(WSREP_EMULATE_BINLOG(thd) || mysql_bin_log.is_open()) &&
|
||||
if (!trust_function_creators &&
|
||||
IF_WSREP((WSREP_EMULATE_BINLOG(thd) || mysql_bin_log.is_open()), mysql_bin_log.is_open()) &&
|
||||
!(thd->security_ctx->master_access & SUPER_ACL))
|
||||
#else
|
||||
if (!trust_function_creators && mysql_bin_log.is_open() &&
|
||||
!(thd->security_ctx->master_access & SUPER_ACL))
|
||||
#endif /* WITH_WSREP */
|
||||
{
|
||||
my_error(ER_BINLOG_CREATE_ROUTINE_NEED_SUPER, MYF(0));
|
||||
DBUG_RETURN(TRUE);
|
||||
|
|
@ -2443,55 +2438,4 @@ bool load_table_name_for_trigger(THD *thd,
|
|||
|
||||
DBUG_RETURN(FALSE);
|
||||
}
|
||||
#ifdef WITH_WSREP
|
||||
int wsrep_create_trigger_query(THD *thd, uchar** buf, size_t* buf_len)
|
||||
{
|
||||
LEX *lex= thd->lex;
|
||||
String stmt_query;
|
||||
|
||||
LEX_STRING definer_user;
|
||||
LEX_STRING definer_host;
|
||||
|
||||
if (!lex->definer)
|
||||
{
|
||||
if (!thd->slave_thread)
|
||||
{
|
||||
if (!(lex->definer= create_default_definer(thd, false)))
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (lex->definer)
|
||||
{
|
||||
/* SUID trigger. */
|
||||
|
||||
definer_user= lex->definer->user;
|
||||
definer_host= lex->definer->host;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* non-SUID trigger. */
|
||||
|
||||
definer_user.str= 0;
|
||||
definer_user.length= 0;
|
||||
|
||||
definer_host.str= 0;
|
||||
definer_host.length= 0;
|
||||
}
|
||||
|
||||
stmt_query.append(STRING_WITH_LEN("CREATE "));
|
||||
|
||||
append_definer(thd, &stmt_query, &definer_user, &definer_host);
|
||||
|
||||
LEX_STRING stmt_definition;
|
||||
stmt_definition.str= (char*) thd->lex->stmt_definition_begin;
|
||||
stmt_definition.length= thd->lex->stmt_definition_end
|
||||
- thd->lex->stmt_definition_begin;
|
||||
trim_whitespace(thd->charset(), & stmt_definition);
|
||||
|
||||
stmt_query.append(stmt_definition.str, stmt_definition.length);
|
||||
|
||||
return wsrep_to_buf_helper(thd, stmt_query.c_ptr(), stmt_query.length(),
|
||||
buf, buf_len);
|
||||
}
|
||||
#endif /* WITH_WSREP */
|
||||
|
|
|
|||
|
|
@ -24,9 +24,7 @@
|
|||
#include "sql_acl.h" // DROP_ACL
|
||||
#include "sql_parse.h" // check_one_table_access()
|
||||
#include "sql_truncate.h"
|
||||
#ifdef WITH_WSREP
|
||||
#include "wsrep_mysqld.h"
|
||||
#endif /* WITH_WSREP */
|
||||
#include "sql_show.h" //append_identifier()
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/* Copyright (c) 2000, 2013, Oracle and/or its affiliates.
|
||||
Copyright (c) 2011, 2013, Monty Program Ab.
|
||||
Copyright (c) 2011, 2014, Monty Program Ab.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -976,11 +976,8 @@ int mysql_update(THD *thd,
|
|||
*/
|
||||
if ((error < 0) || thd->transaction.stmt.modified_non_trans_table)
|
||||
{
|
||||
#ifdef WITH_WSREP
|
||||
if (WSREP_EMULATE_BINLOG(thd) || mysql_bin_log.is_open())
|
||||
#else
|
||||
if (mysql_bin_log.is_open())
|
||||
#endif
|
||||
if (IF_WSREP((WSREP_EMULATE_BINLOG(thd) || mysql_bin_log.is_open()),
|
||||
mysql_bin_log.is_open()))
|
||||
{
|
||||
int errcode= 0;
|
||||
if (error < 0)
|
||||
|
|
@ -2223,11 +2220,8 @@ void multi_update::abort_result_set()
|
|||
The query has to binlog because there's a modified non-transactional table
|
||||
either from the query's list or via a stored routine: bug#13270,23333
|
||||
*/
|
||||
#ifdef WITH_WSREP
|
||||
if (WSREP_EMULATE_BINLOG(thd) || mysql_bin_log.is_open())
|
||||
#else
|
||||
if (mysql_bin_log.is_open())
|
||||
#endif
|
||||
if (IF_WSREP((WSREP_EMULATE_BINLOG(thd) || mysql_bin_log.is_open()),
|
||||
mysql_bin_log.is_open()))
|
||||
{
|
||||
/*
|
||||
THD::killed status might not have been set ON at time of an error
|
||||
|
|
@ -2496,11 +2490,8 @@ bool multi_update::send_eof()
|
|||
|
||||
if (local_error == 0 || thd->transaction.stmt.modified_non_trans_table)
|
||||
{
|
||||
#ifdef WITH_WSREP
|
||||
if (WSREP_EMULATE_BINLOG(thd) || mysql_bin_log.is_open())
|
||||
#else
|
||||
if (mysql_bin_log.is_open())
|
||||
#endif
|
||||
if (IF_WSREP((WSREP_EMULATE_BINLOG(thd) || mysql_bin_log.is_open()),
|
||||
mysql_bin_log.is_open()))
|
||||
{
|
||||
int errcode= 0;
|
||||
if (local_error == 0)
|
||||
|
|
|
|||
|
|
@ -3338,9 +3338,7 @@ static bool fix_autocommit(sys_var *self, THD *thd, enum_var_type type)
|
|||
{
|
||||
thd->variables.option_bits&= ~OPTION_AUTOCOMMIT;
|
||||
thd->mdl_context.release_transactional_locks();
|
||||
#ifdef WITH_WSREP
|
||||
WSREP_DEBUG("autocommit, MDL TRX lock released: %lu", thd->thread_id);
|
||||
#endif /* WITH_WSREP */
|
||||
return true;
|
||||
}
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -40,9 +40,7 @@
|
|||
#include "sql_statistics.h"
|
||||
#include "discover.h"
|
||||
#include "mdl.h" // MDL_wait_for_graph_visitor
|
||||
#ifdef WITH_WSREP
|
||||
#include "ha_partition.h"
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
/* INFORMATION_SCHEMA name */
|
||||
LEX_STRING INFORMATION_SCHEMA_NAME= {C_STRING_WITH_LEN("information_schema")};
|
||||
|
|
|
|||
|
|
@ -98,7 +98,8 @@ static bool xa_trans_force_rollback(THD *thd)
|
|||
*/
|
||||
thd->transaction.xid_state.rm_error= 0;
|
||||
#ifdef WITH_WSREP
|
||||
wsrep_register_hton(thd, TRUE);
|
||||
if (WSREP_ON)
|
||||
wsrep_register_hton(thd, TRUE);
|
||||
#endif /* WITH_WSREP */
|
||||
if (ha_rollback_trans(thd, true))
|
||||
{
|
||||
|
|
@ -139,14 +140,16 @@ bool trans_begin(THD *thd, uint flags)
|
|||
{
|
||||
thd->variables.option_bits&= ~OPTION_TABLE_LOCK;
|
||||
#ifdef WITH_WSREP
|
||||
wsrep_register_hton(thd, TRUE);
|
||||
if (WSREP_ON)
|
||||
wsrep_register_hton(thd, TRUE);
|
||||
#endif /* WITH_WSREP */
|
||||
thd->server_status&=
|
||||
~(SERVER_STATUS_IN_TRANS | SERVER_STATUS_IN_TRANS_READONLY);
|
||||
DBUG_PRINT("info", ("clearing SERVER_STATUS_IN_TRANS"));
|
||||
res= MY_TEST(ha_commit_trans(thd, TRUE));
|
||||
#ifdef WITH_WSREP
|
||||
wsrep_post_commit(thd, TRUE);
|
||||
if (WSREP_ON)
|
||||
wsrep_post_commit(thd, TRUE);
|
||||
#endif /* WITH_WSREP */
|
||||
}
|
||||
|
||||
|
|
@ -228,14 +231,16 @@ bool trans_commit(THD *thd)
|
|||
DBUG_RETURN(TRUE);
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
wsrep_register_hton(thd, TRUE);
|
||||
if (WSREP_ON)
|
||||
wsrep_register_hton(thd, TRUE);
|
||||
#endif /* WITH_WSREP */
|
||||
thd->server_status&=
|
||||
~(SERVER_STATUS_IN_TRANS | SERVER_STATUS_IN_TRANS_READONLY);
|
||||
DBUG_PRINT("info", ("clearing SERVER_STATUS_IN_TRANS"));
|
||||
res= ha_commit_trans(thd, TRUE);
|
||||
#ifdef WITH_WSREP
|
||||
wsrep_post_commit(thd, TRUE);
|
||||
if (WSREP_ON)
|
||||
wsrep_post_commit(thd, TRUE);
|
||||
#endif /* WITH_WSREP */
|
||||
/*
|
||||
if res is non-zero, then ha_commit_trans has rolled back the
|
||||
|
|
@ -283,14 +288,16 @@ bool trans_commit_implicit(THD *thd)
|
|||
if (!thd->locked_tables_mode)
|
||||
thd->variables.option_bits&= ~OPTION_TABLE_LOCK;
|
||||
#ifdef WITH_WSREP
|
||||
wsrep_register_hton(thd, TRUE);
|
||||
if (WSREP_ON)
|
||||
wsrep_register_hton(thd, TRUE);
|
||||
#endif /* WITH_WSREP */
|
||||
thd->server_status&=
|
||||
~(SERVER_STATUS_IN_TRANS | SERVER_STATUS_IN_TRANS_READONLY);
|
||||
DBUG_PRINT("info", ("clearing SERVER_STATUS_IN_TRANS"));
|
||||
res= MY_TEST(ha_commit_trans(thd, TRUE));
|
||||
#ifdef WITH_WSREP
|
||||
wsrep_post_commit(thd, TRUE);
|
||||
if (WSREP_ON)
|
||||
wsrep_post_commit(thd, TRUE);
|
||||
#endif /* WITH_WSREP */
|
||||
}
|
||||
|
||||
|
|
@ -331,7 +338,8 @@ bool trans_rollback(THD *thd)
|
|||
DBUG_RETURN(TRUE);
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
wsrep_register_hton(thd, TRUE);
|
||||
if (WSREP_ON)
|
||||
wsrep_register_hton(thd, TRUE);
|
||||
#endif /* WITH_WSREP */
|
||||
thd->server_status&=
|
||||
~(SERVER_STATUS_IN_TRANS | SERVER_STATUS_IN_TRANS_READONLY);
|
||||
|
|
@ -424,7 +432,8 @@ bool trans_commit_stmt(THD *thd)
|
|||
if (thd->transaction.stmt.ha_list)
|
||||
{
|
||||
#ifdef WITH_WSREP
|
||||
wsrep_register_hton(thd, FALSE);
|
||||
if (WSREP_ON)
|
||||
wsrep_register_hton(thd, FALSE);
|
||||
#endif /* WITH_WSREP */
|
||||
res= ha_commit_trans(thd, FALSE);
|
||||
if (! thd->in_active_multi_stmt_transaction())
|
||||
|
|
@ -432,7 +441,8 @@ bool trans_commit_stmt(THD *thd)
|
|||
thd->tx_isolation= (enum_tx_isolation) thd->variables.tx_isolation;
|
||||
thd->tx_read_only= thd->variables.tx_read_only;
|
||||
#ifdef WITH_WSREP
|
||||
wsrep_post_commit(thd, FALSE);
|
||||
if (WSREP_ON)
|
||||
wsrep_post_commit(thd, FALSE);
|
||||
#endif /* WITH_WSREP */
|
||||
}
|
||||
}
|
||||
|
|
@ -475,7 +485,8 @@ bool trans_rollback_stmt(THD *thd)
|
|||
if (thd->transaction.stmt.ha_list)
|
||||
{
|
||||
#ifdef WITH_WSREP
|
||||
wsrep_register_hton(thd, FALSE);
|
||||
if (WSREP_ON)
|
||||
wsrep_register_hton(thd, FALSE);
|
||||
#endif /* WITH_WSREP */
|
||||
ha_rollback_trans(thd, FALSE);
|
||||
if (! thd->in_active_multi_stmt_transaction())
|
||||
|
|
@ -855,13 +866,15 @@ bool trans_xa_commit(THD *thd)
|
|||
else if (xa_state == XA_IDLE && thd->lex->xa_opt == XA_ONE_PHASE)
|
||||
{
|
||||
#ifdef WITH_WSREP
|
||||
wsrep_register_hton(thd, TRUE);
|
||||
if (WSREP_ON)
|
||||
wsrep_register_hton(thd, TRUE);
|
||||
#endif /* WITH_WSREP */
|
||||
int r= ha_commit_trans(thd, TRUE);
|
||||
if ((res= MY_TEST(r)))
|
||||
my_error(r == 1 ? ER_XA_RBROLLBACK : ER_XAER_RMERR, MYF(0));
|
||||
#ifdef WITH_WSREP
|
||||
wsrep_post_commit(thd, TRUE);
|
||||
if (WSREP_ON)
|
||||
wsrep_post_commit(thd, TRUE);
|
||||
#endif /* WITH_WSREP */
|
||||
}
|
||||
else if (xa_state == XA_PREPARED && thd->lex->xa_opt == XA_NONE)
|
||||
|
|
@ -882,7 +895,8 @@ bool trans_xa_commit(THD *thd)
|
|||
thd->variables.lock_wait_timeout))
|
||||
{
|
||||
#ifdef WITH_WSREP
|
||||
wsrep_register_hton(thd, TRUE);
|
||||
if (WSREP_ON)
|
||||
wsrep_register_hton(thd, TRUE);
|
||||
#endif /* WITH_WSREP */
|
||||
ha_rollback_trans(thd, TRUE);
|
||||
my_error(ER_XAER_RMERR, MYF(0));
|
||||
|
|
|
|||
|
|
@ -2711,7 +2711,8 @@ main(int argc, char **argv)
|
|||
|
||||
#ifdef WITH_WSREP
|
||||
// Replicate MyISAM DDL for this session, cf. lp:1161432
|
||||
printf("SET GLOBAL wsrep_replicate_myisam= ON;\n");
|
||||
// timezone info unfixable in XtraDB Cluster
|
||||
printf("SET GLOBAL wsrep_replicate_myisam= ON;\n");
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
if (argc == 1 && !opt_leap)
|
||||
|
|
|
|||
|
|
@ -15,7 +15,9 @@
|
|||
|
||||
#include "wsrep_binlog.h"
|
||||
#include "wsrep_priv.h"
|
||||
#include "log.h"
|
||||
|
||||
extern handlerton *binlog_hton;
|
||||
/*
|
||||
Write the contents of a cache to a memory buffer.
|
||||
|
||||
|
|
@ -320,7 +322,6 @@ void wsrep_dump_rbr_buf(THD *thd, const void* rbr_buf, size_t buf_len)
|
|||
filename, errno, strerror(errno));
|
||||
}
|
||||
}
|
||||
extern handlerton *binlog_hton;
|
||||
|
||||
/*
|
||||
wsrep exploits binlog's caches even if binlogging itself is not
|
||||
|
|
@ -406,3 +407,8 @@ cleanup:
|
|||
// close file
|
||||
if (of) fclose(of);
|
||||
}
|
||||
|
||||
void thd_binlog_flush_pending_rows_event(THD *thd, bool stmt_end)
|
||||
{
|
||||
thd->binlog_flush_pending_rows_event(stmt_end);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -539,7 +539,7 @@ static int wsrep_hton_init(void *p)
|
|||
wsrep_hton= (handlerton *)p;
|
||||
//wsrep_hton->state=opt_bin_log ? SHOW_OPTION_YES : SHOW_OPTION_NO;
|
||||
wsrep_hton->state= SHOW_OPTION_YES;
|
||||
wsrep_hton->db_type=DB_TYPE_WSREP;
|
||||
wsrep_hton->db_type=(legacy_db_type)0;
|
||||
wsrep_hton->savepoint_offset= sizeof(my_off_t);
|
||||
wsrep_hton->close_connection= wsrep_close_connection;
|
||||
wsrep_hton->savepoint_set= wsrep_savepoint_set;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright 2008-2013 Codership Oy <http://www.codership.com>
|
||||
/* Copyright 2008-2014 Codership Oy <http://www.codership.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -16,6 +16,13 @@
|
|||
#include <mysqld.h>
|
||||
#include <sql_class.h>
|
||||
#include <sql_parse.h>
|
||||
#include "slave.h"
|
||||
#include "rpl_mi.h"
|
||||
#include "sql_repl.h"
|
||||
#include "rpl_filter.h"
|
||||
#include "sql_callback.h"
|
||||
#include "sp_head.h"
|
||||
#include "sp.h"
|
||||
#include "wsrep_priv.h"
|
||||
#include "wsrep_thd.h"
|
||||
#include "wsrep_sst.h"
|
||||
|
|
@ -40,6 +47,13 @@ my_bool wsrep_preordered_opt= FALSE;
|
|||
* Begin configuration options and their default values
|
||||
*/
|
||||
|
||||
extern int wsrep_replaying;
|
||||
extern ulong wsrep_running_threads;
|
||||
extern ulong my_bind_addr;
|
||||
extern my_bool plugins_are_initialized;
|
||||
extern uint kill_cached_threads;
|
||||
extern mysql_cond_t COND_thread_cache;
|
||||
|
||||
const char* wsrep_data_home_dir = NULL;
|
||||
const char* wsrep_dbug_option = "";
|
||||
|
||||
|
|
@ -1292,7 +1306,7 @@ static int wsrep_TOI_begin(THD *thd, char *db_, char *table_,
|
|||
{
|
||||
thd->wsrep_exec_mode= TOTAL_ORDER;
|
||||
wsrep_to_isolation++;
|
||||
if (buf) my_free(buf);
|
||||
my_free(buf);
|
||||
wsrep_keys_free(&key_arr);
|
||||
WSREP_DEBUG("TO BEGIN: %lld, %d",(long long)wsrep_thd_trx_seqno(thd),
|
||||
thd->wsrep_exec_mode);
|
||||
|
|
@ -1407,13 +1421,14 @@ static void wsrep_RSU_end(THD *thd)
|
|||
int wsrep_to_isolation_begin(THD *thd, char *db_, char *table_,
|
||||
const TABLE_LIST* table_list)
|
||||
{
|
||||
int ret= 0;
|
||||
|
||||
/*
|
||||
No isolation for applier or replaying threads.
|
||||
*/
|
||||
if (thd->wsrep_exec_mode == REPL_RECV) return 0;
|
||||
if (thd->wsrep_exec_mode == REPL_RECV)
|
||||
return 0;
|
||||
|
||||
int ret= 0;
|
||||
mysql_mutex_lock(&thd->LOCK_wsrep_thd);
|
||||
|
||||
if (thd->wsrep_conflict_state == MUST_ABORT)
|
||||
|
|
@ -1501,8 +1516,8 @@ wsrep_grant_mdl_exception(MDL_context *requestor_ctx,
|
|||
) {
|
||||
if (!WSREP_ON) return FALSE;
|
||||
|
||||
THD *request_thd = requestor_ctx->wsrep_get_thd();
|
||||
THD *granted_thd = ticket->get_ctx()->wsrep_get_thd();
|
||||
THD *request_thd = requestor_ctx->get_thd();
|
||||
THD *granted_thd = ticket->get_ctx()->get_thd();
|
||||
bool ret = FALSE;
|
||||
|
||||
mysql_mutex_lock(&request_thd->LOCK_wsrep_thd);
|
||||
|
|
@ -1560,3 +1575,856 @@ wsrep_grant_mdl_exception(MDL_context *requestor_ctx,
|
|||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
pthread_handler_t start_wsrep_THD(void *arg)
|
||||
{
|
||||
THD *thd;
|
||||
rpl_sql_thread_info sql_info(NULL);
|
||||
wsrep_thd_processor_fun processor= (wsrep_thd_processor_fun)arg;
|
||||
|
||||
if (my_thread_init())
|
||||
{
|
||||
WSREP_ERROR("Could not initialize thread");
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
if (!(thd= new THD(true)))
|
||||
{
|
||||
return(NULL);
|
||||
}
|
||||
mysql_mutex_lock(&LOCK_thread_count);
|
||||
thd->thread_id=thread_id++;
|
||||
|
||||
thd->real_id=pthread_self(); // Keep purify happy
|
||||
thread_count++;
|
||||
thread_created++;
|
||||
threads.append(thd);
|
||||
|
||||
my_net_init(&thd->net,(st_vio*) 0, MYF(0));
|
||||
|
||||
DBUG_PRINT("wsrep",(("creating thread %lld"), (long long)thd->thread_id));
|
||||
thd->prior_thr_create_utime= thd->start_utime= microsecond_interval_timer();
|
||||
(void) mysql_mutex_unlock(&LOCK_thread_count);
|
||||
|
||||
/* from bootstrap()... */
|
||||
thd->bootstrap=1;
|
||||
thd->max_client_packet_length= thd->net.max_packet;
|
||||
thd->security_ctx->master_access= ~(ulong)0;
|
||||
thd->system_thread_info.rpl_sql_info= &sql_info;
|
||||
|
||||
/* from handle_one_connection... */
|
||||
pthread_detach_this_thread();
|
||||
|
||||
mysql_thread_set_psi_id(thd->thread_id);
|
||||
thd->thr_create_utime= microsecond_interval_timer();
|
||||
if (MYSQL_CALLBACK_ELSE(thread_scheduler, init_new_connection_thread, (), 0))
|
||||
{
|
||||
close_connection(thd, ER_OUT_OF_RESOURCES);
|
||||
statistic_increment(aborted_connects,&LOCK_status);
|
||||
MYSQL_CALLBACK(thread_scheduler, end_thread, (thd, 0));
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
// </5.1.17>
|
||||
/*
|
||||
handle_one_connection() is normally the only way a thread would
|
||||
start and would always be on the very high end of the stack ,
|
||||
therefore, the thread stack always starts at the address of the
|
||||
first local variable of handle_one_connection, which is thd. We
|
||||
need to know the start of the stack so that we could check for
|
||||
stack overruns.
|
||||
*/
|
||||
DBUG_PRINT("wsrep", ("handle_one_connection called by thread %lld\n",
|
||||
(long long)thd->thread_id));
|
||||
/* now that we've called my_thread_init(), it is safe to call DBUG_* */
|
||||
|
||||
thd->thread_stack= (char*) &thd;
|
||||
if (thd->store_globals())
|
||||
{
|
||||
close_connection(thd, ER_OUT_OF_RESOURCES);
|
||||
statistic_increment(aborted_connects,&LOCK_status);
|
||||
MYSQL_CALLBACK(thread_scheduler, end_thread, (thd, 0));
|
||||
delete thd;
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
thd->system_thread= SYSTEM_THREAD_SLAVE_SQL;
|
||||
thd->security_ctx->skip_grants();
|
||||
|
||||
/* handle_one_connection() again... */
|
||||
//thd->version= refresh_version;
|
||||
thd->proc_info= 0;
|
||||
thd->set_command(COM_SLEEP);
|
||||
thd->set_time();
|
||||
thd->init_for_queries();
|
||||
|
||||
mysql_mutex_lock(&LOCK_thread_count);
|
||||
wsrep_running_threads++;
|
||||
mysql_cond_broadcast(&COND_thread_count);
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
|
||||
processor(thd);
|
||||
|
||||
close_connection(thd, 0);
|
||||
|
||||
mysql_mutex_lock(&LOCK_thread_count);
|
||||
wsrep_running_threads--;
|
||||
WSREP_DEBUG("wsrep running threads now: %lu", wsrep_running_threads);
|
||||
mysql_cond_broadcast(&COND_thread_count);
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
|
||||
// Note: We can't call THD destructor without crashing
|
||||
// if plugins have not been initialized. However, in most of the
|
||||
// cases this means that pre SE initialization SST failed and
|
||||
// we are going to exit anyway.
|
||||
if (plugins_are_initialized)
|
||||
{
|
||||
net_end(&thd->net);
|
||||
MYSQL_CALLBACK(thread_scheduler, end_thread, (thd, 1));
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: lightweight cleanup to get rid of:
|
||||
// 'Error in my_thread_global_end(): 2 threads didn't exit'
|
||||
// at server shutdown
|
||||
}
|
||||
|
||||
my_thread_end();
|
||||
if (thread_handling > SCHEDULER_ONE_THREAD_PER_CONNECTION)
|
||||
{
|
||||
mysql_mutex_lock(&LOCK_thread_count);
|
||||
delete thd;
|
||||
thread_count--;
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
}
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
|
||||
/**/
|
||||
static bool abort_replicated(THD *thd)
|
||||
{
|
||||
bool ret_code= false;
|
||||
if (thd->wsrep_query_state== QUERY_COMMITTING)
|
||||
{
|
||||
if (wsrep_debug) WSREP_INFO("aborting replicated trx: %lu", thd->real_id);
|
||||
|
||||
(void)wsrep_abort_thd(thd, thd, TRUE);
|
||||
ret_code= true;
|
||||
}
|
||||
return ret_code;
|
||||
}
|
||||
|
||||
|
||||
/**/
|
||||
static inline bool is_client_connection(THD *thd)
|
||||
{
|
||||
return (thd->wsrep_client_thread && thd->variables.wsrep_on);
|
||||
}
|
||||
|
||||
|
||||
static inline bool is_replaying_connection(THD *thd)
|
||||
{
|
||||
bool ret;
|
||||
|
||||
mysql_mutex_lock(&thd->LOCK_wsrep_thd);
|
||||
ret= (thd->wsrep_conflict_state == REPLAYING) ? true : false;
|
||||
mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static inline bool is_committing_connection(THD *thd)
|
||||
{
|
||||
bool ret;
|
||||
|
||||
mysql_mutex_lock(&thd->LOCK_wsrep_thd);
|
||||
ret= (thd->wsrep_query_state == QUERY_COMMITTING) ? true : false;
|
||||
mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static bool have_client_connections()
|
||||
{
|
||||
THD *tmp;
|
||||
|
||||
I_List_iterator<THD> it(threads);
|
||||
while ((tmp=it++))
|
||||
{
|
||||
DBUG_PRINT("quit",("Informing thread %ld that it's time to die",
|
||||
tmp->thread_id));
|
||||
if (is_client_connection(tmp) && tmp->killed == KILL_CONNECTION)
|
||||
{
|
||||
(void)abort_replicated(tmp);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
returns the number of wsrep appliers running.
|
||||
However, the caller (thd parameter) is not taken in account
|
||||
*/
|
||||
static int have_wsrep_appliers(THD *thd)
|
||||
{
|
||||
int ret= 0;
|
||||
THD *tmp;
|
||||
|
||||
I_List_iterator<THD> it(threads);
|
||||
while ((tmp=it++))
|
||||
{
|
||||
ret+= (tmp != thd && tmp->wsrep_applier);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void wsrep_close_thread(THD *thd)
|
||||
{
|
||||
thd->killed= KILL_CONNECTION;
|
||||
MYSQL_CALLBACK(thread_scheduler, post_kill_notification, (thd));
|
||||
if (thd->mysys_var)
|
||||
{
|
||||
thd->mysys_var->abort=1;
|
||||
mysql_mutex_lock(&thd->mysys_var->mutex);
|
||||
if (thd->mysys_var->current_cond)
|
||||
{
|
||||
mysql_mutex_lock(thd->mysys_var->current_mutex);
|
||||
mysql_cond_broadcast(thd->mysys_var->current_cond);
|
||||
mysql_mutex_unlock(thd->mysys_var->current_mutex);
|
||||
}
|
||||
mysql_mutex_unlock(&thd->mysys_var->mutex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static my_bool have_committing_connections()
|
||||
{
|
||||
THD *tmp;
|
||||
mysql_mutex_lock(&LOCK_thread_count); // For unlink from list
|
||||
|
||||
I_List_iterator<THD> it(threads);
|
||||
while ((tmp=it++))
|
||||
{
|
||||
if (!is_client_connection(tmp))
|
||||
continue;
|
||||
|
||||
if (is_committing_connection(tmp))
|
||||
{
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
int wsrep_wait_committing_connections_close(int wait_time)
|
||||
{
|
||||
int sleep_time= 100;
|
||||
|
||||
while (have_committing_connections() && wait_time > 0)
|
||||
{
|
||||
WSREP_DEBUG("wait for committing transaction to close: %d", wait_time);
|
||||
my_sleep(sleep_time);
|
||||
wait_time -= sleep_time;
|
||||
}
|
||||
if (have_committing_connections())
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void wsrep_close_client_connections(my_bool wait_to_end)
|
||||
{
|
||||
/*
|
||||
First signal all threads that it's time to die
|
||||
*/
|
||||
|
||||
THD *tmp;
|
||||
mysql_mutex_lock(&LOCK_thread_count); // For unlink from list
|
||||
|
||||
bool kill_cached_threads_saved= kill_cached_threads;
|
||||
kill_cached_threads= true; // prevent future threads caching
|
||||
mysql_cond_broadcast(&COND_thread_cache); // tell cached threads to die
|
||||
|
||||
I_List_iterator<THD> it(threads);
|
||||
while ((tmp=it++))
|
||||
{
|
||||
DBUG_PRINT("quit",("Informing thread %ld that it's time to die",
|
||||
tmp->thread_id));
|
||||
/* We skip slave threads & scheduler on this first loop through. */
|
||||
if (!is_client_connection(tmp))
|
||||
continue;
|
||||
|
||||
if (is_replaying_connection(tmp))
|
||||
{
|
||||
tmp->killed= KILL_CONNECTION;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* replicated transactions must be skipped */
|
||||
if (abort_replicated(tmp))
|
||||
continue;
|
||||
|
||||
WSREP_DEBUG("closing connection %ld", tmp->thread_id);
|
||||
wsrep_close_thread(tmp);
|
||||
}
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
|
||||
if (thread_count)
|
||||
sleep(2); // Give threads time to die
|
||||
|
||||
mysql_mutex_lock(&LOCK_thread_count);
|
||||
/*
|
||||
Force remaining threads to die by closing the connection to the client
|
||||
*/
|
||||
|
||||
I_List_iterator<THD> it2(threads);
|
||||
while ((tmp=it2++))
|
||||
{
|
||||
#ifndef __bsdi__ // Bug in BSDI kernel
|
||||
if (is_client_connection(tmp) &&
|
||||
!abort_replicated(tmp) &&
|
||||
!is_replaying_connection(tmp))
|
||||
{
|
||||
WSREP_INFO("killing local connection: %ld",tmp->thread_id);
|
||||
close_connection(tmp,0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
DBUG_PRINT("quit",("Waiting for threads to die (count=%u)",thread_count));
|
||||
if (wsrep_debug)
|
||||
WSREP_INFO("waiting for client connections to close: %u", thread_count);
|
||||
|
||||
while (wait_to_end && have_client_connections())
|
||||
{
|
||||
mysql_cond_wait(&COND_thread_count, &LOCK_thread_count);
|
||||
DBUG_PRINT("quit",("One thread died (count=%u)", thread_count));
|
||||
}
|
||||
|
||||
kill_cached_threads= kill_cached_threads_saved;
|
||||
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
|
||||
/* All client connection threads have now been aborted */
|
||||
}
|
||||
|
||||
|
||||
void wsrep_close_applier(THD *thd)
|
||||
{
|
||||
WSREP_DEBUG("closing applier %ld", thd->thread_id);
|
||||
wsrep_close_thread(thd);
|
||||
}
|
||||
|
||||
|
||||
void wsrep_close_threads(THD *thd)
|
||||
{
|
||||
THD *tmp;
|
||||
mysql_mutex_lock(&LOCK_thread_count); // For unlink from list
|
||||
|
||||
I_List_iterator<THD> it(threads);
|
||||
while ((tmp=it++))
|
||||
{
|
||||
DBUG_PRINT("quit",("Informing thread %ld that it's time to die",
|
||||
tmp->thread_id));
|
||||
/* We skip slave threads & scheduler on this first loop through. */
|
||||
if (tmp->wsrep_applier && tmp != thd)
|
||||
{
|
||||
WSREP_DEBUG("closing wsrep thread %ld", tmp->thread_id);
|
||||
wsrep_close_thread (tmp);
|
||||
}
|
||||
}
|
||||
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
}
|
||||
|
||||
|
||||
void wsrep_close_applier_threads(int count)
|
||||
{
|
||||
THD *tmp;
|
||||
mysql_mutex_lock(&LOCK_thread_count); // For unlink from list
|
||||
|
||||
I_List_iterator<THD> it(threads);
|
||||
while ((tmp=it++) && count)
|
||||
{
|
||||
DBUG_PRINT("quit",("Informing thread %ld that it's time to die",
|
||||
tmp->thread_id));
|
||||
/* We skip slave threads & scheduler on this first loop through. */
|
||||
if (tmp->wsrep_applier)
|
||||
{
|
||||
WSREP_DEBUG("closing wsrep applier thread %ld", tmp->thread_id);
|
||||
tmp->wsrep_applier_closing= TRUE;
|
||||
count--;
|
||||
}
|
||||
}
|
||||
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
}
|
||||
|
||||
|
||||
void wsrep_wait_appliers_close(THD *thd)
|
||||
{
|
||||
/* Wait for wsrep appliers to gracefully exit */
|
||||
mysql_mutex_lock(&LOCK_thread_count);
|
||||
while (have_wsrep_appliers(thd) > 1)
|
||||
// 1 is for rollbacker thread which needs to be killed explicitly.
|
||||
// This gotta be fixed in a more elegant manner if we gonna have arbitrary
|
||||
// number of non-applier wsrep threads.
|
||||
{
|
||||
if (thread_handling > SCHEDULER_ONE_THREAD_PER_CONNECTION)
|
||||
{
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
my_sleep(100);
|
||||
mysql_mutex_lock(&LOCK_thread_count);
|
||||
}
|
||||
else
|
||||
mysql_cond_wait(&COND_thread_count,&LOCK_thread_count);
|
||||
DBUG_PRINT("quit",("One applier died (count=%u)",thread_count));
|
||||
}
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
/* Now kill remaining wsrep threads: rollbacker */
|
||||
wsrep_close_threads (thd);
|
||||
/* and wait for them to die */
|
||||
mysql_mutex_lock(&LOCK_thread_count);
|
||||
while (have_wsrep_appliers(thd) > 0)
|
||||
{
|
||||
if (thread_handling > SCHEDULER_ONE_THREAD_PER_CONNECTION)
|
||||
{
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
my_sleep(100);
|
||||
mysql_mutex_lock(&LOCK_thread_count);
|
||||
}
|
||||
else
|
||||
mysql_cond_wait(&COND_thread_count,&LOCK_thread_count);
|
||||
DBUG_PRINT("quit",("One thread died (count=%u)",thread_count));
|
||||
}
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
|
||||
/* All wsrep applier threads have now been aborted. However, if this thread
|
||||
is also applier, we are still running...
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
void wsrep_kill_mysql(THD *thd)
|
||||
{
|
||||
if (mysqld_server_started)
|
||||
{
|
||||
if (!shutdown_in_progress)
|
||||
{
|
||||
WSREP_INFO("starting shutdown");
|
||||
kill_mysql();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
unireg_abort(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int wsrep_create_sp(THD *thd, uchar** buf, size_t* buf_len)
|
||||
{
|
||||
String log_query;
|
||||
sp_head *sp = thd->lex->sphead;
|
||||
ulong saved_mode= thd->variables.sql_mode;
|
||||
String retstr(64);
|
||||
retstr.set_charset(system_charset_info);
|
||||
|
||||
log_query.set_charset(system_charset_info);
|
||||
|
||||
if (sp->m_type == TYPE_ENUM_FUNCTION)
|
||||
{
|
||||
sp_returns_type(thd, retstr, sp);
|
||||
}
|
||||
|
||||
if (!create_string(thd, &log_query,
|
||||
sp->m_type,
|
||||
(sp->m_explicit_name ? sp->m_db.str : NULL),
|
||||
(sp->m_explicit_name ? sp->m_db.length : 0),
|
||||
sp->m_name.str, sp->m_name.length,
|
||||
sp->m_params.str, sp->m_params.length,
|
||||
retstr.c_ptr(), retstr.length(),
|
||||
sp->m_body.str, sp->m_body.length,
|
||||
sp->m_chistics, &(thd->lex->definer->user),
|
||||
&(thd->lex->definer->host),
|
||||
saved_mode))
|
||||
{
|
||||
WSREP_WARN("SP create string failed: %s", thd->query());
|
||||
return 1;
|
||||
}
|
||||
|
||||
return wsrep_to_buf_helper(thd, log_query.ptr(), log_query.length(), buf, buf_len);
|
||||
}
|
||||
|
||||
|
||||
extern int wsrep_on(void *thd)
|
||||
{
|
||||
return (int)(WSREP(((THD*)thd)));
|
||||
}
|
||||
|
||||
|
||||
extern "C" bool wsrep_thd_is_wsrep_on(THD *thd)
|
||||
{
|
||||
return thd->variables.wsrep_on;
|
||||
}
|
||||
|
||||
|
||||
extern "C" bool wsrep_consistency_check(void *thd)
|
||||
{
|
||||
return ((THD*)thd)->wsrep_consistency_check == CONSISTENCY_CHECK_RUNNING;
|
||||
}
|
||||
|
||||
|
||||
extern "C" void wsrep_thd_set_exec_mode(THD *thd, enum wsrep_exec_mode mode)
|
||||
{
|
||||
thd->wsrep_exec_mode= mode;
|
||||
}
|
||||
|
||||
|
||||
extern "C" void wsrep_thd_set_query_state(
|
||||
THD *thd, enum wsrep_query_state state)
|
||||
{
|
||||
thd->wsrep_query_state= state;
|
||||
}
|
||||
|
||||
|
||||
extern "C" void wsrep_thd_set_conflict_state(
|
||||
THD *thd, enum wsrep_conflict_state state)
|
||||
{
|
||||
thd->wsrep_conflict_state= state;
|
||||
}
|
||||
|
||||
|
||||
extern "C" enum wsrep_exec_mode wsrep_thd_exec_mode(THD *thd)
|
||||
{
|
||||
return thd->wsrep_exec_mode;
|
||||
}
|
||||
|
||||
|
||||
extern "C" const char *wsrep_thd_exec_mode_str(THD *thd)
|
||||
{
|
||||
return
|
||||
(!thd) ? "void" :
|
||||
(thd->wsrep_exec_mode == LOCAL_STATE) ? "local" :
|
||||
(thd->wsrep_exec_mode == REPL_RECV) ? "applier" :
|
||||
(thd->wsrep_exec_mode == TOTAL_ORDER) ? "total order" :
|
||||
(thd->wsrep_exec_mode == LOCAL_COMMIT) ? "local commit" : "void";
|
||||
}
|
||||
|
||||
|
||||
extern "C" enum wsrep_query_state wsrep_thd_query_state(THD *thd)
|
||||
{
|
||||
return thd->wsrep_query_state;
|
||||
}
|
||||
|
||||
|
||||
extern "C" const char *wsrep_thd_query_state_str(THD *thd)
|
||||
{
|
||||
return
|
||||
(!thd) ? "void" :
|
||||
(thd->wsrep_query_state == QUERY_IDLE) ? "idle" :
|
||||
(thd->wsrep_query_state == QUERY_EXEC) ? "executing" :
|
||||
(thd->wsrep_query_state == QUERY_COMMITTING) ? "committing" :
|
||||
(thd->wsrep_query_state == QUERY_EXITING) ? "exiting" :
|
||||
(thd->wsrep_query_state == QUERY_ROLLINGBACK) ? "rolling back" : "void";
|
||||
}
|
||||
|
||||
|
||||
extern "C" enum wsrep_conflict_state wsrep_thd_conflict_state(THD *thd)
|
||||
{
|
||||
return thd->wsrep_conflict_state;
|
||||
}
|
||||
|
||||
|
||||
extern "C" const char *wsrep_thd_conflict_state_str(THD *thd)
|
||||
{
|
||||
return
|
||||
(!thd) ? "void" :
|
||||
(thd->wsrep_conflict_state == NO_CONFLICT) ? "no conflict" :
|
||||
(thd->wsrep_conflict_state == MUST_ABORT) ? "must abort" :
|
||||
(thd->wsrep_conflict_state == ABORTING) ? "aborting" :
|
||||
(thd->wsrep_conflict_state == MUST_REPLAY) ? "must replay" :
|
||||
(thd->wsrep_conflict_state == REPLAYING) ? "replaying" :
|
||||
(thd->wsrep_conflict_state == RETRY_AUTOCOMMIT) ? "retrying" :
|
||||
(thd->wsrep_conflict_state == CERT_FAILURE) ? "cert failure" : "void";
|
||||
}
|
||||
|
||||
|
||||
extern "C" wsrep_ws_handle_t* wsrep_thd_ws_handle(THD *thd)
|
||||
{
|
||||
return &thd->wsrep_ws_handle;
|
||||
}
|
||||
|
||||
|
||||
extern "C" void wsrep_thd_LOCK(THD *thd)
|
||||
{
|
||||
mysql_mutex_lock(&thd->LOCK_wsrep_thd);
|
||||
}
|
||||
|
||||
|
||||
extern "C" void wsrep_thd_UNLOCK(THD *thd)
|
||||
{
|
||||
mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
|
||||
}
|
||||
|
||||
|
||||
extern "C" time_t wsrep_thd_query_start(THD *thd)
|
||||
{
|
||||
return thd->query_start();
|
||||
}
|
||||
|
||||
|
||||
extern "C" uint32 wsrep_thd_wsrep_rand(THD *thd)
|
||||
{
|
||||
return thd->wsrep_rand;
|
||||
}
|
||||
|
||||
|
||||
extern "C" my_thread_id wsrep_thd_thread_id(THD *thd)
|
||||
{
|
||||
return thd->thread_id;
|
||||
}
|
||||
|
||||
|
||||
extern "C" wsrep_seqno_t wsrep_thd_trx_seqno(THD *thd)
|
||||
{
|
||||
return (thd) ? thd->wsrep_trx_meta.gtid.seqno : WSREP_SEQNO_UNDEFINED;
|
||||
}
|
||||
|
||||
|
||||
extern "C" query_id_t wsrep_thd_query_id(THD *thd)
|
||||
{
|
||||
return thd->query_id;
|
||||
}
|
||||
|
||||
|
||||
extern "C" char *wsrep_thd_query(THD *thd)
|
||||
{
|
||||
return (thd) ? thd->query() : NULL;
|
||||
}
|
||||
|
||||
|
||||
extern "C" query_id_t wsrep_thd_wsrep_last_query_id(THD *thd)
|
||||
{
|
||||
return thd->wsrep_last_query_id;
|
||||
}
|
||||
|
||||
|
||||
extern "C" void wsrep_thd_set_wsrep_last_query_id(THD *thd, query_id_t id)
|
||||
{
|
||||
thd->wsrep_last_query_id= id;
|
||||
}
|
||||
|
||||
|
||||
extern "C" void wsrep_thd_awake(THD *thd, my_bool signal)
|
||||
{
|
||||
if (signal)
|
||||
{
|
||||
mysql_mutex_lock(&thd->LOCK_thd_data);
|
||||
thd->awake(KILL_QUERY);
|
||||
mysql_mutex_unlock(&thd->LOCK_thd_data);
|
||||
}
|
||||
else
|
||||
{
|
||||
mysql_mutex_lock(&LOCK_wsrep_replaying);
|
||||
mysql_cond_broadcast(&COND_wsrep_replaying);
|
||||
mysql_mutex_unlock(&LOCK_wsrep_replaying);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
extern "C" int wsrep_thd_retry_counter(THD *thd)
|
||||
{
|
||||
return(thd->wsrep_retry_counter);
|
||||
}
|
||||
|
||||
|
||||
extern int
|
||||
wsrep_trx_order_before(void *thd1, void *thd2)
|
||||
{
|
||||
if (wsrep_thd_trx_seqno((THD*)thd1) < wsrep_thd_trx_seqno((THD*)thd2)) {
|
||||
WSREP_DEBUG("BF conflict, order: %lld %lld\n",
|
||||
(long long)wsrep_thd_trx_seqno((THD*)thd1),
|
||||
(long long)wsrep_thd_trx_seqno((THD*)thd2));
|
||||
return 1;
|
||||
}
|
||||
WSREP_DEBUG("waiting for BF, trx order: %lld %lld\n",
|
||||
(long long)wsrep_thd_trx_seqno((THD*)thd1),
|
||||
(long long)wsrep_thd_trx_seqno((THD*)thd2));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
extern "C" int
|
||||
wsrep_trx_is_aborting(void *thd_ptr)
|
||||
{
|
||||
if (thd_ptr) {
|
||||
if ((((THD *)thd_ptr)->wsrep_conflict_state == MUST_ABORT) ||
|
||||
(((THD *)thd_ptr)->wsrep_conflict_state == ABORTING)) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
my_bool wsrep_read_only_option(THD *thd, TABLE_LIST *all_tables)
|
||||
{
|
||||
int opt_readonly_saved = opt_readonly;
|
||||
ulong flag_saved = (ulong)(thd->security_ctx->master_access & SUPER_ACL);
|
||||
|
||||
opt_readonly = 0;
|
||||
thd->security_ctx->master_access &= ~SUPER_ACL;
|
||||
|
||||
my_bool ret = !deny_updates_if_read_only_option(thd, all_tables);
|
||||
|
||||
opt_readonly = opt_readonly_saved;
|
||||
thd->security_ctx->master_access |= flag_saved;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void wsrep_copy_query(THD *thd)
|
||||
{
|
||||
thd->wsrep_retry_command = thd->get_command();
|
||||
thd->wsrep_retry_query_len = thd->query_length();
|
||||
thd->wsrep_retry_query = (char *)my_malloc(
|
||||
thd->wsrep_retry_query_len + 1, MYF(0));
|
||||
strncpy(thd->wsrep_retry_query, thd->query(), thd->wsrep_retry_query_len);
|
||||
thd->wsrep_retry_query[thd->wsrep_retry_query_len] = '\0';
|
||||
}
|
||||
|
||||
|
||||
bool wsrep_is_show_query(enum enum_sql_command command)
|
||||
{
|
||||
DBUG_ASSERT(command >= 0 && command <= SQLCOM_END);
|
||||
return (sql_command_flags[command] & CF_STATUS_COMMAND) != 0;
|
||||
}
|
||||
|
||||
bool wsrep_create_like_table(THD* thd, TABLE_LIST* table,
|
||||
TABLE_LIST* src_table,
|
||||
HA_CREATE_INFO *create_info)
|
||||
{
|
||||
TABLE *tmp_table;
|
||||
bool is_tmp_table= FALSE;
|
||||
|
||||
for (tmp_table= thd->temporary_tables; tmp_table; tmp_table=tmp_table->next)
|
||||
{
|
||||
if (!strcmp(src_table->db, tmp_table->s->db.str) &&
|
||||
!strcmp(src_table->table_name, tmp_table->s->table_name.str))
|
||||
{
|
||||
is_tmp_table= TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
|
||||
{
|
||||
|
||||
/* CREATE TEMPORARY TABLE LIKE must be skipped from replication */
|
||||
WSREP_DEBUG("CREATE TEMPORARY TABLE LIKE... skipped replication\n %s",
|
||||
thd->query());
|
||||
}
|
||||
else if (!is_tmp_table)
|
||||
{
|
||||
/* this is straight CREATE TABLE LIKE... eith no tmp tables */
|
||||
WSREP_TO_ISOLATION_BEGIN(table->db, table->table_name, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* here we have CREATE TABLE LIKE <temporary table>
|
||||
the temporary table definition will be needed in slaves to
|
||||
enable the create to succeed
|
||||
*/
|
||||
TABLE_LIST tbl;
|
||||
bzero((void*) &tbl, sizeof(tbl));
|
||||
tbl.db= src_table->db;
|
||||
tbl.table_name= tbl.alias= src_table->table_name;
|
||||
tbl.table= tmp_table;
|
||||
char buf[2048];
|
||||
String query(buf, sizeof(buf), system_charset_info);
|
||||
query.length(0); // Have to zero it since constructor doesn't
|
||||
|
||||
(void) store_create_info(thd, &tbl, &query, NULL, TRUE, FALSE);
|
||||
WSREP_DEBUG("TMP TABLE: %s", query.ptr());
|
||||
|
||||
thd->wsrep_TOI_pre_query= query.ptr();
|
||||
thd->wsrep_TOI_pre_query_len= query.length();
|
||||
|
||||
WSREP_TO_ISOLATION_BEGIN(table->db, table->table_name, NULL);
|
||||
|
||||
thd->wsrep_TOI_pre_query= NULL;
|
||||
thd->wsrep_TOI_pre_query_len= 0;
|
||||
}
|
||||
|
||||
return(false);
|
||||
|
||||
error:
|
||||
thd->wsrep_TOI_pre_query= NULL;
|
||||
return (true);
|
||||
}
|
||||
|
||||
|
||||
int wsrep_create_trigger_query(THD *thd, uchar** buf, size_t* buf_len)
|
||||
{
|
||||
LEX *lex= thd->lex;
|
||||
String stmt_query;
|
||||
|
||||
LEX_STRING definer_user;
|
||||
LEX_STRING definer_host;
|
||||
|
||||
if (!lex->definer)
|
||||
{
|
||||
if (!thd->slave_thread)
|
||||
{
|
||||
if (!(lex->definer= create_default_definer(thd, false)))
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (lex->definer)
|
||||
{
|
||||
/* SUID trigger. */
|
||||
|
||||
definer_user= lex->definer->user;
|
||||
definer_host= lex->definer->host;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* non-SUID trigger. */
|
||||
|
||||
definer_user.str= 0;
|
||||
definer_user.length= 0;
|
||||
|
||||
definer_host.str= 0;
|
||||
definer_host.length= 0;
|
||||
}
|
||||
|
||||
stmt_query.append(STRING_WITH_LEN("CREATE "));
|
||||
|
||||
append_definer(thd, &stmt_query, &definer_user, &definer_host);
|
||||
|
||||
LEX_STRING stmt_definition;
|
||||
stmt_definition.str= (char*) thd->lex->stmt_definition_begin;
|
||||
stmt_definition.length= thd->lex->stmt_definition_end
|
||||
- thd->lex->stmt_definition_begin;
|
||||
trim_whitespace(thd->charset(), & stmt_definition);
|
||||
|
||||
stmt_query.append(stmt_definition.str, stmt_definition.length);
|
||||
|
||||
return wsrep_to_buf_helper(thd, stmt_query.c_ptr(), stmt_query.length(),
|
||||
buf, buf_len);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,14 +13,18 @@
|
|||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#ifndef WSREP_MYSQLD_H
|
||||
#include <wsrep.h>
|
||||
|
||||
#if !defined(WSREP_MYSQLD_H) && defined(WITH_WSREP)
|
||||
#define WSREP_MYSQLD_H
|
||||
|
||||
#include "mysqld.h"
|
||||
typedef struct st_mysql_show_var SHOW_VAR;
|
||||
#include <sql_priv.h>
|
||||
//#include "rpl_gtid.h"
|
||||
#include "../wsrep/wsrep_api.h"
|
||||
#include "mdl.h"
|
||||
#include "mysqld.h"
|
||||
#include "sql_table.h"
|
||||
|
||||
#define WSREP_UNDEFINED_TRX_ID ULONGLONG_MAX
|
||||
|
||||
|
|
@ -59,6 +63,15 @@ enum wsrep_consistency_check_mode {
|
|||
CONSISTENCY_CHECK_RUNNING,
|
||||
};
|
||||
|
||||
struct wsrep_thd_shadow {
|
||||
ulonglong options;
|
||||
uint server_status;
|
||||
enum wsrep_exec_mode wsrep_exec_mode;
|
||||
Vio *vio;
|
||||
ulong tx_isolation;
|
||||
char *db;
|
||||
size_t db_length;
|
||||
};
|
||||
|
||||
// Global wsrep parameters
|
||||
extern wsrep_t* wsrep;
|
||||
|
|
@ -203,12 +216,6 @@ extern wsrep_seqno_t wsrep_locked_seqno;
|
|||
fun("WSREP: %s", msg); \
|
||||
}
|
||||
|
||||
#define WSREP_DEBUG(...) \
|
||||
if (wsrep_debug) WSREP_LOG(sql_print_information, ##__VA_ARGS__)
|
||||
#define WSREP_INFO(...) WSREP_LOG(sql_print_information, ##__VA_ARGS__)
|
||||
#define WSREP_WARN(...) WSREP_LOG(sql_print_warning, ##__VA_ARGS__)
|
||||
#define WSREP_ERROR(...) WSREP_LOG(sql_print_error, ##__VA_ARGS__)
|
||||
|
||||
#define WSREP_LOG_CONFLICT_THD(thd, role) \
|
||||
WSREP_LOG(sql_print_information, \
|
||||
"%s: \n " \
|
||||
|
|
@ -279,6 +286,7 @@ extern int wsrep_to_isolation;
|
|||
extern rpl_sidno wsrep_sidno;
|
||||
#endif /* GTID_SUPPORT */
|
||||
extern my_bool wsrep_preordered_opt;
|
||||
extern handlerton *wsrep_hton;
|
||||
|
||||
#ifdef HAVE_PSI_INTERFACE
|
||||
extern PSI_mutex_key key_LOCK_wsrep_ready;
|
||||
|
|
@ -317,4 +325,37 @@ const wsrep_uuid_t* wsrep_xid_uuid(const xid_t*);
|
|||
wsrep_seqno_t wsrep_xid_seqno(const xid_t*);
|
||||
extern "C" int wsrep_is_wsrep_xid(const void* xid);
|
||||
|
||||
extern "C" my_thread_id wsrep_thd_thread_id(THD *thd);
|
||||
extern "C" char *wsrep_thd_query(THD *thd);
|
||||
|
||||
extern bool
|
||||
wsrep_grant_mdl_exception(MDL_context *requestor_ctx,
|
||||
MDL_ticket *ticket);
|
||||
IO_CACHE * get_trans_log(THD * thd);
|
||||
bool wsrep_trans_cache_is_empty(THD *thd);
|
||||
void thd_binlog_flush_pending_rows_event(THD *thd, bool stmt_end);
|
||||
void thd_binlog_rollback_stmt(THD * thd);
|
||||
void thd_binlog_trx_reset(THD * thd);
|
||||
|
||||
typedef void (*wsrep_thd_processor_fun)(THD *);
|
||||
pthread_handler_t start_wsrep_THD(void *arg);
|
||||
int wsrep_wait_committing_connections_close(int wait_time);
|
||||
void wsrep_close_client_connections(my_bool wait_to_end);
|
||||
void wsrep_close_applier(THD *thd);
|
||||
void wsrep_close_applier_threads(int count);
|
||||
void wsrep_wait_appliers_close(THD *thd);
|
||||
void wsrep_kill_mysql(THD *thd);
|
||||
void wsrep_close_threads(THD *thd);
|
||||
int wsrep_create_sp(THD *thd, uchar** buf, size_t* buf_len);
|
||||
my_bool wsrep_read_only_option(THD *thd, TABLE_LIST *all_tables);
|
||||
void wsrep_copy_query(THD *thd);
|
||||
bool wsrep_is_show_query(enum enum_sql_command command);
|
||||
void wsrep_replay_transaction(THD *thd);
|
||||
bool wsrep_create_like_table(THD* thd, TABLE_LIST* table,
|
||||
TABLE_LIST* src_table,
|
||||
HA_CREATE_INFO *create_info);
|
||||
int wsrep_create_trigger_query(THD *thd, uchar** buf, size_t* buf_len);
|
||||
|
||||
extern my_bool deny_updates_if_read_only_option(THD *thd,
|
||||
TABLE_LIST *all_tables);
|
||||
#endif /* WSREP_MYSQLD_H */
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */
|
||||
|
||||
#ifndef WSREP_SST_H
|
||||
#if !defined(WSREP_SST_H) && defined(WITH_WSREP)
|
||||
#define WSREP_SST_H
|
||||
|
||||
#include <mysql.h> // my_bool
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */
|
||||
|
||||
#ifndef WSREP_THD_H
|
||||
#if !defined(WSREP_THD_H) && defined(WITH_WSREP)
|
||||
#define WSREP_THD_H
|
||||
|
||||
#include "sql_class.h"
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */
|
||||
|
||||
#ifndef WSREP_VAR_H
|
||||
#if !defined (WSREP_VAR_H) && defined(WITH_WSREP)
|
||||
#define WSREP_VAR_H
|
||||
|
||||
#define WSREP_CLUSTER_NAME "my_wsrep_cluster"
|
||||
|
|
|
|||
|
|
@ -17326,44 +17326,44 @@ wsrep_innobase_kill_one_trx(void * const bf_thd_ptr,
|
|||
|
||||
if (!thd) {
|
||||
DBUG_PRINT("wsrep", ("no thd for conflicting lock"));
|
||||
WSREP_WARN("no THD for trx: %llu", victim_trx->id);
|
||||
WSREP_WARN("no THD for trx: %lu", victim_trx->id);
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
if (!bf_thd) {
|
||||
DBUG_PRINT("wsrep", ("no BF thd for conflicting lock"));
|
||||
WSREP_WARN("no BF THD for trx: %llu", (bf_trx) ? bf_trx->id : 0);
|
||||
WSREP_WARN("no BF THD for trx: %lu", (bf_trx) ? bf_trx->id : 0);
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
|
||||
WSREP_LOG_CONFLICT(bf_thd, thd, TRUE);
|
||||
|
||||
WSREP_DEBUG("BF kill (%lu, seqno: %lld), victim: (%lu) trx: %llu",
|
||||
WSREP_DEBUG("BF kill (%lu, seqno: %lld), victim: (%lu) trx: %lu",
|
||||
signal, (long long)bf_seqno,
|
||||
wsrep_thd_thread_id(thd),
|
||||
victim_trx->id);
|
||||
|
||||
WSREP_DEBUG("Aborting query: %s",
|
||||
WSREP_DEBUG("Aborting query: %s",
|
||||
(thd && wsrep_thd_query(thd)) ? wsrep_thd_query(thd) : "void");
|
||||
|
||||
wsrep_thd_LOCK(thd);
|
||||
|
||||
if (wsrep_thd_query_state(thd) == QUERY_EXITING) {
|
||||
WSREP_DEBUG("kill trx EXITING for %llu", victim_trx->id);
|
||||
WSREP_DEBUG("kill trx EXITING for %lu", victim_trx->id);
|
||||
wsrep_thd_UNLOCK(thd);
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
if(wsrep_thd_exec_mode(thd) != LOCAL_STATE) {
|
||||
WSREP_DEBUG("withdraw for BF trx: %llu, state: %d",
|
||||
WSREP_DEBUG("withdraw for BF trx: %lu, state: %d",
|
||||
victim_trx->id,
|
||||
wsrep_thd_conflict_state(thd));
|
||||
}
|
||||
|
||||
switch (wsrep_thd_conflict_state(thd)) {
|
||||
case NO_CONFLICT:
|
||||
case NO_CONFLICT:
|
||||
wsrep_thd_set_conflict_state(thd, MUST_ABORT);
|
||||
break;
|
||||
case MUST_ABORT:
|
||||
WSREP_DEBUG("victim %llu in MUST ABORT state",
|
||||
WSREP_DEBUG("victim %lu in MUST ABORT state",
|
||||
victim_trx->id);
|
||||
wsrep_thd_UNLOCK(thd);
|
||||
wsrep_thd_awake(thd, signal);
|
||||
|
|
@ -17372,7 +17372,7 @@ wsrep_innobase_kill_one_trx(void * const bf_thd_ptr,
|
|||
case ABORTED:
|
||||
case ABORTING: // fall through
|
||||
default:
|
||||
WSREP_DEBUG("victim %llu in state %d",
|
||||
WSREP_DEBUG("victim %lu in state %d",
|
||||
victim_trx->id, wsrep_thd_conflict_state(thd));
|
||||
wsrep_thd_UNLOCK(thd);
|
||||
DBUG_RETURN(0);
|
||||
|
|
@ -17385,7 +17385,7 @@ wsrep_innobase_kill_one_trx(void * const bf_thd_ptr,
|
|||
|
||||
WSREP_DEBUG("kill query for: %ld",
|
||||
wsrep_thd_thread_id(thd));
|
||||
WSREP_DEBUG("kill trx QUERY_COMMITTING for %llu",
|
||||
WSREP_DEBUG("kill trx QUERY_COMMITTING for %lu",
|
||||
victim_trx->id);
|
||||
|
||||
if (wsrep_thd_exec_mode(thd) == REPL_RECV) {
|
||||
|
|
@ -17399,7 +17399,7 @@ wsrep_innobase_kill_one_trx(void * const bf_thd_ptr,
|
|||
|
||||
switch (rcode) {
|
||||
case WSREP_WARNING:
|
||||
WSREP_DEBUG("cancel commit warning: %llu",
|
||||
WSREP_DEBUG("cancel commit warning: %lu",
|
||||
victim_trx->id);
|
||||
wsrep_thd_UNLOCK(thd);
|
||||
wsrep_thd_awake(thd, signal);
|
||||
|
|
@ -17409,8 +17409,8 @@ wsrep_innobase_kill_one_trx(void * const bf_thd_ptr,
|
|||
break;
|
||||
default:
|
||||
WSREP_ERROR(
|
||||
"cancel commit bad exit: %d %llu",
|
||||
rcode,
|
||||
"cancel commit bad exit: %d %lu",
|
||||
rcode,
|
||||
victim_trx->id);
|
||||
/* unable to interrupt, must abort */
|
||||
/* note: kill_mysql() will block, if we cannot.
|
||||
|
|
@ -17424,10 +17424,10 @@ wsrep_innobase_kill_one_trx(void * const bf_thd_ptr,
|
|||
wsrep_thd_awake(thd, signal);
|
||||
break;
|
||||
case QUERY_EXEC:
|
||||
/* it is possible that victim trx is itself waiting for some
|
||||
/* it is possible that victim trx is itself waiting for some
|
||||
* other lock. We need to cancel this waiting
|
||||
*/
|
||||
WSREP_DEBUG("kill trx QUERY_EXEC for %llu", victim_trx->id);
|
||||
WSREP_DEBUG("kill trx QUERY_EXEC for %lu", victim_trx->id);
|
||||
|
||||
victim_trx->lock.was_chosen_as_deadlock_victim= TRUE;
|
||||
if (victim_trx->lock.wait_lock) {
|
||||
|
|
@ -17444,7 +17444,7 @@ wsrep_innobase_kill_one_trx(void * const bf_thd_ptr,
|
|||
wsrep_thd_awake(thd, signal);
|
||||
} else {
|
||||
/* abort currently executing query */
|
||||
DBUG_PRINT("wsrep",("sending KILL_QUERY to: %ld",
|
||||
DBUG_PRINT("wsrep",("sending KILL_QUERY to: %ld",
|
||||
wsrep_thd_thread_id(thd)));
|
||||
WSREP_DEBUG("kill query for: %ld",
|
||||
wsrep_thd_thread_id(thd));
|
||||
|
|
@ -17464,8 +17464,8 @@ wsrep_innobase_kill_one_trx(void * const bf_thd_ptr,
|
|||
{
|
||||
bool skip_abort= false;
|
||||
wsrep_aborting_thd_t abortees;
|
||||
|
||||
WSREP_DEBUG("kill IDLE for %llu", victim_trx->id);
|
||||
|
||||
WSREP_DEBUG("kill IDLE for %lu", victim_trx->id);
|
||||
|
||||
if (wsrep_thd_exec_mode(thd) == REPL_RECV) {
|
||||
WSREP_DEBUG("kill BF IDLE, seqno: %lld",
|
||||
|
|
@ -17485,14 +17485,14 @@ wsrep_innobase_kill_one_trx(void * const bf_thd_ptr,
|
|||
/* check if we have a kill message for this already */
|
||||
if (abortees->aborting_thd == thd) {
|
||||
skip_abort = true;
|
||||
WSREP_WARN("duplicate thd aborter %lu",
|
||||
WSREP_WARN("duplicate thd aborter %lu",
|
||||
wsrep_thd_thread_id(thd));
|
||||
}
|
||||
abortees = abortees->next;
|
||||
}
|
||||
if (!skip_abort) {
|
||||
wsrep_aborting_thd_t aborting = (wsrep_aborting_thd_t)
|
||||
my_malloc(sizeof(struct wsrep_aborting_thd),
|
||||
my_malloc(sizeof(struct wsrep_aborting_thd),
|
||||
MYF(0));
|
||||
aborting->aborting_thd = thd;
|
||||
aborting->next = wsrep_aborting_thd;
|
||||
|
|
@ -17512,22 +17512,24 @@ wsrep_innobase_kill_one_trx(void * const bf_thd_ptr,
|
|||
break;
|
||||
}
|
||||
default:
|
||||
WSREP_WARN("bad wsrep query state: %d",
|
||||
WSREP_WARN("bad wsrep query state: %d",
|
||||
wsrep_thd_query_state(thd));
|
||||
wsrep_thd_UNLOCK(thd);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
static int
|
||||
wsrep_abort_transaction(handlerton* hton, THD *bf_thd, THD *victim_thd,
|
||||
|
||||
static
|
||||
int
|
||||
wsrep_abort_transaction(handlerton* hton, THD *bf_thd, THD *victim_thd,
|
||||
my_bool signal)
|
||||
{
|
||||
DBUG_ENTER("wsrep_innobase_abort_thd");
|
||||
trx_t* victim_trx = thd_to_trx(victim_thd);
|
||||
trx_t* bf_trx = (bf_thd) ? thd_to_trx(bf_thd) : NULL;
|
||||
WSREP_DEBUG("abort transaction: BF: %s victim: %s",
|
||||
WSREP_DEBUG("abort transaction: BF: %s victim: %s",
|
||||
wsrep_thd_query(bf_thd),
|
||||
wsrep_thd_query(victim_thd));
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue