[CONC-362] mysql_close() behaviour change leading to connection error in some cases Created: 2018-09-14  Updated: 2018-09-15  Resolved: 2018-09-15

Status: Closed
Project: MariaDB Connector/C
Component/s: None
Affects Version/s: 3.0.6
Fix Version/s: N/A

Type: Bug Priority: Minor
Reporter: Oleg Pereverzev Assignee: Georg Richter
Resolution: Not a Bug Votes: 0
Labels: None
Environment:

Tested on: Arch Linux x86_64, Ubuntu 18.04



 Description   

Hi.

libmariadb (MariaDB Connector/C) version 3 (tested on 3.0.3 and 3.0.6) has somehow changed behaviour of mysql_close() rendering our code to fail at mysql_real_connect() with error:

Lost connection to MySQL server at 'reading authorization packet', system error: 11

Same code works with libmariadb (MariaDB Connector/C) version 2, libmariadbclient (MariaDB database client library) and libmysqlclient (MySQL database client library).

In case of failure (version 3) it seems that connection is made, server greating is read and nothing else happens until server times out and closes connection. Here is strace output:

...
socket(AF_UNIX, SOCK_STREAM, 0)         = 4
fcntl(4, F_SETFL, O_RDONLY|O_NONBLOCK)  = 0
connect(4, {sa_family=AF_UNIX, sun_path="/run/mysqld/mysqld.sock"}, 110) = 0
fcntl(4, F_SETFL, O_RDONLY)             = 0
setsockopt(4, SOL_IP, IP_TOS, [8], 4)   = -1 EOPNOTSUPP
setsockopt(4, SOL_SOCKET, SO_KEEPALIVE, [1], 4) = 0
recvfrom(4, "Y\0\0\0\n5.5.5-10.1.35-MariaDB\0\20\0\0\0b"..., 16384, MSG_DONTWAIT, NULL, NULL) = 93
recvfrom(4, 0x563b1b8e5c30, 16384, MSG_DONTWAIT, NULL, NULL) = -1 EAGAIN
poll([{fd=4, events=POLLIN}], 1, -1)    = 1 ([{fd=4, revents=POLLIN|POLLHUP}])
recvfrom(4, "", 16384, MSG_DONTWAIT, NULL, NULL) = 0
close(4)
...

Here is stripped code block:

...
mysql_init (&mysql);
mysql_options(&mysql,MYSQL_READ_DEFAULT_GROUP,"client");
 
while((query=get_next_query())) {
	if(params_differ_or_first_connect(query)) {
        mysql_close (&mysql);
 
        // This block is needed to make it work on 3.x
        // mysql_init (&mysql);
        // mysql_options(&mysql,MYSQL_READ_DEFAULT_GROUP,"client");
 
        if (!mysql_real_connect(&mysql,...)) {
            ...
        }
    }
 
	if(mysql_query(&mysql, ...)) {
    ...
}
...

Generaly there are such flows:

First query (does not work in 3.x):

  • mysql_init ()
  • mysql_options()
  • mysql_close()
  • mysql_real_connect() <-- Lost connection to MySQL server at 'reading authorization packet', system error: 11
  • mysql_query()

Next query same connect:

  • mysql_query()

Next query new connect (does not work in 3.x):

  • mysql_close()
  • mysql_real_connect() <-- Lost connection to MySQL server at 'reading authorization packet', system error: 11
  • mysql_query()

Next query new connect (does work in 3.x with uncommented block):

  • mysql_close()
  • mysql_init ()
  • mysql_options()
  • mysql_real_connect()
  • mysql_query()

This change may break other code as ours.



 Comments   
Comment by Georg Richter [ 2018-09-15 ]

You cannot call mysql_real_connect after mysql_close(). mysql_close() doesn't close the connection only, it also frees memory which was allocated by mysql_init().

See also

Generated at Thu Feb 08 03:04:46 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.