From 00649525ee8a37336221f1918943eca78f5453df Mon Sep 17 00:00:00 2001 From: Kristian Nielsen Date: Tue, 6 Jan 2015 16:32:41 +0100 Subject: [PATCH] MDEV-7189: main.processlist fails sporadically in buildbot The test case tried to trigger a DEBUG_SYNC point at the end of a SELECT SLEEP(5) statement. It did this by using EXECUTE 2, intending to trigger first at the end of SET DEBUG_SYNC, and second at the end of the SELECT SLEEP(5). However, in --ps-protocol mode, this does not work, because the SELECT is executed in two steps (Prepare followed by Execute). Thus, the DEBUG_SYNC got triggered too early, during the Prepare stage rather than Execute, and the test case could race and information_schema.processlist see the thread in the wrong state. This patch fixes by changing the way the DEBUG_SYNC point is triggered. Now we add a DBUG injection inside the code for SLEEP(5). This ensures that the DEBUG_SYNC point is not activated until the SLEEP(5) is running, ensuring that the following wait for completion will be effective. --- mysql-test/mysql-test-run.pl | 1 + mysql-test/r/processlist.result | 5 ++--- mysql-test/t/processlist.test | 18 +++++++++--------- sql/item_func.cc | 5 +++++ 4 files changed, 17 insertions(+), 12 deletions(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 60f3475bd17..50fb36d8989 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -2495,6 +2495,7 @@ sub environment_setup { # ---------------------------------------------------- my $exe_replace= mtr_exe_exists(vs_config_dirs('extra', 'replace'), "$basedir/extra/replace", + "$bindir/extra$opt_vs_config/replace", "$path_client_bindir/replace"); $ENV{'REPLACE'}= native_path($exe_replace); diff --git a/mysql-test/r/processlist.result b/mysql-test/r/processlist.result index 0182245c278..eb3af67c5bf 100644 --- a/mysql-test/r/processlist.result +++ b/mysql-test/r/processlist.result @@ -7,9 +7,8 @@ SELECT ID, TIME,TIME_MS FROM INFORMATION_SCHEMA.PROCESSLIST WHERE CONCAT(":", ID SET DEBUG_SYNC = 'now SIGNAL fill_schema_proceed'; ID TIME TIME_MS TID 0 0.000 -SET DEBUG_SYNC = 'dispatch_command_end SIGNAL query_done EXECUTE 2'; -SET DEBUG_SYNC= 'now WAIT_FOR query_done'; -SET DEBUG_SYNC= 'now SIGNAL nosignal'; +set debug_sync='reset'; +SET debug_dbug="+d,sleep_inject_query_done_debug_sync"; select sleep(5); sleep(5) 0 diff --git a/mysql-test/t/processlist.test b/mysql-test/t/processlist.test index 9c555c0f9fb..a8f8a4ed64c 100644 --- a/mysql-test/t/processlist.test +++ b/mysql-test/t/processlist.test @@ -2,6 +2,7 @@ # MDEV-4578 information_schema.processlist reports incorrect value for Time (2147483647) # +source include/have_debug.inc; source include/have_debug_sync.inc; let $tid= `SELECT CONNECTION_ID()`; @@ -21,6 +22,7 @@ SET DEBUG_SYNC = 'now SIGNAL fill_schema_proceed'; connection con1; --replace_result $tid TID reap; +set debug_sync='reset'; connection default; # @@ -28,15 +30,13 @@ connection default; # connection con1; -# Trigger a signal once the thread has gone from "Query" to "Sleep" command -# state. Note we need to execute this twice: Once at the end of SET DEBUG_SYNC, -# and once for the intended time, at the end of SELECT SLEEP(). -SET DEBUG_SYNC = 'dispatch_command_end SIGNAL query_done EXECUTE 2'; -connection default; -# Wait for and clear the first signal set during SET DEBUG_SYNC. -SET DEBUG_SYNC= 'now WAIT_FOR query_done'; -SET DEBUG_SYNC= 'now SIGNAL nosignal'; -connection con1; +# This DBUG insertion triggers a DEBUG_SYNC signal "query_done" once +# the below SELECT SLEEP(5) has gone from "Query" to "Sleep" command +# state. (We cannot just set the DEBUG_SYNC directly here, because +# then it can trigger at the end of the SET DEBUG_SYNC statement (or +# at the end of the Prepare step of the SELECT, if --ps-protocol), +# thus occuring too early). +SET debug_dbug="+d,sleep_inject_query_done_debug_sync"; select sleep(5); #run a query that will take some time connection default; diff --git a/sql/item_func.cc b/sql/item_func.cc index 93eafdfa938..90257406e1e 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -4482,6 +4482,11 @@ longlong Item_func_sleep::val_int() mysql_cond_destroy(&cond); + DBUG_EXECUTE_IF("sleep_inject_query_done_debug_sync", { + debug_sync_set_action + (thd, STRING_WITH_LEN("dispatch_command_end SIGNAL query_done")); + };); + return test(!error); // Return 1 killed }