Commit 74f80b34 authored by Daniele Sciascia's avatar Daniele Sciascia Committed by Nirbhay Choubey

MW-267 Enforce wsrep_max_ws_size limit in wsrep provider

This changes variable wsrep_max_ws_size so that its value
is linked to the value of provider option repl.max_ws_size.
That is, changing the value of variable wsrep_max_ws_size
will change the value of provider option repl.max_ws_size,
and viceversa.
The writeset size limit is always enforced in the provider,
regardless of which option is used.
parent 5197fcf6
......@@ -30,7 +30,7 @@ WSREP_FORCED_BINLOG_FORMAT NONE
WSREP_LOAD_DATA_SPLITTING ON
WSREP_LOG_CONFLICTS OFF
WSREP_MAX_WS_ROWS 0
WSREP_MAX_WS_SIZE 1073741824
WSREP_MAX_WS_SIZE 2147483647
WSREP_MYSQL_REPLICATION_BUNDLE 0
WSREP_NOTIFY_CMD
WSREP_ON ON
......
......@@ -5,4 +5,13 @@ ERROR HY000: Got error 5 "Input/output error" during COMMIT
SELECT COUNT(*) = 0 FROM t1;
COUNT(*) = 0
1
SET GLOBAL wsrep_provider_options = 'repl.max_ws_size=10000';
SELECT @@wsrep_max_ws_size = 10000;
@@wsrep_max_ws_size = 10000
1
SET GLOBAL wsrep_provider_options = 'repl.max_ws_size=20000';
SET GLOBAL wsrep_provider_options = 'repl.max_ws_size=10000';
SET GLOBAL wsrep_max_ws_size = 20000;
provider_options_match
1
DROP TABLE t1;
......@@ -16,6 +16,29 @@ SET GLOBAL wsrep_max_ws_size = 1024;
INSERT INTO t1 VALUES (DEFAULT, REPEAT('X', 1024));
SELECT COUNT(*) = 0 FROM t1;
#
# Changing repl.max_ws_size also changes wsrep_max_ws_size
#
SET GLOBAL wsrep_provider_options = 'repl.max_ws_size=10000';
SELECT @@wsrep_max_ws_size = 10000;
#
# Changing wsrep_max_ws_size is equivalent to changing repl.max_ws_size
#
SET GLOBAL wsrep_provider_options = 'repl.max_ws_size=20000';
--let $provider_options = `SELECT @@wsrep_provider_options`
SET GLOBAL wsrep_provider_options = 'repl.max_ws_size=10000';
SET GLOBAL wsrep_max_ws_size = 20000;
--let $provider_options_updated = `SELECT @@wsrep_provider_options`
--disable_query_log
--eval SELECT STRCMP('$provider_options', '$provider_options_updated') = 0 AS provider_options_match
--enable_query_log
--disable_query_log
--eval SET GLOBAL wsrep_max_ws_size = $wsrep_max_ws_size_orig
--enable_query_log
......
......@@ -4688,8 +4688,9 @@ static Sys_var_charptr Sys_wsrep_start_position (
static Sys_var_ulong Sys_wsrep_max_ws_size (
"wsrep_max_ws_size", "Max write set size (bytes)",
GLOBAL_VAR(wsrep_max_ws_size), CMD_LINE(REQUIRED_ARG),
/* Upper limit is 65K short of 4G to avoid overlows on 32-bit systems */
VALID_RANGE(1024, WSREP_MAX_WS_SIZE), DEFAULT(1073741824UL), BLOCK_SIZE(1));
VALID_RANGE(1024, WSREP_MAX_WS_SIZE), DEFAULT(WSREP_MAX_WS_SIZE),
BLOCK_SIZE(1), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
ON_UPDATE(wsrep_max_ws_size_update));
static Sys_var_ulong Sys_wsrep_max_ws_rows (
"wsrep_max_ws_rows", "Max number of rows in write set",
......
......@@ -39,15 +39,9 @@ static Log_event* wsrep_read_log_event(
const char *error= 0;
Log_event *res= 0;
if (data_len > wsrep_max_ws_size)
{
error = "Event too big";
goto err;
}
res= Log_event::read_log_event(buf, data_len, &error, description_event, true);
res= Log_event::read_log_event(buf, data_len, &error, description_event,
true);
err:
if (!res)
{
DBUG_ASSERT(error != 0);
......
......@@ -19,7 +19,7 @@
#include "sql_class.h" // THD, IO_CACHE
#define HEAP_PAGE_SIZE 65536 /* 64K */
#define WSREP_MAX_WS_SIZE (0xFFFFFFFFUL - HEAP_PAGE_SIZE)
#define WSREP_MAX_WS_SIZE 2147483647 /* 2GB */
/*
Write the contents of a cache to a memory buffer.
......
......@@ -179,6 +179,32 @@ void wsrep_start_position_init (const char* val)
wsrep_set_local_position (val, false);
}
static int get_provider_option_value(const char* opts,
const char* opt_name,
ulong* opt_value)
{
int ret= 1;
ulong opt_value_tmp;
char *opt_value_str, *s, *opts_copy= my_strdup(opts, MYF(MY_WME));
if ((opt_value_str= strstr(opts_copy, opt_name)) == NULL)
goto end;
opt_value_str= strtok_r(opt_value_str, "=", &s);
if (opt_value_str == NULL) goto end;
opt_value_str= strtok_r(NULL, ";", &s);
if (opt_value_str == NULL) goto end;
opt_value_tmp= strtoul(opt_value_str, NULL, 10);
if (errno == ERANGE) goto end;
*opt_value= opt_value_tmp;
ret= 0;
end:
my_free(opts_copy);
return ret;
}
static bool refresh_provider_options()
{
WSREP_DEBUG("refresh_provider_options: %s",
......@@ -186,9 +212,10 @@ static bool refresh_provider_options()
char* opts= wsrep->options_get(wsrep);
if (opts)
{
if (wsrep_provider_options) my_free((void *)wsrep_provider_options);
wsrep_provider_options = (char*)my_memdup(opts, strlen(opts) + 1,
MYF(MY_WME));
wsrep_provider_options_init(opts);
get_provider_option_value(wsrep_provider_options,
(char*)"repl.max_ws_size",
&wsrep_max_ws_size);
}
else
{
......@@ -531,6 +558,21 @@ bool wsrep_desync_update (sys_var *self, THD* thd, enum_var_type type)
return false;
}
bool wsrep_max_ws_size_update (sys_var *self, THD *thd, enum_var_type)
{
char max_ws_size_opt[128];
my_snprintf(max_ws_size_opt, sizeof(max_ws_size_opt),
"repl.max_ws_size=%d", wsrep_max_ws_size);
wsrep_status_t ret= wsrep->options_set(wsrep, max_ws_size_opt);
if (ret != WSREP_OK)
{
WSREP_ERROR("Set options returned %d", ret);
refresh_provider_options();
return true;
}
return refresh_provider_options();
}
/*
* Status variables stuff below
*/
......
......@@ -83,4 +83,6 @@ extern bool wsrep_slave_threads_update UPDATE_ARGS;
extern bool wsrep_desync_check CHECK_ARGS;
extern bool wsrep_desync_update UPDATE_ARGS;
extern bool wsrep_max_ws_size_update UPDATE_ARGS;
#endif /* WSREP_VAR_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment