Bug #99728 mysql shell segfaults when connected to ProxySQL
Submitted: 28 May 2020 15:34 Modified: 19 Jun 2020 12:14
Reporter: Eduardo Ortega Email Updates:
Status: Closed Impact on me:
None 
Category:Shell General / Core Client Severity:S2 (Serious)
Version:mysqlsh Ver 8.0.20 for Linux on x86_64 OS:Ubuntu ("Ubuntu 18.04.4 LTS")
Assigned to: CPU Architecture:x86

[28 May 2020 15:34] Eduardo Ortega
Description:
# what you did

1. Start ProxySQL (seen with 2.0.12-38-g58a909a0)
2. Attempt to connect to it with mysqlsh
3. Once connected, issue a "SHOW DATABASES" command

# what you wanted to happen

Get the list of proxysql databases as seen when connecting using the classic mysql client:

mysql> show databases;
+-----+---------------+---------------------------------------------------------+
| seq | name          | file                                                    |
+-----+---------------+---------------------------------------------------------+
| 0   | main          |                                                         |
| 2   | disk          | /home/user/proxysql-sandboxes/6042/proxysql.db       |
| 3   | stats         |                                                         |
| 4   | monitor       |                                                         |
| 5   | stats_history | /home/user/proxysql-sandboxes/6042/proxysql_stats.db |
+-----+---------------+---------------------------------------------------------+
5 rows in set (0,00 sec)

# what actually happened.

MySQL shell process SIGSEGVed:

[ 2075 ] eurrego@sabre ~/git_tree/badmin (master) % ➜  gdb mysqlsh                     
GNU gdb (Ubuntu 8.1-0ubuntu3.2) 8.1.0.20180409-git
Copyright (C) 2018 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-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from mysqlsh...(no debugging symbols found)...done.
(gdb) r
Starting program: /usr/bin/mysqlsh 
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
[New Thread 0x7ffff033d700 (LWP 13482)]
[New Thread 0x7fffefb3c700 (LWP 13483)]
[New Thread 0x7fffef33b700 (LWP 13484)]
[New Thread 0x7fffeeb3a700 (LWP 13485)]
[New Thread 0x7fffee339700 (LWP 13486)]
[New Thread 0x7fffedb38700 (LWP 13487)]
[New Thread 0x7fffed337700 (LWP 13488)]
MySQL Shell 8.0.20

Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its affiliates.
Other names may be trademarks of their respective owners.

Type '\help' or '\?' for help; '\quit' to exit.
 MySQL  Py > \c admin@127.0.0.1:6042
Creating a session to 'admin@127.0.0.1:6042'
[New Thread 0x7fffec902700 (LWP 13493)]
[Thread 0x7fffec902700 (LWP 13493) exited]
Fetching schema names for autocompletion... Press ^C to stop.
MySQL Error 1045 (28000): ProxySQL Admin Error: unrecognized token: "@"
 MySQL  127.0.0.1:6042  Py > \sql
Switching to SQL mode... Commands end with ;
Error during auto-completion cache update: ClassicSession.runSql: ProxySQL Admin Error: no such function: schema
 MySQL  127.0.0.1:6042  SQL > show databases;

Thread 1 "mysqlsh" received signal SIGSEGV, Segmentation fault.
0x0000555556125e5e in shcore::Shell_sql::handle_input(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&, shcore::Input_state&) ()
(gdb) bt
#0  0x0000555556125e5e in shcore::Shell_sql::handle_input(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&, shcore::Input_state&) ()
#1  0x00005555560f7626 in shcore::Shell_core::handle_input(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&, shcore::Input_state&) ()
#2  0x00005555560c83e0 in mysqlsh::Base_shell::process_line(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) ()
#3  0x0000555555c9b065 in mysqlsh::Mysql_shell::process_line(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) ()
#4  0x0000555555c7e3d4 in mysqlsh::Command_line_shell::command_loop() ()
#5  0x0000555555b7405b in main ()
(gdb) gcore mysqldh_segv
warning: Memory read failed for corefile section, 4096 bytes at 0xffffffffff600000.
Saved corefile mysqldh_segv
(gdb) 

I get that ProxySQL is not part of MySQL, but if for some reason ProxySQL is sending back information that is somehow invalid, the client should show some error message, not crash.

How to repeat:
See description, it has all the steps
[29 May 2020 8:07] MySQL Verification Team
Hello Eduardo Ortega,

Thank you for the report and feedback.
Verified as described.

regards,
Umesh
[29 May 2020 8:09] MySQL Verification Team
MySQL Shell 8.0.20 test results

Attachment: 99728.results (application/octet-stream, text), 10.80 KiB.

[29 May 2020 10:07] Frederic Descamps
Just a comment:

This is when connecting to ProxySQL's admin API

The header is : 

