From 56274466be1f722de0f785a02dd820291f59ec1b Mon Sep 17 00:00:00 2001 From: "tnurnberg@mysql.com/white.intern.koehntopp.de" <> Date: Sat, 1 Dec 2007 19:55:06 +0100 Subject: [PATCH] Bug#31177: Server variables can't be set to their current values 5.1+ specific fixes (plugins etc.) --- include/my_getopt.h | 3 +- mysql-test/r/index_merge_myisam.result | 2 ++ mysql-test/r/innodb.result | 4 +-- mysql-test/r/variables.result | 34 +++++++++++++++--- mysql-test/t/variables.test | 2 +- mysys/my_getopt.c | 48 +++++++++++++++++++------- sql/mysqld.cc | 2 +- sql/sql_plugin.cc | 35 ++++++++++++++++--- 8 files changed, 104 insertions(+), 26 deletions(-) diff --git a/include/my_getopt.h b/include/my_getopt.h index c0101fd4cdb..14f8e6df95b 100644 --- a/include/my_getopt.h +++ b/include/my_getopt.h @@ -75,7 +75,8 @@ extern void my_getopt_register_get_addr(uchar ** (*func_addr)(const char *, uint const struct my_option *)); ulonglong getopt_ull_limit_value(ulonglong num, const struct my_option *optp, - bool *fixed); + bool *fix); +longlong getopt_ll_limit_value(longlong, const struct my_option *,bool *fix); my_bool getopt_compare_strings(const char *s, const char *t, uint length); C_MODE_END diff --git a/mysql-test/r/index_merge_myisam.result b/mysql-test/r/index_merge_myisam.result index 9d7d06f7f1b..1827871861e 100644 --- a/mysql-test/r/index_merge_myisam.result +++ b/mysql-test/r/index_merge_myisam.result @@ -342,6 +342,8 @@ create table t4 (a int); insert into t4 values (1),(4),(3); set @save_join_buffer_size=@@join_buffer_size; set join_buffer_size= 4000; +Warnings: +Warning 1292 Truncated incorrect join_buffer_size value: '4000' explain select max(A.key1 + B.key1 + A.key2 + B.key2 + A.key3 + B.key3 + A.key4 + B.key4 + A.key5 + B.key5) from t0 as A force index(i1,i2), t0 as B force index (i1,i2) where (A.key1 < 500000 or A.key2 < 3) diff --git a/mysql-test/r/innodb.result b/mysql-test/r/innodb.result index c932be6415e..2a3ef37d7a9 100644 --- a/mysql-test/r/innodb.result +++ b/mysql-test/r/innodb.result @@ -1793,7 +1793,7 @@ Variable_name Value innodb_thread_concurrency 8 set global innodb_thread_concurrency=1001; Warnings: -Warning 1292 Truncated incorrect innodb_thread_concurrency value: '1001' +Warning 1292 Truncated incorrect thread_concurrency value: '1001' show variables like "innodb_thread_concurrency"; Variable_name Value innodb_thread_concurrency 1000 @@ -1814,7 +1814,7 @@ Variable_name Value innodb_concurrency_tickets 1000 set global innodb_concurrency_tickets=0; Warnings: -Warning 1292 Truncated incorrect innodb_concurrency_tickets value: '0' +Warning 1292 Truncated incorrect concurrency_tickets value: '0' show variables like "innodb_concurrency_tickets"; Variable_name Value innodb_concurrency_tickets 1 diff --git a/mysql-test/r/variables.result b/mysql-test/r/variables.result index bdaec70021b..e57f82aca26 100644 --- a/mysql-test/r/variables.result +++ b/mysql-test/r/variables.result @@ -279,6 +279,8 @@ NET_READ_TIMEOUT 600 NET_RETRY_COUNT 10 NET_WRITE_TIMEOUT 500 set net_buffer_length=1; +Warnings: +Warning 1292 Truncated incorrect net_buffer_length value: '1' show variables like 'net_buffer_length'; Variable_name Value net_buffer_length 1024 @@ -312,14 +314,14 @@ show variables like '%alloc%'; Variable_name Value query_alloc_block_size 8192 query_prealloc_size 8192 -range_alloc_block_size 2048 +range_alloc_block_size 4096 transaction_alloc_block_size 8192 transaction_prealloc_size 4096 select * from information_schema.session_variables where variable_name like '%alloc%' order by 1; VARIABLE_NAME VARIABLE_VALUE QUERY_ALLOC_BLOCK_SIZE 8192 QUERY_PREALLOC_SIZE 8192 -RANGE_ALLOC_BLOCK_SIZE 2048 +RANGE_ALLOC_BLOCK_SIZE 4096 TRANSACTION_ALLOC_BLOCK_SIZE 8192 TRANSACTION_PREALLOC_SIZE 4096 set @@range_alloc_block_size=1024*16; @@ -351,14 +353,14 @@ show variables like '%alloc%'; Variable_name Value query_alloc_block_size 8192 query_prealloc_size 8192 -range_alloc_block_size 2048 +range_alloc_block_size 4096 transaction_alloc_block_size 8192 transaction_prealloc_size 4096 select * from information_schema.session_variables where variable_name like '%alloc%' order by 1; VARIABLE_NAME VARIABLE_VALUE QUERY_ALLOC_BLOCK_SIZE 8192 QUERY_PREALLOC_SIZE 8192 -RANGE_ALLOC_BLOCK_SIZE 2048 +RANGE_ALLOC_BLOCK_SIZE 4096 TRANSACTION_ALLOC_BLOCK_SIZE 8192 TRANSACTION_PREALLOC_SIZE 4096 SELECT @@version LIKE 'non-existent'; @@ -416,6 +418,8 @@ select @@autocommit, @@big_tables; @@autocommit @@big_tables 1 1 set global binlog_cache_size=100; +Warnings: +Warning 1292 Truncated incorrect binlog_cache_size value: '100' set bulk_insert_buffer_size=100; set character set cp1251_koi8; set character set default; @@ -444,6 +448,8 @@ set global flush_time=100; set insert_id=1; set interactive_timeout=100; set join_buffer_size=100; +Warnings: +Warning 1292 Truncated incorrect join_buffer_size value: '100' set last_insert_id=1; set global local_infile=1; set long_query_time=0.000001; @@ -456,12 +462,20 @@ select @@long_query_time; 100.000001 set low_priority_updates=1; set max_allowed_packet=100; +Warnings: +Warning 1292 Truncated incorrect max_allowed_packet value: '100' set global max_binlog_cache_size=100; +Warnings: +Warning 1292 Truncated incorrect max_binlog_cache_size value: '100' set global max_binlog_size=100; +Warnings: +Warning 1292 Truncated incorrect max_binlog_size value: '100' set global max_connect_errors=100; set global max_connections=100; set global max_delayed_threads=100; set max_heap_table_size=100; +Warnings: +Warning 1292 Truncated incorrect max_heap_table_size value: '100' set max_join_size=100; set max_sort_length=100; set max_tmp_tables=100; @@ -472,17 +486,25 @@ select @@max_user_connections; set global max_write_lock_count=100; set myisam_sort_buffer_size=100; set net_buffer_length=100; +Warnings: +Warning 1292 Truncated incorrect net_buffer_length value: '100' set net_read_timeout=100; set net_write_timeout=100; set global query_cache_limit=100; set global query_cache_size=100; set global query_cache_type=demand; set read_buffer_size=100; +Warnings: +Warning 1292 Truncated incorrect read_buffer_size value: '100' set read_rnd_buffer_size=100; +Warnings: +Warning 1292 Truncated incorrect read_rnd_buffer_size value: '100' set global rpl_recovery_rank=100; set global server_id=100; set global slow_launch_time=100; set sort_buffer_size=100; +Warnings: +Warning 1292 Truncated incorrect sort_buffer_size value: '100' set @@max_sp_recursion_depth=10; select @@max_sp_recursion_depth; @@max_sp_recursion_depth @@ -522,6 +544,8 @@ set storage_engine=myisam; set global thread_cache_size=100; set timestamp=1, timestamp=default; set tmp_table_size=100; +Warnings: +Warning 1292 Truncated incorrect tmp_table_size value: '100' set tx_isolation="READ-COMMITTED"; set wait_timeout=100; set log_warnings=1; @@ -691,6 +715,8 @@ SELECT * FROM INFORMATION_SCHEMA.SESSION_VARIABLES WHERE VARIABLE_NAME LIKE 'MYI VARIABLE_NAME VARIABLE_VALUE MYISAM_DATA_POINTER_SIZE 7 SET GLOBAL table_open_cache=-1; +Warnings: +Warning 1292 Truncated incorrect table_open_cache value: '0' SHOW VARIABLES LIKE 'table_open_cache'; Variable_name Value table_open_cache 1 diff --git a/mysql-test/t/variables.test b/mysql-test/t/variables.test index c61972be3eb..45cd986aa6d 100644 --- a/mysql-test/t/variables.test +++ b/mysql-test/t/variables.test @@ -141,7 +141,7 @@ set GLOBAL myisam_max_sort_file_size=2000000; show global variables like 'myisam_max_sort_file_size'; select * from information_schema.global_variables where variable_name like 'myisam_max_sort_file_size'; set GLOBAL myisam_max_sort_file_size=default; ---replace_result 2147482624 FILE_SIZE 2146435072 FILE_SIZE +--replace_result 2147483647 FILE_SIZE 2146435072 FILE_SIZE show variables like 'myisam_max_sort_file_size'; --replace_result 2147483647 FILE_SIZE 9223372036854775807 FILE_SIZE select * from information_schema.session_variables where variable_name like 'myisam_max_sort_file_size'; diff --git a/mysys/my_getopt.c b/mysys/my_getopt.c index af48e9cb0df..3c0faf0c0af 100644 --- a/mysys/my_getopt.c +++ b/mysys/my_getopt.c @@ -34,7 +34,6 @@ my_bool getopt_compare_strings(const char *s, const char *t, uint length); static longlong getopt_ll(char *arg, const struct my_option *optp, int *err); -static longlong getopt_ll_limit_value(longlong, const struct my_option *); static ulonglong getopt_ull(char *arg, const struct my_option *optp, int *err); static double getopt_double(char *arg, const struct my_option *optp, int *err); @@ -87,7 +86,7 @@ static void default_reporter(enum loglevel level, fprintf(stderr, "%s", "Info: "); vfprintf(stderr, format, args); va_end(args); - fputs('\n', stderr); + fputc('\n', stderr); fflush(stderr); } @@ -785,7 +784,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); - return getopt_ll_limit_value(num, optp); + return getopt_ll_limit_value(num, optp, NULL); } /* @@ -795,11 +794,11 @@ static longlong getopt_ll(char *arg, const struct my_option *optp, int *err) Returns "fixed" value. */ -static longlong getopt_ll_limit_value(longlong num, - const struct my_option *optp) +longlong getopt_ll_limit_value(longlong num, const struct my_option *optp, + bool *fix) { longlong old= num; - bool trunc= FALSE; + bool adjusted= FALSE; char buf1[255], buf2[255]; ulonglong block_size= (optp->block_size ? (ulonglong) optp->block_size : 1L); @@ -807,7 +806,29 @@ static longlong getopt_ll_limit_value(longlong num, optp->max_value) /* if max value is not set -> no upper limit */ { num= (ulonglong) optp->max_value; - trunc= TRUE; + adjusted= TRUE; + } + + switch ((optp->var_type & GET_TYPE_MASK)) { + case GET_INT: + if (num > (longlong) INT_MAX) + { + num= ((longlong) INT_MAX); + adjusted= TRUE; + } + break; + case GET_LONG: +#if SIZEOF_LONG < SIZEOF_LONG_LONG + if (num > (longlong) LONG_MAX) + { + num= ((longlong) LONG_MAX); + adjusted= TRUE; + } +#endif + break; + default: + DBUG_ASSERT((optp->var_type & GET_TYPE_MASK) == GET_LL); + break; } num= ((num - optp->sub_size) / block_size); @@ -816,10 +837,12 @@ static longlong getopt_ll_limit_value(longlong num, if (num < optp->min_value) { num= optp->min_value; - trunc= TRUE; + adjusted= TRUE; } - if (trunc) + if (fix) + *fix= adjusted; + else if (adjusted) my_getopt_error_reporter(WARNING_LEVEL, "option '%s': signed value %s adjusted to %s", optp->name, llstr(old, buf1), llstr(num, buf2)); @@ -888,14 +911,13 @@ ulonglong getopt_ull_limit_value(ulonglong num, const struct my_option *optp, adjusted= TRUE; } - if (adjusted) + if (fix) + *fix= adjusted; + else if (adjusted) my_getopt_error_reporter(WARNING_LEVEL, "option '%s': unsigned value %s adjusted to %s", optp->name, ullstr(old, buf1), ullstr(num, buf2)); - if (fix) - *fix= adjusted; - return num; } diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 9d753f905dc..b81ccfc5db9 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -5216,7 +5216,7 @@ struct my_option my_long_options[] = {"concurrent-insert", OPT_CONCURRENT_INSERT, "Use concurrent insert with MyISAM. Disable with --concurrent-insert=0", (uchar**) &myisam_concurrent_insert, (uchar**) &myisam_concurrent_insert, - 0, GET_LONG, OPT_ARG, 1, 0, 2, 0, 0, 0}, + 0, GET_ULONG, OPT_ARG, 1, 0, 2, 0, 0, 0}, {"console", OPT_CONSOLE, "Write error output on screen; Don't remove the console window on windows.", (uchar**) &opt_console, (uchar**) &opt_console, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index 2af528f6699..07bf313067a 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -1874,11 +1874,20 @@ err: static int check_func_int(THD *thd, struct st_mysql_sys_var *var, void *save, st_mysql_value *value) { + bool fixed; long long tmp; struct my_option options; value->val_int(value, &tmp); plugin_opt_set_limits(&options, var); - *(int *)save= (int) getopt_ull_limit_value(tmp, &options); + *(int *)save= (int) getopt_ull_limit_value(tmp, &options, &fixed); + if (fixed) + { + char buf[22]; + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_TRUNCATED_WRONG_VALUE, + ER(ER_TRUNCATED_WRONG_VALUE), var->name, + ullstr(tmp, buf)); + } return (thd->variables.sql_mode & MODE_STRICT_ALL_TABLES) && (*(int *)save != (int) tmp); } @@ -1887,24 +1896,42 @@ static int check_func_int(THD *thd, struct st_mysql_sys_var *var, static int check_func_long(THD *thd, struct st_mysql_sys_var *var, void *save, st_mysql_value *value) { + bool fixed; long long tmp; struct my_option options; value->val_int(value, &tmp); plugin_opt_set_limits(&options, var); - *(long *)save= (long) getopt_ull_limit_value(tmp, &options); + *(long *)save= (long) getopt_ull_limit_value(tmp, &options, &fixed); + if (fixed) + { + char buf[22]; + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_TRUNCATED_WRONG_VALUE, + ER(ER_TRUNCATED_WRONG_VALUE), var->name, + ullstr(tmp, buf)); + } return (thd->variables.sql_mode & MODE_STRICT_ALL_TABLES) && (*(long *)save != (long) tmp); } static int check_func_longlong(THD *thd, struct st_mysql_sys_var *var, - void *save, st_mysql_value *value) + void *save, st_mysql_value *value) { + bool fixed; long long tmp; struct my_option options; value->val_int(value, &tmp); plugin_opt_set_limits(&options, var); - *(ulonglong *)save= getopt_ull_limit_value(tmp, &options); + *(ulonglong *)save= getopt_ull_limit_value(tmp, &options, &fixed); + if (fixed) + { + char buf[22]; + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_TRUNCATED_WRONG_VALUE, + ER(ER_TRUNCATED_WRONG_VALUE), var->name, + ullstr(tmp, buf)); + } return (thd->variables.sql_mode & MODE_STRICT_ALL_TABLES) && (*(long long *)save != tmp); }