Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions include/thr_timer.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ extern "C" {
typedef struct st_timer {
struct timespec expire_time;
ulonglong period;
ulonglong timeout; /* Timeout value in microseconds */
my_bool expired;
uint index_in_queue;
void (*func)(void*);
Expand Down
4 changes: 2 additions & 2 deletions mysql-test/main/alter_table_lock.result
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,9 @@ LOCK TABLE t READ;
connection con1;
SET max_statement_time=0.001;
ALTER TABLE t FORCE;
ERROR 70100: Query execution was interrupted (max_statement_time exceeded)
ERROR 70100: Query was interrupted: execution time limit 0.001 sec exceeded
ALTER TABLE IF EXISTS t FORCE;
ERROR 70100: Query execution was interrupted (max_statement_time exceeded)
ERROR 70100: Query was interrupted: execution time limit 0.001 sec exceeded
disconnect con1;
connection default;
UNLOCK TABLES;
Expand Down
2 changes: 1 addition & 1 deletion mysql-test/main/backup_lock.result
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ MDL_SHARED_WRITE Table metadata lock test t1
MDL_SHARED_UPGRADABLE Table metadata lock test t1
MDL_INTENTION_EXCLUSIVE Schema metadata lock test
SET STATEMENT max_statement_time=1 FOR backup stage block_ddl;
ERROR 70100: Query execution was interrupted (max_statement_time exceeded)
ERROR 70100: Query was interrupted: execution time limit 1.0 sec exceeded
backup stage block_ddl;
connection default;
commit;
Expand Down
8 changes: 4 additions & 4 deletions mysql-test/main/backup_locks.result
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,13 @@ connection con1;
CREATE OR REPLACE SEQUENCE seq1 START -28;
ERROR HY000: Sequence 'test.seq1' has out of range value for options
SET STATEMENT max_statement_time=10 FOR CREATE OR REPLACE SEQUENCE seq1 START 50;
ERROR 70100: Query execution was interrupted (max_statement_time exceeded)
ERROR 70100: Query was interrupted: execution time limit 10.0 sec exceeded
SET STATEMENT max_statement_time=10 FOR ALTER SEQUENCE IF EXISTS seq1 NOMAXVALUE;
ERROR 70100: Query execution was interrupted (max_statement_time exceeded)
ERROR 70100: Query was interrupted: execution time limit 10.0 sec exceeded
SET STATEMENT max_statement_time=10 FOR ALTER SEQUENCE IF EXISTS seq1 MAXVALUE 1000;
ERROR 70100: Query execution was interrupted (max_statement_time exceeded)
ERROR 70100: Query was interrupted: execution time limit 10.0 sec exceeded
SET STATEMENT max_statement_time=10 for rename table seq2 to seq3, seq3 to seq1;
ERROR 70100: Query execution was interrupted (max_statement_time exceeded)
ERROR 70100: Query was interrupted: execution time limit 10.0 sec exceeded
connection default;
backup unlock;
drop table seq1,seq2;
Expand Down
24 changes: 12 additions & 12 deletions mysql-test/main/func_json_notembedded.result
Original file line number Diff line number Diff line change
Expand Up @@ -13,29 +13,29 @@ set max_statement_time=0.0001;
SET @old_debug= @@debug_dbug;
SET debug_dbug='+d,debug_max_statement_time exceeded';
select json_array_append(@arr, '$[0]', 1);
ERROR 70100: Query execution was interrupted (max_statement_time exceeded)
ERROR 70100: Query was interrupted: execution time limit 0.0001 sec exceeded
select json_array_insert(@arr, '$[0]', 1);
ERROR 70100: Query execution was interrupted (max_statement_time exceeded)
ERROR 70100: Query was interrupted: execution time limit 0.0001 sec exceeded
select json_insert(@obj, '$.meta', 1);
ERROR 70100: Query execution was interrupted (max_statement_time exceeded)
ERROR 70100: Query was interrupted: execution time limit 0.0001 sec exceeded
select json_compact(@arr);
ERROR 70100: Query execution was interrupted (max_statement_time exceeded)
ERROR 70100: Query was interrupted: execution time limit 0.0001 sec exceeded
select json_detailed(@arr);
ERROR 70100: Query execution was interrupted (max_statement_time exceeded)
ERROR 70100: Query was interrupted: execution time limit 0.0001 sec exceeded
select json_loose(@arr);
ERROR 70100: Query execution was interrupted (max_statement_time exceeded)
ERROR 70100: Query was interrupted: execution time limit 0.0001 sec exceeded
select json_merge(@obj, @arr);
ERROR 70100: Query execution was interrupted (max_statement_time exceeded)
ERROR 70100: Query was interrupted: execution time limit 0.0001 sec exceeded
select json_merge_patch(@obj, @obj);
ERROR 70100: Query execution was interrupted (max_statement_time exceeded)
ERROR 70100: Query was interrupted: execution time limit 0.0001 sec exceeded
select json_merge_preserve(@obj, @arr);
ERROR 70100: Query execution was interrupted (max_statement_time exceeded)
ERROR 70100: Query was interrupted: execution time limit 0.0001 sec exceeded
select json_remove(@obj,'$.foo');
ERROR 70100: Query execution was interrupted (max_statement_time exceeded)
ERROR 70100: Query was interrupted: execution time limit 0.0001 sec exceeded
select json_replace(@obj,'$.foo',1);
ERROR 70100: Query execution was interrupted (max_statement_time exceeded)
ERROR 70100: Query was interrupted: execution time limit 0.0001 sec exceeded
select json_set(@arr,'$[1000]',1);
ERROR 70100: Query execution was interrupted (max_statement_time exceeded)
ERROR 70100: Query was interrupted: execution time limit 0.0001 sec exceeded
SET debug_dbug= @old_debug;
disconnect u;
connection default;
Expand Down
20 changes: 10 additions & 10 deletions mysql-test/main/opt_hint_timeout.result
Original file line number Diff line number Diff line change
Expand Up @@ -5,36 +5,36 @@ CREATE TABLE t1 (a INT);
INSERT INTO t1 SELECT seq FROM seq_1_to_5000;
# Correct hint usage
SELECT /*+ MAX_EXECUTION_TIME(10) */* FROM t1 a, t1 b;
ERROR 70100: Query execution was interrupted (max_statement_time exceeded)
ERROR 70100: Query was interrupted: execution time limit 0.01 sec exceeded
EXPLAIN EXTENDED SELECT /*+ MAX_EXECUTION_TIME(0001490) */* FROM t1;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 5000 100.00
Warnings:
Note 1003 select /*+ MAX_EXECUTION_TIME(0001490) */ `test`.`t1`.`a` AS `a` from `test`.`t1`
SELECT /*+ MAX_EXECUTION_TIME(20) */ *, SLEEP(1) FROM t1 UNION SELECT 1, 2;
ERROR 70100: Query execution was interrupted (max_statement_time exceeded)
ERROR 70100: Query was interrupted: execution time limit 0.02 sec exceeded
(SELECT /*+ MAX_EXECUTION_TIME(300) */ *, SLEEP(1) FROM t1) UNION (SELECT 1, 2);
ERROR 70100: Query execution was interrupted (max_statement_time exceeded)
ERROR 70100: Query was interrupted: execution time limit 0.3 sec exceeded
((SELECT /*+ MAX_EXECUTION_TIME(500) */ *, SLEEP(1) FROM t1));
ERROR 70100: Query execution was interrupted (max_statement_time exceeded)
ERROR 70100: Query was interrupted: execution time limit 0.5 sec exceeded
# Make sure the hint overrides global/session/statement settings.
# Global setting 30 seconds, won't be exceeded for sure
SET @@max_statement_time = 30;
SELECT /*+ MAX_EXECUTION_TIME(10)*/ count(*) FROM t1 a natural join t1 b natural join t1 c;
ERROR 70100: Query execution was interrupted (max_statement_time exceeded)
ERROR 70100: Query was interrupted: execution time limit 0.01 sec exceeded
# Session setting 30 seconds, too long to be exceeded
SET SESSION max_statement_time = 30;
SELECT /*+ MAX_EXECUTION_TIME(15) */ count(*) FROM t1 a natural join t1 b natural join t1 c;
ERROR 70100: Query execution was interrupted (max_statement_time exceeded)
ERROR 70100: Query was interrupted: execution time limit 0.015 sec exceeded
SET STATEMENT max_statement_time = 20 FOR
SELECT /*+ MAX_EXECUTION_TIME(5)*/ count(*) FROM t1 a natural join t1 b natural join t1 c;
ERROR 70100: Query execution was interrupted (max_statement_time exceeded)
ERROR 70100: Query was interrupted: execution time limit 0.005 sec exceeded
# Check that prepared statements process the hint correctly
PREPARE s FROM 'SELECT /*+ MAX_EXECUTION_TIME(20) */ seq, SLEEP(1) FROM seq_1_to_10';
EXECUTE s;
ERROR 70100: Query execution was interrupted (max_statement_time exceeded)
ERROR 70100: Query was interrupted: execution time limit 0.02 sec exceeded
EXECUTE s;
ERROR 70100: Query execution was interrupted (max_statement_time exceeded)
ERROR 70100: Query was interrupted: execution time limit 0.02 sec exceeded
# Hint duplication
SELECT /*+ MAX_EXECUTION_TIME(50000) MAX_EXECUTION_TIME(100) */ count(*) FROM t1;
count(*)
Expand Down Expand Up @@ -111,5 +111,5 @@ Warning 4172 'MAX_EXECUTION_TIME(30)' is not allowed in this context
SELECT /*+ MAX_EXECUTION_TIME(20) */ count(*), SLEEP(1) FROM t1
UNION
SELECT count(*), SLEEP(1) FROM t1;
ERROR 70100: Query execution was interrupted (max_statement_time exceeded)
ERROR 70100: Query was interrupted: execution time limit 0.02 sec exceeded
DROP TABLE t1, t2;
2 changes: 1 addition & 1 deletion mysql-test/main/set_statement_notembedded.result
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ SHOW STATUS LIKE "max_statement_time_exceeded";
Variable_name Value
Max_statement_time_exceeded 0
SET STATEMENT MAX_STATEMENT_TIME=1 FOR SELECT SLEEP(10);
ERROR 70100: Query execution was interrupted (max_statement_time exceeded)
ERROR 70100: Query was interrupted: execution time limit 1.0 sec exceeded
SHOW STATUS LIKE "max_statement_time_exceeded";
Variable_name Value
Max_statement_time_exceeded 1
Expand Down
2 changes: 1 addition & 1 deletion mysql-test/suite/parts/r/print_error.result
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ CREATE TABLE t2 SELECT * FROM t1;;
connect con2,localhost,root,,test;
SET max_statement_time= 1;
DELETE FROM t1 PARTITION (p1) ORDER BY i LIMIT 2;
ERROR 70100: Query execution was interrupted (max_statement_time exceeded)
ERROR 70100: Query was interrupted: execution time limit 1.0 sec exceeded
disconnect con2;
connection default;
XA END 'xid';
Expand Down
2 changes: 1 addition & 1 deletion mysql-test/suite/versioning/r/not_embedded.result
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ connection default;
set timestamp= unix_timestamp('2000-01-01 01:00:00');
update t set a= a + 3;
connection con1;
ERROR 70100: Query execution was interrupted (max_statement_time exceeded)
ERROR 70100: Query was interrupted: execution time limit 1.0 sec exceeded
disconnect con1;
connection default;
commit;
Expand Down
1 change: 1 addition & 0 deletions mysys/thr_timer.c
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ my_bool thr_timer_settime(thr_timer_t *timer_data, ulonglong micro_seconds)

DBUG_ASSERT(timer_data->expired == 1);

timer_data->timeout= micro_seconds;
set_timespec_nsec(timer_data->expire_time, micro_seconds*1000);
timer_data->expired= 0;

Expand Down
8 changes: 4 additions & 4 deletions sql/share/errmsg-utf8.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10516,10 +10516,10 @@ ER_PLUGIN_INSTALLED
spa "Ya instalado el enchufe (plugin) '%-.192s'"
sw "Programu-jalizi '%-.192s' tayari imesakinishwa"
ER_STATEMENT_TIMEOUT 70100
chi "查询执行中断(超出MAX_STATEMENT_TIME)"
eng "Query execution was interrupted (max_statement_time exceeded)"
sw "Utekelezaji wa hoja ulikatizwa (muda_wa_max_statement umepitwa)"
spa "Se ha interrumpido la ejecución de una consulta (query) (excedido max_statement_time)
chi "查询被中断:执行时间限制 %s 已超出"
eng "Query was interrupted: execution time limit %s exceeded"
sw "Hoja ilikatizwa: kikomo cha muda wa utekelezaji %s kimepitwa"
spa "Consulta interrumpida: límite de tiempo de ejecución %s excedido"
ER_SUBQUERIES_NOT_SUPPORTED 42000
chi "%s不支持子查询或存储的函数"
eng "%s does not support subqueries or stored functions"
Expand Down
31 changes: 27 additions & 4 deletions sql/sql_class.cc
Original file line number Diff line number Diff line change
Expand Up @@ -631,8 +631,29 @@ extern "C" void thd_kill_timeout(void *thd_)
{
THD *thd= static_cast<THD *>(thd_);
thd->status_var.max_statement_time_exceeded++;
/* Kill queries that can't cause data corruptions */
thd->awake(KILL_TIMEOUT);

if (thd->slave_thread)
{
/* Slave threads use ER_SLAVE_STATEMENT_TIMEOUT without custom message */
thd->awake(KILL_TIMEOUT);
}
else
{
char msg[256], timeout_str[32];
double timeout_sec= thd->query_timer.timeout / 1000000.0;
size_t len= my_snprintf(timeout_str, sizeof(timeout_str), "%g", timeout_sec);
/*
Ensure at least one decimal digit (e.g., "1" -> "1.0"),
but not for scientific notation
*/
if (!strchr(timeout_str, '.') && !strchr(timeout_str, 'e'))
len+= my_snprintf(timeout_str + len, sizeof(timeout_str) - len, ".0");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't ever print "NaN" or "Inf" does it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That should not occur: timeout is ulonglong from user-set timeout values (which are already checked for valid ranges). Division by 1000000.0 always produces a valid positive double.

my_snprintf(timeout_str + len, sizeof(timeout_str) - len, " sec");
my_snprintf(msg, sizeof(msg), ER_THD(thd, ER_STATEMENT_TIMEOUT), timeout_str);

/* Kill queries that can't cause data corruptions */
thd->awake(KILL_TIMEOUT, ER_STATEMENT_TIMEOUT, msg);
}
}

const char *thd_where(THD *thd)
Expand Down Expand Up @@ -2060,7 +2081,9 @@ void add_diff_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var,
NOT_KILLED is used to awake a thread for a slave
*/
extern std::atomic<my_thread_id> shutdown_thread_id;
void THD::awake_no_mutex(killed_state state_to_set)
void THD::awake_no_mutex(killed_state state_to_set,
int killed_errno_arg,
const char *killed_err_msg_arg)
{
DBUG_ENTER("THD::awake_no_mutex");
DBUG_PRINT("enter", ("this: %p current_thd: %p state: %d",
Expand All @@ -2078,7 +2101,7 @@ void THD::awake_no_mutex(killed_state state_to_set)
if (killed >= KILL_CONNECTION)
state_to_set= killed;

set_killed_no_mutex(state_to_set);
set_killed_no_mutex(state_to_set, killed_errno_arg, killed_err_msg_arg);

if (state_to_set >= KILL_CONNECTION || state_to_set == NOT_KILLED)
{
Expand Down
10 changes: 7 additions & 3 deletions sql/sql_class.h
Original file line number Diff line number Diff line change
Expand Up @@ -4399,12 +4399,16 @@ class THD: public THD_count, /* this must be first */
}
void close_active_vio();
#endif
void awake_no_mutex(killed_state state_to_set);
void awake(killed_state state_to_set)
void awake_no_mutex(killed_state state_to_set,
int killed_errno_arg= 0,
const char *killed_err_msg_arg= 0);
void awake(killed_state state_to_set,
int killed_errno_arg= 0,
const char *killed_err_msg_arg= 0)
{
mysql_mutex_lock(&LOCK_thd_kill);
mysql_mutex_lock(&LOCK_thd_data);
awake_no_mutex(state_to_set);
awake_no_mutex(state_to_set, killed_errno_arg, killed_err_msg_arg);
mysql_mutex_unlock(&LOCK_thd_data);
mysql_mutex_unlock(&LOCK_thd_kill);
}
Expand Down