sysown / proxysql

High-performance MySQL proxy with a GPL license.
http://www.proxysql.com
GNU General Public License v3.0
6.05k stars 983 forks source link

Query mirroring broken in 2.0.6 #2264

Open btimby opened 5 years ago

btimby commented 5 years ago

Hello,

I am testing mirroring with ProxySQL v2.0.6. I installed using the CentOS 7 rpm available from github.

https://github.com/sysown/proxysql/releases/download/v2.0.6/proxysql-2.0.6-1-centos7.x86_64.rpm

To reproduce, enable mirroring for a query rule. When you execute that query, proxysql immediately crashes with signal 11. Mirroring seems to be completely broken since this addition:

https://github.com/sysown/proxysql/commit/f3e7f039980f781b1cd87e07e1ad6e2ba104fe8e#diff-81ac570c4e1288d33fc5c4f49508a300R2222

In case of mirroring, _myprot == NULL, accessing _myprot->myds results in a segmentation fault.

Reading symbols from /usr/bin/proxysql...done.
(gdb) bt
#0  0x0000000000659519 in MySQL_ResultSet::init (this=0x7f771a388f80, _myprot=0x0, 
    _res=0x7f771a38f2a0, _my=0x7f7716a07c00, _stmt=0x0) at MySQL_Protocol.cpp:2222
#1  0x000000000079107f in MySQL_Connection::handler (this=0x7f7718717700, event=1)
    at mysql_connection.cpp:1073
#2  0x000000000079209c in MySQL_Connection::async_query (this=0x7f7718717700, event=1, 
    stmt=0x7f77200ae935 "SELECT c FROM sbtest5 WHERE id=502321\245\245\245\245\245\245\220\350\001=\034\321\367o\330Wm\030w\177", length=37, _stmt=0x0, stmt_meta=0x0) at mysql_connection.cpp:1391
#3  0x00000000006385de in MySQL_Session::handler (this=0x7f771a42b200) at MySQL_Session.cpp:3497
#4  0x0000000000619e2b in MySQL_Thread::process_all_sessions (this=0x7f771a381800)
    at MySQL_Thread.cpp:3816
#5  0x0000000000618f62 in MySQL_Thread::run (this=0x7f771a381800) at MySQL_Thread.cpp:3565
#6  0x00000000005b0c5d in mysql_worker_thread_func (arg=0x7f7720094360) at main.cpp:648
#7  0x00007f7721768dd5 in ?? ()
#8  0x0000000000000000 in ?? ()

Moving the declaration MySQL_Data_Stream * c_myds = *(myprot->myds) after the if statement on lines 2250-2252 would resolve this.

diff --git a/lib/MySQL_Protocol.cpp b/lib/MySQL_Protocol.cpp
index 530a471d..c7c70c33 100644
--- a/lib/MySQL_Protocol.cpp
+++ b/lib/MySQL_Protocol.cpp
@@ -2219,7 +2219,6 @@ void MySQL_ResultSet::init(MySQL_Protocol *_myprot, MYSQL_RES *_res, MYSQL *_my,
        resultset_completed=false;
        myprot=_myprot;
        mysql=_my;
-       MySQL_Data_Stream * c_myds = *(myprot->myds);
        if (buffer==NULL) {
        //if (_stmt==NULL) { // we allocate this buffer only for not prepared statements
        // removing the previous assumption. We allocate this buffer also for prepared statements
@@ -2250,6 +2249,7 @@ void MySQL_ResultSet::init(MySQL_Protocol *_myprot, MYSQL_RES *_res, MYSQL *_my,
        if (myprot==NULL) {
                return; // this is a mirror
        }
+       MySQL_Data_Stream * c_myds = *(myprot->myds);
        if (c_myds->com_field_list==false) {
                myprot->generate_pkt_column_count(false,&pkt.ptr,&pkt.size,sid,num_fields,this);
                sid++;

This change fixes the segfault problem. Unfortunately, mirroring then exceeds max_connections for the mirror_hostgroup. I think connections for the mirrored queries are not being closed.

dyipon commented 5 years ago

I have the same issue with 2.0.7, after applying the next rule: "INSERT INTO mysql_query_rules (rule_id,active,match_pattern,destination_hostgroup,mirror_hostgroup,apply) VALUES (1,1,'^SELECT',1,1,1);"

Error: signal 11: /usr/bin/proxysql(_Z13crash_handleri+0x1d)[0x5578b8004f9d] /lib/x86_64-linux-gnu/libc.so.6(+0x37840)[0x7f882ba6f840] /usr/bin/proxysql(_ZN15MySQL_ResultSet4initEP14MySQL_ProtocolP12st_mysql_resP8st_mysqlP13st_mysql_stmt+0x11)[0x5578b806ecb1] /usr/bin/proxysql(_ZN16MySQL_Connection7handlerEs+0x10b1)[0x5578b815cfd1] /usr/bin/proxysql(_ZN16MySQL_Connection11async_queryEsPcmPP13st_mysql_stmtP23stmt_execute_metadata_t+0x94)[0x5578b815d2b4] /usr/bin/proxysql(_ZN13MySQL_Session7handlerEv+0x233f)[0x5578b806232f] /usr/bin/proxysql(_ZN12MySQL_Thread20process_all_sessionsEv+0x26a)[0x5578b803f14a] /usr/bin/proxysql(_ZN12MySQL_Thread3runEv+0xa08)[0x5578b8048168] /usr/bin/proxysql(_Z24mysql_worker_thread_funcPv+0x6c)[0x5578b8001a5c] /lib/x86_64-linux-gnu/libpthread.so.0(+0x7fa3)[0x7f882c150fa3] /lib/x86_64-linux-gnu/libc.so.6(clone+0x3f)[0x7f882bb314cf] 2019-10-09 15:22:40 main.cpp:1395:ProxySQL_daemonize_phase3(): [ERROR] ProxySQL crashed. Restarting!