diff options
-rw-r--r-- | scripts/mysqld_safe.sh | 50 | ||||
-rw-r--r-- | scripts/wsrep_sst_rsync.sh | 11 | ||||
-rw-r--r-- | sql/wsrep_hton.cc | 5 | ||||
-rw-r--r-- | storage/innobase/handler/ha_innodb.cc | 1 | ||||
-rw-r--r-- | storage/innobase/include/srv0srv.h | 8 | ||||
-rw-r--r-- | storage/innobase/include/trx0trx.h | 3 | ||||
-rw-r--r-- | storage/innobase/srv/srv0srv.c | 33 | ||||
-rw-r--r-- | storage/innobase/trx/trx0trx.c | 3 | ||||
-rw-r--r-- | storage/xtradb/handler/ha_innodb.cc | 1 | ||||
-rw-r--r-- | storage/xtradb/include/srv0srv.h | 8 | ||||
-rw-r--r-- | storage/xtradb/include/trx0trx.h | 3 | ||||
-rw-r--r-- | storage/xtradb/srv/srv0srv.c | 33 | ||||
-rw-r--r-- | storage/xtradb/trx/trx0trx.c | 3 |
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); } |