Skip to content

MDEV-37062 Fixes for wsrep provider options plugin #495

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: 11.4
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions mysql-test/suite/wsrep/r/wsrep_provider_plugin_config.result
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
SHOW VARIABLES LIKE 'wsrep_provider_pc_npvo';
Variable_name Value
wsrep_provider_pc_npvo ON
SELECT REGEXP_SUBSTR(@@wsrep_provider_options, 'pc.npvo = [^;]+') AS provider_option;
provider_option
pc.npvo = true
SHOW VARIABLES LIKE 'wsrep_provider_repl_max_ws_size';
Variable_name Value
wsrep_provider_repl_max_ws_size 1024
SELECT REGEXP_SUBSTR(@@wsrep_provider_options, 'repl.max_ws_size = [^;]+') AS provider_option;
provider_option
repl.max_ws_size = 1024
SHOW VARIABLES LIKE 'wsrep_provider_evs_install_timeout';
Variable_name Value
wsrep_provider_evs_install_timeout 8.100000
SELECT REGEXP_SUBSTR(@@wsrep_provider_options, 'evs.install_timeout = [^;]+') AS provider_option;
provider_option
evs.install_timeout = PT8.1S
SHOW VARIABLES LIKE 'wsrep_provider_gcache_size';
Variable_name Value
wsrep_provider_gcache_size 10485760
SELECT REGEXP_SUBSTR(@@wsrep_provider_options, 'gcache.size = [^;]+') AS provider_option;
provider_option
gcache.size = 10M
26 changes: 26 additions & 0 deletions mysql-test/suite/wsrep/t/wsrep_provider_plugin_config.cnf
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
!include include/default_my.cnf

[mysqld.1]
wsrep-on=ON
wsrep-cluster-address=gcomm://
wsrep-provider=@ENV.WSREP_PROVIDER
binlog-format=ROW
plugin-wsrep-provider=ON
wsrep-provider-base-port=@OPT.port

# Test different type of options
wsrep-provider-gcache-size=1024
wsrep-provider-pc-npvo=ON
wsrep-provider-evs-install-timeout=8.1
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe it would be good to use interger value to avoid potential issues with floating point representation?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is specifically testing integers, booleans, and floating point value.


# Repeat same variable again
wsrep_provider_gcache_size=10M
wsrep_provider_pc_npvo=OFF
wsrep_provider_pc_npvo=ON

# Option wsrep_provider_options can be used even if plugin-wsrep-provider
# is enabled. However, settings in wsrep_provider_options have lower
# precedence. For instance, the setting gcache.size below will
# be ignored because it was already set through provider options
# plugin above.
wsrep_provider_options='gcache.size=20M;repl.max_ws_size=1024'
14 changes: 14 additions & 0 deletions mysql-test/suite/wsrep/t/wsrep_provider_plugin_config.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
--source include/have_wsrep.inc
--source include/have_innodb.inc

SHOW VARIABLES LIKE 'wsrep_provider_pc_npvo';
SELECT REGEXP_SUBSTR(@@wsrep_provider_options, 'pc.npvo = [^;]+') AS provider_option;

SHOW VARIABLES LIKE 'wsrep_provider_repl_max_ws_size';
SELECT REGEXP_SUBSTR(@@wsrep_provider_options, 'repl.max_ws_size = [^;]+') AS provider_option;

SHOW VARIABLES LIKE 'wsrep_provider_evs_install_timeout';
SELECT REGEXP_SUBSTR(@@wsrep_provider_options, 'evs.install_timeout = [^;]+') AS provider_option;

SHOW VARIABLES LIKE 'wsrep_provider_gcache_size';
SELECT REGEXP_SUBSTR(@@wsrep_provider_options, 'gcache.size = [^;]+') AS provider_option;
2 changes: 2 additions & 0 deletions sql/wsrep_client_service.cc
Original file line number Diff line number Diff line change
Expand Up @@ -393,3 +393,5 @@ int Wsrep_client_service::bf_rollback()

DBUG_RETURN(ret);
}

void Wsrep_client_service::notify_state_change() {}
2 changes: 2 additions & 0 deletions sql/wsrep_client_service.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ class Wsrep_client_service : public wsrep::client_service
void debug_sync(const char*) override;
void debug_crash(const char*) override;
int bf_rollback() override;
void notify_state_change() override;

private:
friend class Wsrep_server_service;
THD* m_thd;
Expand Down
10 changes: 7 additions & 3 deletions sql/wsrep_mysqld.cc
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
#include "wsrep_schema.h"
#include "wsrep_xid.h"
#include "wsrep_trans_observer.h"
#include "wsrep_plugin.h" /* wsrep_load_provider_plugin_defaults() */
#include "mysql/service_wsrep.h"
#include <cstdio>
#include <cstdlib>
Expand Down Expand Up @@ -897,9 +898,12 @@ int wsrep_init()

