Skip to content

Commit

Permalink
[upstream] PS-8385, Bug #108471 (change redo log consumer registrator…
Browse files Browse the repository at this point in the history
… to allow user to specify a consumer name)

https://jira.percona.com/browse/PS-8385

Problem:
Currently implementation of redo log consumer UDF does not allow users
to specify a custom name for the consumer. This can be misleading when
ER_IB_MSG_LOG_WRITER_WAIT_ON_CONSUMER error is issued as it will always
report MEB as consumer name.

Fix:
Adjust the UDF to allow users to optionally specify a consumer name. In
case of no consumer name specified, assume MEB.
Also adjusted Log_consumer class to have a consumer_type ENUM. This is
used log_writer_wait_on_consumers to validate we are not waiting on
CONSUMER_TYPE_SERVER (log archive or checkpointer).
  • Loading branch information
altmannmarcelo authored and oleksandr-kachan committed Jan 19, 2024
1 parent 18e77ef commit ec08f4a
Show file tree
Hide file tree
Showing 6 changed files with 40 additions and 9 deletions.
4 changes: 4 additions & 0 deletions storage/innobase/arch/arch0log.cc
Original file line number Diff line number Diff line change
Expand Up @@ -944,6 +944,10 @@ const std::string &Arch_log_consumer::get_name() const {
return name;
}

Log_consumer::consumer_type Arch_log_consumer::get_consumer_type() const {
return Log_consumer::consumer_type::SERVER;
}

lsn_t Arch_log_consumer::get_consumed_lsn() const {
ut_a(arch_log_sys != nullptr);
ut_a(arch_log_sys->is_active());
Expand Down
2 changes: 2 additions & 0 deletions storage/innobase/include/arch0arch.h
Original file line number Diff line number Diff line change
Expand Up @@ -1308,6 +1308,8 @@ using Arch_Grp_List_Iter = Arch_Grp_List::iterator;

class Arch_log_consumer : public Log_consumer {
public:
Log_consumer::consumer_type get_consumer_type() const override;

const std::string &get_name() const override;

lsn_t get_consumed_lsn() const override;
Expand Down
9 changes: 9 additions & 0 deletions storage/innobase/include/log0consumer.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@ class Log_consumer {
is the most lagging one and it is critical to consume
the oldest redo log file. */
virtual void consumption_requested() = 0;

enum class consumer_type { SERVER, USER };

/** @return Type of this consumer. */
virtual consumer_type get_consumer_type() const = 0;
};

class Log_user_consumer : public Log_consumer {
Expand All @@ -69,6 +74,8 @@ class Log_user_consumer : public Log_consumer {

void consumption_requested() override;

Log_consumer::consumer_type get_consumer_type() const override;

private:
/** Name of this consumer (saved value from ctor). */
const std::string m_name;
Expand All @@ -82,6 +89,8 @@ class Log_checkpoint_consumer : public Log_consumer {
public:
explicit Log_checkpoint_consumer(log_t &log);

Log_consumer::consumer_type get_consumer_type() const override;

const std::string &get_name() const override;

lsn_t get_consumed_lsn() const override;
Expand Down
8 changes: 8 additions & 0 deletions storage/innobase/log/log0consumer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ lsn_t Log_user_consumer::get_consumed_lsn() const { return m_consumed_lsn; }

void Log_user_consumer::consumption_requested() {}

Log_consumer::consumer_type Log_user_consumer::get_consumer_type() const {
return Log_consumer::consumer_type::USER;
}

Log_checkpoint_consumer::Log_checkpoint_consumer(log_t &log) : m_log{log} {}

const std::string &Log_checkpoint_consumer::get_name() const {
Expand All @@ -69,6 +73,10 @@ void Log_checkpoint_consumer::consumption_requested() {
log_request_checkpoint_in_next_file(m_log);
}

Log_consumer::consumer_type Log_checkpoint_consumer::get_consumer_type() const {
return Log_consumer::consumer_type::SERVER;
}

void log_consumer_register(log_t &log, Log_consumer *log_consumer) {
ut_ad(log_files_mutex_own(log) || srv_is_being_started);

Expand Down
17 changes: 12 additions & 5 deletions storage/innobase/log/log0meb.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1669,7 +1669,8 @@ static bool redo_log_archive_flush(THD *thd) {
static std::unique_ptr<Log_user_consumer> log_meb_consumer;
static innodb_session_t *log_meb_consumer_session;

static bool redo_log_consumer_register(innodb_session_t *session) {
static bool redo_log_consumer_register(innodb_session_t *session,
std::string const &name) {
log_t &log = *log_sys;

IB_mutex_guard checkpointer_latch{&(log.checkpointer_mutex),
Expand All @@ -1683,7 +1684,7 @@ static bool redo_log_consumer_register(innodb_session_t *session) {

ut_a(log_meb_consumer.get() == nullptr);

log_meb_consumer = std::make_unique<Log_user_consumer>("MEB");
log_meb_consumer = std::make_unique<Log_user_consumer>(name);

log_meb_consumer->set_consumed_lsn(log_get_checkpoint_lsn(log));

Expand Down Expand Up @@ -2292,7 +2293,7 @@ long long innodb_redo_log_sharp_checkpoint(
*/
bool innodb_redo_log_consumer_register_init([[maybe_unused]] UDF_INIT *initid,
UDF_ARGS *args, char *message) {
if (args->arg_count != 0) {
if (args->arg_count > 1) {
snprintf(message, MYSQL_ERRMSG_SIZE, "Invalid number of arguments.");
return true;
}
Expand Down Expand Up @@ -2321,12 +2322,18 @@ long long innodb_redo_log_consumer_register(
[[maybe_unused]] UDF_INIT *initid, [[maybe_unused]] UDF_ARGS *args,
[[maybe_unused]] unsigned char *null_value,
[[maybe_unused]] unsigned char *error) {
std::string name = "MEB";
if (current_thd == nullptr ||
verify_privilege(current_thd, backup_admin_privilege)) {
return 1;
}
return static_cast<long long>(
meb::redo_log_consumer_register(thd_to_innodb_session(current_thd)));

if (args->arg_count >= 1) {
name.assign(args->args[0]);
}

return static_cast<long long>(meb::redo_log_consumer_register(
thd_to_innodb_session(current_thd), name));
}

/**
Expand Down
9 changes: 5 additions & 4 deletions storage/innobase/log/log0write.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2085,11 +2085,12 @@ static void log_writer_wait_on_consumers(log_t &log, lsn_t next_write_lsn) {
break;
}
const std::string name = consumer->get_name();

log_files_mutex_exit(*log_sys);
/* This should not be a checkpointer nor archiver, as we've used dedicated
log_writer_wait_on_checkpoint() and log_writer_wait_on_archiver() to wait
for them already */
ut_ad(name == "MEB");
/* This should not be a checkpointer nor archiver (CONSUMER_TYPE_SERVER), as
we've used dedicated log_writer_wait_on_checkpoint() and
log_writer_wait_on_archiver() to wait for them already */
ut_ad(consumer->get_consumer_type() == Log_consumer::consumer_type::USER);
log_writer_mutex_exit(log);
if (attempt++ % ATTEMPTS_BETWEEN_WARNINGS == 0) {
ib::log_warn(ER_IB_MSG_LOG_WRITER_WAIT_ON_CONSUMER, name.c_str(),
Expand Down

0 comments on commit ec08f4a

Please sign in to comment.