summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSachin Setiya <sachinsetia1001@gmail.com>2017-01-10 10:08:04 +0530
committerSachin Setiya <sachinsetia1001@gmail.com>2017-01-27 17:09:35 +0530
commit06853d45de66cf825e7c6aaf3190c5bf6715625e (patch)
tree3e9c8ed78d5ffb255e72ad3c882dcd2f79b41dba
parentb72b9bead74601b6b0ee166e8b55f9417ad0faac (diff)
downloadmariadb-git-bb-10.0-gal-sachin.tar.gz
MDEV-4774 Strangeness with max_binlog_stmt_cache_size Settingsbb-10.0-gal-sachin
Problem:- When setting max_binlog_stmt_cache_size=18446744073709547520 from either command line or .cnf file, server fails to start. Solution:- Added one more function eval_num_suffix_ull , which uses strtoull to get unsigned ulonglong from string. And getopt_ull calls this function instead of eval_num_suffix. Also changed previous eval_num_suffix to eval_num_suffix_ll to remain consistent.
-rw-r--r--mysql-test/suite/binlog/r/binlog_max_binlog_stmt_cache_size.result16
-rw-r--r--mysql-test/suite/binlog/t/binlog_max_binlog_stmt_cache_size.opt1
-rw-r--r--mysql-test/suite/binlog/t/binlog_max_binlog_stmt_cache_size.test30
-rw-r--r--mysys/my_getopt.c72
4 files changed, 107 insertions, 12 deletions
diff --git a/mysql-test/suite/binlog/r/binlog_max_binlog_stmt_cache_size.result b/mysql-test/suite/binlog/r/binlog_max_binlog_stmt_cache_size.result
new file mode 100644
index 00000000000..6659148f24a
--- /dev/null
+++ b/mysql-test/suite/binlog/r/binlog_max_binlog_stmt_cache_size.result
@@ -0,0 +1,16 @@
+select @@max_binlog_stmt_cache_size;
+@@max_binlog_stmt_cache_size
+18446744073709547520
+SET @cache_size= @@max_binlog_stmt_cache_size;
+SET @max_uint64= 18446744073709551615;
+SET @max_uint32= 4294967295;
+SET @max_absolute_value = if (@max_uint32 < @cache_size, @max_uint64, @max_uint32);
+set global max_binlog_stmt_cache_size= @cache_size+1;
+select @@max_binlog_stmt_cache_size;
+@@max_binlog_stmt_cache_size
+18446744073709547520
+set global max_binlog_stmt_cache_size= @cache_size-1;
+select @@max_binlog_stmt_cache_size = @cache_size-4096;
+@@max_binlog_stmt_cache_size = @cache_size-4096
+1
+set @@global.max_binlog_stmt_cache_size= @cache_size;
diff --git a/mysql-test/suite/binlog/t/binlog_max_binlog_stmt_cache_size.opt b/mysql-test/suite/binlog/t/binlog_max_binlog_stmt_cache_size.opt
new file mode 100644
index 00000000000..c52ef14d5d0
--- /dev/null
+++ b/mysql-test/suite/binlog/t/binlog_max_binlog_stmt_cache_size.opt
@@ -0,0 +1 @@
+--max_binlog_stmt_cache_size=18446744073709547520
diff --git a/mysql-test/suite/binlog/t/binlog_max_binlog_stmt_cache_size.test b/mysql-test/suite/binlog/t/binlog_max_binlog_stmt_cache_size.test
new file mode 100644
index 00000000000..10769efb9f9
--- /dev/null
+++ b/mysql-test/suite/binlog/t/binlog_max_binlog_stmt_cache_size.test
@@ -0,0 +1,30 @@
+source include/have_log_bin.inc;
+select @@max_binlog_stmt_cache_size;
+
+--replace_result 18446744073709547520 max_binlog_stmt_cache_size 4294963200 max_binlog_stmt_cache_size
+--disable_warnings
+SET @cache_size= @@max_binlog_stmt_cache_size;
+SET @max_uint64= 18446744073709551615;
+SET @max_uint32= 4294967295;
+SET @max_absolute_value = if (@max_uint32 < @cache_size, @max_uint64, @max_uint32);
+
+set global max_binlog_stmt_cache_size= @cache_size+1;
+select @@max_binlog_stmt_cache_size;
+
+set global max_binlog_stmt_cache_size= @cache_size-1;
+select @@max_binlog_stmt_cache_size = @cache_size-4096;
+
+
+#this can be commented out if IF(cond, expr,expr) bug is solved
+#Select @max_absolute_value;
+#set global max_binlog_stmt_cache_size= @max_absolute_value-4096;
+#select @@max_binlog_stmt_cache_size;
+
+#set global max_binlog_stmt_cache_size= @max_absolute_value -1;
+#select @@max_binlog_stmt_cache_size;
+
+#--error ER_WRONG_TYPE_FOR_VAR
+#set global max_binlog_stmt_cache_size= @max_absolute_value +1;
+#select @@max_binlog_stmt_cache_size;
+
+set @@global.max_binlog_stmt_cache_size= @cache_size;
diff --git a/mysys/my_getopt.c b/mysys/my_getopt.c
index 2a4557118b0..e68a08ee735 100644
--- a/mysys/my_getopt.c
+++ b/mysys/my_getopt.c
@@ -895,15 +895,39 @@ my_bool getopt_compare_strings(register const char *s, register const char *t,
/*
function: eval_num_suffix
+ Transforms suffix like k/m/g to their real value.
+*/
+
+static inline long eval_num_suffix(char *suffix, int *error)
+{
+ long num= 1;
+ if (*suffix == 'k' || *suffix == 'K')
+ num*= 1024L;
+ else if (*suffix == 'm' || *suffix == 'M')
+ num*= 1024L * 1024L;
+ else if (*suffix == 'g' || *suffix == 'G')
+ num*= 1024L * 1024L * 1024L;
+ else if (*suffix)
+ {
+ *error= 1;
+ return 0;
+ }
+ return num;
+}
+
+/*
+ function: eval_num_suffix_ll
+
Transforms a number with a suffix to real number. Suffix can
be k|K for kilo, m|M for mega or g|G for giga.
*/
-static longlong eval_num_suffix(char *argument, int *error, char *option_name)
+static longlong eval_num_suffix_ll(char *argument,
+ int *error, char *option_name)
{
char *endchar;
longlong num;
- DBUG_ENTER("eval_num_suffix");
+ DBUG_ENTER("eval_num_suffix_ll");
*error= 0;
@@ -916,23 +940,47 @@ static longlong eval_num_suffix(char *argument, int *error, char *option_name)
*error= 1;
DBUG_RETURN(0);
}
- if (*endchar == 'k' || *endchar == 'K')
- num*= 1024L;
- else if (*endchar == 'm' || *endchar == 'M')
- num*= 1024L * 1024L;
- else if (*endchar == 'g' || *endchar == 'G')
- num*= 1024L * 1024L * 1024L;
- else if (*endchar)
- {
+ num*= eval_num_suffix(endchar, error);
+ if (*error)
fprintf(stderr,
"Unknown suffix '%c' used for variable '%s' (value '%s')\n",
*endchar, option_name, argument);
+ DBUG_RETURN(num);
+}
+
+/*
+ function: eval_num_suffix_ull
+
+ Transforms a number with a suffix to positive Integer. Suffix can
+ be k|K for kilo, m|M for mega or g|G for giga.
+*/
+
+static ulonglong eval_num_suffix_ull(char *argument,
+ int *error, char *option_name)
+{
+ char *endchar;
+ ulonglong num;
+ DBUG_ENTER("eval_num_suffix_ull");
+
+ *error= 0;
+ errno= 0;
+ num= strtoull(argument, &endchar, 10);
+ if (errno == ERANGE)
+ {
+ my_getopt_error_reporter(ERROR_LEVEL,
+ "Incorrect integer value: '%s'", argument);
*error= 1;
DBUG_RETURN(0);
}
+ num*= eval_num_suffix(endchar, error);
+ if (*error)
+ fprintf(stderr,
+ "Unknown suffix '%c' used for variable '%s' (value '%s')\n",
+ *endchar, option_name, argument);
DBUG_RETURN(num);
}
+
/*
function: getopt_ll
@@ -946,7 +994,7 @@ static longlong eval_num_suffix(char *argument, int *error, char *option_name)
static longlong getopt_ll(char *arg, const struct my_option *optp, int *err)
{
- longlong num=eval_num_suffix(arg, err, (char*) optp->name);
+ longlong num=eval_num_suffix_ll(arg, err, (char*) optp->name);
return getopt_ll_limit_value(num, optp, NULL);
}
@@ -1023,7 +1071,7 @@ longlong getopt_ll_limit_value(longlong num, const struct my_option *optp,
static ulonglong getopt_ull(char *arg, const struct my_option *optp, int *err)
{
- ulonglong num= eval_num_suffix(arg, err, (char*) optp->name);
+ ulonglong num= eval_num_suffix_ull(arg, err, (char*) optp->name);
return getopt_ull_limit_value(num, optp, NULL);
}