Bug #76156 Python Connector hangs if a query is killed (error 1317)
Submitted: 4 Mar 2015 22:29 Modified: 30 Jun 2015 18:43
Reporter: Trevor Carlson Email Updates:
Status: Closed Impact on me:
None 
Category:Connector / Python Severity:S3 (Non-critical)
Version:2.0.3 OS:Windows
Assigned to: CPU Architecture:Any

[4 Mar 2015 22:29] Trevor Carlson
Description:
If the Python connector is running a long query, which is manually killed in the middle, it will hang until timeout (which can be infinite).

I'm using Python 2.7.6 on Windows, connector 2.0.3, and MySQL 5.6.20 on Linux.

I checked 2.1.1, and the relevant code has not changed.

How to repeat:
conn = mysql.connector.connect()
cursor = conn.cursor()
#This needs to be a long-running query; you'll need enough time to manually kill the query.
cursor.execute("SELECT * FROM big_table")
print cursor.fetchall()

Start the code running, then switch to a second window and run "kill query X", where X is the id of the connection. (Or in workbench, select the connection, and hit Kill Query.)

Note:
1) "select sleep(99999)" will NOT cause this; that function is a special case.
2) "kill X" (kill the connection) will NOT cause this; you have to use "kill query X".

Suggested fix:
(For reference, the packet is "\x00\x00\x87\xff%\x05#70100Query execution was interrupted".)
Starting in read_text_result() from protocol.py, the connector pulls the interruption packet from sock.recv(), then calls utils.read_lc_string_list(packet[4:]). That returns None, and on the next loop, when it asks to recv() from the socket it'll stay there until timeout because the server will not be sending any further data.

I suggest editing read_text_result() and read_binary_result() to have a "if packet[4] == 255:" section that raises a 1317 exception to be handled by the user's calling code.
[5 Mar 2015 11:51] MySQL Verification Team
Hello Trevor Carlson,

Thank you for the report.

Thanks,
Umesh
[12 Mar 2015 17:39] Trevor Carlson
A related problem. Even after adjusting the code to catch 1317 errors, the connection ends up broken. Repro:
conn = mysql.connector.connect()
cursor = conn.cursor()
try:
    cursor.execute("SELECT * from huge_table")
    cursor.fetchall()
except Exception as e:
    print e
finally:
    cursor.close()
    conn.close()

This needs modified code to catch 1317 errors and throw an exception. The query needs to be killed while running.

An exception will be raised on the "cursor.close()" line: "Unread result found.".
[12 May 2015 3:14] Ricardo Oliveira
this is a nasty bug, can someone change this to critical please
[30 Jun 2015 18:43] Paul DuBois
Noted in 2.1.3 changelog.

Connector/Python hung until timeout if the query it was running was
killed.