Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package galera-4 for openSUSE:Factory checked in at 2024-07-17 15:13:51 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/galera-4 (Old) and /work/SRC/openSUSE:Factory/.galera-4.new.17339 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "galera-4" Wed Jul 17 15:13:51 2024 rev:11 rq:1187880 version:26.4.18 Changes: -------- --- /work/SRC/openSUSE:Factory/galera-4/galera-4.changes 2024-02-21 17:51:59.581698072 +0100 +++ /work/SRC/openSUSE:Factory/.galera-4.new.17339/galera-4.changes 2024-07-17 15:14:15.520116836 +0200 @@ -1,0 +2,22 @@ +Sat Jun 29 20:31:08 UTC 2024 - Dirk Müller <dmuel...@suse.com> + +- update to 26.4.18: + * The garbd process hangs due to exceptions in the GCS layer not + being caught within the receive loop, necessitating a forceful + termination. Fixing this requires catching all exceptions + within the loop, closing the connection first, and then + continuing until a 'SELF-LEAVE' message ensures graceful exit. + * When using SSL, crashes of garbd during graceful node shutdowns + may occur, and result in the cluster becoming non-Primary; + garbd now ignores the SIGPIPE signal to prevent this. + * socket_ssl_compression is deprecated, now it isn't attempt to + be set, and the user receives a warning if it was explicitly + set. + * Fixed commit cut tracking on node leave, and bumped GCS protocol + version for backwards compatibility. + * Executing the gcomm join process in the database server thread + can lead to issues during allowlist callbacks, which should + only be handled by Galera service threads. The gcomm join + process is run within the gcomm service thread now. + +------------------------------------------------------------------- Old: ---- galera-4-26.4.17.tar.gz galera-4-26.4.17.tar.gz.asc New: ---- galera-4-26.4.18.tar.gz galera-4-26.4.18.tar.gz.asc ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ galera-4.spec ++++++ --- /var/tmp/diff_new_pack.B505Pv/_old 2024-07-17 15:14:16.000134248 +0200 +++ /var/tmp/diff_new_pack.B505Pv/_new 2024-07-17 15:14:16.004134393 +0200 @@ -25,7 +25,7 @@ %define _fillupdir %{_localstatedir}/adm/fillup-templates %endif Name: galera-4 -Version: 26.4.17 +Version: 26.4.18 Release: 0 Summary: Galera: a synchronous multi-master wsrep provider (replication engine) License: GPL-2.0-only ++++++ galera-4-26.4.17.tar.gz -> galera-4-26.4.18.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/galera-4-26.4.17/GALERA_GIT_REVISION new/galera-4-26.4.18/GALERA_GIT_REVISION --- old/galera-4-26.4.17/GALERA_GIT_REVISION 2024-01-02 12:54:15.000000000 +0100 +++ new/galera-4-26.4.18/GALERA_GIT_REVISION 2024-03-22 12:54:22.000000000 +0100 @@ -1 +1 @@ -b6cd015f \ No newline at end of file +0bc393fb \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/galera-4-26.4.17/GALERA_REVISION new/galera-4-26.4.18/GALERA_REVISION --- old/galera-4-26.4.17/GALERA_REVISION 2024-01-02 12:54:15.000000000 +0100 +++ new/galera-4-26.4.18/GALERA_REVISION 2024-03-22 12:54:22.000000000 +0100 @@ -1 +1 @@ -b6cd015f \ No newline at end of file +0bc393fb \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/galera-4-26.4.17/GALERA_VERSION new/galera-4-26.4.18/GALERA_VERSION --- old/galera-4-26.4.17/GALERA_VERSION 2024-01-02 12:54:13.000000000 +0100 +++ new/galera-4-26.4.18/GALERA_VERSION 2024-03-22 12:54:21.000000000 +0100 @@ -1,4 +1,4 @@ GALERA_VERSION_WSREP_API=26 GALERA_VERSION_MAJOR=4 -GALERA_VERSION_MINOR=17 +GALERA_VERSION_MINOR=18 GALERA_VERSION_EXTRA= diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/galera-4-26.4.17/SConstruct new/galera-4-26.4.18/SConstruct --- old/galera-4-26.4.17/SConstruct 2024-01-02 12:54:13.000000000 +0100 +++ new/galera-4-26.4.18/SConstruct 2024-03-22 12:54:21.000000000 +0100 @@ -163,7 +163,7 @@ install = ARGUMENTS.get('install', None) version_script = int(ARGUMENTS.get('version_script', 1)) -GALERA_VER = ARGUMENTS.get('version', '4.17') +GALERA_VER = ARGUMENTS.get('version', '4.18') GALERA_REV = ARGUMENTS.get('revno', 'XXXX') # Attempt to read from file if not given diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/galera-4-26.4.17/debian/changelog new/galera-4-26.4.18/debian/changelog --- old/galera-4-26.4.17/debian/changelog 2024-01-02 12:54:13.000000000 +0100 +++ new/galera-4-26.4.18/debian/changelog 2024-03-22 12:54:21.000000000 +0100 @@ -1,5 +1,5 @@ -galera-4 (26.4.17) UNRELEASED; urgency=medium +galera-4 (26.4.18) UNRELEASED; urgency=medium * Galera 4 release - -- Codership Oy <i...@codership.com> Fri, 29 Dec 2023 19:44:46 +0200 + -- Codership Oy <i...@codership.com> Fri, 22 Mar 2024 09:07:35 +0200 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/galera-4-26.4.17/galera/src/certification.cpp new/galera-4-26.4.18/galera/src/certification.cpp --- old/galera-4-26.4.17/galera/src/certification.cpp 2024-01-02 12:54:13.000000000 +0100 +++ new/galera-4-26.4.18/galera/src/certification.cpp 2024-03-22 12:54:21.000000000 +0100 @@ -427,13 +427,15 @@ // trx->is_certified() == true during index rebuild from IST, do_test() // must not fail, just populate index + auto const cert_interval(trx->global_seqno() - trx->last_seen_seqno()); if (gu_unlikely(trx->certified() == false && (trx->last_seen_seqno() < initial_position_ || - trx->global_seqno()-trx->last_seen_seqno() > max_length_))) + cert_interval > max_length_))) { - if (trx->global_seqno() - trx->last_seen_seqno() > max_length_) + if (cert_interval > max_length_) { - log_warn << "certification interval for trx " << *trx + log_warn << "certification interval " << cert_interval + << " for trx " << *trx << " exceeds the limit of " << max_length_; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/galera-4-26.4.17/galerautils/src/gu_asio.cpp new/galera-4-26.4.18/galerautils/src/gu_asio.cpp --- old/galera-4-26.4.17/galerautils/src/gu_asio.cpp 2024-01-02 12:54:13.000000000 +0100 +++ new/galera-4-26.4.18/galerautils/src/gu_asio.cpp 2024-03-22 12:54:21.000000000 +0100 @@ -600,20 +600,20 @@ conf.set(conf::ssl_cipher, cipher_list); // compression - bool compression(conf.get(conf::ssl_compression, true)); - if (compression == false) - { - log_info << "disabling SSL compression"; - sk_SSL_COMP_zero(SSL_COMP_get_compression_methods()); - } - else + try { + (void) conf.get(conf::ssl_compression); + // warn the user if socket.ssl_compression is set explicitly log_warn << "SSL compression is not effective. The option " << conf::ssl_compression << " is deprecated and " << "will be removed in future releases."; } - conf.set(conf::ssl_compression, compression); - + catch (NotSet&) + { + // this is a desirable situation + } + log_info << "not using SSL compression"; + sk_SSL_COMP_zero(SSL_COMP_get_compression_methods()); // verify that asio::ssl::context can be initialized with provided // values diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/galera-4-26.4.17/galerautils/src/gu_barrier.hpp new/galera-4-26.4.18/galerautils/src/gu_barrier.hpp --- old/galera-4-26.4.17/galerautils/src/gu_barrier.hpp 2024-01-02 12:54:13.000000000 +0100 +++ new/galera-4-26.4.18/galerautils/src/gu_barrier.hpp 1970-01-01 01:00:00.000000000 +0100 @@ -1,57 +0,0 @@ -// -// Copyright (C) 2016-2017 Codership Oy <i...@codership.com> -// - - -#ifndef GU_BARRIER -#define GU_BARRIER - -#include <gu_threads.h> -#include "gu_throw.hpp" - - -namespace gu -{ - class Barrier - { - public: - Barrier(unsigned count) - : - barrier_() - { - int err; - if ((err = gu_barrier_init(&barrier_, 0, count)) != 0) - { - gu_throw_error(err) << "Barrier init failed"; - } - } - - ~Barrier() - { - int err; - if ((err = gu_barrier_destroy(&barrier_)) != 0) - { - assert(0); - log_warn << "Barrier destroy failed: " << ::strerror(err); - } - } - - void wait() - { - int err(gu_barrier_wait(&barrier_)); - if (err != 0 && err != GU_BARRIER_SERIAL_THREAD) - { - gu_throw_error(err) << "Barrier wait failed"; - } - } - - private: - // Non-copyable - Barrier(const Barrier&); - Barrier& operator=(const Barrier&); - gu_barrier_t barrier_; - }; -} - - -#endif // GU_BARRIER diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/galera-4-26.4.17/galerautils/src/gu_progress.hpp new/galera-4-26.4.18/galerautils/src/gu_progress.hpp --- old/galera-4-26.4.17/galerautils/src/gu_progress.hpp 2024-01-02 12:54:13.000000000 +0100 +++ new/galera-4-26.4.18/galerautils/src/gu_progress.hpp 2024-03-22 12:54:21.000000000 +0100 @@ -49,10 +49,10 @@ void log(gu::datetime::Date const now) { - log_info << prefix_ << "..." - << std::fixed << std::setprecision(1) << std::setw(5) + log_info << prefix_ << "... " + << std::fixed << std::setprecision(1) << (double(current_)/total_ * 100) << "% (" - << std::setw(total_digits_) << current_ << '/' << total_ + << current_ << '/' << total_ << units_ << ") complete."; last_log_time_ = now; @@ -121,7 +121,7 @@ /* while we may want to limit the rate of logging the progress, * it still makes sense (for monitoring) to call the callback * much more frequently */ - static gu::datetime::Period cb_interval("PT0.5S"); + static gu::datetime::Period const cb_interval("PT0.5S"); current_ += increment; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/galera-4-26.4.17/galerautils/tests/gu_asio_test.cpp new/galera-4-26.4.18/galerautils/tests/gu_asio_test.cpp --- old/galera-4-26.4.17/galerautils/tests/gu_asio_test.cpp 2024-01-02 12:54:13.000000000 +0100 +++ new/galera-4-26.4.18/galerautils/tests/gu_asio_test.cpp 2024-03-22 12:54:21.000000000 +0100 @@ -925,6 +925,8 @@ #include <openssl/engine.h> #include <openssl/pem.h> #include <openssl/x509v3.h> +#include <openssl/ssl.h> +#include <openssl/opensslv.h> #include <sys/stat.h> #include <sys/types.h> #include <dirent.h> @@ -934,7 +936,7 @@ static std::string get_cert_dir() { - static_assert(::strlen(GU_ASIO_TEST_CERT_DIR) > 0); + assert(::strlen(GU_ASIO_TEST_CERT_DIR) > 0); const std::string ret{ GU_ASIO_TEST_CERT_DIR }; auto* dir = opendir(ret.c_str()); if (!dir) @@ -1052,7 +1054,7 @@ X509V3_CTX ctx; X509V3_set_ctx(&ctx, issuer ? issuer : x509, x509, nullptr, nullptr, 0); X509V3_set_nconf(&ctx, conf); - if (!X509V3_EXT_add_nconf(conf, &ctx, "extensions", x509)) + if (!X509V3_EXT_add_nconf(conf, &ctx, (char *)"extensions", x509)) { throw_error("Could not add extension"); } @@ -1183,6 +1185,12 @@ static void generate_certificates() { +#if OPENSSL_VERSION_NUMBER < 0x30004000L +#ifdef OPENSSL_INIT_LOAD_SSL_STRINGS + OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, NULL); +#endif +#endif + generate_self_signed(); generate_chains(); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/galera-4-26.4.17/garb/garb_gcs.cpp new/galera-4-26.4.18/garb/garb_gcs.cpp --- old/galera-4-26.4.17/garb/garb_gcs.cpp 2024-01-02 12:54:13.000000000 +0100 +++ new/galera-4-26.4.18/garb/garb_gcs.cpp 2024-03-22 12:54:21.000000000 +0100 @@ -163,6 +163,7 @@ else { log_warn << "Attempt to close a closed connection"; + assert(0); } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/galera-4-26.4.17/garb/garb_main.cpp new/galera-4-26.4.18/garb/garb_main.cpp --- old/galera-4-26.4.17/garb/garb_main.cpp 2024-01-02 12:54:13.000000000 +0100 +++ new/galera-4-26.4.18/garb/garb_main.cpp 2024-03-22 12:54:21.000000000 +0100 @@ -1,4 +1,4 @@ -/* Copyright (C) 2011 Codership Oy <i...@codership.com> */ +/* Copyright (C) 2011-2024 Codership Oy <i...@codership.com> */ #include "garb_config.hpp" #include "garb_recv_loop.hpp" @@ -10,6 +10,7 @@ #include <stdlib.h> // exit() #include <unistd.h> // setsid(), chdir() #include <fcntl.h> // open() +#include <signal.h> // sigaction namespace garb { @@ -100,6 +101,18 @@ try { + /* Ignore SIGPIPE which could be raised when cluster connections are + closed abruptly. */ + struct sigaction isa; + memset (&isa, 0, sizeof(isa)); + isa.sa_handler = SIG_IGN; + + if (sigaction (SIGPIPE, &isa, NULL)) + { + gu_throw_error(errno) << "Falied to install signal handler for signal " + << "SIGPIPE"; + } + RecvLoop loop (config); return 0; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/galera-4-26.4.17/garb/garb_recv_loop.cpp new/galera-4-26.4.18/garb/garb_recv_loop.cpp --- old/galera-4-26.4.17/garb/garb_recv_loop.cpp 2024-01-02 12:54:13.000000000 +0100 +++ new/galera-4-26.4.18/garb/garb_recv_loop.cpp 2024-03-22 12:54:21.000000000 +0100 @@ -1,4 +1,4 @@ -/* Copyright (C) 2011-2020 Codership Oy <i...@codership.com> */ +/* Copyright (C) 2011-2023 Codership Oy <i...@codership.com> */ #include "garb_recv_loop.hpp" @@ -17,6 +17,15 @@ global_gcs->close(); } +void +RecvLoop::close_connection() +{ + if (!closed_) + { + gcs_.close(); + closed_ = true; + } +} RecvLoop::RecvLoop (const Config& config) : @@ -27,7 +36,8 @@ gcs_ (gconf_, config_.name(), config_.address(), config_.group()), uuid_ (GU_UUID_NIL), seqno_ (GCS_SEQNO_ILL), - proto_ (0) + proto_ (0), + closed_(false) { /* set up signal handlers */ global_gcs = &gcs_; @@ -52,88 +62,106 @@ loop(); } -void -RecvLoop::loop() +/* return true to exit loop */ +bool +RecvLoop::one_loop() { - while (1) - { - gcs_action act; + gcs_action act; - gcs_.recv (act); + gcs_.recv (act); - switch (act.type) - { - case GCS_ACT_WRITESET: - seqno_ = act.seqno_g; - if (gu_unlikely(proto_ == 0 && !(seqno_ & 127))) - /* report_interval_ of 128 in old protocol */ - { - gcs_.set_last_applied (gu::GTID(uuid_, seqno_)); - } - break; - case GCS_ACT_COMMIT_CUT: - break; - case GCS_ACT_STATE_REQ: - /* we can't donate state */ - gcs_.join (gu::GTID(uuid_, seqno_),-ENOSYS); - break; - case GCS_ACT_CCHANGE: + switch (act.type) + { + case GCS_ACT_WRITESET: + seqno_ = act.seqno_g; + if (gu_unlikely(proto_ == 0 && !(seqno_ & 127))) { - gcs_act_cchange const cc(act.buf, act.size); - - if (cc.conf_id > 0) /* PC */ - { - int const my_idx(act.seqno_g); - assert(my_idx >= 0); + /* report_interval_ of 128 in old protocol */ + gcs_.set_last_applied (gu::GTID(uuid_, seqno_)); + } + break; + case GCS_ACT_COMMIT_CUT: + break; + case GCS_ACT_STATE_REQ: + /* we can't donate state */ + gcs_.join (gu::GTID(uuid_, seqno_),-ENOSYS); + break; + case GCS_ACT_CCHANGE: + { + gcs_act_cchange const cc(act.buf, act.size); - gcs_node_state const my_state(cc.memb[my_idx].state_); + if (cc.conf_id > 0) /* PC */ + { + int const my_idx(act.seqno_g); + assert(my_idx >= 0); - if (GCS_NODE_STATE_PRIM == my_state) - { - uuid_ = cc.uuid; - seqno_ = cc.seqno; - gcs_.request_state_transfer (config_.sst(),config_.donor()); - gcs_.join(gu::GTID(cc.uuid, cc.seqno), 0); - } + gcs_node_state const my_state(cc.memb[my_idx].state_); - proto_ = gcs_.proto_ver(); - } - else + if (GCS_NODE_STATE_PRIM == my_state) { - if (cc.memb.size() == 0) // SELF-LEAVE after closing connection - { - log_info << "Exiting main loop"; - return; - } - uuid_ = GU_UUID_NIL; - seqno_ = GCS_SEQNO_ILL; + uuid_ = cc.uuid; + seqno_ = cc.seqno; + gcs_.request_state_transfer (config_.sst(),config_.donor()); + gcs_.join(gu::GTID(cc.uuid, cc.seqno), 0); } - if (config_.sst() != Config::DEFAULT_SST) + proto_ = gcs_.proto_ver(); + } + else + { + if (cc.memb.size() == 0) // SELF-LEAVE after closing connection { - // we requested custom SST, so we're done here - gcs_.close(); + log_info << "Exiting main loop"; + return true; } - - break; + uuid_ = GU_UUID_NIL; + seqno_ = GCS_SEQNO_ILL; } - case GCS_ACT_INCONSISTENCY: - // something went terribly wrong, restart needed - gcs_.close(); - return; - case GCS_ACT_JOIN: - case GCS_ACT_SYNC: - case GCS_ACT_FLOW: - case GCS_ACT_VOTE: - case GCS_ACT_SERVICE: - case GCS_ACT_ERROR: - case GCS_ACT_UNKNOWN: - break; + + if (config_.sst() != Config::DEFAULT_SST) + { + // we requested custom SST, so we're done here + close_connection(); } - if (act.buf) + break; + } + case GCS_ACT_INCONSISTENCY: + // something went terribly wrong, restart needed + close_connection(); + break; + case GCS_ACT_JOIN: + case GCS_ACT_SYNC: + case GCS_ACT_FLOW: + case GCS_ACT_VOTE: + case GCS_ACT_SERVICE: + case GCS_ACT_ERROR: + case GCS_ACT_UNKNOWN: + break; + } + + if (act.buf) + { + ::free(const_cast<void*>(act.buf)); + } + + return false; +} + +void +RecvLoop::loop() +{ + while (true) + { + try + { + if (one_loop()) return; + } + catch(gu::Exception& e) { - ::free(const_cast<void*>(act.buf)); + log_error << e.what(); + close_connection(); + /* continue looping to clear recv queue */ } } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/galera-4-26.4.17/garb/garb_recv_loop.hpp new/galera-4-26.4.18/garb/garb_recv_loop.hpp --- old/galera-4-26.4.17/garb/garb_recv_loop.hpp 2024-01-02 12:54:13.000000000 +0100 +++ new/galera-4-26.4.18/garb/garb_recv_loop.hpp 2024-03-22 12:54:21.000000000 +0100 @@ -1,4 +1,4 @@ -/* Copyright (C) 2011-2016 Codership Oy <i...@codership.com> */ +/* Copyright (C) 2011-2023 Codership Oy <i...@codership.com> */ #ifndef _GARB_RECV_LOOP_HPP_ #define _GARB_RECV_LOOP_HPP_ @@ -25,7 +25,9 @@ private: + bool one_loop(); void loop(); + void close_connection(); const Config& config_; gu::Config gconf_; @@ -59,6 +61,7 @@ gu::UUID uuid_; gu::seqno_t seqno_; int proto_; + bool closed_; }; /* RecvLoop */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/galera-4-26.4.17/gcs/src/gcs.cpp new/galera-4-26.4.18/gcs/src/gcs.cpp --- old/galera-4-26.4.17/gcs/src/gcs.cpp 2024-01-02 12:54:13.000000000 +0100 +++ new/galera-4-26.4.18/gcs/src/gcs.cpp 2024-03-22 12:54:21.000000000 +0100 @@ -1395,7 +1395,7 @@ assert (GCS_CONN_CLOSED == conn->state); } - gu_info ("Closing replication queue."); + gu_info ("Closing send queue."); struct gcs_repl_act** act_ptr; /* At this point (state == CLOSED) no new threads should be able to * queue for repl (check gcs_repl()), and recv thread is joined, so no @@ -1418,7 +1418,7 @@ /* wake all gcs_recv() threads () */ // FIXME: this can block waiting for applicaiton threads to fetch all // items. In certain situations this can block forever. Ticket #113 - gu_info ("Closing slave action queue."); + gu_info ("Closing receive queue."); gu_fifo_close (conn->recv_q); } @@ -2230,6 +2230,7 @@ } else { + log_debug << "Sending last applied seqno: " << gtid.seqno(); ret = gcs_core_set_last_applied(conn->core, gtid); gcs_sm_leave(conn->sm); if (ret < 0) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/galera-4-26.4.17/gcs/src/gcs_act_proto.hpp new/galera-4-26.4.18/gcs/src/gcs_act_proto.hpp --- old/galera-4-26.4.17/gcs/src/gcs_act_proto.hpp 2024-01-02 12:54:13.000000000 +0100 +++ new/galera-4-26.4.18/gcs/src/gcs_act_proto.hpp 2024-03-22 12:54:21.000000000 +0100 @@ -22,8 +22,10 @@ * 0 - initial version * 1 - support for totally ordered CC events * 2 - support for commit cut in state exchange msg + * 3 - fix for commit cut tracking issue + * (needs protocol version bump to keep it identical on all nodes) */ -#define GCS_PROTO_MAX 2 +#define GCS_PROTO_MAX 3 /*! Internal action fragment data representation */ typedef struct gcs_act_frag diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/galera-4-26.4.17/gcs/src/gcs_gcomm.cpp new/galera-4-26.4.18/gcs/src/gcs_gcomm.cpp --- old/galera-4-26.4.17/gcs/src/gcs_gcomm.cpp 2024-01-02 12:54:13.000000000 +0100 +++ new/galera-4-26.4.18/gcs/src/gcs_gcomm.cpp 2024-03-22 12:54:21.000000000 +0100 @@ -24,10 +24,10 @@ #include <gu_backtrace.hpp> #include <gu_throw.hpp> #include <gu_logger.hpp> -#include <gu_barrier.hpp> #include <gu_thread.hpp> #include <deque> +#include <future> using namespace std; using namespace gu; @@ -148,7 +148,6 @@ uuid_(), thd_(), schedparam_(conf_.get(gcomm_thread_schedparam_opt)), - barrier_(2), uri_(u), net_(Protonet::create(conf_)), tp_(0), @@ -157,7 +156,8 @@ terminated_(false), error_(0), recv_buf_(), - current_view_() + current_view_(), + connect_task_() { log_info << "backend: " << net_->type(); } @@ -172,7 +172,7 @@ void connect(bool) { } - void connect(const string& channel, bool const bootstrap); + void connect(string channel, bool const bootstrap); void close(bool force = false) { @@ -283,11 +283,12 @@ void unref() { } + void print_connect_diag(const std::string&, bool boostrap) const; + gu::Config& conf_; gcomm::UUID uuid_; gu_thread_t thd_; ThreadSchedparam schedparam_; - Barrier barrier_; URI uri_; Protonet* net_; Transport* tp_; @@ -297,6 +298,7 @@ int error_; RecvBuf recv_buf_; View current_view_; + std::packaged_task<void()> connect_task_; }; extern "C" @@ -306,43 +308,9 @@ gu_thread_exit(0); } -void GCommConn::connect(const string& channel, bool const bootstrap) +void GCommConn::print_connect_diag(const std::string& channel, + bool const bootstrap) const { - if (tp_ != 0) - { - gu_throw_fatal << "backend connection already open"; - } - - - error_ = ENOTCONN; - int err; - if ((err = gu_thread_create( - &thd_, 0, run_fn, this)) != 0) - { - gu_throw_error(err) << "Failed to create thread"; - } - - // Helper to call barrier_.wait() when goes out of scope - class StartBarrier - { - public: - StartBarrier(Barrier& barrier) : barrier_(barrier) { } - ~StartBarrier() - { - barrier_.wait(); - } - private: - Barrier& barrier_; - } start_barrier(barrier_); - - thread_set_schedparam(thd_, schedparam_); - log_info << "gcomm thread scheduling priority set to " - << thread_get_schedparam(thd_) << " "; - - uri_.set_option("gmcast.group", channel); - tp_ = Transport::create(*net_, uri_); - gcomm::connect(tp_, this); - if (bootstrap) { log_info << "gcomm: bootstrapping new group '" << channel << '\''; @@ -369,14 +337,48 @@ log_info << "gcomm: connecting to group '" << channel << "', peer '" << peer << "'"; } +} + +void GCommConn::connect(string channel, bool const bootstrap) +{ + if (tp_ != 0) + { + gu_throw_fatal << "backend connection already open"; + } + + /* This task is invoked at the very beginning of + * run() method. */ + connect_task_ = std::packaged_task<void()>{ + [this, channel, bootstrap]() + { + gcomm::Critical<Protonet> crit(*net_); + uri_.set_option("gmcast.group", channel); + tp_ = Transport::create(*net_, uri_); + gcomm::connect(tp_, this); + print_connect_diag(channel, bootstrap); + tp_->connect(bootstrap); + uuid_ = tp_->uuid(); + error_ = 0; + log_info << "gcomm: connected"; + } + }; - tp_->connect(bootstrap); + auto future = connect_task_.get_future(); - uuid_ = tp_->uuid(); + error_ = ENOTCONN; + int err; + if ((err = gu_thread_create( + &thd_, 0, run_fn, this)) != 0) + { + gu_throw_error(err) << "Failed to create thread"; + } - error_ = 0; + thread_set_schedparam(thd_, schedparam_); + log_info << "gcomm thread scheduling priority set to " + << thread_get_schedparam(thd_) << " "; - log_info << "gcomm: connected"; + /* Will throw if an exception was thrown in connect_task. */ + future.get(); } void @@ -417,7 +419,7 @@ void GCommConn::run() { - barrier_.wait(); + connect_task_(); if (error_ != 0) return; while (true) @@ -721,7 +723,6 @@ try { - gcomm::Critical<Protonet> crit(conn.get_pnet()); conn.connect(channel, bootstrap); } catch (Exception& e) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/galera-4-26.4.17/gcs/src/gcs_group.cpp new/galera-4-26.4.18/gcs/src/gcs_group.cpp --- old/galera-4-26.4.17/gcs/src/gcs_group.cpp 2024-01-02 12:54:13.000000000 +0100 +++ new/galera-4-26.4.18/gcs/src/gcs_group.cpp 2024-03-22 12:54:21.000000000 +0100 @@ -230,8 +230,8 @@ assert( 0 < group->last_applied_proto_ver || -1 == group->last_applied_proto_ver /* for unit tests */); - log_debug << "last_last_applied[" << n << "]: " - << node->id << ", " << node->last_applied << ", " + log_debug << "last_last_applied[" << group->nodes[n].name << "]: " + << node->id << ", " << node->last_applied << ", count: " << (group_count_last_applied(*group, *node) ? "yes" : "no"); /* NOTE: It is crucial for consistency that last_applied algorithm @@ -287,7 +287,7 @@ } log_debug << "final last_applied on " << group->nodes[group->my_idx].name - << "): " << group->last_applied; + << ": " << group->last_applied; } static void @@ -436,8 +436,10 @@ group->prim_uuid = group->state_uuid; group->state_uuid = GU_UUID_NIL; - if (quorum->gcs_proto_ver >= 2) // see below for older version + if (quorum->gcs_proto_ver == 2) // see below for other versions { + /* version 2 was a mistake, but we can't eliminate this code + * path for the sake of backward compatibility */ assert(quorum->last_applied >= 0); group->last_applied = quorum->last_applied; } @@ -465,11 +467,10 @@ GROUP_UPDATE_PROTO_VER(appl); #undef GROUP_UPDATE_PROTO_VER - if (quorum->gcs_proto_ver < 2) // see above for newer version + if (quorum->gcs_proto_ver != 2) // see above for version 2 { group_redo_last_applied(group); } - // votes will be recounted on CC action creation } else { // non-primary configuration @@ -812,6 +813,11 @@ gcs_node_set_last_applied (&group->nodes[msg->sender_idx], gtid.seqno()); assert(group->nodes[msg->sender_idx].last_applied >= 0); + log_debug << "Got last applied " << gtid.seqno() << " from " + << msg->sender_idx << " (" << group->nodes[msg->sender_idx].name + << "). Last node: " << group->last_node << " (" + << group->nodes[group->last_node].name << ")"; + if (msg->sender_idx == group->last_node && gtid.seqno() > group->last_applied) { /* node that was responsible for the last value, has changed it. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/galera-4-26.4.17/scripts/packages/codership-galera.spec new/galera-4-26.4.18/scripts/packages/codership-galera.spec --- old/galera-4-26.4.17/scripts/packages/codership-galera.spec 2024-01-02 12:54:18.000000000 +0100 +++ new/galera-4-26.4.18/scripts/packages/codership-galera.spec 2024-03-22 12:54:24.000000000 +0100 @@ -21,7 +21,7 @@ %define name galera-4 %define wsrep_api 26 -%{!?version: %define version 26.4.17} +%{!?version: %define version 26.4.18} %{!?release: %define release 1} %define copyright Copyright 2007-2020 Codership Oy. All rights reserved. Use is subject to license terms under GPLv2 license. %define libs %{_libdir}/%{name}