summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergei Golubchik <sergii@pisem.net>2013-06-13 20:19:32 +0200
committerSergei Golubchik <sergii@pisem.net>2013-06-13 20:19:32 +0200
commit85a8de31b1105f3b42eb7f67106850425894b26a (patch)
tree65a8bde57416aa990134061ae86461fe203700ef
parent1fb33e4a67918009e015967a41da6dbd65760ffa (diff)
downloadmariadb-git-85a8de31b1105f3b42eb7f67106850425894b26a.tar.gz
MDEV-4578 information_schema.processlist reports incorrect value for Time (2147483647)
SHOW PROCESSLIST might see a thread that started executing a query *after* processlist has started. Don't show a negative or huge wrapped-around query execution time.
-rw-r--r--mysql-test/r/processlist.result9
-rw-r--r--mysql-test/t/processlist.test22
-rw-r--r--sql/sql_parse.cc3
-rw-r--r--sql/sql_show.cc7
4 files changed, 38 insertions, 3 deletions
diff --git a/mysql-test/r/processlist.result b/mysql-test/r/processlist.result
new file mode 100644
index 00000000000..c8fb4ed6bd5
--- /dev/null
+++ b/mysql-test/r/processlist.result
@@ -0,0 +1,9 @@
+SET DEBUG_SYNC = 'dispatch_command_before_set_time WAIT_FOR do_set_time';
+SELECT 1;
+SET DEBUG_SYNC = 'fill_schema_processlist_after_unow SIGNAL do_set_time WAIT_FOR fill_schema_proceed';
+SELECT INFO,TIME,TIME_MS FROM INFORMATION_SCHEMA.PROCESSLIST WHERE INFO IS NULL;
+1
+1
+SET DEBUG_SYNC = 'now SIGNAL fill_schema_proceed';
+INFO TIME TIME_MS
+NULL 0 0.000
diff --git a/mysql-test/t/processlist.test b/mysql-test/t/processlist.test
new file mode 100644
index 00000000000..eff1daff3aa
--- /dev/null
+++ b/mysql-test/t/processlist.test
@@ -0,0 +1,22 @@
+#
+# MDEV-4578 information_schema.processlist reports incorrect value for Time (2147483647)
+#
+
+source include/have_debug_sync.inc;
+
+SET DEBUG_SYNC = 'dispatch_command_before_set_time WAIT_FOR do_set_time';
+send SELECT 1;
+
+connect (con1,localhost,root,,);
+
+SET DEBUG_SYNC = 'fill_schema_processlist_after_unow SIGNAL do_set_time WAIT_FOR fill_schema_proceed';
+send SELECT INFO,TIME,TIME_MS FROM INFORMATION_SCHEMA.PROCESSLIST WHERE INFO IS NULL;
+
+connection default;
+reap;
+SET DEBUG_SYNC = 'now SIGNAL fill_schema_proceed';
+
+connection con1;
+reap;
+disconnect con1;
+
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 05957197817..57969b60858 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -914,6 +914,9 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
thd->enable_slow_log= TRUE;
thd->query_plan_flags= QPLAN_INIT;
thd->lex->sql_command= SQLCOM_END; /* to avoid confusing VIEW detectors */
+
+ DEBUG_SYNC(thd,"dispatch_command_before_set_time");
+
thd->set_time();
thd->set_query_id(get_query_id());
if (!(server_command_flags[command] & CF_SKIP_QUERY_ID))
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index b120479c998..a6d72068590 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -2297,6 +2297,8 @@ int fill_schema_processlist(THD* thd, TABLE_LIST* tables, COND* cond)
my_hrtime_t unow= my_hrtime();
DBUG_ENTER("fill_schema_processlist");
+ DEBUG_SYNC(thd,"fill_schema_processlist_after_unow");
+
user= thd->security_ctx->master_access & PROCESS_ACL ?
NullS : thd->security_ctx->priv_user;
@@ -2355,9 +2357,8 @@ int fill_schema_processlist(THD* thd, TABLE_LIST* tables, COND* cond)
table->field[4]->store(command_name[tmp->command].str,
command_name[tmp->command].length, cs);
/* MYSQL_TIME */
- const ulonglong utime= (tmp->start_time ?
- (unow.val - tmp->start_time * HRTIME_RESOLUTION -
- tmp->start_time_sec_part) : 0);
+ ulonglong start_utime= tmp->start_time * HRTIME_RESOLUTION + tmp->start_time_sec_part;
+ ulonglong utime= start_utime < unow.val ? unow.val - start_utime : 0;
table->field[5]->store(utime / HRTIME_RESOLUTION, TRUE);
/* STATE */
if ((val= thread_state_info(tmp)))