From 95e0d3bd061b086e94450b6a028c9d5b48a86376 Mon Sep 17 00:00:00 2001 From: "Tatiana A. Nurnberg" Date: Mon, 12 Jan 2009 06:32:49 +0100 Subject: [PATCH] Bug#31177: Server variables can't be set to their current values Bounds-checks and blocksize corrections were applied to user-input, but constants in the server were trusted implicitly. If these values did not actually meet the requirements, the user could not set change a variable, then set it back to the (wonky) factory default or maximum by explicitly specifying it (SET = vs SET =DEFAULT). Now checks also apply to the server's presets. Wonky values and maxima get corrected at startup. Consequently all non-offsetted values the user sees are valid, and users can set the variable to that exact value if they so desire. mysql-test/r/read_buffer_size_basic.result: test sets out of bounds value; we now throw a warning for this. This is a side-effect: before, the maximum was higher than the value we set here. The value was corrected to block-size, the maximum was not, hence the value was smaller than the maximum in this particular case. Now that we align the maxima at startup, the value in SET is larger than the (corrected) maximum, and we see a warning in this particular case. "This means we're doing it right." mysql-test/r/read_rnd_buffer_size_basic.result: test sets out of bounds value; we now throw a warning for this. This is a side-effect: before, the maximum was higher than the value we set here. The value was corrected to block-size, the maximum was not, hence the value was smaller than the maximum in this particular case. Now that we align the maxima at startup, the value in SET is larger than the (corrected) maximum, and we see a warning in this particular case. "This means we're doing it right." mysys/my_getopt.c: Do bounds-checking at start-up time so we'll catch and correct wonky default values and upper limits. sql/mysqld.cc: If 0 is a legal value per the docs, not to mention the default, we shouldn't give 1 as the lower limit. storage/innobase/handler/ha_innodb.cc: We are setting upper bounds here. ~0L gives -1. That is NOT what we want! --- mysql-test/r/read_buffer_size_basic.result | 4 ++++ mysql-test/r/read_rnd_buffer_size_basic.result | 4 ++++ mysys/my_getopt.c | 14 ++++++++------ sql/mysqld.cc | 2 +- storage/innobase/handler/ha_innodb.cc | 6 +++--- 5 files changed, 20 insertions(+), 10 deletions(-) diff --git a/mysql-test/r/read_buffer_size_basic.result b/mysql-test/r/read_buffer_size_basic.result index 799f7b56235..3c007dc1515 100644 --- a/mysql-test/r/read_buffer_size_basic.result +++ b/mysql-test/r/read_buffer_size_basic.result @@ -86,6 +86,8 @@ SELECT @@global.read_buffer_size= 8200 OR @@global.read_buffer_size= 8228 ; @@global.read_buffer_size= 8200 OR @@global.read_buffer_size= 8228 1 SET @@global.read_buffer_size = 2147479553; +Warnings: +Warning 1292 Truncated incorrect read_buffer_size value: '2147479553' SELECT @@global.read_buffer_size; @@global.read_buffer_size 2147479552 @@ -114,6 +116,8 @@ SELECT @@session.read_buffer_size= 8200 OR @@session.read_buffer_size= 8228 ; SET @@session.read_buffer_size = 65530.34.; ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '.' at line 1 SET @@session.read_buffer_size = 2147479553; +Warnings: +Warning 1292 Truncated incorrect read_buffer_size value: '2147479553' SELECT @@session.read_buffer_size; @@session.read_buffer_size 2147479552 diff --git a/mysql-test/r/read_rnd_buffer_size_basic.result b/mysql-test/r/read_rnd_buffer_size_basic.result index c51b0591054..c6440ac032e 100644 --- a/mysql-test/r/read_rnd_buffer_size_basic.result +++ b/mysql-test/r/read_rnd_buffer_size_basic.result @@ -88,6 +88,8 @@ SELECT @@global.read_rnd_buffer_size= 8200 OR @@global.read_rnd_buffer_size= 822 @@global.read_rnd_buffer_size= 8200 OR @@global.read_rnd_buffer_size= 8228 1 SET @@global.read_rnd_buffer_size = 2147479553; +Warnings: +Warning 1292 Truncated incorrect read_rnd_buffer_size value: '2147479553' SELECT @@global.read_rnd_buffer_size; @@global.read_rnd_buffer_size 2147479552 @@ -116,6 +118,8 @@ SELECT @@session.read_rnd_buffer_size= 8200 OR @@session.read_rnd_buffer_size= 8 SET @@session.read_rnd_buffer_size = 65530.34.; ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '.' at line 1 SET @@session.read_rnd_buffer_size = 2147479553; +Warnings: +Warning 1292 Truncated incorrect read_rnd_buffer_size value: '2147479553' SELECT @@session.read_rnd_buffer_size; @@session.read_rnd_buffer_size 2147479552 diff --git a/mysys/my_getopt.c b/mysys/my_getopt.c index 0f8055860d4..f97550d4429 100644 --- a/mysys/my_getopt.c +++ b/mysys/my_getopt.c @@ -976,24 +976,26 @@ static void init_one_value(const struct my_option *option, uchar* *variable, *((my_bool*) variable)= (my_bool) value; break; case GET_INT: - *((int*) variable)= (int) value; + *((int*) variable)= (int) getopt_ll_limit_value((int) value, option, NULL); break; - case GET_UINT: case GET_ENUM: *((uint*) variable)= (uint) value; break; + case GET_UINT: + *((uint*) variable)= (uint) getopt_ull_limit_value((uint) value, option, NULL); + break; case GET_LONG: - *((long*) variable)= (long) value; + *((long*) variable)= (long) getopt_ll_limit_value((long) value, option, NULL); break; case GET_ULONG: - *((ulong*) variable)= (ulong) value; + *((ulong*) variable)= (ulong) getopt_ull_limit_value((ulong) value, option, NULL); break; case GET_LL: - *((longlong*) variable)= (longlong) value; + *((longlong*) variable)= (longlong) getopt_ll_limit_value((longlong) value, option, NULL); break; case GET_ULL: case GET_SET: - *((ulonglong*) variable)= (ulonglong) value; + *((ulonglong*) variable)= (ulonglong) getopt_ull_limit_value((ulonglong) value, option, NULL); break; case GET_DOUBLE: *((double*) variable)= (double) value; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 1e9d942b1dd..a2ccbc42e77 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -6611,7 +6611,7 @@ The minimum value for this variable is 4096.", {"max_user_connections", OPT_MAX_USER_CONNECTIONS, "The maximum number of active connections for a single user (0 = no limit).", (uchar**) &max_user_connections, (uchar**) &max_user_connections, 0, GET_UINT, - REQUIRED_ARG, 0, 1, UINT_MAX, 0, 1, 0}, + REQUIRED_ARG, 0, 0, UINT_MAX, 0, 1, 0}, {"max_write_lock_count", OPT_MAX_WRITE_LOCK_COUNT, "After this many write locks, allow some read locks to run in between.", (uchar**) &max_write_lock_count, (uchar**) &max_write_lock_count, 0, GET_ULONG, diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index bf777b982db..6358f7ce055 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -8249,7 +8249,7 @@ static MYSQL_SYSVAR_BOOL(adaptive_hash_index, innobase_adaptive_hash_index, static MYSQL_SYSVAR_LONG(additional_mem_pool_size, innobase_additional_mem_pool_size, PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY, "Size of a memory pool InnoDB uses to store data dictionary information and other internal data structures.", - NULL, NULL, 1*1024*1024L, 512*1024L, ~0L, 1024); + NULL, NULL, 1*1024*1024L, 512*1024L, LONG_MAX, 1024); static MYSQL_SYSVAR_ULONG(autoextend_increment, srv_auto_extend_increment, PLUGIN_VAR_RQCMDARG, @@ -8289,7 +8289,7 @@ static MYSQL_SYSVAR_LONG(lock_wait_timeout, innobase_lock_wait_timeout, static MYSQL_SYSVAR_LONG(log_buffer_size, innobase_log_buffer_size, PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY, "The size of the buffer which InnoDB uses to write log to the log files on disk.", - NULL, NULL, 1024*1024L, 256*1024L, ~0L, 1024); + NULL, NULL, 1024*1024L, 256*1024L, LONG_MAX, 1024); static MYSQL_SYSVAR_LONGLONG(log_file_size, innobase_log_file_size, PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY, @@ -8309,7 +8309,7 @@ static MYSQL_SYSVAR_LONG(mirrored_log_groups, innobase_mirrored_log_groups, static MYSQL_SYSVAR_LONG(open_files, innobase_open_files, PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY, "How many files at the maximum InnoDB keeps open at the same time.", - NULL, NULL, 300L, 10L, ~0L, 0); + NULL, NULL, 300L, 10L, LONG_MAX, 0); static MYSQL_SYSVAR_ULONG(sync_spin_loops, srv_n_spin_wait_rounds, PLUGIN_VAR_RQCMDARG,