Skip to content

Commit dab56d5

Browse files
committed
MDEV-23879 server hangs with threadpool, compression, and client pipelining
Amend check for unread client data in threadpool. THD::NET will have unread data, in case client uses compression, and wraps multiple commands into a single compression packet MariaDB C/C sends COM_STMT_RESET+COM_STMT_EXECUTE, and wraps it into a single compressed packet, when compression is on, thus trying to use compression and prepared statements against a threadpool-enabled server will result into a hang, before this patch.
1 parent b8b1aef commit dab56d5

File tree

3 files changed

+22
-3
lines changed

3 files changed

+22
-3
lines changed

mysql-test/r/pool_of_threads.result

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2188,3 +2188,8 @@ sleep(50)
21882188
connection extracon;
21892189
sleep(5.5)
21902190
0
2191+
connect comp_con,localhost,root,,,,,COMPRESS;
2192+
SELECT 1;
2193+
1
2194+
1
2195+
disconnect comp_con;

mysql-test/t/pool_of_threads.test

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,3 +92,9 @@ connection con2;
9292

9393
connection extracon;
9494
--reap
95+
96+
# Check if compression works OK
97+
connect (comp_con,localhost,root,,,,,COMPRESS);
98+
SELECT 1;
99+
disconnect comp_con;
100+

sql/threadpool_common.cc

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,16 @@ static void handle_wait_timeout(THD *thd)
324324
thd->net.error= 2;
325325
}
326326

327+
/** Check if some client data is cached in thd->net or thd->net.vio */
328+
static bool has_unread_data(THD* thd)
329+
{
330+
NET *net= &thd->net;
331+
if (net->compress && net->remain_in_buf)
332+
return true;
333+
Vio *vio= net->vio;
334+
return vio->has_data(vio);
335+
}
336+
327337

328338
/**
329339
Process a single client request or a single batch.
@@ -358,7 +368,6 @@ static int threadpool_process_request(THD *thd)
358368
*/
359369
for(;;)
360370
{
361-
Vio *vio;
362371
thd->net.reading_or_writing= 0;
363372
if (mysql_audit_release_required(thd))
364373
mysql_audit_release(thd);
@@ -374,8 +383,7 @@ static int threadpool_process_request(THD *thd)
374383

375384
set_thd_idle(thd);
376385

377-
vio= thd->net.vio;
378-
if (!vio->has_data(vio))
386+
if (!has_unread_data(thd))
379387
{
380388
/* More info on this debug sync is in sql_parse.cc*/
381389
DEBUG_SYNC(thd, "before_do_command_net_read");

0 commit comments

Comments
 (0)