Your MySQL connection id is 1
Server version: 5.5.30 (ProxySQL Admin Module

mysql> select version();
+-----------+
| version() |
+-----------+
|           |
+-----------+
1 row in set (0.00 sec)

mysql> select @@version;
+-----------+
| @@version |
+-----------+
|           |
+-----------+
1 row in set (0.00 sec)

mysql> select @@mysql-server_version;
+------------------------+
| @@mysql-server_version |
+------------------------+
| 5.5.30                 |
+------------------------+
1 row in set (0.00 sec)

When trying to connect using MySQL Shell:

$ mysqlsh admin@127.0.0.1:6032
Please provide the password for 'admin@127.0.0.1:6032': *****
Save password for 'admin@127.0.0.1:6032'? [Y]es/[N]o/Ne[v]er (default No): 
MySQL Shell 8.0.21-commercial

Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its affiliates.
Other names may be trademarks of their respective owners.

Type '\help' or '\?' for help; '\quit' to exit.
Creating a session to 'admin@127.0.0.1:6032'
Fetching schema names for autocompletion... Press ^C to stop.
ERROR: MySQL Error 1045 (28000): ProxySQL Admin Error: unrecognized token: "@"
[29 May 2020 10:54] Frederic Descamps
But I confirm that when using MySQL Shell and a user created in ProxySQL with the usual proxy port, it crashes:

$ mysqlsh -u alfredo -p -h 127.0.0.1 -P 6033
 MySQL   127.0.0.1:6033   information_schema  2020-05-29 12:51:28  
 SQL  show databases;
ERROR: 2006 (HY000): MySQL server has gone away
The global session got disconnected..
Attempting to reconnect to 'mysql://alfredo@127.0.0.1:6033'..
The global session was successfully reconnected.

But when not using interractive it works:

$ mysqlsh --sql -u alfredo -p -h 127.0.0.1 -P 6033 -e 'show databases'
Database
big
bookstore
clusterdemo
...
[1 Jun 2020 17:27] Miguel Araujo
MySQL Shell, when switching to SQL mode, verifies if ANSI quotes are enabled and for that, it runs the query "select @@sql_mode;". The root cause of the crash is that MySQL Shell assumes that the query returns a result set.

However, ProxySQL does not return a result set for that query, when the session is established to its Admin interface.

MySQL Shell should *not* assume the query returns a result set, but on the other hand ProxySQL should return a result set for that query.

A simple workaround is to not switch to SQL mode and use the function .runSql()/run_sql() or to use the inline SQL switch:

mysql-js> \c admin@localhost:6032
Creating a session to 'admin@localhost:6032'
Please provide the password for 'admin@localhost:6032': *****
Save password for 'admin@localhost:6032'? [Y]es/[N]o/Ne[v]er (default No): 
Fetching schema names for autocompletion... Press ^C to stop.
MySQL Error 1045 (28000): ProxySQL Admin Error: unrecognized token: "@"
mysql-js> session.runSql("show schemas")
+-----+---------------+--------------------------------+
| seq | name          | file                           |
+-----+---------------+--------------------------------+
| 0   | main          |                                |
| 2   | disk          | /home/miguel/proxysql.db       |
| 3   | stats         |                                |
| 4   | monitor       |                                |
| 5   | stats_history | /home/miguel/proxysql_stats.db |
+-----+---------------+--------------------------------+
5 rows in set (0.0004 sec)
mysql-js> \sql show schemas;
Error during auto-completion cache update: ClassicSession.runSql: ProxySQL Admin Error: no such function: schema
+-----+---------------+--------------------------------+
| seq | name          | file                           |
+-----+---------------+--------------------------------+
| 0   | main          |                                |
| 2   | disk          | /home/miguel/proxysql.db       |
| 3   | stats         |                                |
| 4   | monitor       |                                |
| 5   | stats_history | /home/miguel/proxysql_stats.db |
+-----+---------------+--------------------------------+
5 rows in set (0.0003 sec)

--

As for the other error mentioned in the comments: 

ERROR: MySQL Error 1045 (28000): ProxySQL Admin Error: unrecognized token: "@"

That is caused by a query executed by MySQL Shell: select concat(@@version, ' ', @@version_comment)

The resultset for that query is not forged by ProxySQL resulting in that error. This has been already discussed with the ProxySQL developers and an issue was created:

https://github.com/sysown/proxysql/issues/2854
[19 Jun 2020 12:14] Margaret Fisher
Posted by developer:
 
Changelog entry added for MySQL Shell 8.0.21:

When switching to SQL mode, MySQL Shell queries the SQL mode of the connected server to establish whether the ANSI_QUOTES mode is enabled. Previously, MySQL Shell could not proceed if it did not receive a result set in response to the query. The absence of a result is now handled appropriately.