summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVladislav Vaintroub <wlad@mariadb.com>2020-10-03 00:24:53 +0200
committerVladislav Vaintroub <wlad@mariadb.com>2020-10-03 00:24:53 +0200
commitdab56d5e8e9c64d3815594b412521e36ba539f48 (patch)
treee98e1dd0b77daeebea8c91936a62733448c94674
parentb8b1aef6b1a30349c989536aa80d06f38742c29e (diff)
downloadmariadb-git-dab56d5e8e9c64d3815594b412521e36ba539f48.tar.gz
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.
-rw-r--r--mysql-test/r/pool_of_threads.result5
-rw-r--r--mysql-test/t/pool_of_threads.test6
-rw-r--r--sql/threadpool_common.cc14
3 files changed, 22 insertions, 3 deletions
diff --git a/mysql-test/r/pool_of_threads.result b/mysql-test/r/pool_of_threads.result
index 9c02dfac9cd..5f501eb1b68 100644
--- a/mysql-test/r/pool_of_threads.result
+++ b/mysql-test/r/pool_of_threads.result
@@ -2188,3 +2188,8 @@ sleep(50)
connection extracon;
sleep(5.5)
0
+connect comp_con,localhost,root,,,,,COMPRESS;
+SELECT 1;
+1
+1
+disconnect comp_con;
diff --git a/mysql-test/t/pool_of_threads.test b/mysql-test/t/pool_of_threads.test
index cb62a27faeb..95b320e6dad 100644
--- a/mysql-test/t/pool_of_threads.test
+++ b/mysql-test/t/pool_of_threads.test
@@ -92,3 +92,9 @@ connection con2;
connection extracon;
--reap
+
+# Check if compression works OK
+connect (comp_con,localhost,root,,,,,COMPRESS);
+SELECT 1;
+disconnect comp_con;
+
diff --git a/sql/threadpool_common.cc b/sql/threadpool_common.cc
index b0438770aae..fc9a79432f0 100644
--- a/sql/threadpool_common.cc
+++ b/sql/threadpool_common.cc
@@ -324,6 +324,16 @@ static void handle_wait_timeout(THD *thd)
thd->net.error= 2;
}
+/** Check if some client data is cached in thd->net or thd->net.vio */
+static bool has_unread_data(THD* thd)
+{
+ NET *net= &thd->net;
+ if (net->compress && net->remain_in_buf)
+ return true;
+ Vio *vio= net->vio;
+ return vio->has_data(vio);
+}
+
/**
Process a single client request or a single batch.
@@ -358,7 +368,6 @@ static int threadpool_process_request(THD *thd)
*/
for(;;)
{
- Vio *vio;
thd->net.reading_or_writing= 0;
if (mysql_audit_release_required(thd))
mysql_audit_release(thd);
@@ -374,8 +383,7 @@ static int threadpool_process_request(THD *thd)
set_thd_idle(thd);
- vio= thd->net.vio;
- if (!vio->has_data(vio))
+ if (!has_unread_data(thd))
{
/* More info on this debug sync is in sql_parse.cc*/
DEBUG_SYNC(thd, "before_do_command_net_read");