Commit 4cb68c0e authored by Michael Widenius's avatar Michael Widenius

mysqltest: Write command to be executed to the log BEFORE executing the command.

Fixed race condition in event that could cause hang when stopping event scheduler with SET GLOBAL event_scheduler=OFF 

client/mysqltest.cc:
  Write command to be executed to the log BEFORE executing the command.
  This makes it easier to debug crashes as the log will contain the fatal command.
mysql-test/r/mysqltest.result:
  Updated results (we now get more things logged)
sql/event_queue.cc:
  Fixed race condition in event that could cause hang when stopping event scheduler with SET GLOBAL event_scheduler=OFF.
  The reason was that a kill signal could be sent between last check of thd->killed and before thd->enter_cond() in which case the signal
  would be missed and we would be stuck in Event_scheduler::stop() forever.
parent a50a5f64
...@@ -601,6 +601,10 @@ class LogFile { ...@@ -601,6 +601,10 @@ class LogFile {
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
DBUG_ASSERT(ds->str); DBUG_ASSERT(ds->str);
#ifdef EXTRA_DEBUG
DBUG_PRINT("QQ", ("str: %*s", (int) ds->length, ds->str));
#endif
if (fwrite(ds->str, 1, ds->length, m_file) != ds->length) if (fwrite(ds->str, 1, ds->length, m_file) != ds->length)
die("Failed to write %lu bytes to '%s', errno: %d", die("Failed to write %lu bytes to '%s', errno: %d",
(unsigned long)ds->length, m_file_name, errno); (unsigned long)ds->length, m_file_name, errno);
...@@ -1288,6 +1292,7 @@ void die(const char *fmt, ...) ...@@ -1288,6 +1292,7 @@ void die(const char *fmt, ...)
DBUG_ENTER("die"); DBUG_ENTER("die");
DBUG_PRINT("enter", ("start_lineno: %d", start_lineno)); DBUG_PRINT("enter", ("start_lineno: %d", start_lineno));
fflush(stdout);
/* Print the error message */ /* Print the error message */
fprintf(stderr, "mysqltest: "); fprintf(stderr, "mysqltest: ");
if (cur_file && cur_file != file_stack) if (cur_file && cur_file != file_stack)
...@@ -1374,6 +1379,7 @@ void verbose_msg(const char *fmt, ...) ...@@ -1374,6 +1379,7 @@ void verbose_msg(const char *fmt, ...)
if (!verbose) if (!verbose)
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
fflush(stdout);
va_start(args, fmt); va_start(args, fmt);
fprintf(stderr, "mysqltest: "); fprintf(stderr, "mysqltest: ");
if (cur_file && cur_file != file_stack) if (cur_file && cur_file != file_stack)
...@@ -1384,6 +1390,7 @@ void verbose_msg(const char *fmt, ...) ...@@ -1384,6 +1390,7 @@ void verbose_msg(const char *fmt, ...)
vfprintf(stderr, fmt, args); vfprintf(stderr, fmt, args);
fprintf(stderr, "\n"); fprintf(stderr, "\n");
va_end(args); va_end(args);
fflush(stderr);
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
...@@ -1468,6 +1475,8 @@ static int run_command(char* cmd, ...@@ -1468,6 +1475,8 @@ static int run_command(char* cmd,
char buf[512]= {0}; char buf[512]= {0};
FILE *res_file; FILE *res_file;
int error; int error;
DBUG_ENTER("run_command");
DBUG_PRINT("enter", ("cmd: %s", cmd));
if (!(res_file= popen(cmd, "r"))) if (!(res_file= popen(cmd, "r")))
die("popen(\"%s\", \"r\") failed", cmd); die("popen(\"%s\", \"r\") failed", cmd);
...@@ -1488,7 +1497,7 @@ static int run_command(char* cmd, ...@@ -1488,7 +1497,7 @@ static int run_command(char* cmd,
} }
error= pclose(res_file); error= pclose(res_file);
return WEXITSTATUS(error); DBUG_RETURN(WEXITSTATUS(error));
} }
...@@ -7545,6 +7554,15 @@ void run_query(struct st_connection *cn, struct st_command *command, int flags) ...@@ -7545,6 +7554,15 @@ void run_query(struct st_connection *cn, struct st_command *command, int flags)
dynstr_append_mem(ds, "\n", 1); dynstr_append_mem(ds, "\n", 1);
} }
/*
Write the command to the result file before we execute the query
This is needed to be able to analyse the log if something goes
wrong
*/
log_file.write(&ds_res);
log_file.flush();
dynstr_set(&ds_res, 0);
if (view_protocol_enabled && if (view_protocol_enabled &&
complete_query && complete_query &&
match_re(&view_re, query)) match_re(&view_re, query))
......
...@@ -8,16 +8,19 @@ otto ...@@ -8,16 +8,19 @@ otto
select otto from (select 1 as otto) as t1; select otto from (select 1 as otto) as t1;
otto otto
1 1
select friedrich from (select 1 as otto) as t1;
mysqltest: At line 1: query 'select friedrich from (select 1 as otto) as t1' failed: 1054: Unknown column 'friedrich' in 'field list' mysqltest: At line 1: query 'select friedrich from (select 1 as otto) as t1' failed: 1054: Unknown column 'friedrich' in 'field list'
select friedrich from (select 1 as otto) as t1; select friedrich from (select 1 as otto) as t1;
ERROR 42S22: Unknown column 'friedrich' in 'field list' ERROR 42S22: Unknown column 'friedrich' in 'field list'
select otto from (select 1 as otto) as t1; select otto from (select 1 as otto) as t1;
otto otto
1 1
select otto from (select 1 as otto) as t1;
mysqltest: At line 1: query 'select otto from (select 1 as otto) as t1' succeeded - should have failed with sqlstate 42S22... mysqltest: At line 1: query 'select otto from (select 1 as otto) as t1' succeeded - should have failed with sqlstate 42S22...
mysqltest: At line 1: expecting a SQL-state (00000) from query 'remove_file MYSQLTEST_VARDIR/tmp/test_nonexistent.tmp' which cannot produce one... mysqltest: At line 1: expecting a SQL-state (00000) from query 'remove_file MYSQLTEST_VARDIR/tmp/test_nonexistent.tmp' which cannot produce one...
select friedrich from (select 1 as otto) as t1; select friedrich from (select 1 as otto) as t1;
ERROR 42S22: Unknown column 'friedrich' in 'field list' ERROR 42S22: Unknown column 'friedrich' in 'field list'
select friedrich from (select 1 as otto) as t1;
mysqltest: At line 1: query 'select friedrich from (select 1 as otto) as t1' failed with wrong sqlstate 42S22: 'Unknown column 'friedrich' in 'field list'', instead of 00000... mysqltest: At line 1: query 'select friedrich from (select 1 as otto) as t1' failed with wrong sqlstate 42S22: 'Unknown column 'friedrich' in 'field list'', instead of 00000...
select otto from (select 1 as otto) as t1; select otto from (select 1 as otto) as t1;
otto otto
...@@ -135,6 +138,7 @@ ERROR 42S02: Table 'test.t1' doesn't exist ...@@ -135,6 +138,7 @@ ERROR 42S02: Table 'test.t1' doesn't exist
select 1146 as "after_!errno_masked_error" ; select 1146 as "after_!errno_masked_error" ;
after_!errno_masked_error after_!errno_masked_error
1146 1146
select 3 from t1;
mysqltest: At line 1: query 'select 3 from t1' failed with wrong errno 1146: 'Table 'test.t1' doesn't exist', instead of 1000... mysqltest: At line 1: query 'select 3 from t1' failed with wrong errno 1146: 'Table 'test.t1' doesn't exist', instead of 1000...
garbage ; garbage ;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'garbage' at line 1 ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'garbage' at line 1
...@@ -143,6 +147,7 @@ after_--enable_abort_on_error ...@@ -143,6 +147,7 @@ after_--enable_abort_on_error
1064 1064
select 3 from t1 ; select 3 from t1 ;
ERROR 42S02: Table 'test.t1' doesn't exist ERROR 42S02: Table 'test.t1' doesn't exist
select 3 from t1;
mysqltest: At line 1: query 'select 3 from t1' failed with wrong errno 1146: 'Table 'test.t1' doesn't exist', instead of 1064... mysqltest: At line 1: query 'select 3 from t1' failed with wrong errno 1146: 'Table 'test.t1' doesn't exist', instead of 1064...
hello hello
hello hello
...@@ -336,6 +341,7 @@ included from MYSQLTEST_VARDIR/tmp/recursive.sql at line 1: ...@@ -336,6 +341,7 @@ included from MYSQLTEST_VARDIR/tmp/recursive.sql at line 1:
included from MYSQLTEST_VARDIR/tmp/recursive.sql at line 1: included from MYSQLTEST_VARDIR/tmp/recursive.sql at line 1:
included from MYSQLTEST_VARDIR/tmp/recursive.sql at line 1: included from MYSQLTEST_VARDIR/tmp/recursive.sql at line 1:
At line 1: Source directives are nesting too deep At line 1: Source directives are nesting too deep
garbage ;
mysqltest: In included file "MYSQLTEST_VARDIR/tmp/error.sql": mysqltest: In included file "MYSQLTEST_VARDIR/tmp/error.sql":
included from MYSQLTEST_VARDIR/tmp/error.sql at line 1: included from MYSQLTEST_VARDIR/tmp/error.sql at line 1:
At line 1: query 'garbage ' failed: 1064: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'garbage' at line 1 At line 1: query 'garbage ' failed: 1064: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'garbage' at line 1
...@@ -440,6 +446,7 @@ mysqltest: At line 1: missing ')' in while ...@@ -440,6 +446,7 @@ mysqltest: At line 1: missing ')' in while
mysqltest: At line 1: Missing '{' after while. Found "dec $i" mysqltest: At line 1: Missing '{' after while. Found "dec $i"
mysqltest: At line 1: Stray '}' - end of block before beginning mysqltest: At line 1: Stray '}' - end of block before beginning
mysqltest: At line 1: Stray 'end' command - end of block before beginning mysqltest: At line 1: Stray 'end' command - end of block before beginning
{;
mysqltest: At line 1: query '{' failed: 1064: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '{' at line 1 mysqltest: At line 1: query '{' failed: 1064: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '{' at line 1
mysqltest: At line 1: Missing '{' after while. Found "echo hej" mysqltest: At line 1: Missing '{' after while. Found "echo hej"
mysqltest: At line 3: Missing end of block mysqltest: At line 3: Missing end of block
...@@ -533,6 +540,10 @@ this will be executed ...@@ -533,6 +540,10 @@ this will be executed
this will be executed this will be executed
mysqltest: The test didn't produce any output mysqltest: The test didn't produce any output
Failing multi statement query Failing multi statement query
create table t1 (a int primary key);
insert into t1 values (1);
select 'select-me';
insertz 'error query'||||
mysqltest: At line 3: query 'create table t1 (a int primary key); mysqltest: At line 3: query 'create table t1 (a int primary key);
insert into t1 values (1); insert into t1 values (1);
select 'select-me'; select 'select-me';
...@@ -603,8 +614,8 @@ Abcd ...@@ -603,8 +614,8 @@ Abcd
select * from t1;; select * from t1;;
f1 f1
Abcd Abcd
mysqltest: At line 2: Cannot run query on connection between send and reap
select * from t1;; select * from t1;;
mysqltest: At line 2: Cannot run query on connection between send and reap
drop table t1; drop table t1;
mysqltest: At line 1: Missing required argument 'filename' to command 'remove_file' mysqltest: At line 1: Missing required argument 'filename' to command 'remove_file'
mysqltest: At line 1: Missing required argument 'directory' to command 'remove_files_wildcard' mysqltest: At line 1: Missing required argument 'directory' to command 'remove_files_wildcard'
......
...@@ -734,12 +734,14 @@ Event_queue::cond_wait(THD *thd, struct timespec *abstime, const char* msg, ...@@ -734,12 +734,14 @@ Event_queue::cond_wait(THD *thd, struct timespec *abstime, const char* msg,
thd->enter_cond(&COND_queue_state, &LOCK_event_queue, msg); thd->enter_cond(&COND_queue_state, &LOCK_event_queue, msg);
DBUG_PRINT("info", ("pthread_cond_%swait", abstime? "timed":"")); if (!thd->killed)
if (!abstime) {
pthread_cond_wait(&COND_queue_state, &LOCK_event_queue); DBUG_PRINT("info", ("pthread_cond_%swait", abstime ? "timed" : ""));
else if (!abstime)
pthread_cond_timedwait(&COND_queue_state, &LOCK_event_queue, abstime); pthread_cond_wait(&COND_queue_state, &LOCK_event_queue);
else
pthread_cond_timedwait(&COND_queue_state, &LOCK_event_queue, abstime);
}
mutex_last_locked_in_func= func; mutex_last_locked_in_func= func;
mutex_last_locked_at_line= line; mutex_last_locked_at_line= line;
mutex_queue_data_locked= TRUE; mutex_queue_data_locked= TRUE;
......
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