Commit 87d1ab9a authored by Vladislav Vaintroub's avatar Vladislav Vaintroub

MDEV-28561 Assertion failed: !pfs->m_idle || (state == PSI_SOCKET_STATE_ACTIVE)

The error was specific to threadpool/compressed protocol.
set_thd_idle() set socket state to idle twice, causing assert failure.

This happens if unread compressed data on connection,after query was
finished. On a protocol level, this means a single compression packet
contains multiple command packets.
parent 3c65434b
...@@ -124,12 +124,17 @@ static void re_init_net_server_extension(THD *thd) ...@@ -124,12 +124,17 @@ static void re_init_net_server_extension(THD *thd)
#endif /* HAVE_PSI_INTERFACE */ #endif /* HAVE_PSI_INTERFACE */
static inline bool has_unread_compressed_data(const NET *net)
{
return net->compress && net->remain_in_buf;
}
static inline void set_thd_idle(THD *thd) static inline void set_thd_idle(THD *thd)
{ {
thd->net.reading_or_writing= 1; thd->net.reading_or_writing= 1;
#ifdef HAVE_PSI_INTERFACE #ifdef HAVE_PSI_INTERFACE
net_before_header_psi(&thd->net, thd, 0); if (!has_unread_compressed_data(&thd->net))
net_before_header_psi(&thd->net, thd, 0);
#endif #endif
} }
...@@ -326,10 +331,8 @@ static void handle_wait_timeout(THD *thd) ...@@ -326,10 +331,8 @@ static void handle_wait_timeout(THD *thd)
static bool has_unread_data(THD* thd) static bool has_unread_data(THD* thd)
{ {
NET *net= &thd->net; NET *net= &thd->net;
if (net->compress && net->remain_in_buf)
return true;
Vio *vio= net->vio; Vio *vio= net->vio;
return vio->has_data(vio); return vio->has_data(vio) || has_unread_compressed_data(net);
} }
......
...@@ -20040,8 +20040,10 @@ static void test_bug17512527() ...@@ -20040,8 +20040,10 @@ static void test_bug17512527()
static void test_compressed_protocol() static void test_compressed_protocol()
{ {
MYSQL *mysql_local; MYSQL *mysql_local;
MYSQL_STMT *stmt;
char query[4096], *end; char query[4096], *end;
int i; int i;
int rc;
myheader("test_compressed_protocol"); myheader("test_compressed_protocol");
if (!(mysql_local= mysql_client_init(NULL))) if (!(mysql_local= mysql_client_init(NULL)))
...@@ -20064,14 +20066,34 @@ static void test_compressed_protocol() ...@@ -20064,14 +20066,34 @@ static void test_compressed_protocol()
for (i=0 ; i < 2 ; i++) for (i=0 ; i < 2 ; i++)
{ {
MYSQL_RES *res; MYSQL_RES *res;
rc= mysql_real_query(mysql, query, (int) (end-query));
int rc= mysql_real_query(mysql, query, (int) (end-query));
myquery(rc); myquery(rc);
res= mysql_store_result(mysql); res= mysql_store_result(mysql);
DBUG_ASSERT(res != 0); DBUG_ASSERT(res != 0);
mysql_free_result(res); mysql_free_result(res);
} }
/*
Special compression protocol feature - it can pack
multiple protocol commands inside the same compression packet.
mariadbclient does it when MYSQL_STMT is reused in multiple
mysql_stmt_prepare() calls. It sends then COM_STMT_CLOSE and
COM_STMT_PREPARE together in a single compression packet.
Let's test, how server can handle that. There can be bugs
(MDEV-28561)
*/
stmt= mysql_stmt_init(mysql_local);
check_stmt(stmt);
for (i= 0; i < 2; i++)
{
rc= mysql_stmt_prepare(stmt, "DO 1", -1);
myquery(rc);
}
rc= mysql_stmt_close(stmt);
myquery(rc);
mysql_close(mysql_local); mysql_close(mysql_local);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment