Bug #83136 | for libmysql the [client] group may be read twice | ||
---|---|---|---|
Submitted: | 24 Sep 2016 15:47 | Modified: | 17 Nov 2016 10:13 |
Reporter: | John Fawcett | Email Updates: | |
Status: | No Feedback | Impact on me: | |
Category: | MySQL Server: C API (client library) | Severity: | S3 (Non-critical) |
Version: | 5.7.15 | OS: | Any |
Assigned to: | Assigned Account | CPU Architecture: | Any |
Tags: | libmysql [client] group |
[24 Sep 2016 15:47]
John Fawcett
[3 Oct 2016 9:15]
Bharathy Satish
Just by calling below two functions in an application will not make the config file to be read. mysql_options(&mysql,MYSQL_READ_DEFAULT_FILE,"abc.cnf"); mysql_options(&mysql,MYSQL_READ_DEFAULT_GROUP,"client"); We need to call mysql_read_default_options ( this function is internal and not exposed). Or my_load_defaults() which is not recommended. So i want to know how is your application program which links to libmysql is written. groups[0]= (char*) "client"; groups[1]= (char*) group; groups[2]=0; Here we set "client" as default group only to ensure that for any client application "client" group is read by default.
[4 Oct 2016 20:19]
John Fawcett
Here is a minimal program that demonstrates the issue. Before compiling it is necessary to change the credentials to a valid user_name, password and database. // CODE START #include <stdio.h> #include <mysql.h> int main(int argc, char **argv) { char *host_name="localhost"; char *user_name="testuser"; char *password="password"; char *db_name="test"; MYSQL *mysql; if ((mysql = mysql_init(NULL)) == NULL) printf("insufficient memory\n"); if (mysql_options(mysql,MYSQL_READ_DEFAULT_GROUP,"client")) { printf("mysql_options() failed\n"); mysql_close(mysql); exit(1); } if (mysql_real_connect (mysql, host_name, user_name, password, db_name, 3306, 0, CLIENT_MULTI_STATEMENTS) == NULL) { printf("mysql_real_connect() failed\n"); mysql_close(mysql); exit(1); } mysql_close(mysql); return 0; } // CODE END The following are the compile commands for the above program cc -g -c test.c -o test.o -I/usr/include/mysql cc test.o -o test -lmysqlclient -L/usr/lib64/mysql Here is a run of the program under gdb debuuger using a breakpoint at the function my_load_defaults() At that point the input arguments to the function include the groups parameter which has the following contents; $1 = {0x7ffff787cab1 "client", 0x602720 "client", 0x0} So client group is being passed in as the first and second parameter. That seems inefficient. It is sufficient to pass only the first parameter when the second parameter is also "client". gdb ./test GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-80.el7 Copyright (C) 2013 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "x86_64-redhat-linux-gnu". For bug reporting instructions, please see: <http://www.gnu.org/software/gdb/bugs/>... Reading symbols from /root/test...done. (gdb) b my_load_defaults Function "my_load_defaults" not defined. Make breakpoint pending on future shared library load? (y or [n]) y Breakpoint 1 (my_load_defaults) pending. (gdb) run Starting program: /root/./test [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib64/libthread_db.so.1". Breakpoint 1, my_load_defaults (conf_file=0x7ffff787cb16 "my", groups=groups@entry=0x7fffffffd9a0, argc=argc@entry=0x7fffffffd960, argv=argv@entry=0x7fffffffd980, default_directories=default_directories@entry=0x0) at /export/home2/pb2/build/sb_1-20188648-1472134462.7/rpm/BUILD/mysql-5.7.15/mysql-5.7.15/mysys_ssl/my_default.cc:631 631 /export/home2/pb2/build/sb_1-20188648-1472134462.7/rpm/BUILD/mysql-5.7.15/mysql-5.7.15/mysys_ssl/my_default.cc: No such file or directory. Missing separate debuginfos, use: debuginfo-install glibc-2.17-106.el7_2.8.x86_64 libgcc-4.8.5-4.el7.x86_64 libstdc++-4.8.5-4.el7.x86_64 (gdb) print *groups@3 $1 = {0x7ffff787cab1 "client", 0x602720 "client", 0x0} (gdb) continue Continuing. [Inferior 1 (process 2182) exited normally] (gdb)
[5 Oct 2016 6:40]
Bharathy Satish
$1 = {0x7ffff787cab1 "client", 0x602720 "client", 0x0} Yes there is definitely a duplicate entry in the array, however this does not mean that the "client" group from the config file is read twice. This array is passed as an input in order to compare with the group read from the config file. If groups is present in the array then the contents of the group are read. In my opinion there is an issue of same entries in the array, but this is not going to affect any behaviour or performance, also this is more of an end user issue. Since "client" group is read by default in all client application why does end user still set "client" group using mysql_options().
[5 Oct 2016 19:21]
John Fawcett
Just to be sure I understood: are you saying that the group client is not read twice in the example I gave or are you saying it is read twice but as the result is functionally correct and the performance impact of reading it twice is negligible, it is not worth fixing? You said that <<client" group is read by default in all client application why does end user still set "client" group using mysql_options()>>. Actually that statement does not correspond to how the code works and contrasts with the documentation too. As the code stands when using the C API the client group is only read if MYSQL_READ_DEFAULT_FILE or MYSQL_READ_DEFAULT_GROUP is set via mysql_options call prior to connecting. So if I only want to read the client group from the default file I have to call mysql_options with "client" group. But then it gets passed in twice. If the code should work as you said, always reading the "client" group, then I would open a bug report to make the code and documentation compliant, as that is not the way it works now. See below that the client group is read only if there is cnf file or cnf group specified. MYSQL * STDCALL CLI_MYSQL_REAL_CONNECT(MYSQL *mysql, ... other args... { /* use default options */ BUG->>if (mysql->options.my_cnf_file || mysql->options.my_cnf_group)<<-BUG { mysql_read_default_options(&mysql->options, (mysql->options.my_cnf_file ? mysql->options.my_cnf_file : "my"), mysql->options.my_cnf_group);
[5 Oct 2016 19:50]
John Fawcett
Just to claify in the 5.7 code base the potential bug is in function mysql_real_connect() in file libmysqld/libmysqld.c line 107 if (mysql->options.my_cnf_file || mysql->options.my_cnf_group)
[7 Oct 2016 4:55]
Bharathy Satish
Hello John, Iam saying that "client" group from the config file is not read twice even if the groups parameter which is passed to my_load_defaults() has two "client" entries. If you check this function handle_default_option() you can see that group parameter is used only to do a comparison to see if the group is present in the config file. If present read the option and populate in ctx. if (find_type((char *)group_name, ctx->group, FIND_TYPE_NO_PREFIX)) { if (!(tmp= (char *) alloc_root(ctx->alloc, strlen(option) + 1))) return 1; .... }
[8 Oct 2016 7:42]
John Fawcett
Hi Satish thanks for clarifying this. As there is no duplication of processing when passing in client group twice this bug should be closed. Only doubt now is whether I should open a bug report so that clien group is read by default in all client application using the C API instead of as now where it is read only if MYSQL_READ_DEFAULT_FILE or MYSQL_READ_DEFAULT_GROUP is set via mysql_options call prior to connecting. Thanks again.
[17 Oct 2016 10:11]
Bharathy Satish
Hello John, Irrespective of calling mysql_options() with MYSQL_READ_DEFAULT_FILE or MYSQL_READ_DEFAULT_GROUP "client" group is always read. Please do a grep of "load_default_groups" in client folder you will see that the array has "client" as an entry, which states that "client" is always read.
[18 Nov 2016 1:00]
Bugs System
No feedback was provided for this bug for over a month, so it is being suspended automatically. If you are able to provide the information that was originally requested, please do so and change the status of the bug back to "Open".