| Bug #54569 | Some options are not allowed to take argument when passed with loose- prefix | ||
|---|---|---|---|
| Submitted: | 16 Jun 2010 21:49 | Modified: | 20 Nov 2010 17:44 |
| Reporter: | Elena Stepanova | Email Updates: | |
| Status: | Closed | Impact on me: | |
| Category: | MySQL Server: General | Severity: | S3 (Non-critical) |
| Version: | 5.5.4-m3, 5.5.5-m3 | OS: | Any |
| Assigned to: | Kristofer Pettersson | CPU Architecture: | Any |
| Tags: | regression | ||
[16 Jun 2010 21:49]
Elena Stepanova
[28 Jun 2010 2:40]
Jimmy Yang
This is not a bug.
The options that in question have PLUGIN_VAR_NOCMDARG bit set, so they suppose not taking any argument:
static MYSQL_SYSVAR_BOOL(use_native_aio, srv_use_native_aio,
PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY, <=============
"Use native AIO if supported on this platform.",
NULL, NULL, TRUE);
static MYSQL_SYSVAR_BOOL(locks_unsafe_for_binlog, innobase_locks_unsafe_for_binlog,
PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY, <=============
"Force InnoDB to not use next-key locking, to use only row-level locking.",
NULL, NULL, FALSE);
Those options ran OK do not have this bit, for example, "innodb_table_lock":
static MYSQL_THDVAR_BOOL(table_locks, PLUGIN_VAR_OPCMDARG,
"Enable InnoDB locking in LOCK TABLES",
/* check_func */ NULL, /* update_func */ NULL,
/* default */ TRUE);
The actual argument check happens in mysys/my_getopt.c handle_options(), error message raised:
321 if (must_be_var && optp->arg_type == NO_ARG) <====
322 {
323 if (my_getopt_print_errors)
324 my_getopt_error_reporter(ERROR_LEVEL,
325 "%s: option '%s' cannot take an argument",
326 my_progname, optp->name);
327 return EXIT_NO_ARGUMENT_ALLOWED;
328 }
So this is expected.
When you specify the option without "loose" prefix and with argument, such as "innodb_use_native_aio=0", this option will not recognized at all, and simply skipped, so you do not see the error message:
251 if (!opt_found) <=== the "innodb_use_native_aio=0" not recognized
252 {
253 if (my_getopt_skip_unknown)
254 {
255 /* Preserve all the components of this unknown option. */
256 do {
257 (*argv)[argvpos++]= *first++;
258 } while (first <= pos);
259 continue; <=== simply skipped.
260 }
4: opt_str = 0xbffff665 "innodb_use_native_aio=0"
(gdb) p opt_found
$22 = 0
(gdb) p my_getopt_skip_unknown
$23 = 1 '\001'
So user should use "skip", "enable", "disable" prefixes for these PLUGIN_VAR_NOCMDARG options. And error message clearly state the arguement is not allowed.
[28 Jun 2010 3:54]
Calvin Sun
Jimmy - this is a real bug, and a regression. According to design loose_innodb_use_sys_malloc=0 and innodb_use_sys_malloc=0 should have the same result if the engine can recognize it. In this case, it does not. I have verified that innodb_use_sys_malloc=0 (or =1) works, but loose_innodb_use_sys_malloc=0 does not. It is a regression because loose_innodb_use_sys_malloc=0/1 works in 5.1, but does not work in 5.5. The bug may be in the server layer. Please check it out. You may check the InnoDB 1.0 under 5.1.
[28 Jun 2010 10:24]
Jimmy Yang
Calvin, here is the difference between 5.1 and 5.5
mysys/my_getopt.c
handle_options()
{
- if (must_be_var && (optp->var_type & GET_TYPE_MASK) == GET_NO_ARG)
+ if (must_be_var && optp->arg_type == NO_ARG)
{
if (my_getopt_print_errors)
my_getopt_error_reporter(ERROR_LEVEL,
"%s: option '%s' cannot take an argument",
my_progname, optp->name);
return EXIT_NO_ARGUMENT_ALLOWED;
}
}
Notice optp->var_type != GET_NO_ARG, but optp->arg_type == NO_ARG
gdb) p optp->var_type
$57 = 2 <======== GET_BOOL
(gdb) p optp->arg_type
$58 = NO_ARG
So we are getting a BOOLEAN datatype data for a option with NO_ARG bit.
In 5.1, it checks optp->var_type instead of optp->arg_type when deciding whether to print error. So someone might thinking it is not appropriate and changed to optp->arg_type instead.
Just from the plain meaning of NO_ARG or PLUGIN_VAR_NOCMDARG, it is normal to think these options should not have argument. User should use "enable/disable/skip etc." prefixes to modify these variables. If that is case, then it should be documented. However, if there is long tradition of provide 1/0 option to these NO_ARG options, then it need to consider to change back.
In addition, use loose- and without loose- prefix, the result are also different. The difference is simply due to the "must_be_var" is set or not.
Only with loose-prefix, "must_be_var" is set to 1. As shown in following code chunk, you can see "must_be_var" set depending on whether these is special prefix (such as loose-) for the variable:
handle_options()
{
if (!(opt_found= findopt(opt_str, length, &optp, &prev_found)))
{
/*
Didn't find any matching option. Let's see if someone called
option with a special option prefix
*/
if (!must_be_var)
{
if (optend)
must_be_var= 1; /* option is followed by an argument */ <===
for (i= 0; special_opt_prefix[i]; i++)
{
/*
We were called with a special prefix, we can reuse opt_found
*/
if ((opt_found= findopt(opt_str, length, &optp, &prev_found)))
...
}
}
Thus the variable setting has different behavior with this check:
if (must_be_var && optp->arg_type == NO_ARG)
{
if (my_getopt_print_errors)
}
All these are in server code mysys/my_getopt.c. Two issues to decide
1) whether the change from optp->var_type to optp->arg_type is correct, whether you want all NO_ARG option really comes with no arg.
2) The difference behavior with loose- prefix set or not, the behavior needs to be consistent.
[8 Oct 2010 11:22]
Kristofer Pettersson
My analysis is slightly different. I believe that maybe Sergei G introduced the failing if-statement without proper analysis of the code. If I apply this patch:
- if (must_be_var && optp->arg_type == NO_ARG)
- {
- if (my_getopt_print_errors)
- my_getopt_error_reporter(ERROR_LEVEL,
- "%s: option '%s' cannot take an argument",
- my_progname, optp->name);
- return EXIT_NO_ARGUMENT_ALLOWED;
- }
I can get this debug trace which seems like perfectly valid behavior:
Known variable and patch is applied
----------------------------------------
Pass 1..n:
cur_arg= --loose-innodb_use_native_aio=0, argc= 11
-- didn't find a registered opt variable to match the key.
-- There is an equal sign after the key so we can expect a value; must_be_var=1
-- The 'loose'-prefix has been identified; lets remove it and try again.
-- Despite removing the prefix from the key we didn't find a matching option variable.
-- Preserve all the components of this unknown option.
Pass n+1:
-- Loaded option: Use_native_aio (Use native AIO if supported on this platform.) is a bool option.
cur_arg= --innodb_use_native_aio=0, argc= 2
-- Found registerd option; arg_type is NO_ARG
-- Option var type is BOOL; Setting option value to true or false depending on argument value 1 or 0.
Pass 1..n:
cur_arg= --innodb_use_native_aio=0, argc= 10
-- didn't find a registered opt variable to match the key.
-- There is an equal sign after the key so we can expect a value; must_be_var=1
-- Despite removing the prefix from the key we didn't find a matching option variable.
-- Preserve all the components of this unknown option.
Pass n+1:
-- load innodb
-- Loaded use_native_aio (Use native AIO if supported on this platform.) and it's a bool option.
cur_arg= --innodb_use_native_aio=0, argc= 2
-- Option arg_type is NO_ARG
-- Option var type is BOOL; Setting option value to true or false depending on argument value 1 or 0.
For totally unknown variables using the patch
----------------------------------------------
Pass 1..n
cur_arg= --loose-innodb_not_such_var=2, argc= 2
-- didn't find a registered opt variable to match the key.
-- There is an equal sign after the key so we can expect a value; must_be_var=1
-- The 'loose'-prefix has been identified; lets remove it and try again.
-- Despite removing the prefix from the key we didn't find a matching option variable.
-- Preserve all the components of this unknown option.
Pass n+1
cur_arg= --loose-innodb_not_such_var=2, argc= 1
-- didn't find a registered opt variable to match the key.
-- There is an equal sign after the key so we can expect a value; must_be_var=1
-- The 'loose'-prefix has been identified; lets remove it and try again.
-- Despite removing any prefix from the key we didn't find a matching option variable.
The supplied argument is a key-value pair (must_be_var=1).
=> [Warning] /home/thek/bzr/mysql-5.5-bugteam/build/sql/mysqld: unknown variable 'loose-innodb_not_such_var=2'
-- The loose prefix makes us count down the available arguments and continue (skip ahead) the loop.
Pass 1..n
cur_arg= --innodb_not_such_var=2, argc= 2
-- didn't find a registered opt variable to match the key.
-- There is an equal sign after the key so we can expect a value; must_be_var=1
-- Despite removing any prefix from the key we didn't find a matching option variable.
-- Preserve all the components of this unknown option.
Pass n+1
cur_arg= --innodb_not_such_var=2, argc= 2
-- didn't find a registered opt variable to match the key.
-- There is an equal sign after the key so we can expect a value; must_be_var=1
-- Despite removing any the prefix from the key we didn't find a matching option variable.
-- The supplied argument is a key-value pair (must_be_var=1).
=> [ERROR] /home/thek/bzr/mysql-5.5-bugteam/build/sql/mysqld: unknown variable 'innodb_not_such_var=2'
-- We still have a loose prefix so we return EXIT_UNKNOWN_VARIABLE
Without the patch for totally unknown variables
------------------------------------------------
cur_arg= --loose-innodb_not_such_var=2, argc= 2
-- didn't find a registered opt variable to match the key.
-- There is an equal sign after the key so we can expect a value; must_be_var=1
-- The 'loose'-prefix has been identified; lets remove it and try again.
-- Despite removing the prefix from the key we didn't find a matching option variable.
-- Preserve all the components of this unknown option.
cur_arg= --loose-innodb_not_such_var=2, argc= 1
-- didn't find a registered opt variable to match the key.
-- There is an equal sign after the key so we can expect a value; must_be_var=1
-- The 'loose'-prefix has been identified; lets remove it and try again.
-- Despite removing the prefix from the key we didn't find a matching option variable.
-- The supplied argument is a key-value pair (must_be_var=1).
=> [Warning] unknown variable 'loose-innodb_not_such_var=2'
-- The loose prefix makes us count down the available arguments and continue (skip ahead) the loop.
Pass 1..n
cur_arg= --innodb_not_such_var=2, argc= 11
-- didn't find a registered opt variable to match the key.
-- There is an equal sign after the key so we can expect a value; must_be_var=1
-- Despite removing the prefix from the key we didn't find a matching option variable.
-- Preserve all the components of this unknown option.
Pass n+1
cur_arg= --innodb_not_such_var=2, argc= 1
-- didn't find a registered opt variable to match the key.
-- There is an equal sign after the key so we can expect a value; must_be_var=1
-- Despite removing the prefix from the key we didn't find a matching option variable.
-- The supplied argument is a key-value pair (must_be_var=1).
=> [ERROR] unknown variable 'innodb_not_such_var=2'
-- We still have a loose prefix so we return EXIT_UNKNOWN_VARIABLE
Without the patch for known variables
--------------------------------------
Pass 1..n:
cur_arg= --loose-innodb_use_native_aio=0, argc= 11
-- didn't find a registered opt variable to match the key.
-- There is an equal sign after the key so we can expect a value; must_be_var=1
-- The 'loose'-prefix has been identified; lets remove it and try again.
-- Despite removing the prefix from the key we didn't find a matching option variable.
-- Preserve all the components of this unknown option.
Pass n+1:
-- loaded InnoDB
-- Loaded use_native_aio (Use native AIO if supported on this platform.) and it's a bool option.
cur_arg= --loose-innodb_use_native_aio=0, argc= 3
-- didn't find a registered opt variable to match the key.
-- There is an equal sign after the key so we can expect a value; must_be_var=1
-- The 'loose'-prefix has been identified; lets remove it and try again.
=> [ERROR] mysqld: option 'innodb-use-native-aio' cannot take an argument
=> [ERROR] Parsing options for plugin 'InnoDB' failed.
[8 Oct 2010 11:31]
Bugs System
A patch for this bug has been committed. After review, it may be pushed to the relevant source trees for release in the next version. You can access the patch from: http://lists.mysql.com/commits/120361 3095 Kristofer Pettersson 2010-10-08 Bug#54569 Some options are not allowed to take argument when passed with loose- prefix Boolean options cause parsing failures when they are given with prefix loose- and an argument, either in the command line or in configuration file. The reason was a faulty logic which forced the parsing to throw an error when an argument of type NO_ARG was used together with an argument which has been identified as a key-value pair. Despite the attribute NO_ARG these options actually take arguments if they are of type BOOL. @ mysys/my_getopt.c * removed if-statement which prevented logic for handling boolean types with arguments to be executed.
[25 Oct 2010 12:30]
Bugs System
A patch for this bug has been committed. After review, it may be pushed to the relevant source trees for release in the next version. You can access the patch from: http://lists.mysql.com/commits/121804 3095 Kristofer Pettersson 2010-10-25 Bug#54569 Some options are not allowed to take argument when passed with loose- prefix Boolean options cause parsing failures when they are given with prefix loose- and an argument, either in the command line or in configuration file. The reason was a faulty logic which forced the parsing to throw an error when an argument of type NO_ARG was used together with an argument which has been identified as a key-value pair. Despite the attribute NO_ARG these options actually take arguments if they are of type BOOL. @ include/my_getopt.h * More comments to help future refactoring @ mysys/my_getopt.c * removed if-statement which prevented logic for handling boolean types with arguments to be executed. * Added comments to aid in future refactoring.
[13 Nov 2010 16:14]
Bugs System
Pushed into mysql-trunk 5.6.99-m5 (revid:alexander.nozdrin@oracle.com-20101113155825-czmva9kg4n31anmu) (version source revid:alexander.nozdrin@oracle.com-20101113152450-2zzcm50e7i4j35v7) (merge vers: 5.6.1-m4) (pib:21)
[13 Nov 2010 16:37]
Bugs System
Pushed into mysql-next-mr (revid:alexander.nozdrin@oracle.com-20101113160336-atmtmfb3mzm4pz4i) (version source revid:vasil.dimov@oracle.com-20100629074804-359l9m9gniauxr94) (pib:21)
[20 Nov 2010 17:44]
Paul DuBois
Noted in 5.5.8 changelog. Boolean command options caused an error if given with an option value and the loose- option prefix.
[20 Nov 2010 17:44]
Paul DuBois
Noted in 5.5.8 changelog. Boolean command options caused an error if given with an option value and the loose- option prefix.
[16 Dec 2010 22:33]
Bugs System
Pushed into mysql-5.5 5.5.9 (revid:jonathan.perkin@oracle.com-20101216101358-fyzr1epq95a3yett) (version source revid:jonathan.perkin@oracle.com-20101216101358-fyzr1epq95a3yett) (merge vers: 5.5.9) (pib:24)
