summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.bzrignore1
-rw-r--r--cmake/wsrep.cmake2
-rw-r--r--scripts/wsrep_sst_common.sh26
-rwxr-xr-xscripts/wsrep_sst_rsync.sh6
-rw-r--r--scripts/wsrep_sst_xtrabackup-v2.sh70
-rw-r--r--scripts/wsrep_sst_xtrabackup.sh2
-rw-r--r--sql/event_data_objects.cc13
-rw-r--r--sql/events.cc41
-rw-r--r--sql/mysqld.cc3
-rw-r--r--sql/sql_yacc.yy12
-rw-r--r--sql/wsrep_mysqld.cc18
-rw-r--r--sql/wsrep_mysqld.h1
-rw-r--r--sql/wsrep_thd.cc15
-rw-r--r--storage/innobase/lock/lock0lock.c10
-rw-r--r--storage/innobase/row/row0ins.c11
-rw-r--r--storage/xtradb/lock/lock0lock.c10
-rw-r--r--storage/xtradb/row/row0ins.c11
-rw-r--r--support-files/mysql.spec.sh2
-rw-r--r--wsrep/wsrep_dummy.c21
19 files changed, 236 insertions, 39 deletions
diff --git a/.bzrignore b/.bzrignore
index 125c1bf7d34..0c300408180 100644
--- a/.bzrignore
+++ b/.bzrignore
@@ -12,6 +12,7 @@
*.dll
*.dsp
*.dylib
+*.diff
*.exe
*.exp
*.gcda
diff --git a/cmake/wsrep.cmake b/cmake/wsrep.cmake
index 628cfd1b092..dde6c0b4d2d 100644
--- a/cmake/wsrep.cmake
+++ b/cmake/wsrep.cmake
@@ -23,7 +23,7 @@ SET(WSREP_PATCH_VERSION "10")
# MariaDB addition: Revision number of the last revision merged from
# codership branch visible in @@visible_comment.
# Branch : codership-mysql/5.5
-SET(WSREP_PATCH_REVNO "3980") # Should be updated on every merge.
+SET(WSREP_PATCH_REVNO "3997") # Should be updated on every merge.
# MariaDB: Obtain patch revision number:
# Update WSREP_PATCH_REVNO if WSREP_REV environment variable is set.
diff --git a/scripts/wsrep_sst_common.sh b/scripts/wsrep_sst_common.sh
index b6c10ba4e7d..d9aa24169ce 100644
--- a/scripts/wsrep_sst_common.sh
+++ b/scripts/wsrep_sst_common.sh
@@ -1,4 +1,4 @@
-# Copyright (C) 2012 Codership Oy
+# Copyright (C) 2012-2014 Codership Oy
#
# 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
@@ -125,3 +125,27 @@ wsrep_cleanup_progress_file()
{
[ -n "$SST_PROGRESS_FILE" ] && rm -f "$SST_PROGRESS_FILE" 2>/dev/null
}
+
+wsrep_check_program()
+{
+ local prog=$1
+
+ if ! which $prog >/dev/null
+ then
+ echo "'$prog' not found in PATH"
+ return 2 # no such file or directory
+ fi
+}
+
+wsrep_check_programs()
+{
+ local ret=0
+
+ while [ $# -gt 0 ]
+ do
+ wsrep_check_program $1 || ret=$?
+ shift
+ done
+
+ return $ret
+}
diff --git a/scripts/wsrep_sst_rsync.sh b/scripts/wsrep_sst_rsync.sh
index bd8f03846e9..464b2b1ef3e 100755
--- a/scripts/wsrep_sst_rsync.sh
+++ b/scripts/wsrep_sst_rsync.sh
@@ -1,6 +1,6 @@
#!/bin/bash -ue
-# Copyright (C) 2010 Codership Oy
+# Copyright (C) 2010-2014 Codership Oy
#
# 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
@@ -28,6 +28,8 @@ export PATH="/usr/sbin:/sbin:$PATH"
. $(dirname $0)/wsrep_sst_common
+wsrep_check_programs rsync
+
cleanup_joiner()
{
wsrep_log_info "Joiner cleanup."
@@ -202,6 +204,8 @@ then
elif [ "$WSREP_SST_OPT_ROLE" = "joiner" ]
then
+ wsrep_check_programs lsof
+
touch $SST_PROGRESS_FILE
MYSQLD_PID=$WSREP_SST_OPT_PARENT
diff --git a/scripts/wsrep_sst_xtrabackup-v2.sh b/scripts/wsrep_sst_xtrabackup-v2.sh
index 59017fff8df..865547ad9d8 100644
--- a/scripts/wsrep_sst_xtrabackup-v2.sh
+++ b/scripts/wsrep_sst_xtrabackup-v2.sh
@@ -63,6 +63,10 @@ STATDIR=""
uextra=0
disver=""
+tmpopts=""
+itmpdir=""
+xtmpdir=""
+
scomp=""
sdecomp=""
@@ -236,7 +240,7 @@ parse_cnf()
get_footprint()
{
pushd $WSREP_SST_OPT_DATA 1>/dev/null
- payload=$(du --block-size=1 -c **/*.ibd **/*.MYI **/*.MYI ibdata1 | awk 'END { print $1 }')
+ payload=$(find . -regex '.*\.ibd$\|.*\.MYI$\|.*\.MYD$\|.*ibdata1$' -type f -print0 | xargs -0 du --block-size=1 -c | awk 'END { print $1 }')
if my_print_defaults -c $WSREP_SST_OPT_CONF xtrabackup | grep -q -- "--compress";then
# QuickLZ has around 50% compression ratio
# When compression/compaction used, the progress is only an approximate.
@@ -299,6 +303,7 @@ read_cnf()
iopts=$(parse_cnf sst inno-backup-opts "")
iapts=$(parse_cnf sst inno-apply-opts "")
impts=$(parse_cnf sst inno-move-opts "")
+ stimeout=$(parse_cnf sst sst-initial-timeout 100)
}
get_stream()
@@ -370,20 +375,29 @@ cleanup_donor()
wsrep_log_error "Cleanup after exit with status:$estatus"
fi
- if [[ -n $XTRABACKUP_PID ]];then
+ if [[ -n ${XTRABACKUP_PID:-} ]];then
if check_pid $XTRABACKUP_PID
then
wsrep_log_error "xtrabackup process is still running. Killing... "
kill_xtrabackup
fi
- rm -f $XTRABACKUP_PID
fi
- rm -f ${DATA}/${IST_FILE}
+ rm -f ${DATA}/${IST_FILE} || true
if [[ -n $progress && -p $progress ]];then
wsrep_log_info "Cleaning up fifo file $progress"
- rm $progress
+ rm -f $progress || true
+ fi
+
+ wsrep_log_info "Cleaning up temporary directories"
+
+ if [[ -n $xtmpdir ]];then
+ [[ -d $xtmpdir ]] && rm -rf $xtmpdir || true
+ fi
+
+ if [[ -n $itmpdir ]];then
+ [[ -d $itmpdir ]] && rm -rf $itmpdir || true
fi
}
@@ -391,7 +405,8 @@ kill_xtrabackup()
{
local PID=$(cat $XTRABACKUP_PID)
[ -n "$PID" -a "0" != "$PID" ] && kill $PID && (kill $PID && kill -9 $PID) || :
- rm -f "$XTRABACKUP_PID"
+ wsrep_log_info "Removing xtrabackup pid file $XTRABACKUP_PID"
+ rm -f "$XTRABACKUP_PID" || true
}
setup_ports()
@@ -453,13 +468,30 @@ recv_joiner()
{
local dir=$1
local msg=$2
+ local tmt=$3
+ local ltcmd
pushd ${dir} 1>/dev/null
set +e
- timeit "$msg" "$tcmd | $strmcmd; RC=( "\${PIPESTATUS[@]}" )"
+
+ if [[ $tmt -gt 0 && -x `which timeout` ]];then
+ if timeout --help | grep -q -- '-k';then
+ ltcmd="timeout -k $(( tmt+10 )) $tmt $tcmd"
+ else
+ ltcmd="timeout $tmt $tcmd"
+ fi
+ timeit "$msg" "$ltcmd | $strmcmd; RC=( "\${PIPESTATUS[@]}" )"
+ else
+ timeit "$msg" "$tcmd | $strmcmd; RC=( "\${PIPESTATUS[@]}" )"
+ fi
+
set -e
popd 1>/dev/null
+ if [[ ${RC[0]} -eq 124 ]];then
+ wsrep_log_error "Possible timeout in receving first data from donor in gtid stage"
+ exit 32
+ fi
for ecode in "${RC[@]}";do
if [[ $ecode -ne 0 ]];then
@@ -501,7 +533,7 @@ send_donor()
}
-if [[ ! -x `which innobackupex` ]];then
+if [[ ! -x `which $INNOBACKUPEX_BIN` ]];then
wsrep_log_error "innobackupex not in path: $PATH"
exit 2
fi
@@ -526,7 +558,7 @@ fi
INNOEXTRA=""
INNOAPPLY="${INNOBACKUPEX_BIN} $disver $iapts --apply-log \$rebuildcmd \${DATA} &>\${DATA}/innobackup.prepare.log"
INNOMOVE="${INNOBACKUPEX_BIN} --defaults-file=${WSREP_SST_OPT_CONF} $disver $impts --move-back --force-non-empty-directories \${DATA} &>\${DATA}/innobackup.move.log"
-INNOBACKUP="${INNOBACKUPEX_BIN} --defaults-file=${WSREP_SST_OPT_CONF} $disver $iopts \$INNOEXTRA --galera-info --stream=\$sfmt \${TMPDIR} 2>\${DATA}/innobackup.backup.log"
+INNOBACKUP="${INNOBACKUPEX_BIN} --defaults-file=${WSREP_SST_OPT_CONF} $disver $iopts \$tmpopts \$INNOEXTRA --galera-info --stream=\$sfmt \$itmpdir 2>\${DATA}/innobackup.backup.log"
if [ "$WSREP_SST_OPT_ROLE" = "donor" ]
then
@@ -535,7 +567,14 @@ then
if [ $WSREP_SST_OPT_BYPASS -eq 0 ]
then
- TMPDIR="${TMPDIR:-/tmp}"
+ if [[ -z $(parse_cnf mysqld tmpdir "") && -z $(parse_cnf xtrabackup tmpdir "") ]];then
+ xtmpdir=$(mktemp -d)
+ tmpopts=" --tmpdir=$xtmpdir "
+ wsrep_log_info "Using $xtmpdir as xtrabackup temporary directory"
+ fi
+
+ itmpdir=$(mktemp -d)
+ wsrep_log_info "Using $itmpdir as innobackupex temporary directory"
if [ "${AUTH[0]}" != "(null)" ]; then
INNOEXTRA+=" --user=${AUTH[0]}"
@@ -613,8 +652,8 @@ then
exit 22
fi
- # innobackupex implicitly writes PID to fixed location in ${TMPDIR}
- XTRABACKUP_PID="${TMPDIR}/xtrabackup_pid"
+ # innobackupex implicitly writes PID to fixed location in $xtmpdir
+ XTRABACKUP_PID="$xtmpdir/xtrabackup_pid"
else # BYPASS FOR IST
@@ -717,7 +756,7 @@ then
STATDIR=$(mktemp -d)
MAGIC_FILE="${STATDIR}/${INFO_FILE}"
- recv_joiner $STATDIR "${stagemsg}-gtid" 1
+ recv_joiner $STATDIR "${stagemsg}-gtid" $stimeout
if ! ps -p ${WSREP_SST_OPT_PARENT} &>/dev/null
then
@@ -767,7 +806,7 @@ then
MAGIC_FILE="${DATA}/${INFO_FILE}"
- recv_joiner $DATA "${stagemsg}-SST" 0
+ recv_joiner $DATA "${stagemsg}-SST" 0
get_proc
@@ -867,11 +906,10 @@ then
wsrep_log_info "${IST_FILE} received from donor: Running IST"
fi
- if [[ ! -r ${MAGIC_FILE} ]];then
+ if [[ ! -r ${MAGIC_FILE} ]];then
wsrep_log_error "SST magic file ${MAGIC_FILE} not found/readable"
exit 2
fi
-
cat "${MAGIC_FILE}" # output UUID:seqno
wsrep_log_info "Total time on joiner: $totime seconds"
fi
diff --git a/scripts/wsrep_sst_xtrabackup.sh b/scripts/wsrep_sst_xtrabackup.sh
index 01c9c3f3049..6b33eabee23 100644
--- a/scripts/wsrep_sst_xtrabackup.sh
+++ b/scripts/wsrep_sst_xtrabackup.sh
@@ -205,7 +205,7 @@ parse_cnf()
get_footprint()
{
pushd $WSREP_SST_OPT_DATA 1>/dev/null
- payload=$(du --block-size=1 -c **/*.ibd **/*.MYI **/*.MYI ibdata1 | awk 'END { print $1 }')
+ payload=$(find . -regex '.*\.ibd$\|.*\.MYI$\|.*\.MYD$\|.*ibdata1$' -type f -print0 | xargs -0 du --block-size=1 -c | awk 'END { print $1 }')
if my_print_defaults -c $WSREP_SST_OPT_CONF xtrabackup | grep -q -- "--compress";then
# QuickLZ has around 50% compression ratio
# When compression/compaction used, the progress is only an approximate.
diff --git a/sql/event_data_objects.cc b/sql/event_data_objects.cc
index dfd35583581..dbf35bd94b7 100644
--- a/sql/event_data_objects.cc
+++ b/sql/event_data_objects.cc
@@ -1467,8 +1467,21 @@ end:
saved_master_access= thd->security_ctx->master_access;
thd->security_ctx->master_access |= SUPER_ACL;
+#ifdef WITH_WSREP
+ // sql_print_information("sizeof(LEX) = %d", sizeof(struct LEX));
+ // sizeof(LEX) = 4512, so it's relatively safe to allocate it on stack.
+ LEX lex;
+ lex.sql_command = SQLCOM_DROP_EVENT;
+ thd->lex = &lex;
+ WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL);
+#endif
+
ret= Events::drop_event(thd, dbname, name, FALSE);
+#ifdef WITH_WSREP
+ WSREP_TO_ISOLATION_END;
+ error:
+#endif
thd->security_ctx->master_access= saved_master_access;
}
}
diff --git a/sql/events.cc b/sql/events.cc
index e016ccd2b84..9e15a5f47bd 100644
--- a/sql/events.cc
+++ b/sql/events.cc
@@ -1104,6 +1104,20 @@ Events::load_events_from_db(THD *thd)
delete et;
goto end;
}
+#ifdef WITH_WSREP
+ // when SST from master node who initials event, the event status is ENABLED
+ // this is problematic because there are two nodes with same events and both enabled.
+ if (et->originator != thd->server_id)
+ {
+ store_record(table, record[1]);
+ table->field[ET_FIELD_STATUS]->
+ store((longlong) Event_parse_data::SLAVESIDE_DISABLED,
+ TRUE);
+ (void) table->file->ha_update_row(table->record[1], table->record[0]);
+ delete et;
+ continue;
+ }
+#endif
drop_on_completion= (et->on_completion ==
Event_parse_data::ON_COMPLETION_DROP);
@@ -1158,6 +1172,33 @@ int wsrep_create_event_query(THD *thd, uchar** buf, size_t* buf_len)
}
return wsrep_to_buf_helper(thd, log_query.ptr(), log_query.length(), buf, buf_len);
}
+static int
+wsrep_alter_query_string(THD *thd, String *buf)
+{
+ /* Append the "ALTER" part of the query */
+ if (buf->append(STRING_WITH_LEN("ALTER ")))
+ return 1;
+ /* Append definer */
+ append_definer(thd, buf, &(thd->lex->definer->user), &(thd->lex->definer->host));
+ /* Append the left part of thd->query after event name part */
+ if (buf->append(thd->lex->stmt_definition_begin,
+ thd->lex->stmt_definition_end -
+ thd->lex->stmt_definition_begin))
+ return 1;
+
+ return 0;
+}
+int wsrep_alter_event_query(THD *thd, uchar** buf, size_t* buf_len)
+{
+ String log_query;
+
+ if (wsrep_alter_query_string(thd, &log_query))
+ {
+ WSREP_WARN("events alter 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 */
/**
@} (End of group Event_Scheduler)
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 33e5e47bff1..6d9c9eb0b7a 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -2761,7 +2761,8 @@ bool one_thread_per_connection_end(THD *thd, bool put_in_cache)
/* Mark that current_thd is not valid anymore */
my_pthread_setspecific_ptr(THR_THD, 0);
#ifdef WITH_WSREP
- if (put_in_cache && !thd->wsrep_applier)
+ const bool wsrep_applier(thd->wsrep_applier);
+ if (put_in_cache && !wsrep_applier)
#else
if (put_in_cache)
#endif /* WITH_WSREP */
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 0a116b41308..5a9c71acc52 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -6550,7 +6550,7 @@ alter:
}
view_tail
{}
- | ALTER definer_opt EVENT_SYM sp_name
+ | ALTER definer_opt remember_name EVENT_SYM sp_name
{
/*
It is safe to use Lex->spname because
@@ -6562,9 +6562,12 @@ alter:
if (!(Lex->event_parse_data= Event_parse_data::new_instance(thd)))
MYSQL_YYABORT;
- Lex->event_parse_data->identifier= $4;
+ Lex->event_parse_data->identifier= $5;
Lex->sql_command= SQLCOM_ALTER_EVENT;
+#ifdef WITH_WSREP
+ Lex->stmt_definition_begin= $3;
+#endif
}
ev_alter_on_schedule_completion
opt_ev_rename_to
@@ -6572,7 +6575,7 @@ alter:
opt_ev_comment
opt_ev_sql_stmt
{
- if (!($6 || $7 || $8 || $9 || $10))
+ if (!($7 || $8 || $9 || $10 || $11))
{
my_parse_error(ER(ER_SYNTAX_ERROR));
MYSQL_YYABORT;
@@ -6582,6 +6585,9 @@ alter:
can overwrite it
*/
Lex->sql_command= SQLCOM_ALTER_EVENT;
+#ifdef WITH_WSREP
+ Lex->stmt_definition_end= (char*)YYLIP->get_cpp_ptr();
+#endif
}
| ALTER TABLESPACE alter_tablespace_info
{
diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc
index 4fd07a9945c..1d869ab84c5 100644
--- a/sql/wsrep_mysqld.cc
+++ b/sql/wsrep_mysqld.cc
@@ -509,7 +509,20 @@ int wsrep_init()
wsrep_ready_set(TRUE);
wsrep_inited= 1;
global_system_variables.wsrep_on = 0;
- return 0;
+ wsrep_init_args args;
+ args.logger_cb = wsrep_log_cb;
+ args.options = (wsrep_provider_options) ?
+ wsrep_provider_options : "";
+ rcode = wsrep->init(wsrep, &args);
+ if (rcode)
+ {
+ DBUG_PRINT("wsrep",("wsrep::init() failed: %d", rcode));
+ WSREP_ERROR("wsrep::init() failed: %d, must shutdown", rcode);
+ wsrep->free(wsrep);
+ free(wsrep);
+ wsrep = NULL;
+ }
+ return rcode;
}
else
{
@@ -1216,6 +1229,9 @@ static int wsrep_TOI_begin(THD *thd, char *db_, char *table_,
case SQLCOM_CREATE_EVENT:
buf_err= wsrep_create_event_query(thd, &buf, &buf_len);
break;
+ case SQLCOM_ALTER_EVENT:
+ buf_err= wsrep_alter_event_query(thd, &buf, &buf_len);
+ break;
default:
buf_err= wsrep_to_buf_helper(thd, thd->query(), thd->query_length(), &buf,
&buf_len);
diff --git a/sql/wsrep_mysqld.h b/sql/wsrep_mysqld.h
index ec2a38278ab..7939bf55684 100644
--- a/sql/wsrep_mysqld.h
+++ b/sql/wsrep_mysqld.h
@@ -298,6 +298,7 @@ int wsrep_to_buf_helper(
int wsrep_create_sp(THD *thd, uchar** buf, size_t* buf_len);
int wsrep_create_trigger_query(THD *thd, uchar** buf, size_t* buf_len);
int wsrep_create_event_query(THD *thd, uchar** buf, size_t* buf_len);
+int wsrep_alter_event_query(THD *thd, uchar** buf, size_t* buf_len);
const wsrep_uuid_t* wsrep_cluster_uuid();
struct xid_t;
diff --git a/sql/wsrep_thd.cc b/sql/wsrep_thd.cc
index 3fed6db6d0d..132cfc7c5d2 100644
--- a/sql/wsrep_thd.cc
+++ b/sql/wsrep_thd.cc
@@ -23,11 +23,20 @@
#include "sql_base.h" // close_thread_tables()
#include "mysqld.h" // start_wsrep_THD();
-static long long wsrep_bf_aborts_counter = 0;
+
+#if (__LP64__)
+static volatile int64 wsrep_bf_aborts_counter(0);
+#define WSREP_ATOMIC_LOAD_LONG my_atomic_load64
+#define WSREP_ATOMIC_ADD_LONG my_atomic_add64
+#else
+static volatile int32 wsrep_bf_aborts_counter(0);
+#define WSREP_ATOMIC_LOAD_LONG my_atomic_load32
+#define WSREP_ATOMIC_ADD_LONG my_atomic_add32
+#endif
int wsrep_show_bf_aborts (THD *thd, SHOW_VAR *var, char *buff)
{
- wsrep_local_bf_aborts = my_atomic_load64(&wsrep_bf_aborts_counter);
+ wsrep_local_bf_aborts = WSREP_ATOMIC_LOAD_LONG(&wsrep_bf_aborts_counter);
var->type = SHOW_LONGLONG;
var->value = (char*)&wsrep_local_bf_aborts;
return 0;
@@ -39,7 +48,7 @@ void wsrep_client_rollback(THD *thd)
WSREP_DEBUG("client rollback due to BF abort for (%ld), query: %s",
thd->thread_id, thd->query());
- my_atomic_add64(&wsrep_bf_aborts_counter, 1);
+ WSREP_ATOMIC_ADD_LONG(&wsrep_bf_aborts_counter, 1);
thd->wsrep_conflict_state= ABORTING;
mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
diff --git a/storage/innobase/lock/lock0lock.c b/storage/innobase/lock/lock0lock.c
index 98cb239befc..48bb3183f9f 100644
--- a/storage/innobase/lock/lock0lock.c
+++ b/storage/innobase/lock/lock0lock.c
@@ -1820,7 +1820,12 @@ lock_rec_create(
automatically of the gap type */
if (UNIV_UNLIKELY(heap_no == PAGE_HEAP_NO_SUPREMUM)) {
+#ifdef WITH_WSREP
+ ut_ad(!(type_mode & LOCK_REC_NOT_GAP) ||
+ wsrep_thd_is_BF(trx->mysql_thd, FALSE));
+#else
ut_ad(!(type_mode & LOCK_REC_NOT_GAP));
+#endif /* WITH_WSREP */
type_mode = type_mode & ~(LOCK_GAP | LOCK_REC_NOT_GAP);
}
@@ -2104,7 +2109,12 @@ lock_rec_add_to_queue(
struct for a gap type lock */
if (UNIV_UNLIKELY(heap_no == PAGE_HEAP_NO_SUPREMUM)) {
+#ifdef WITH_WSREP
+ ut_ad(!(type_mode & LOCK_REC_NOT_GAP) ||
+ wsrep_thd_is_BF(trx->mysql_thd, FALSE));
+#else
ut_ad(!(type_mode & LOCK_REC_NOT_GAP));
+#endif /* WITH_WSREP */
/* There should never be LOCK_REC_NOT_GAP on a supremum
record, but let us play safe */
diff --git a/storage/innobase/row/row0ins.c b/storage/innobase/row/row0ins.c
index 3419297f059..d250a8b47b8 100644
--- a/storage/innobase/row/row0ins.c
+++ b/storage/innobase/row/row0ins.c
@@ -1696,10 +1696,6 @@ row_ins_scan_sec_index_for_duplicate(
mem_heap_t* heap = NULL;
ulint offsets_[REC_OFFS_NORMAL_SIZE];
ulint* offsets = offsets_;
-#ifdef WITH_WSREP
- /* appliers don't need dupkey checks */
- if (wsrep_thd_is_BF(thr_get_trx(thr)->mysql_thd, 0)) return(DB_SUCCESS);
-#endif /* WITH_WSREP */
rec_offs_init(offsets_);
n_unique = dict_index_get_n_unique(index);
@@ -1764,6 +1760,13 @@ row_ins_scan_sec_index_for_duplicate(
lock_type, block, rec, index, offsets, thr);
} else {
+#ifdef WITH_WSREP
+ if (wsrep_thd_is_BF(thr_get_trx(thr)->mysql_thd, 0)) {
+ if (!(lock_type & LOCK_REC_NOT_GAP)) {
+ lock_type |= LOCK_REC_NOT_GAP;
+ }
+ }
+#endif /* WITH_WSREP */
err = row_ins_set_shared_rec_lock(
lock_type, block, rec, index, offsets, thr);
}
diff --git a/storage/xtradb/lock/lock0lock.c b/storage/xtradb/lock/lock0lock.c
index d9a5768d94c..e17398fe0e3 100644
--- a/storage/xtradb/lock/lock0lock.c
+++ b/storage/xtradb/lock/lock0lock.c
@@ -1821,7 +1821,12 @@ lock_rec_create(
automatically of the gap type */
if (UNIV_UNLIKELY(heap_no == PAGE_HEAP_NO_SUPREMUM)) {
+#ifdef WITH_WSREP
+ ut_ad(!(type_mode & LOCK_REC_NOT_GAP) ||
+ wsrep_thd_is_BF(trx->mysql_thd, FALSE));
+#else
ut_ad(!(type_mode & LOCK_REC_NOT_GAP));
+#endif /* WITH_WSREP */
type_mode = type_mode & ~(LOCK_GAP | LOCK_REC_NOT_GAP);
}
@@ -2111,7 +2116,12 @@ lock_rec_add_to_queue(
struct for a gap type lock */
if (UNIV_UNLIKELY(heap_no == PAGE_HEAP_NO_SUPREMUM)) {
+#ifdef WITH_WSREP
+ ut_ad(!(type_mode & LOCK_REC_NOT_GAP) ||
+ wsrep_thd_is_BF(trx->mysql_thd, FALSE));
+#else
ut_ad(!(type_mode & LOCK_REC_NOT_GAP));
+#endif /* WITH_WSREP */
/* There should never be LOCK_REC_NOT_GAP on a supremum
record, but let us play safe */
diff --git a/storage/xtradb/row/row0ins.c b/storage/xtradb/row/row0ins.c
index a1ee411b8cd..3f38a080c3b 100644
--- a/storage/xtradb/row/row0ins.c
+++ b/storage/xtradb/row/row0ins.c
@@ -1705,10 +1705,6 @@ row_ins_scan_sec_index_for_duplicate(
mem_heap_t* heap = NULL;
ulint offsets_[REC_OFFS_NORMAL_SIZE];
ulint* offsets = offsets_;
-#ifdef WITH_WSREP
- /* appliers don't need dupkey checks */
- if (wsrep_thd_is_BF(thr_get_trx(thr)->mysql_thd, 0)) return(DB_SUCCESS);
-#endif /* WITH_WSREP */
rec_offs_init(offsets_);
n_unique = dict_index_get_n_unique(index);
@@ -1773,6 +1769,13 @@ row_ins_scan_sec_index_for_duplicate(
lock_type, block, rec, index, offsets, thr);
} else {
+#ifdef WITH_WSREP
+ if (wsrep_thd_is_BF(thr_get_trx(thr)->mysql_thd, 0)) {
+ if (!(lock_type & LOCK_REC_NOT_GAP)) {
+ lock_type |= LOCK_REC_NOT_GAP;
+ }
+ }
+#endif /* WITH_WSREP */
err = row_ins_set_shared_rec_lock(
lock_type, block, rec, index, offsets, thr);
}
diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh
index c03763c7d45..1764e7d518f 100644
--- a/support-files/mysql.spec.sh
+++ b/support-files/mysql.spec.sh
@@ -304,7 +304,7 @@ Version: %{mysql_version}
Summary: MySQL: a very fast and reliable SQL database server
Group: Applications/Databases
%if %{defined with_wsrep}
-Requires: %{distro_requires} rsync
+Requires: %{distro_requires} rsync lsof
%else
Requires: %{distro_requires}
%endif
diff --git a/wsrep/wsrep_dummy.c b/wsrep/wsrep_dummy.c
index 3c7f97ede3f..fb5881410ff 100644
--- a/wsrep/wsrep_dummy.c
+++ b/wsrep/wsrep_dummy.c
@@ -20,11 +20,13 @@
#include <errno.h>
#include <stdbool.h>
+#include <string.h>
/*! Dummy backend context. */
typedef struct wsrep_dummy
{
wsrep_log_cb_t log_fn;
+ char* options;
} wsrep_dummy_t;
/* Get pointer to wsrep_dummy context from wsrep_t pointer */
@@ -43,6 +45,10 @@ static void dummy_free(wsrep_t *w)
{
WSREP_DBUG_ENTER(w);
free(w->ctx);
+ if (WSREP_DUMMY(w)->options) {
+ free(WSREP_DUMMY(w)->options);
+ WSREP_DUMMY(w)->options = NULL;
+ }
w->ctx = NULL;
}
@@ -51,6 +57,9 @@ static wsrep_status_t dummy_init (wsrep_t* w,
{
WSREP_DUMMY(w)->log_fn = args->logger_cb;
WSREP_DBUG_ENTER(w);
+ if (args->options) {
+ WSREP_DUMMY(w)->options = strdup(args->options);
+ }
return WSREP_OK;
}
@@ -61,16 +70,23 @@ static uint64_t dummy_capabilities (wsrep_t* w __attribute__((unused)))
static wsrep_status_t dummy_options_set(
wsrep_t* w,
- const char* conf __attribute__((unused)))
+ const char* conf)
{
WSREP_DBUG_ENTER(w);
+ if (WSREP_DUMMY(w)->options) {
+ free(WSREP_DUMMY(w)->options);
+ WSREP_DUMMY(w)->options = NULL;
+ }
+ if (conf) {
+ WSREP_DUMMY(w)->options = strdup(conf);
+ }
return WSREP_OK;
}
static char* dummy_options_get (wsrep_t* w)
{
WSREP_DBUG_ENTER(w);
- return NULL;
+ return WSREP_DUMMY(w)->options;
}
static wsrep_status_t dummy_connect(
@@ -385,6 +401,7 @@ int wsrep_dummy_loader(wsrep_t* w)
// initialize private context
WSREP_DUMMY(w)->log_fn = NULL;
+ WSREP_DUMMY(w)->options = NULL;
return 0;
}