aiomysql: SSCursor can't close while raise Error

if server send a error to SSCurosr, SSCursor try to call self._result._finish_unbuffered_query in close function

# SSCursor close funcion in  cursor.py line 604
if self._result is not None and self._result is conn._result:
    await self._result._finish_unbuffered_query()

but there is not a byte to read after recived a error packge, so the loop is allways waiting in the time, the error could’t raise out .

# _finish_unbuffered_query function in connection.py line 1197  
while self.unbuffered_active:
    packet = await self.connection._read_packet()

I met the bug after I seted a mysql variable

SET GLOBAL MAX_EXECUTION_TIME=3000

a SELECT statement will be aborted if it takes more than 3s.

the connection received a error package with erorno 3024, but the loop is waiting packge to finitshed unbuffered_query

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Comments: 17 (2 by maintainers)

Commits related to this issue

Most upvoted comments

they actually can, you need to carefully craft the queries though.

example (mysql 8.0):

mysql> SELECT /*+ MAX_EXECUTION_TIME(1) */ data, sleep(1) FROM test;
ERROR 3024 (HY000): Query execution was interrupted, maximum statement execution time exceeded

from mysql 8.0 docs about SLEEP():

When SLEEP() is the only thing invoked by a query that is interrupted, it returns 1 and the query itself returns no error.

When SLEEP() is only part of a query that is interrupted, the query returns an error

the key takeaway is that sleep cannot be the only part of the query.

see for example https://github.com/Nothing4You/PyMySQL/blob/8c373feb9036b4c19eb338220f47586f26e5afd0/pymysql/tests/test_cursor.py#L137

https://github.com/PyMySQL/PyMySQL/pull/1035 isn’t ported yet - once I’ve done that I’ll close this.

I fixed the issue for pymysql in the commit