summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--scripts/mysqld_safe.sh50
-rw-r--r--scripts/wsrep_sst_rsync.sh11
-rw-r--r--sql/wsrep_hton.cc5
-rw-r--r--storage/innobase/handler/ha_innodb.cc1
-rw-r--r--storage/innobase/include/srv0srv.h8
-rw-r--r--storage/innobase/include/trx0trx.h3
-rw-r--r--storage/innobase/srv/srv0srv.c33
-rw-r--r--storage/innobase/trx/trx0trx.c3
-rw-r--r--storage/xtradb/handler/ha_innodb.cc1
-rw-r--r--storage/xtradb/include/srv0srv.h8
-rw-r--r--storage/xtradb/include/trx0trx.h3
-rw-r--r--storage/xtradb/srv/srv0srv.c33
-rw-r--r--storage/xtradb/trx/trx0trx.c3
13 files changed, 140 insertions, 22 deletions
diff --git a/scripts/mysqld_safe.sh b/scripts/mysqld_safe.sh
index 0bd49af876e..bbe12db35f3 100644
--- a/scripts/mysqld_safe.sh
+++ b/scripts/mysqld_safe.sh
@@ -214,29 +214,39 @@ wsrep_pick_url() {
# Run mysqld with --wsrep-recover and parse recovered position from log.
# Position will be stored in wsrep_start_position_opt global.
-wsrep_recovery() {
+wsrep_start_position_opt=""
+wsrep_recover_position() {
local mysqld_cmd="$@"
- wr_logfile=$(mktemp)
- [ "$EUID" = "0" ] && chown $user $wr_logfile
+ local wr_logfile=$(mktemp)
+ local euid=$(id -u)
+ local ret=0
+
+ [ "$euid" = "0" ] && chown $user $wr_logfile
chmod 600 $wr_logfile
+
log_notice "WSREP: Running position recovery with --log_error=$wr_logfile"
+
$mysqld_cmd --log_error=$wr_logfile --wsrep-recover
- rp=$(grep "WSREP: Recovered position:" $wr_logfile)
+
+ local rp="$(grep 'WSREP: Recovered position:' $wr_logfile)"
if [ -z "$rp" ]; then
- skipped=$(grep WSREP $wr_logfile | grep "skipping position recovery")
+ local skipped="$(grep WSREP $wr_logfile | grep 'skipping position recovery')"
if [ -z "$skipped" ]; then
- log_error "WSREP: Failed to recover position: " \
- `cat $wr_logfile`;
+ log_error "WSREP: Failed to recover position: " `cat $wr_logfile`;
+ ret=1
else
log_notice "WSREP: Position recovery skipped"
fi
else
- start_pos=$(echo $rp | sed 's/.*WSREP\:\ Recovered\ position://' \
- | sed 's/^[ \t]*//')
- wsrep_start_position_opt="--wsrep_start_position=$start_pos"
+ local start_pos="$(echo $rp | sed 's/.*WSREP\:\ Recovered\ position://' \
+ | sed 's/^[ \t]*//')"
log_notice "WSREP: Recovered position $start_pos"
+ wsrep_start_position_opt="--wsrep_start_position=$start_pos"
fi
+
rm $wr_logfile
+
+ return $ret
}
parse_arguments() {
@@ -303,9 +313,9 @@ parse_arguments() {
--wsrep[-_]provider=*)
if test -n "$val" && test "$val" != "none"
then
- wsrep_restart=1
- fi
- ;;
+ wsrep_restart=1
+ fi
+ ;;
--help) usage ;;
*)
@@ -864,20 +874,26 @@ have_sleep=1
# maximum number of wsrep restarts
max_wsrep_restarts=0
+# maximum number of wsrep restarts
+max_wsrep_restarts=0
+
while true
do
rm -f $safe_mysql_unix_port "$pid_file" # Some extra safety
- [ -n "$wsrep_urls" ] && url=`wsrep_pick_url $wsrep_urls` # check connect address
-
start_time=`date +%M%S`
+ # this sets wsrep_start_position_opt
+ wsrep_recover_position "$cmd"
+
+ [ $? -ne 0 ] && exit 1 #
+
+ [ -n "$wsrep_urls" ] && url=`wsrep_pick_url $wsrep_urls` # check connect address
+
if [ -z "$url" ]
then
- wsrep_recovery "$cmd"
eval_log_error "$cmd $wsrep_start_position_opt $nohup_redir"
else
- wsrep_recovery "$cmd"
eval_log_error "$cmd $wsrep_start_position_opt --wsrep_cluster_address=$url $nohup_redir"
fi
diff --git a/scripts/wsrep_sst_rsync.sh b/scripts/wsrep_sst_rsync.sh
index d510477535c..7cbfd8cbcdb 100644
--- a/scripts/wsrep_sst_rsync.sh
+++ b/scripts/wsrep_sst_rsync.sh
@@ -89,14 +89,14 @@ then
# --exclude '*.[0-9][0-9][0-9][0-9][0-9][0-9]' --exclude '*.index')
# New filter - exclude everything except dirs (schemas) and innodb files
- FILTER=(-f '+ /ibdata*' -f '+ /ib_logfile*' -f '+ */' -f '-! */*')
+ FILTER=(-f '- lost+found' -f '+ /ibdata*' -f '+ /ib_logfile*' -f '+ */' -f '-! */*')
RC=0
rsync --archive --no-times --ignore-times --inplace --delete --quiet \
$WHOLE_FILE_OPT "${FILTER[@]}" "$WSREP_SST_OPT_DATA" \
rsync://$WSREP_SST_OPT_ADDR || RC=$?
- [ $RC -ne 0 ] && echo "rsync returned code $RC:" >> /dev/stderr
+ [ $RC -ne 0 ] && wsrep_log_error "rsync returned code $RC:"
case $RC in
0) RC=0 # Success
@@ -136,7 +136,7 @@ then
if check_pid $RSYNC_PID
then
- echo "rsync daemon already running."
+ wsrep_log_error "rsync daemon already running."
exit 114 # EALREADY
fi
rm -rf "$RSYNC_PID"
@@ -189,7 +189,8 @@ EOF
if ! ps -p $MYSQLD_PID >/dev/null
then
- echo "Parent mysqld process (PID:$MYSQLD_PID) terminated unexpectedly." >&2
+ wsrep_log_error \
+ "Parent mysqld process (PID:$MYSQLD_PID) terminated unexpectedly."
exit 32
fi
@@ -203,7 +204,7 @@ EOF
# cleanup_joiner
else
- echo "Unrecognized role: '$WSREP_SST_OPT_ROLE'"
+ wsrep_log_error "Unrecognized role: '$WSREP_SST_OPT_ROLE'"
exit 22 # EINVAL
fi
diff --git a/sql/wsrep_hton.cc b/sql/wsrep_hton.cc
index 0e013556f45..576e6b8ad47 100644
--- a/sql/wsrep_hton.cc
+++ b/sql/wsrep_hton.cc
@@ -178,6 +178,7 @@ int wsrep_commit(handlerton *hton, THD *thd, bool all)
extern Rpl_filter* binlog_filter;
extern my_bool opt_log_slave_updates;
+extern void wsrep_write_rbr_buf(THD *thd, const void* rbr_buf, size_t buf_len);
enum wsrep_trx_status
wsrep_run_wsrep_commit(
THD *thd, handlerton *hton, bool all)
@@ -337,6 +338,10 @@ wsrep_run_wsrep_commit(
(thd->wsrep_PA_safe) ? WSREP_FLAG_PA_SAFE : 0ULL,
&thd->wsrep_trx_seqno);
if (rcode == WSREP_TRX_MISSING) {
+ WSREP_WARN("Transaction missing in provider, thd: %ld, SQL: %s",
+ thd->thread_id, thd->query());
+ wsrep_write_rbr_buf(thd, rbr_data, data_len);
+
rcode = WSREP_OK;
} else if (rcode == WSREP_BF_ABORT) {
mysql_mutex_lock(&thd->LOCK_wsrep_thd);
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index 1b211ab4226..f54098814b8 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -12626,6 +12626,7 @@ wsrep_abort_transaction(handlerton* hton, THD *bf_thd, THD *victim_thd,
int rcode = wsrep_innobase_kill_one_trx(
bf_thd, bf_trx, victim_trx, signal);
mutex_exit(&kernel_mutex);
+ wsrep_srv_conc_cancel_wait(victim_trx);
DBUG_RETURN(rcode);
} else {
WSREP_DEBUG("victim does not have transaction");
diff --git a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h
index 093be2a6dcb..91151312367 100644
--- a/storage/innobase/include/srv0srv.h
+++ b/storage/innobase/include/srv0srv.h
@@ -566,6 +566,14 @@ srv_conc_enter_innodb(
/*==================*/
trx_t* trx); /*!< in: transaction object associated with the
thread */
+#ifdef WITH_WSREP
+UNIV_INTERN
+void
+wsrep_srv_conc_cancel_wait(
+/*==================*/
+ trx_t* trx); /*!< in: transaction object associated with the
+ thread */
+#endif /* WITH_WSREP */
/*********************************************************************//**
This lets a thread enter InnoDB regardless of the number of threads inside
InnoDB. This must be called when a thread ends a lock wait. */
diff --git a/storage/innobase/include/trx0trx.h b/storage/innobase/include/trx0trx.h
index 7572c766301..40474344cff 100644
--- a/storage/innobase/include/trx0trx.h
+++ b/storage/innobase/include/trx0trx.h
@@ -729,6 +729,9 @@ struct trx_struct{
/*------------------------------*/
char detailed_error[256]; /*!< detailed error message for last
error, or empty. */
+#ifdef WITH_WSREP
+ os_event_t wsrep_event; /* event waited for in srv_conc_slot */
+#endif /* WITH_WSREP */
};
#define TRX_MAX_N_THREADS 32 /* maximum number of
diff --git a/storage/innobase/srv/srv0srv.c b/storage/innobase/srv/srv0srv.c
index 57046ff644c..dfa5a683acf 100644
--- a/storage/innobase/srv/srv0srv.c
+++ b/storage/innobase/srv/srv0srv.c
@@ -1148,6 +1148,23 @@ srv_general_init(void)
/* Maximum allowable purge history length. <=0 means 'infinite'. */
UNIV_INTERN ulong srv_max_purge_lag = 0;
+#ifdef WITH_WSREP
+UNIV_INTERN
+void
+wsrep_srv_conc_cancel_wait(
+/*==================*/
+ trx_t* trx) /*!< in: transaction object associated with the
+ thread */
+{
+ os_fast_mutex_lock(&srv_conc_mutex);
+ if (trx->wsrep_event) {
+ if (wsrep_debug)
+ fprintf(stderr, "WSREP: conc slot cancel\n");
+ os_event_set(trx->wsrep_event);
+ }
+ os_fast_mutex_unlock(&srv_conc_mutex);
+}
+#endif /* WITH_WSREP */
/*********************************************************************//**
Puts an OS thread to wait if there are too many concurrent threads
(>= srv_thread_concurrency) inside InnoDB. The threads wait in a FIFO queue. */
@@ -1299,6 +1316,19 @@ retry:
srv_conc_n_waiting_threads++;
+#ifdef WITH_WSREP
+ if (wsrep_on(trx->mysql_thd) &&
+ wsrep_trx_is_aborting(trx->mysql_thd)) {
+ srv_conc_n_waiting_threads--;
+ os_fast_mutex_unlock(&srv_conc_mutex);
+ if (wsrep_debug)
+ fprintf(stderr, "srv_conc_enter due to MUST_ABORT");
+ trx->declared_to_be_inside_innodb = TRUE;
+ trx->n_tickets_to_enter_innodb = SRV_FREE_TICKETS_TO_ENTER;
+ return;
+ }
+ trx->wsrep_event = slot->event;
+#endif /* WITH_WSREP */
os_fast_mutex_unlock(&srv_conc_mutex);
/* Go to wait for the event; when a thread leaves InnoDB it will
@@ -1313,6 +1343,9 @@ retry:
thd_wait_begin(trx->mysql_thd, THD_WAIT_USER_LOCK);
os_event_wait(slot->event);
thd_wait_end(trx->mysql_thd);
+#ifdef WITH_WSREP
+ trx->wsrep_event = NULL;
+#endif /* WITH_WSREP */
trx->op_info = "";
diff --git a/storage/innobase/trx/trx0trx.c b/storage/innobase/trx/trx0trx.c
index 23cac1e11db..42c326fc3e0 100644
--- a/storage/innobase/trx/trx0trx.c
+++ b/storage/innobase/trx/trx0trx.c
@@ -193,6 +193,9 @@ trx_create(
/* Remember to free the vector explicitly. */
trx->autoinc_locks = ib_vector_create(
mem_heap_create(sizeof(ib_vector_t) + sizeof(void*) * 4), 4);
+#ifdef WITH_WSREP
+ trx->wsrep_event = NULL;
+#endif /* WITH_WSREP */
return(trx);
}
diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc
index fc68878d860..7b96c18d835 100644
--- a/storage/xtradb/handler/ha_innodb.cc
+++ b/storage/xtradb/handler/ha_innodb.cc
@@ -13752,6 +13752,7 @@ wsrep_abort_transaction(handlerton* hton, THD *bf_thd, THD *victim_thd,
int rcode = wsrep_innobase_kill_one_trx(bf_trx, victim_trx,
signal);
mutex_exit(&kernel_mutex);
+ wsrep_srv_conc_cancel_wait(victim_trx);
DBUG_RETURN(rcode);
} else {
WSREP_DEBUG("victim does not have transaction");
diff --git a/storage/xtradb/include/srv0srv.h b/storage/xtradb/include/srv0srv.h
index e125d1c3853..6f0b53ef2ba 100644
--- a/storage/xtradb/include/srv0srv.h
+++ b/storage/xtradb/include/srv0srv.h
@@ -635,6 +635,14 @@ srv_conc_enter_innodb(
/*==================*/
trx_t* trx); /*!< in: transaction object associated with the
thread */
+#ifdef WITH_WSREP
+UNIV_INTERN
+void
+wsrep_srv_conc_cancel_wait(
+/*==================*/
+ trx_t* trx); /*!< in: transaction object associated with the
+ thread */
+#endif /* WITH_WSREP */
/*********************************************************************//**
This lets a thread enter InnoDB regardless of the number of threads inside
InnoDB. This must be called when a thread ends a lock wait. */
diff --git a/storage/xtradb/include/trx0trx.h b/storage/xtradb/include/trx0trx.h
index eded5c303fa..2a08fdf442b 100644
--- a/storage/xtradb/include/trx0trx.h
+++ b/storage/xtradb/include/trx0trx.h
@@ -747,6 +747,9 @@ struct trx_struct{
/*------------------------------*/
char detailed_error[256]; /*!< detailed error message for last
error, or empty. */
+#ifdef WITH_WSREP
+ os_event_t wsrep_event; /* event waited for in srv_conc_slot */
+#endif /* WITH_WSREP */
/*------------------------------*/
ulint io_reads;
ib_uint64_t io_read;
diff --git a/storage/xtradb/srv/srv0srv.c b/storage/xtradb/srv/srv0srv.c
index c46977e4812..ee03c6b050d 100644
--- a/storage/xtradb/srv/srv0srv.c
+++ b/storage/xtradb/srv/srv0srv.c
@@ -1234,6 +1234,23 @@ srv_general_init(void)
/* Maximum allowable purge history length. <=0 means 'infinite'. */
UNIV_INTERN ulong srv_max_purge_lag = 0;
+#ifdef WITH_WSREP
+UNIV_INTERN
+void
+wsrep_srv_conc_cancel_wait(
+/*==================*/
+ trx_t* trx) /*!< in: transaction object associated with the
+ thread */
+{
+ os_fast_mutex_lock(&srv_conc_mutex);
+ if (trx->wsrep_event) {
+ if (wsrep_debug)
+ fprintf(stderr, "WSREP: conc slot cancel\n");
+ os_event_set(trx->wsrep_event);
+ }
+ os_fast_mutex_unlock(&srv_conc_mutex);
+}
+#endif /* WITH_WSREP */
/*********************************************************************//**
Puts an OS thread to wait if there are too many concurrent threads
(>= srv_thread_concurrency) inside InnoDB. The threads wait in a FIFO queue. */
@@ -1466,6 +1483,19 @@ retry:
srv_conc_n_waiting_threads++;
+#ifdef WITH_WSREP
+ if (wsrep_on(trx->mysql_thd) &&
+ wsrep_trx_is_aborting(trx->mysql_thd)) {
+ srv_conc_n_waiting_threads--;
+ os_fast_mutex_unlock(&srv_conc_mutex);
+ if (wsrep_debug)
+ fprintf(stderr, "srv_conc_enter due to MUST_ABORT");
+ trx->declared_to_be_inside_innodb = TRUE;
+ trx->n_tickets_to_enter_innodb = SRV_FREE_TICKETS_TO_ENTER;
+ return;
+ }
+ trx->wsrep_event = slot->event;
+#endif /* WITH_WSREP */
os_fast_mutex_unlock(&srv_conc_mutex);
/* Go to wait for the event; when a thread leaves InnoDB it will
@@ -1488,6 +1518,9 @@ retry:
thd_wait_begin(trx->mysql_thd, THD_WAIT_USER_LOCK);
os_event_wait(slot->event);
thd_wait_end(trx->mysql_thd);
+#ifdef WITH_WSREP
+ trx->wsrep_event = NULL;
+#endif /* WITH_WSREP */
trx->op_info = "";
diff --git a/storage/xtradb/trx/trx0trx.c b/storage/xtradb/trx/trx0trx.c
index 521fc96d35c..e6c72c09184 100644
--- a/storage/xtradb/trx/trx0trx.c
+++ b/storage/xtradb/trx/trx0trx.c
@@ -211,6 +211,9 @@ trx_create(
/* Remember to free the vector explicitly. */
trx->autoinc_locks = ib_vector_create(
mem_heap_create(sizeof(ib_vector_t) + sizeof(void*) * 4), 4);
+#ifdef WITH_WSREP
+ trx->wsrep_event = NULL;
+#endif /* WITH_WSREP */
return(trx);
}