Wsrep_server_state::init_provider_services();
if (Wsrep_server_state::instance().load_provider(
wsrep_provider,
wsrep_provider_options,
Wsrep_server_state::instance().provider_services()))
wsrep_provider,
[](const wsrep::provider_options &opts, std::string& defaults) {
defaults.append(wsrep_provider_options);
return wsrep_load_provider_plugin_defaults(opts, defaults);
},
Wsrep_server_state::instance().provider_services()))
{
WSREP_ERROR("Failed to load provider");
Wsrep_server_state::deinit_provider_services();
Expand Down
105 changes: 104 additions & 1 deletion sql/wsrep_plugin.cc
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
in favor of single options which are initialized from provider.
*/

#include "wsrep_plugin.h"
#include "sql_plugin.h"
#include "sql_priv.h"
#include "sql_class.h"
Expand Down Expand Up @@ -131,7 +132,8 @@ static void wsrep_provider_sysvar_update(THD *thd,
T new_value= *((T *) save);

auto options= Wsrep_server_state::get_options();
if (options->set(opt->name(), make_option_value(new_value)))
if (options->set(Wsrep_server_state::get_provider(), opt->name(),
make_option_value(new_value)))
{
my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), opt->name(),
make_option_value(new_value)->as_string());
Expand Down Expand Up @@ -275,6 +277,107 @@ void wsrep_destroy_sysvar(struct st_mysql_sys_var *var)
my_free(var);
}

struct st_mysql_sys_var
{
MYSQL_PLUGIN_VAR_HEADER;
};

struct my_option_arg
{
wsrep::provider_options::option *option;
struct st_mysql_sys_var *sysvar;
std::string *defaults;
};

static void my_option_init(struct my_option &my_opt,
struct my_option_arg &my_arg)
{
std::string option_name("wsrep-provider-");
option_name.append(my_arg.sysvar->name);
for (size_t i= 0; i < option_name.size(); ++i)
if (option_name[i] == '_')
option_name[i]= '-';
my_opt.name= my_strdup(PSI_INSTRUMENT_ME, option_name.c_str(), MYF(0));
my_opt.id= 0;
plugin_opt_set_limits(&my_opt, my_arg.sysvar);
my_opt.value= my_opt.u_max_value= *(uchar ***) (my_arg.sysvar + 1);
my_opt.block_size= 0;
my_opt.app_type= &my_arg;
}

static void my_option_deinit(struct my_option &my_opt)
{
if (my_opt.name)
my_free((void*)my_opt.name);
}

static void make_my_options(std::vector<struct my_option_arg> &my_args,
std::vector<struct my_option> &my_options)
{
for (auto& arg : my_args)
{
struct my_option my_opt;
my_option_init(my_opt, arg);
my_options.push_back(my_opt);
}
struct my_option null_opt;
null_opt.name= NULL;
my_options.push_back(null_opt);
}

static void make_my_option_args(const wsrep::provider_options &options,
std::string &defaults,
std::vector<struct my_option_arg> &my_args)
{
options.for_each([&](wsrep::provider_options::option *opt) {
my_args.push_back({opt, wsrep_make_sysvar_for_option(opt), &defaults});
});
}

static my_bool option_changed(const struct my_option *opt, const char *value,
const char *filename)
{
my_option_arg *my_arg= (struct my_option_arg *) opt->app_type;
if (my_arg->defaults->size())
my_arg->defaults->append(";");
my_arg->defaults->append(my_arg->option->real_name());
my_arg->defaults->append("=");
my_arg->defaults->append(value);
return 0;
}

int wsrep_load_provider_plugin_defaults(const wsrep::provider_options &options,
std::string &extra_options)
{
int argc= orig_argc;
char **argv= orig_argv;

if (load_defaults(MYSQL_CONFIG_NAME, load_default_groups, &argc, &argv))
{
return 1;
}
char **defaults_argv= argv;

std::vector<struct my_option> my_options;
std::vector<struct my_option_arg> my_option_args;
make_my_option_args(options, extra_options, my_option_args);
make_my_options(my_option_args, my_options);

my_bool skip_unknown_orig= my_getopt_skip_unknown;
my_getopt_skip_unknown= TRUE;
int error= handle_options(&argc, &argv, &my_options[0], option_changed);
my_getopt_skip_unknown= skip_unknown_orig;

for (struct my_option &opt : my_options)
my_option_deinit(opt);
for (struct my_option_arg &arg : my_option_args)
wsrep_destroy_sysvar(arg.sysvar);
if (argv)
free_defaults(defaults_argv);

return error;
}

static int wsrep_provider_plugin_init(void *p)
{
WSREP_DEBUG("wsrep_provider_plugin_init()");
Expand Down
8 changes: 7 additions & 1 deletion sql/wsrep_plugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@
#ifndef WSREP_PLUGIN_H
#define WSREP_PLUGIN_H

class option;
#include "wsrep/provider_options.hpp"

struct st_mysql_sys_var;

/* Returns true if provider plugin was initialized and is active */
Expand All @@ -33,4 +34,9 @@ wsrep_make_sysvar_for_option(wsrep::provider_options::option *);
/* Destroy a sysvar created by make_sysvar_for_option */
void wsrep_destroy_sysvar(struct st_mysql_sys_var *);

/* Parse defaults from config/command line, returns corresponding
provider options string */
int wsrep_load_provider_plugin_defaults(const wsrep::provider_options &,
std::string &);

#endif /* WSREP_PLUGIN_H */
6 changes: 3 additions & 3 deletions sql/wsrep_server_state.cc
Original file line number Diff line number Diff line change
Expand Up @@ -99,9 +99,9 @@ int Wsrep_server_state::init_provider(const std::string& provider,
int Wsrep_server_state::init_options()
{
if (!m_instance) return 1;
m_options= std::unique_ptr<wsrep::provider_options>(
new wsrep::provider_options(m_instance->provider()));
int ret= m_options->initial_options();
m_options=
std::unique_ptr<wsrep::provider_options>(new wsrep::provider_options());
int ret= m_options->initial_options(m_instance->provider());
if (ret)
{
WSREP_ERROR("Failed to initialize provider options");
Expand Down