diff options
66 files changed, 1821 insertions, 817 deletions
diff --git a/.gitignore b/.gitignore index 2ed53e5365d..2c7e5c890ae 100644 --- a/.gitignore +++ b/.gitignore @@ -75,6 +75,7 @@ mysql-test/mtr mysql-test/mysql-test-run mysql-test/var/ mysys/thr_lock +mysys/thr_timer packaging/rpm-oel/mysql.spec packaging/rpm-uln/mysql.10.0.11.spec packaging/solaris/postinstall-solaris diff --git a/include/thr_timer.h b/include/thr_timer.h new file mode 100644 index 00000000000..892bbc1a01f --- /dev/null +++ b/include/thr_timer.h @@ -0,0 +1,45 @@ +/* Copyright (c) 2012 Monty Program Ab + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 or later of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + +/* Prototypes when using thr_timer functions */ + +#ifndef _thr_timer_h +#define _thr_timer_h +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct st_timer { + struct timespec expire_time; + my_bool expired; + uint index_in_queue; + void (*func)(void*); + void *func_arg; +} thr_timer_t; + +/* Main functions for library */ +my_bool init_thr_timer(uint init_size_for_timer_queue); +void end_thr_timer(); + +/* Functions for handling one timer */ +void thr_timer_init(thr_timer_t *timer_data, void(*function)(void*), + void *arg); +my_bool thr_timer_settime(thr_timer_t *timer_data, ulonglong microseconds); +void thr_timer_end(thr_timer_t *timer_data); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _thr_timer_h */ diff --git a/mysql-test/r/grant.result b/mysql-test/r/grant.result index 25fe976b7ed..6c769e60780 100644 --- a/mysql-test/r/grant.result +++ b/mysql-test/r/grant.result @@ -58,6 +58,7 @@ authentication_string password_expired N is_role N default_role +max_statement_time 0.000000 show grants for mysqltest_1@localhost; Grants for mysqltest_1@localhost GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' REQUIRE CIPHER 'EDH-RSA-DES-CBC3-SHA' @@ -85,7 +86,7 @@ delete from mysql.user where user='mysqltest_1'; flush privileges; delete from mysql.user where user='mysqltest_1'; flush privileges; -grant usage on *.* to mysqltest_1@localhost with max_queries_per_hour 10; +grant usage on *.* to mysqltest_1@localhost with max_queries_per_hour 10 max_statement_time 60; select * from mysql.user where user="mysqltest_1"; Host localhost User mysqltest_1 @@ -132,10 +133,11 @@ authentication_string password_expired N is_role N default_role +max_statement_time 60.000000 show grants for mysqltest_1@localhost; Grants for mysqltest_1@localhost -GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' WITH MAX_QUERIES_PER_HOUR 10 -grant usage on *.* to mysqltest_1@localhost with max_updates_per_hour 20 max_connections_per_hour 30; +GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' WITH MAX_QUERIES_PER_HOUR 10 MAX_STATEMENT_TIME 60.000000 +grant usage on *.* to mysqltest_1@localhost with max_updates_per_hour 20 max_connections_per_hour 30 max_statement_time 0; select * from mysql.user where user="mysqltest_1"; Host localhost User mysqltest_1 @@ -182,6 +184,7 @@ authentication_string password_expired N is_role N default_role +max_statement_time 0.000000 show grants for mysqltest_1@localhost; Grants for mysqltest_1@localhost GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' WITH MAX_QUERIES_PER_HOUR 10 MAX_UPDATES_PER_HOUR 20 MAX_CONNECTIONS_PER_HOUR 30 diff --git a/mysql-test/r/max_statement_time.result b/mysql-test/r/max_statement_time.result new file mode 100644 index 00000000000..2681575daea --- /dev/null +++ b/mysql-test/r/max_statement_time.result @@ -0,0 +1,147 @@ + +# Test the MAX_STATEMENT_TIME option. + +SET @@MAX_STATEMENT_TIME=2; +select @@max_statement_time; +@@max_statement_time +2.000000 +SELECT SLEEP(1); +SLEEP(1) +0 +SELECT SLEEP(3); +SLEEP(3) +1 +SET @@MAX_STATEMENT_TIME=0; +SELECT SLEEP(1); +SLEEP(1) +0 +SHOW STATUS LIKE "max_statement_time_exceeded"; +Variable_name Value +Max_statement_time_exceeded 1 +CREATE TABLE t1 (a INT, b VARCHAR(300)) engine=myisam; +INSERT INTO t1 VALUES (1, 'string'); +SELECT 0; +0 +0 + +# Test the MAX_STATEMENT_TIME option with SF (should have no effect). + +CREATE PROCEDURE p1() +BEGIN +declare tmp int; +SET @@MAX_STATEMENT_TIME=0.0001; +SELECT COUNT(*) INTO tmp FROM t1 WHERE b LIKE '%z%'; +SET @@MAX_STATEMENT_TIME=0; +END| +CREATE PROCEDURE p2() +BEGIN +SET @@MAX_STATEMENT_TIME=5; +END| +SELECT @@MAX_STATEMENT_TIME; +@@MAX_STATEMENT_TIME +0.000000 +CALL p1(); +CALL p2(); +SELECT @@MAX_STATEMENT_TIME; +@@MAX_STATEMENT_TIME +5.000000 +SET @@MAX_STATEMENT_TIME=0; +DROP PROCEDURE p1; +DROP PROCEDURE p2; +DROP TABLE t1; + +# MAX_STATEMENT_TIME account resource + +GRANT USAGE ON *.* TO user1@localhost WITH MAX_STATEMENT_TIME 1.005; +# con1 +SELECT @@max_statement_time; +@@max_statement_time +1.005000 +# restart and reconnect +set @global.userstat=1; +SELECT @@global.max_statement_time,@@session.max_statement_time; +@@global.max_statement_time @@session.max_statement_time +0.000000 1.005000 +select sleep(100); +sleep(100) +1 +SHOW STATUS LIKE "max_statement_time_exceeded"; +Variable_name Value +Max_statement_time_exceeded 1 +show grants for user1@localhost; +Grants for user1@localhost +GRANT USAGE ON *.* TO 'user1'@'localhost' WITH MAX_STATEMENT_TIME 1.005000 +set @global.userstat=0; +DROP USER user1@localhost; + +# MAX_STATEMENT_TIME status variables. + +flush status; +SET @@max_statement_time=0; +SELECT CONVERT(VARIABLE_VALUE, UNSIGNED) INTO @time_exceeded +FROM INFORMATION_SCHEMA.GLOBAL_STATUS +WHERE VARIABLE_NAME = 'max_statement_time_exceeded'; +SET @@max_statement_time=0.5; +SELECT SLEEP(2); +SLEEP(2) +1 +SHOW STATUS LIKE '%timeout%'; +Variable_name Value +Ssl_default_timeout 0 +Ssl_session_cache_timeouts 0 +SET @@max_statement_time=0; +# Ensure that the counters for: +# - statements that exceeded their maximum execution time +# are incremented. +SELECT 1 AS STATUS FROM INFORMATION_SCHEMA.GLOBAL_STATUS +WHERE VARIABLE_NAME = 'max_statement_time_exceeded' + AND CONVERT(VARIABLE_VALUE, UNSIGNED) > @time_exceeded; +STATUS +1 + +# Check that the appropriate error status is set. + +CREATE TABLE t1 (a INT) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1); +START TRANSACTION; +SELECT * FROM t1 FOR UPDATE; +a +1 +SET @@SESSION.max_statement_time = 0.5; +UPDATE t1 SET a = 2; +ERROR 70100: Query execution was interrupted (max_statement_time exceeded) +SHOW WARNINGS; +Level Code Message +Error 1967 Query execution was interrupted (max_statement_time exceeded) +ROLLBACK; +DROP TABLE t1; + +# Test interaction with lock waits. + +CREATE TABLE t1 (a INT) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1); +SET @@SESSION.max_statement_time= 0.5; +LOCK TABLES t1 WRITE; +SELECT @@SESSION.max_statement_time; +@@SESSION.max_statement_time +0.500000 +LOCK TABLES t1 READ; +ERROR 70100: Query execution was interrupted (max_statement_time exceeded) +UNLOCK TABLES; +BEGIN; +SELECT * FROM t1; +a +1 +ALTER TABLE t1 ADD COLUMN b INT; +ERROR 70100: Query execution was interrupted (max_statement_time exceeded) +ROLLBACK; +SELECT GET_LOCK('lock', 1); +GET_LOCK('lock', 1) +1 +SELECT GET_LOCK('lock', 1); +GET_LOCK('lock', 1) +NULL +SELECT RELEASE_LOCK('lock'); +RELEASE_LOCK('lock') +1 +DROP TABLE t1; diff --git a/mysql-test/r/mysqld--help.result b/mysql-test/r/mysqld--help.result index 5a2142c402c..80ba45be72a 100644 --- a/mysql-test/r/mysqld--help.result +++ b/mysql-test/r/mysqld--help.result @@ -422,6 +422,11 @@ The following options may be given as the first argument: value are used; the rest are ignored) --max-sp-recursion-depth[=#] Maximum stored procedure recursion depth + --max-statement-time=# + A SELECT query that have taken more than + max_statement_time seconds will be aborted. The argument + will be treated as a decimal value with microsecond + precision. A value of 0 (default) means no timeout --max-tmp-tables=# Maximum number of temporary tables a client can keep open at a time --max-user-connections=# @@ -1196,6 +1201,7 @@ max-relay-log-size 1073741824 max-seeks-for-key 18446744073709551615 max-sort-length 1024 max-sp-recursion-depth 0 +max-statement-time 0 max-tmp-tables 32 max-user-connections 0 max-write-lock-count 18446744073709551615 diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result index 7db51eadbe6..e30fa9a1966 100644 --- a/mysql-test/r/ps.result +++ b/mysql-test/r/ps.result @@ -1202,13 +1202,13 @@ SET @aux= "SELECT COUNT(*) prepare my_stmt from @aux; execute my_stmt; COUNT(*) -45 +46 execute my_stmt; COUNT(*) -45 +46 execute my_stmt; COUNT(*) -45 +46 deallocate prepare my_stmt; drop procedure if exists p1| drop table if exists t1| diff --git a/mysql-test/r/status_user.result b/mysql-test/r/status_user.result index 829c8abb634..766a00f6f78 100644 --- a/mysql-test/r/status_user.result +++ b/mysql-test/r/status_user.result @@ -25,6 +25,7 @@ DENIED_CONNECTIONS bigint(21) NO 0 LOST_CONNECTIONS bigint(21) NO 0 ACCESS_DENIED bigint(21) NO 0 EMPTY_QUERIES bigint(21) NO 0 +MAX_STATEMENT_TIME_EXCEEDED bigint(21) NO 0 show columns from information_schema.user_statistics; Field Type Null Key Default Extra USER varchar(128) NO @@ -50,6 +51,7 @@ DENIED_CONNECTIONS bigint(21) NO 0 LOST_CONNECTIONS bigint(21) NO 0 ACCESS_DENIED bigint(21) NO 0 EMPTY_QUERIES bigint(21) NO 0 +MAX_STATEMENT_TIME_EXCEEDED bigint(21) NO 0 show columns from information_schema.index_statistics; Field Type Null Key Default Extra TABLE_SCHEMA varchar(192) NO diff --git a/mysql-test/r/system_mysql_db.result b/mysql-test/r/system_mysql_db.result index 0204354d9e3..f195b0a607e 100644 --- a/mysql-test/r/system_mysql_db.result +++ b/mysql-test/r/system_mysql_db.result @@ -131,6 +131,7 @@ user CREATE TABLE `user` ( `password_expired` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', `is_role` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', `default_role` char(80) COLLATE utf8_bin NOT NULL DEFAULT '', + `max_statement_time` decimal(12,6) NOT NULL DEFAULT '0.000000', PRIMARY KEY (`Host`,`User`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='Users and global privileges' show create table func; diff --git a/mysql-test/r/system_mysql_db_fix40123.result b/mysql-test/r/system_mysql_db_fix40123.result index 0204354d9e3..f195b0a607e 100644 --- a/mysql-test/r/system_mysql_db_fix40123.result +++ b/mysql-test/r/system_mysql_db_fix40123.result @@ -131,6 +131,7 @@ user CREATE TABLE `user` ( `password_expired` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', `is_role` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', `default_role` char(80) COLLATE utf8_bin NOT NULL DEFAULT '', + `max_statement_time` decimal(12,6) NOT NULL DEFAULT '0.000000', PRIMARY KEY (`Host`,`User`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='Users and global privileges' show create table func; diff --git a/mysql-test/r/system_mysql_db_fix50030.result b/mysql-test/r/system_mysql_db_fix50030.result index 0204354d9e3..f195b0a607e 100644 --- a/mysql-test/r/system_mysql_db_fix50030.result +++ b/mysql-test/r/system_mysql_db_fix50030.result @@ -131,6 +131,7 @@ user CREATE TABLE `user` ( `password_expired` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', `is_role` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', `default_role` char(80) COLLATE utf8_bin NOT NULL DEFAULT '', + `max_statement_time` decimal(12,6) NOT NULL DEFAULT '0.000000', PRIMARY KEY (`Host`,`User`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='Users and global privileges' show create table func; diff --git a/mysql-test/r/system_mysql_db_fix50117.result b/mysql-test/r/system_mysql_db_fix50117.result index 0204354d9e3..f195b0a607e 100644 --- a/mysql-test/r/system_mysql_db_fix50117.result +++ b/mysql-test/r/system_mysql_db_fix50117.result @@ -131,6 +131,7 @@ user CREATE TABLE `user` ( `password_expired` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', `is_role` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', `default_role` char(80) COLLATE utf8_bin NOT NULL DEFAULT '', + `max_statement_time` decimal(12,6) NOT NULL DEFAULT '0.000000', PRIMARY KEY (`Host`,`User`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='Users and global privileges' show create table func; diff --git a/mysql-test/suite/funcs_1/r/is_columns_is.result b/mysql-test/suite/funcs_1/r/is_columns_is.result index 8f2f81a4616..c73eaa874c7 100644 --- a/mysql-test/suite/funcs_1/r/is_columns_is.result +++ b/mysql-test/suite/funcs_1/r/is_columns_is.result @@ -36,6 +36,7 @@ def information_schema CLIENT_STATISTICS CPU_TIME 6 0 NO double NULL NULL 21 NUL def information_schema CLIENT_STATISTICS DENIED_CONNECTIONS 20 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21) select def information_schema CLIENT_STATISTICS EMPTY_QUERIES 23 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21) select def information_schema CLIENT_STATISTICS LOST_CONNECTIONS 21 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21) select +def information_schema CLIENT_STATISTICS MAX_STATEMENT_TIME_EXCEEDED 24 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21) select def information_schema CLIENT_STATISTICS OTHER_COMMANDS 17 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21) select def information_schema CLIENT_STATISTICS ROLLBACK_TRANSACTIONS 19 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21) select def information_schema CLIENT_STATISTICS ROWS_DELETED 12 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21) select @@ -408,6 +409,7 @@ def information_schema USER_STATISTICS CPU_TIME 6 0 NO double NULL NULL 21 NULL def information_schema USER_STATISTICS DENIED_CONNECTIONS 20 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21) select def information_schema USER_STATISTICS EMPTY_QUERIES 23 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21) select def information_schema USER_STATISTICS LOST_CONNECTIONS 21 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21) select +def information_schema USER_STATISTICS MAX_STATEMENT_TIME_EXCEEDED 24 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21) select def information_schema USER_STATISTICS OTHER_COMMANDS 17 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21) select def information_schema USER_STATISTICS ROLLBACK_TRANSACTIONS 19 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21) select def information_schema USER_STATISTICS ROWS_DELETED 12 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21) select @@ -533,6 +535,7 @@ NULL information_schema CLIENT_STATISTICS DENIED_CONNECTIONS bigint NULL NULL NU NULL information_schema CLIENT_STATISTICS LOST_CONNECTIONS bigint NULL NULL NULL NULL bigint(21) NULL information_schema CLIENT_STATISTICS ACCESS_DENIED bigint NULL NULL NULL NULL bigint(21) NULL information_schema CLIENT_STATISTICS EMPTY_QUERIES bigint NULL NULL NULL NULL bigint(21) +NULL information_schema CLIENT_STATISTICS MAX_STATEMENT_TIME_EXCEEDED bigint NULL NULL NULL NULL bigint(21) 3.0000 information_schema COLLATIONS COLLATION_NAME varchar 32 96 utf8 utf8_general_ci varchar(32) 3.0000 information_schema COLLATIONS CHARACTER_SET_NAME varchar 32 96 utf8 utf8_general_ci varchar(32) NULL information_schema COLLATIONS ID bigint NULL NULL NULL NULL bigint(11) @@ -906,6 +909,7 @@ NULL information_schema USER_STATISTICS DENIED_CONNECTIONS bigint NULL NULL NULL NULL information_schema USER_STATISTICS LOST_CONNECTIONS bigint NULL NULL NULL NULL bigint(21) NULL information_schema USER_STATISTICS ACCESS_DENIED bigint NULL NULL NULL NULL bigint(21) NULL information_schema USER_STATISTICS EMPTY_QUERIES bigint NULL NULL NULL NULL bigint(21) +NULL information_schema USER_STATISTICS MAX_STATEMENT_TIME_EXCEEDED bigint NULL NULL NULL NULL bigint(21) 3.0000 information_schema VIEWS TABLE_CATALOG varchar 512 1536 utf8 utf8_general_ci varchar(512) 3.0000 information_schema VIEWS TABLE_SCHEMA varchar 64 192 utf8 utf8_general_ci varchar(64) 3.0000 information_schema VIEWS TABLE_NAME varchar 64 192 utf8 utf8_general_ci varchar(64) diff --git a/mysql-test/suite/funcs_1/r/is_columns_mysql.result b/mysql-test/suite/funcs_1/r/is_columns_mysql.result index d05c120bfa8..09adebfab1c 100644 --- a/mysql-test/suite/funcs_1/r/is_columns_mysql.result +++ b/mysql-test/suite/funcs_1/r/is_columns_mysql.result @@ -227,6 +227,7 @@ def mysql user is_role 44 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum def mysql user Lock_tables_priv 21 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references def mysql user max_connections 39 0 NO int NULL NULL 10 0 NULL NULL NULL int(11) unsigned select,insert,update,references def mysql user max_questions 37 0 NO int NULL NULL 10 0 NULL NULL NULL int(11) unsigned select,insert,update,references +def mysql user max_statement_time 46 0.000000 NO decimal NULL NULL 12 6 NULL NULL NULL decimal(12,6) select,insert,update,references def mysql user max_updates 38 0 NO int NULL NULL 10 0 NULL NULL NULL int(11) unsigned select,insert,update,references def mysql user max_user_connections 40 0 NO int NULL NULL 10 0 NULL NULL NULL int(11) select,insert,update,references def mysql user Password 3 NO char 41 41 NULL NULL NULL latin1 latin1_bin char(41) select,insert,update,references @@ -568,3 +569,4 @@ NULL mysql user max_user_connections int NULL NULL NULL NULL int(11) 3.0000 mysql user password_expired enum 1 3 utf8 utf8_general_ci enum('N','Y') 3.0000 mysql user is_role enum 1 3 utf8 utf8_general_ci enum('N','Y') 3.0000 mysql user default_role char 80 240 utf8 utf8_bin char(80) +NULL mysql user max_statement_time decimal NULL NULL NULL NULL decimal(12,6) diff --git a/mysql-test/suite/funcs_1/r/is_user_privileges.result b/mysql-test/suite/funcs_1/r/is_user_privileges.result index 5296a37c98d..dfbe50ad862 100644 --- a/mysql-test/suite/funcs_1/r/is_user_privileges.result +++ b/mysql-test/suite/funcs_1/r/is_user_privileges.result @@ -132,6 +132,7 @@ authentication_string password_expired N is_role N default_role +max_statement_time 0.000000 Host localhost User testuser2 Password @@ -177,6 +178,7 @@ authentication_string password_expired N is_role N default_role +max_statement_time 0.000000 Host localhost User testuser3 Password @@ -222,6 +224,7 @@ authentication_string password_expired N is_role N default_role +max_statement_time 0.000000 # # Add GRANT OPTION db_datadict.* to testuser1; GRANT UPDATE ON db_datadict.* TO 'testuser1'@'localhost' WITH GRANT OPTION; @@ -291,6 +294,7 @@ authentication_string password_expired N is_role N default_role +max_statement_time 0.000000 Host localhost User testuser2 Password @@ -336,6 +340,7 @@ authentication_string password_expired N is_role N default_role +max_statement_time 0.000000 Host localhost User testuser3 Password @@ -381,6 +386,7 @@ authentication_string password_expired N is_role N default_role +max_statement_time 0.000000 # Establish connection testuser1 (user=testuser1) SELECT * FROM information_schema.user_privileges WHERE grantee LIKE '''testuser%''' @@ -436,6 +442,7 @@ authentication_string password_expired N is_role N default_role +max_statement_time 0.000000 Host localhost User testuser2 Password @@ -481,6 +488,7 @@ authentication_string password_expired N is_role N default_role +max_statement_time 0.000000 Host localhost User testuser3 Password @@ -526,6 +534,7 @@ authentication_string password_expired N is_role N default_role +max_statement_time 0.000000 SHOW GRANTS; Grants for testuser1@localhost GRANT USAGE ON *.* TO 'testuser1'@'localhost' @@ -603,6 +612,7 @@ authentication_string password_expired N is_role N default_role +max_statement_time 0.000000 Host localhost User testuser2 Password @@ -648,6 +658,7 @@ authentication_string password_expired N is_role N default_role +max_statement_time 0.000000 Host localhost User testuser3 Password @@ -693,6 +704,7 @@ authentication_string password_expired N is_role N default_role +max_statement_time 0.000000 GRANT SELECT ON *.* TO 'testuser1'@'localhost' WITH GRANT OPTION; # # Here <SELECT YES> is shown correctly for testuser1; @@ -762,6 +774,7 @@ authentication_string password_expired N is_role N default_role +max_statement_time 0.000000 Host localhost User testuser2 Password @@ -807,6 +820,7 @@ authentication_string password_expired N is_role N default_role +max_statement_time 0.000000 Host localhost User testuser3 Password @@ -852,6 +866,7 @@ authentication_string password_expired N is_role N default_role +max_statement_time 0.000000 # Switch to connection testuser1 SELECT * FROM information_schema.user_privileges WHERE grantee LIKE '''testuser%''' @@ -907,6 +922,7 @@ authentication_string password_expired N is_role N default_role +max_statement_time 0.000000 Host localhost User testuser2 Password @@ -952,6 +968,7 @@ authentication_string password_expired N is_role N default_role +max_statement_time 0.000000 Host localhost User testuser3 Password @@ -997,6 +1014,7 @@ authentication_string password_expired N is_role N default_role +max_statement_time 0.000000 SHOW GRANTS; Grants for testuser1@localhost GRANT SELECT ON *.* TO 'testuser1'@'localhost' WITH GRANT OPTION @@ -1104,6 +1122,7 @@ authentication_string password_expired N is_role N default_role +max_statement_time 0.000000 Host localhost User testuser2 Password @@ -1149,6 +1168,7 @@ authentication_string password_expired N is_role N default_role +max_statement_time 0.000000 Host localhost User testuser3 Password @@ -1194,6 +1214,7 @@ authentication_string password_expired N is_role N default_role +max_statement_time 0.000000 # Switch to connection testuser1 SELECT * FROM information_schema.user_privileges WHERE grantee LIKE '''testuser%''' @@ -1296,6 +1317,7 @@ authentication_string password_expired N is_role N default_role +max_statement_time 0.000000 Host localhost User testuser2 Password @@ -1341,6 +1363,7 @@ authentication_string password_expired N is_role N default_role +max_statement_time 0.000000 Host localhost User testuser3 Password @@ -1386,6 +1409,7 @@ authentication_string password_expired N is_role N default_role +max_statement_time 0.000000 # Switch to connection testuser1 SELECT * FROM information_schema.user_privileges WHERE grantee LIKE '''testuser%''' @@ -1441,6 +1465,7 @@ authentication_string password_expired N is_role N default_role +max_statement_time 0.000000 Host localhost User testuser2 Password @@ -1486,6 +1511,7 @@ authentication_string password_expired N is_role N default_role +max_statement_time 0.000000 Host localhost User testuser3 Password @@ -1531,6 +1557,7 @@ authentication_string password_expired N is_role N default_role +max_statement_time 0.000000 SHOW GRANTS; Grants for testuser1@localhost GRANT USAGE ON *.* TO 'testuser1'@'localhost' @@ -1593,6 +1620,7 @@ authentication_string password_expired N is_role N default_role +max_statement_time 0.000000 Host localhost User testuser2 Password @@ -1638,6 +1666,7 @@ authentication_string password_expired N is_role N default_role +max_statement_time 0.000000 Host localhost User testuser3 Password @@ -1683,6 +1712,7 @@ authentication_string password_expired N is_role N default_role +max_statement_time 0.000000 SHOW GRANTS; Grants for testuser1@localhost GRANT USAGE ON *.* TO 'testuser1'@'localhost' @@ -1760,6 +1790,7 @@ authentication_string password_expired N is_role N default_role +max_statement_time 0.000000 Host localhost User testuser2 Password @@ -1805,6 +1836,7 @@ authentication_string password_expired N is_role N default_role +max_statement_time 0.000000 Host localhost User testuser3 Password @@ -1850,6 +1882,7 @@ authentication_string password_expired N is_role N default_role +max_statement_time 0.000000 # Switch to connection testuser1 SELECT * FROM information_schema.user_privileges WHERE grantee LIKE '''testuser%''' diff --git a/mysql-test/suite/perfschema/r/digest_table_full.result b/mysql-test/suite/perfschema/r/digest_table_full.result index 9c0efb7b1ca..4c7de82abc2 100644 --- a/mysql-test/suite/perfschema/r/digest_table_full.result +++ b/mysql-test/suite/perfschema/r/digest_table_full.result @@ -109,11 +109,11 @@ DROP TRIGGER trg; #################################### # QUERYING PS STATEMENT DIGEST #################################### -SELECT SCHEMA_NAME, DIGEST, DIGEST_TEXT, COUNT_STAR, SUM_ROWS_AFFECTED, SUM_WARNINGS, +SELECT SCHEMA_NAME, DIGEST_TEXT, COUNT_STAR, SUM_ROWS_AFFECTED, SUM_WARNINGS, SUM_ERRORS FROM performance_schema.events_statements_summary_by_digest; -SCHEMA_NAME DIGEST DIGEST_TEXT COUNT_STAR SUM_ROWS_AFFECTED SUM_WARNINGS SUM_ERRORS -NULL NULL NULL 55 32 1 2 -statements_digest 0e98ee6a98e296530ec59c12dbc08dfe TRUNCATE TABLE performance_schema . events_statements_summary_by_digest 1 0 0 0 +SCHEMA_NAME DIGEST_TEXT COUNT_STAR SUM_ROWS_AFFECTED SUM_WARNINGS SUM_ERRORS +NULL NULL 55 32 1 2 +statements_digest TRUNCATE TABLE performance_schema . events_statements_summary_by_digest 1 0 0 0 SHOW VARIABLES LIKE "performance_schema_digests_size"; Variable_name Value performance_schema_digests_size 2 diff --git a/mysql-test/suite/perfschema/r/rpl_gtid_func.result b/mysql-test/suite/perfschema/r/rpl_gtid_func.result index 98342bc4869..86c8347addd 100644 --- a/mysql-test/suite/perfschema/r/rpl_gtid_func.result +++ b/mysql-test/suite/perfschema/r/rpl_gtid_func.result @@ -33,11 +33,11 @@ TABLE information_schema % NO NO TABLE master foo YES YES TABLE mysql % NO NO TABLE performance_schema % NO NO -select digest, digest_text, count_star +select digest_text, count_star from performance_schema.events_statements_summary_by_digest where digest_text like "%in_%_digest%"; -digest digest_text count_star -e315485f9cbc06befb4e59970905a034 SELECT ? AS in_master_digest 1 +digest_text count_star +SELECT ? AS in_master_digest 1 insert into test.marker values (2); **** On Slave **** select * from test.marker; @@ -60,11 +60,11 @@ TABLE information_schema % NO NO TABLE mysql % NO NO TABLE performance_schema % NO NO TABLE slave foo YES YES -select digest, digest_text, count_star +select digest_text, count_star from performance_schema.events_statements_summary_by_digest where digest_text like "%in_%_digest%"; -digest digest_text count_star -bd2f53b41efcd037df41a3dd8bf3312a SELECT ? AS in_slave_digest 1 +digest_text count_star +SELECT ? AS in_slave_digest 1 **** On Master **** delete from performance_schema.setup_objects where object_schema='master'; diff --git a/mysql-test/suite/perfschema/r/start_server_no_digests.result b/mysql-test/suite/perfschema/r/start_server_no_digests.result index 4f6fa9bc5da..e4b389716a9 100644 --- a/mysql-test/suite/perfschema/r/start_server_no_digests.result +++ b/mysql-test/suite/perfschema/r/start_server_no_digests.result @@ -109,9 +109,9 @@ DROP TRIGGER trg; #################################### # QUERYING PS STATEMENT DIGEST #################################### -SELECT SCHEMA_NAME, DIGEST, DIGEST_TEXT, COUNT_STAR, SUM_ROWS_AFFECTED, SUM_WARNINGS, +SELECT SCHEMA_NAME, DIGEST_TEXT, COUNT_STAR, SUM_ROWS_AFFECTED, SUM_WARNINGS, SUM_ERRORS FROM performance_schema.events_statements_summary_by_digest; -SCHEMA_NAME DIGEST DIGEST_TEXT COUNT_STAR SUM_ROWS_AFFECTED SUM_WARNINGS SUM_ERRORS +SCHEMA_NAME DIGEST_TEXT COUNT_STAR SUM_ROWS_AFFECTED SUM_WARNINGS SUM_ERRORS SHOW VARIABLES LIKE "performance_schema_digests_size"; Variable_name Value performance_schema_digests_size 0 diff --git a/mysql-test/suite/perfschema/r/statement_digest.result b/mysql-test/suite/perfschema/r/statement_digest.result index 41cba435cb6..a7983e5baaa 100644 --- a/mysql-test/suite/perfschema/r/statement_digest.result +++ b/mysql-test/suite/perfschema/r/statement_digest.result @@ -109,46 +109,46 @@ DROP TRIGGER trg; #################################### # QUERYING PS STATEMENT DIGEST #################################### -SELECT SCHEMA_NAME, DIGEST, DIGEST_TEXT, COUNT_STAR, SUM_ROWS_AFFECTED, SUM_WARNINGS, +SELECT SCHEMA_NAME, DIGEST_TEXT, COUNT_STAR, SUM_ROWS_AFFECTED, SUM_WARNINGS, SUM_ERRORS FROM performance_schema.events_statements_summary_by_digest; -SCHEMA_NAME DIGEST DIGEST_TEXT COUNT_STAR SUM_ROWS_AFFECTED SUM_WARNINGS SUM_ERRORS -statements_digest 0e98ee6a98e296530ec59c12dbc08dfe TRUNCATE TABLE performance_schema . events_statements_summary_by_digest 1 0 0 0 -statements_digest 954f43425c3234acc8e194afd97e8a0a SELECT ? FROM t1 1 0 0 0 -statements_digest fc365a54bc19d746bd24c27aba46b990 SELECT ? FROM `t1` 1 0 0 0 -statements_digest 27ba28f6252e4ae0e9b14b36da536fbe SELECT ?, ... FROM t1 2 0 0 0 -statements_digest 81d03922612900032ec4b81934ab4841 SELECT ? FROM t2 1 0 0 0 -statements_digest adce8aec12b6b5046cd4bf55951014c7 SELECT ?, ... FROM t2 2 0 0 0 -statements_digest 59a1bd93c424b10802fe66bb6dcd94d2 INSERT INTO t1 VALUES (?) 1 1 0 0 -statements_digest 91b2da58b0eb49c35a38fbc49f5e491d INSERT INTO t2 VALUES (?) 1 1 0 0 -statements_digest 967114adbf91d8a4a99ec5e49e909ff4 INSERT INTO t3 VALUES (...) 4 4 0 0 -statements_digest 8f25e7a48487e0aa7377e816816bb658 INSERT INTO t4 VALUES (...) 1 1 0 0 -statements_digest 4e51253af793867fba66166de1f314f7 INSERT INTO t5 VALUES (...) 1 1 0 0 -statements_digest fa47b3109e117216cd10209690d28596 INSERT INTO t1 VALUES (?) /* , ... */ 2 7 0 0 -statements_digest 72409f84bc236e6fe9f2f7b4d727f2d3 INSERT INTO t3 VALUES (...) /* , ... */ 1 3 0 0 -statements_digest d40aaddb41ed794d65dd8273f0c75700 INSERT INTO t5 VALUES (...) /* , ... */ 1 3 0 0 -statements_digest 57a82b28388e52e99fc64339dd30edde INSERT INTO t1 VALUES ( NULL ) 1 1 0 0 -statements_digest 6a56b694106442474cb0e5fb7575c8b9 INSERT INTO t6 VALUES (...) 5 5 0 0 -statements_digest c9abf55e296c4317dbaf2d14ef907ad7 SELECT ? + ? 3 0 0 0 -statements_digest 156304a0851a3e3626b39fb3da841a82 SELECT ? 1 0 0 0 -statements_digest 3b085ab0d2063dfca1a39212e3ea1831 CREATE SCHEMA statements_digest_temp 2 2 0 0 -statements_digest 09f9fabef2feb9a54ba01455e5ae83b9 DROP SCHEMA statements_digest_temp 2 0 0 0 -statements_digest 7910a63ffd31cbcb742e15270c8958c8 SELECT ? FROM no_such_table 1 0 0 1 -statements_digest fa34540a438bc672478b1162505ee28c CREATE TABLE dup_table ( c CHARACTER (?) ) 2 0 0 1 -statements_digest 2c720f176bb7c8510ff8aca8921b9945 DROP TABLE dup_table 1 0 0 0 -statements_digest 0c7d9fd8c27ab067511da41ca3bcdff3 INSERT INTO t11 VALUES (?) 1 1 1 0 -statements_digest 81681ff345065ed72bcd1e9407ab85e4 SHOW WARNINGS 1 0 0 0 -statements_digest d766f5823ae5d8e4cf4602b8e7a3fb80 PREPARE stmt FROM ? 1 0 0 0 -statements_digest 3ab1e87eabd9688edf919754cce6348b EXECUTE stmt 2 0 0 0 -statements_digest 470094469d250b9f45cab45bf610efe8 DEALLOCATE PREPARE stmt 1 0 0 0 -statements_digest 1b4d25358e08b35ad54e49dfe5eaf3e4 CREATE PROCEDURE p1 ( ) BEGIN SELECT * FROM t12 ; END 1 0 0 0 -statements_digest 84554971243e91106214dcb8f4eaa89b CALL p1 ( ) 2 0 0 0 -statements_digest 77206e4bf30979c56752a7ed9150213a DROP PROCEDURE p1 1 0 0 0 -statements_digest 03b91dcdba6b0e29f7fb240ae4bcd97f CREATE FUNCTION `func` ( a INTEGER , b INTEGER ) RETURNS INTEGER (?) RETURN a + b 1 0 0 0 -statements_digest 72bc532f308f2dca62f5291df8c50e6f SELECT func (...) 2 0 0 0 -statements_digest 0b5a5297689c5036def6af8e8a8ce113 DROP FUNCTION func 1 0 0 0 -statements_digest d08331e42c67555ece50e46eef0f2b47 CREATE TRIGGER trg BEFORE INSERT ON t12 FOR EACH ROW SET @ ? := ? 1 0 0 0 -statements_digest 754a49a4de995c5a729e9ab52f135f59 INSERT INTO t12 VALUES (?) 2 2 0 0 -statements_digest 68df17752bca7c2c8ee2a6a19a0674e7 DROP TRIGGER trg 1 0 0 0 +SCHEMA_NAME DIGEST_TEXT COUNT_STAR SUM_ROWS_AFFECTED SUM_WARNINGS SUM_ERRORS +statements_digest TRUNCATE TABLE performance_schema . events_statements_summary_by_digest 1 0 0 0 +statements_digest SELECT ? FROM t1 1 0 0 0 +statements_digest SELECT ? FROM `t1` 1 0 0 0 +statements_digest SELECT ?, ... FROM t1 2 0 0 0 +statements_digest SELECT ? FROM t2 1 0 0 0 +statements_digest SELECT ?, ... FROM t2 2 0 0 0 +statements_digest INSERT INTO t1 VALUES (?) 1 1 0 0 +statements_digest INSERT INTO t2 VALUES (?) 1 1 0 0 +statements_digest INSERT INTO t3 VALUES (...) 4 4 0 0 +statements_digest INSERT INTO t4 VALUES (...) 1 1 0 0 +statements_digest INSERT INTO t5 VALUES (...) 1 1 0 0 +statements_digest INSERT INTO t1 VALUES (?) /* , ... */ 2 7 0 0 +statements_digest INSERT INTO t3 VALUES (...) /* , ... */ 1 3 0 0 +statements_digest INSERT INTO t5 VALUES (...) /* , ... */ 1 3 0 0 +statements_digest INSERT INTO t1 VALUES ( NULL ) 1 1 0 0 +statements_digest INSERT INTO t6 VALUES (...) 5 5 0 0 +statements_digest SELECT ? + ? 3 0 0 0 +statements_digest SELECT ? 1 0 0 0 +statements_digest CREATE SCHEMA statements_digest_temp 2 2 0 0 +statements_digest DROP SCHEMA statements_digest_temp 2 0 0 0 +statements_digest SELECT ? FROM no_such_table 1 0 0 1 +statements_digest CREATE TABLE dup_table ( c CHARACTER (?) ) 2 0 0 1 +statements_digest DROP TABLE dup_table 1 0 0 0 +statements_digest INSERT INTO t11 VALUES (?) 1 1 1 0 +statements_digest SHOW WARNINGS 1 0 0 0 +statements_digest PREPARE stmt FROM ? 1 0 0 0 +statements_digest EXECUTE stmt 2 0 0 0 +statements_digest DEALLOCATE PREPARE stmt 1 0 0 0 +statements_digest CREATE PROCEDURE p1 ( ) BEGIN SELECT * FROM t12 ; END 1 0 0 0 +statements_digest CALL p1 ( ) 2 0 0 0 +statements_digest DROP PROCEDURE p1 1 0 0 0 +statements_digest CREATE FUNCTION `func` ( a INTEGER , b INTEGER ) RETURNS INTEGER (?) RETURN a + b 1 0 0 0 +statements_digest SELECT func (...) 2 0 0 0 +statements_digest DROP FUNCTION func 1 0 0 0 +statements_digest CREATE TRIGGER trg BEFORE INSERT ON t12 FOR EACH ROW SET @ ? := ? 1 0 0 0 +statements_digest INSERT INTO t12 VALUES (?) 2 2 0 0 +statements_digest DROP TRIGGER trg 1 0 0 0 #################################### # CLEANUP #################################### diff --git a/mysql-test/suite/perfschema/r/statement_digest_consumers.result b/mysql-test/suite/perfschema/r/statement_digest_consumers.result index 21e62e13b19..8c5696bb139 100644 --- a/mysql-test/suite/perfschema/r/statement_digest_consumers.result +++ b/mysql-test/suite/perfschema/r/statement_digest_consumers.result @@ -123,47 +123,47 @@ DROP TRIGGER trg; #################################### # QUERYING PS STATEMENT DIGEST #################################### -SELECT schema_name, digest, digest_text, count_star FROM performance_schema.events_statements_summary_by_digest; -schema_name digest digest_text count_star -statements_digest 0e98ee6a98e296530ec59c12dbc08dfe TRUNCATE TABLE performance_schema . events_statements_summary_by_digest 1 -statements_digest 954f43425c3234acc8e194afd97e8a0a SELECT ? FROM t1 1 -statements_digest fc365a54bc19d746bd24c27aba46b990 SELECT ? FROM `t1` 1 -statements_digest 27ba28f6252e4ae0e9b14b36da536fbe SELECT ?, ... FROM t1 2 -statements_digest 81d03922612900032ec4b81934ab4841 SELECT ? FROM t2 1 -statements_digest adce8aec12b6b5046cd4bf55951014c7 SELECT ?, ... FROM t2 2 -statements_digest 59a1bd93c424b10802fe66bb6dcd94d2 INSERT INTO t1 VALUES (?) 1 -statements_digest 91b2da58b0eb49c35a38fbc49f5e491d INSERT INTO t2 VALUES (?) 1 -statements_digest 967114adbf91d8a4a99ec5e49e909ff4 INSERT INTO t3 VALUES (...) 4 -statements_digest 8f25e7a48487e0aa7377e816816bb658 INSERT INTO t4 VALUES (...) 1 -statements_digest 4e51253af793867fba66166de1f314f7 INSERT INTO t5 VALUES (...) 1 -statements_digest fa47b3109e117216cd10209690d28596 INSERT INTO t1 VALUES (?) /* , ... */ 2 -statements_digest 72409f84bc236e6fe9f2f7b4d727f2d3 INSERT INTO t3 VALUES (...) /* , ... */ 1 -statements_digest d40aaddb41ed794d65dd8273f0c75700 INSERT INTO t5 VALUES (...) /* , ... */ 1 -statements_digest 57a82b28388e52e99fc64339dd30edde INSERT INTO t1 VALUES ( NULL ) 1 -statements_digest 6a56b694106442474cb0e5fb7575c8b9 INSERT INTO t6 VALUES (...) 5 -statements_digest c9abf55e296c4317dbaf2d14ef907ad7 SELECT ? + ? 3 -statements_digest 156304a0851a3e3626b39fb3da841a82 SELECT ? 1 -statements_digest 3b085ab0d2063dfca1a39212e3ea1831 CREATE SCHEMA statements_digest_temp 2 -statements_digest 09f9fabef2feb9a54ba01455e5ae83b9 DROP SCHEMA statements_digest_temp 2 -statements_digest 7910a63ffd31cbcb742e15270c8958c8 SELECT ? FROM no_such_table 1 -statements_digest fa34540a438bc672478b1162505ee28c CREATE TABLE dup_table ( c CHARACTER (?) ) 2 -statements_digest 2c720f176bb7c8510ff8aca8921b9945 DROP TABLE dup_table 1 -statements_digest 0c7d9fd8c27ab067511da41ca3bcdff3 INSERT INTO t11 VALUES (?) 1 -statements_digest 81681ff345065ed72bcd1e9407ab85e4 SHOW WARNINGS 1 -statements_digest d766f5823ae5d8e4cf4602b8e7a3fb80 PREPARE stmt FROM ? 1 -statements_digest 3ab1e87eabd9688edf919754cce6348b EXECUTE stmt 2 -statements_digest 470094469d250b9f45cab45bf610efe8 DEALLOCATE PREPARE stmt 1 -statements_digest 1b4d25358e08b35ad54e49dfe5eaf3e4 CREATE PROCEDURE p1 ( ) BEGIN SELECT * FROM t12 ; END 1 -statements_digest 84554971243e91106214dcb8f4eaa89b CALL p1 ( ) 2 -statements_digest 77206e4bf30979c56752a7ed9150213a DROP PROCEDURE p1 1 -statements_digest 03b91dcdba6b0e29f7fb240ae4bcd97f CREATE FUNCTION `func` ( a INTEGER , b INTEGER ) RETURNS INTEGER (?) RETURN a + b 1 -statements_digest 72bc532f308f2dca62f5291df8c50e6f SELECT func (...) 2 -statements_digest 0b5a5297689c5036def6af8e8a8ce113 DROP FUNCTION func 1 -statements_digest d08331e42c67555ece50e46eef0f2b47 CREATE TRIGGER trg BEFORE INSERT ON t12 FOR EACH ROW SET @ ? := ? 1 -statements_digest 754a49a4de995c5a729e9ab52f135f59 INSERT INTO t12 VALUES (?) 2 -statements_digest 68df17752bca7c2c8ee2a6a19a0674e7 DROP TRIGGER trg 1 -SELECT digest, digest_text FROM performance_schema.events_statements_current; -digest digest_text +SELECT schema_name,digest_text, count_star FROM performance_schema.events_statements_summary_by_digest; +schema_name digest_text count_star +statements_digest TRUNCATE TABLE performance_schema . events_statements_summary_by_digest 1 +statements_digest SELECT ? FROM t1 1 +statements_digest SELECT ? FROM `t1` 1 +statements_digest SELECT ?, ... FROM t1 2 +statements_digest SELECT ? FROM t2 1 +statements_digest SELECT ?, ... FROM t2 2 +statements_digest INSERT INTO t1 VALUES (?) 1 +statements_digest INSERT INTO t2 VALUES (?) 1 +statements_digest INSERT INTO t3 VALUES (...) 4 +statements_digest INSERT INTO t4 VALUES (...) 1 +statements_digest INSERT INTO t5 VALUES (...) 1 +statements_digest INSERT INTO t1 VALUES (?) /* , ... */ 2 +statements_digest INSERT INTO t3 VALUES (...) /* , ... */ 1 +statements_digest INSERT INTO t5 VALUES (...) /* , ... */ 1 +statements_digest INSERT INTO t1 VALUES ( NULL ) 1 +statements_digest INSERT INTO t6 VALUES (...) 5 +statements_digest SELECT ? + ? 3 +statements_digest SELECT ? 1 +statements_digest CREATE SCHEMA statements_digest_temp 2 +statements_digest DROP SCHEMA statements_digest_temp 2 +statements_digest SELECT ? FROM no_such_table 1 +statements_digest CREATE TABLE dup_table ( c CHARACTER (?) ) 2 +statements_digest DROP TABLE dup_table 1 +statements_digest INSERT INTO t11 VALUES (?) 1 +statements_digest SHOW WARNINGS 1 +statements_digest PREPARE stmt FROM ? 1 +statements_digest EXECUTE stmt 2 +statements_digest DEALLOCATE PREPARE stmt 1 +statements_digest CREATE PROCEDURE p1 ( ) BEGIN SELECT * FROM t12 ; END 1 +statements_digest CALL p1 ( ) 2 +statements_digest DROP PROCEDURE p1 1 +statements_digest CREATE FUNCTION `func` ( a INTEGER , b INTEGER ) RETURNS INTEGER (?) RETURN a + b 1 +statements_digest SELECT func (...) 2 +statements_digest DROP FUNCTION func 1 +statements_digest CREATE TRIGGER trg BEFORE INSERT ON t12 FOR EACH ROW SET @ ? := ? 1 +statements_digest INSERT INTO t12 VALUES (?) 2 +statements_digest DROP TRIGGER trg 1 +SELECT digest_text FROM performance_schema.events_statements_current; +digest_text #################################### # CLEANUP #################################### diff --git a/mysql-test/suite/perfschema/r/statement_digest_long_query.result b/mysql-test/suite/perfschema/r/statement_digest_long_query.result index bb355304537..8bc7a877bda 100644 --- a/mysql-test/suite/perfschema/r/statement_digest_long_query.result +++ b/mysql-test/suite/perfschema/r/statement_digest_long_query.result @@ -6,7 +6,7 @@ SELECT 1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1 #################################### # QUERYING PS STATEMENT DIGEST #################################### -SELECT schema_name, digest, digest_text, count_star FROM events_statements_summary_by_digest; -schema_name digest digest_text count_star -performance_schema 9d35ff74210c6b30efa4559d627ed0f7 TRUNCATE TABLE events_statements_summary_by_digest 1 -performance_schema d78a04c1c42765b8552e0483c50ae9ff SELECT ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ... 1 +SELECT schema_name, digest_text, count_star FROM events_statements_summary_by_digest; +schema_name digest_text count_star +performance_schema TRUNCATE TABLE events_statements_summary_by_digest 1 +performance_schema SELECT ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ... 1 diff --git a/mysql-test/suite/perfschema/t/digest_table_full.test b/mysql-test/suite/perfschema/t/digest_table_full.test index cb9d7ea4ea8..dbbce662256 100644 --- a/mysql-test/suite/perfschema/t/digest_table_full.test +++ b/mysql-test/suite/perfschema/t/digest_table_full.test @@ -19,7 +19,7 @@ TRUNCATE TABLE performance_schema.events_statements_summary_by_digest; --echo #################################### --echo # QUERYING PS STATEMENT DIGEST --echo #################################### -SELECT SCHEMA_NAME, DIGEST, DIGEST_TEXT, COUNT_STAR, SUM_ROWS_AFFECTED, SUM_WARNINGS, +SELECT SCHEMA_NAME, DIGEST_TEXT, COUNT_STAR, SUM_ROWS_AFFECTED, SUM_WARNINGS, SUM_ERRORS FROM performance_schema.events_statements_summary_by_digest; diff --git a/mysql-test/suite/perfschema/t/rpl_gtid_func.test b/mysql-test/suite/perfschema/t/rpl_gtid_func.test index 27837572bff..f337f95bf84 100644 --- a/mysql-test/suite/perfschema/t/rpl_gtid_func.test +++ b/mysql-test/suite/perfschema/t/rpl_gtid_func.test @@ -45,7 +45,7 @@ insert into performance_schema.setup_objects select * from performance_schema.setup_objects order by object_type, object_schema, object_name; -select digest, digest_text, count_star +select digest_text, count_star from performance_schema.events_statements_summary_by_digest where digest_text like "%in_%_digest%"; @@ -67,7 +67,7 @@ insert into performance_schema.setup_objects select * from performance_schema.setup_objects order by object_type, object_schema, object_name; -select digest, digest_text, count_star +select digest_text, count_star from performance_schema.events_statements_summary_by_digest where digest_text like "%in_%_digest%"; diff --git a/mysql-test/suite/perfschema/t/start_server_no_digests.test b/mysql-test/suite/perfschema/t/start_server_no_digests.test index cb9d7ea4ea8..dbbce662256 100644 --- a/mysql-test/suite/perfschema/t/start_server_no_digests.test +++ b/mysql-test/suite/perfschema/t/start_server_no_digests.test @@ -19,7 +19,7 @@ TRUNCATE TABLE performance_schema.events_statements_summary_by_digest; --echo #################################### --echo # QUERYING PS STATEMENT DIGEST --echo #################################### -SELECT SCHEMA_NAME, DIGEST, DIGEST_TEXT, COUNT_STAR, SUM_ROWS_AFFECTED, SUM_WARNINGS, +SELECT SCHEMA_NAME, DIGEST_TEXT, COUNT_STAR, SUM_ROWS_AFFECTED, SUM_WARNINGS, SUM_ERRORS FROM performance_schema.events_statements_summary_by_digest; diff --git a/mysql-test/suite/perfschema/t/statement_digest.test b/mysql-test/suite/perfschema/t/statement_digest.test index ed1f99e4318..59486ad61d8 100644 --- a/mysql-test/suite/perfschema/t/statement_digest.test +++ b/mysql-test/suite/perfschema/t/statement_digest.test @@ -16,7 +16,7 @@ TRUNCATE TABLE performance_schema.events_statements_summary_by_digest; --echo #################################### --echo # QUERYING PS STATEMENT DIGEST --echo #################################### -SELECT SCHEMA_NAME, DIGEST, DIGEST_TEXT, COUNT_STAR, SUM_ROWS_AFFECTED, SUM_WARNINGS, +SELECT SCHEMA_NAME, DIGEST_TEXT, COUNT_STAR, SUM_ROWS_AFFECTED, SUM_WARNINGS, SUM_ERRORS FROM performance_schema.events_statements_summary_by_digest; # Cleanup for Digest diff --git a/mysql-test/suite/perfschema/t/statement_digest_consumers.test b/mysql-test/suite/perfschema/t/statement_digest_consumers.test index e7510e32049..16fa300b975 100644 --- a/mysql-test/suite/perfschema/t/statement_digest_consumers.test +++ b/mysql-test/suite/perfschema/t/statement_digest_consumers.test @@ -28,8 +28,8 @@ TRUNCATE TABLE performance_schema.events_statements_summary_by_digest; --echo #################################### --echo # QUERYING PS STATEMENT DIGEST --echo #################################### -SELECT schema_name, digest, digest_text, count_star FROM performance_schema.events_statements_summary_by_digest; -SELECT digest, digest_text FROM performance_schema.events_statements_current; +SELECT schema_name,digest_text, count_star FROM performance_schema.events_statements_summary_by_digest; +SELECT digest_text FROM performance_schema.events_statements_current; # Cleanup for Digest --source ../include/digest_cleanup.inc diff --git a/mysql-test/suite/perfschema/t/statement_digest_long_query.test b/mysql-test/suite/perfschema/t/statement_digest_long_query.test index 3969383a6fb..be80917c9af 100644 --- a/mysql-test/suite/perfschema/t/statement_digest_long_query.test +++ b/mysql-test/suite/perfschema/t/statement_digest_long_query.test @@ -20,4 +20,4 @@ SELECT 1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1 --echo #################################### --echo # QUERYING PS STATEMENT DIGEST --echo #################################### -SELECT schema_name, digest, digest_text, count_star FROM events_statements_summary_by_digest; +SELECT schema_name, digest_text, count_star FROM events_statements_summary_by_digest; diff --git a/mysql-test/suite/roles/create_and_drop_role_invalid_user_table.result b/mysql-test/suite/roles/create_and_drop_role_invalid_user_table.result deleted file mode 100644 index df4bc6ce5f6..00000000000 --- a/mysql-test/suite/roles/create_and_drop_role_invalid_user_table.result +++ /dev/null @@ -1,25 +0,0 @@ -use mysql; -alter table user drop column is_role; -alter table user drop column default_role; -flush privileges; -create role test_role; -ERROR HY000: Column count of mysql.user is wrong. Expected 44, found 43. Created with MariaDB MYSQL_VERSION_ID, now running MYSQL_VERSION_ID. Please use mysql_upgrade to fix this error. -drop role test_role; -ERROR HY000: Operation DROP ROLE failed for 'test_role' -alter table user add column is_role enum('N', 'Y') default 'N' not null -COLLATE utf8_general_ci -after password_expired; -create role test_role; -create user test_user@localhost; -grant test_role to test_user@localhost; -set default role test_role for root@localhost; -ERROR HY000: Column count of mysql.user is wrong. Expected 45, found 44. Created with MariaDB MYSQL_VERSION_ID, now running MYSQL_VERSION_ID. Please use mysql_upgrade to fix this error. -drop role test_role; -drop user test_user@localhost; -alter table user add column default_role char(80) binary default '' not null -COLLATE utf8_general_ci -after is_role; -update user set is_role='N'; -flush privileges; -create role test_role; -drop role test_role; diff --git a/mysql-test/suite/roles/create_and_drop_role_invalid_user_table.test b/mysql-test/suite/roles/create_and_drop_role_invalid_user_table.test deleted file mode 100644 index 5122a2fed9a..00000000000 --- a/mysql-test/suite/roles/create_and_drop_role_invalid_user_table.test +++ /dev/null @@ -1,38 +0,0 @@ -source include/not_embedded.inc; - -connect (mysql, localhost, root,,); -use mysql; - -alter table user drop column is_role; -alter table user drop column default_role; - -flush privileges; - ---replace_regex /10\d\d\d\d/MYSQL_VERSION_ID/ ---error ER_COL_COUNT_DOESNT_MATCH_PLEASE_UPDATE -create role test_role; ---error ER_CANNOT_USER -drop role test_role; -alter table user add column is_role enum('N', 'Y') default 'N' not null - COLLATE utf8_general_ci -after password_expired; - -# Test default role column -create role test_role; -create user test_user@localhost; -grant test_role to test_user@localhost; ---replace_regex /10\d\d\d\d/MYSQL_VERSION_ID/ ---error ER_COL_COUNT_DOESNT_MATCH_PLEASE_UPDATE -set default role test_role for root@localhost; -drop role test_role; -drop user test_user@localhost; - -alter table user add column default_role char(80) binary default '' not null - COLLATE utf8_general_ci -after is_role; - -update user set is_role='N'; - -flush privileges; -create role test_role; -drop role test_role; diff --git a/mysql-test/suite/roles/set_role-recursive.result b/mysql-test/suite/roles/set_role-recursive.result index 008de2c3265..9e62558fc14 100644 --- a/mysql-test/suite/roles/set_role-recursive.result +++ b/mysql-test/suite/roles/set_role-recursive.result @@ -16,11 +16,11 @@ Host User Role Admin_option test_role1 test_role2 N grant select on *.* to test_role2; select * from mysql.user where user like 'test_role1'; -Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv Create_tablespace_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin authentication_string password_expired is_role default_role - test_role1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 N Y +Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv Create_tablespace_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin authentication_string password_expired is_role default_role max_statement_time + test_role1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 N Y 0.000000 select * from mysql.user where user like 'test_role2'; -Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv Create_tablespace_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin authentication_string password_expired is_role default_role - test_role2 Y N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 N Y +Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv Create_tablespace_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin authentication_string password_expired is_role default_role max_statement_time + test_role2 Y N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 N Y 0.000000 select * from mysql.roles_mapping; ERROR 42000: SELECT command denied to user 'test_user'@'localhost' for table 'roles_mapping' show grants; diff --git a/mysql-test/suite/roles/set_role-simple.result b/mysql-test/suite/roles/set_role-simple.result index f870bf8eb30..3ce6d5c054b 100644 --- a/mysql-test/suite/roles/set_role-simple.result +++ b/mysql-test/suite/roles/set_role-simple.result @@ -11,8 +11,8 @@ localhost root test_role1 Y localhost test_user test_role1 N grant select on *.* to test_role1; select * from mysql.user where user='test_role1'; -Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv Create_tablespace_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin authentication_string password_expired is_role default_role - test_role1 Y N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 N Y +Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv Create_tablespace_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin authentication_string password_expired is_role default_role max_statement_time + test_role1 Y N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 N Y 0.000000 select * from mysql.roles_mapping; ERROR 42000: SELECT command denied to user 'test_user'@'localhost' for table 'roles_mapping' show grants; diff --git a/mysql-test/suite/sys_vars/r/max_statement_time_basic.result b/mysql-test/suite/sys_vars/r/max_statement_time_basic.result new file mode 100644 index 00000000000..8b384ac6765 --- /dev/null +++ b/mysql-test/suite/sys_vars/r/max_statement_time_basic.result @@ -0,0 +1,172 @@ +SET @start_global_value = @@global.max_statement_time; +SELECT @start_global_value; +@start_global_value +0 +SET @start_session_value = @@session.max_statement_time; +SELECT @start_session_value; +@start_session_value +0 +'#--------------------FN_DYNVARS_068_01-------------------------#' +SET @@global.max_statement_time = 100; +SET @@global.max_statement_time = DEFAULT; +SELECT @@global.max_statement_time; +@@global.max_statement_time +0.000000 +SET @@session.max_statement_time = 200; +SET @@session.max_statement_time = DEFAULT; +SELECT @@session.max_statement_time; +@@session.max_statement_time +0.000000 +'#--------------------FN_DYNVARS_068_02-------------------------#' +SET @@global.max_statement_time = DEFAULT; +SELECT @@global.max_statement_time = 0; +@@global.max_statement_time = 0 +1 +SET @@session.max_statement_time = DEFAULT; +SELECT @@session.max_statement_time = 0; +@@session.max_statement_time = 0 +1 +'#--------------------FN_DYNVARS_068_03-------------------------#' +SET @@global.max_statement_time = 0; +SELECT @@global.max_statement_time; +@@global.max_statement_time +0.000000 +SET @@global.max_statement_time = 0.123456; +SELECT @@global.max_statement_time; +@@global.max_statement_time +0.123456 +SET @@global.max_statement_time = 60020; +SELECT @@global.max_statement_time; +@@global.max_statement_time +60020.000000 +SET @@global.max_statement_time = 31536000; +SELECT @@global.max_statement_time; +@@global.max_statement_time +31536000.000000 +SET @@global.max_statement_time = 65536; +SELECT @@global.max_statement_time; +@@global.max_statement_time +65536.000000 +'#--------------------FN_DYNVARS_068_04-------------------------#' +SET @@session.max_statement_time = 0; +SELECT @@session.max_statement_time; +@@session.max_statement_time +0.000000 +SET @@session.max_statement_time = 1; +SELECT @@session.max_statement_time; +@@session.max_statement_time +1.000000 +SET @@session.max_statement_time = 50050; +SELECT @@session.max_statement_time; +@@session.max_statement_time +50050.000000 +SET @@session.max_statement_time = 31536000; +SELECT @@session.max_statement_time; +@@session.max_statement_time +31536000.000000 +SET @@session.max_statement_time = 65550; +SELECT @@session.max_statement_time; +@@session.max_statement_time +65550.000000 +'#------------------FN_DYNVARS_068_05-----------------------#' +SET @@global.max_statement_time = 100000000000; +Warnings: +Warning 1292 Truncated incorrect max_statement_time value: '100000000000' +SELECT @@global.max_statement_time; +@@global.max_statement_time +31536000.000000 +SET @@global.max_statement_time = -1; +Warnings: +Warning 1292 Truncated incorrect max_statement_time value: '-1' +SELECT @@global.max_statement_time; +@@global.max_statement_time +0.000000 +SET @@global.max_statement_time = 65530.34; +SELECT @@global.max_statement_time; +@@global.max_statement_time +65530.340000 +SET @@global.max_statement_time = test; +ERROR 42000: Incorrect argument type to variable 'max_statement_time' +SELECT @@global.max_statement_time; +@@global.max_statement_time +65530.340000 +SET @@session.max_statement_time = 100000000000; +Warnings: +Warning 1292 Truncated incorrect max_statement_time value: '100000000000' +SELECT @@session.max_statement_time; +@@session.max_statement_time +31536000.000000 +SET @@session.max_statement_time = -2; +Warnings: +Warning 1292 Truncated incorrect max_statement_time value: '-2' +SELECT @@session.max_statement_time; +@@session.max_statement_time +0.000000 +SET @@session.max_statement_time = 65530.34; +SELECT @@session.max_statement_time; +@@session.max_statement_time +65530.340000 +SET @@session.max_statement_time = test; +ERROR 42000: Incorrect argument type to variable 'max_statement_time' +SELECT @@session.max_statement_time; +@@session.max_statement_time +65530.340000 +'#------------------FN_DYNVARS_068_06-----------------------#' +SELECT @@global.max_statement_time = VARIABLE_VALUE +FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES +WHERE VARIABLE_NAME='max_statement_time'; +@@global.max_statement_time = VARIABLE_VALUE +1 +'#------------------FN_DYNVARS_068_07-----------------------#' +SELECT @@session.max_statement_time = VARIABLE_VALUE +FROM INFORMATION_SCHEMA.SESSION_VARIABLES +WHERE VARIABLE_NAME='max_statement_time'; +@@session.max_statement_time = VARIABLE_VALUE +1 +'#------------------FN_DYNVARS_068_08-----------------------#' +SET @@global.max_statement_time = TRUE; +SELECT @@global.max_statement_time; +@@global.max_statement_time +1.000000 +SET @@global.max_statement_time = FALSE; +SELECT @@global.max_statement_time; +@@global.max_statement_time +0.000000 +'#---------------------FN_DYNVARS_001_09----------------------#' +SET @@global.max_statement_time = 10; +SELECT @@max_statement_time = @@global.max_statement_time; +@@max_statement_time = @@global.max_statement_time +0 +'#---------------------FN_DYNVARS_001_10----------------------#' +SET @@max_statement_time = 100; +SELECT @@max_statement_time = @@local.max_statement_time; +@@max_statement_time = @@local.max_statement_time +1 +SELECT @@local.max_statement_time = @@session.max_statement_time; +@@local.max_statement_time = @@session.max_statement_time +1 +'#---------------------FN_DYNVARS_001_11----------------------#' +SET max_statement_time = 1; +SELECT @@max_statement_time; +@@max_statement_time +1.000000 +SELECT local.max_statement_time; +ERROR 42S02: Unknown table 'local' in field list +SELECT session.max_statement_time; +ERROR 42S02: Unknown table 'session' in field list +SELECT max_statement_time = @@session.max_statement_time; +ERROR 42S22: Unknown column 'max_statement_time' in 'field list' +# +# Check that one can use max_statement_time as a field +# +drop table if exists t1; +create table t1 (a int, max_statement_time int); +drop table t1; +SET @@global.max_statement_time = @start_global_value; +SELECT @@global.max_statement_time; +@@global.max_statement_time +0.000000 +SET @@session.max_statement_time = @start_session_value; +SELECT @@session.max_statement_time; +@@session.max_statement_time +0.000000 diff --git a/mysql-test/suite/sys_vars/t/max_statement_time_basic.test b/mysql-test/suite/sys_vars/t/max_statement_time_basic.test new file mode 100644 index 00000000000..186589dcee2 --- /dev/null +++ b/mysql-test/suite/sys_vars/t/max_statement_time_basic.test @@ -0,0 +1,217 @@ +####################### mysql-test\t\max_statement_time_basic.test ############### +# # +# Variable Name: max_statement_time # +# Scope: GLOBAL | SESSION # +# Access Type: Dynamic # +# Data Type: numeric # +# Default Value:10 # +# Min Value: 1 # +# # +# # +# Creation Date: 2012-12-30 # +# Author: Monty # +# # +# Description: Test Cases of Dynamic System Variable max_statement_time # +# that checks the behavior of this variable in the following ways# +# * Default Value # +# * Valid & Invalid values # +# * Scope & Access method # +# * Data Integrity # +# # +# Reference: https://kb.askmonty.org/en/how-to-limittimeout-queries/ # +# server-system-variables.html # +# # +############################################################################### + +--source include/load_sysvars.inc + +############################################################ +# START OF max_statement_time TESTS # +############################################################ + + +############################################################# +# Save initial value # +############################################################# + +SET @start_global_value = @@global.max_statement_time; +SELECT @start_global_value; +SET @start_session_value = @@session.max_statement_time; +SELECT @start_session_value; + + +--echo '#--------------------FN_DYNVARS_068_01-------------------------#' +############################################################### +# Display the DEFAULT value of max_statement_time # +############################################################### + +SET @@global.max_statement_time = 100; +SET @@global.max_statement_time = DEFAULT; +SELECT @@global.max_statement_time; + +SET @@session.max_statement_time = 200; +SET @@session.max_statement_time = DEFAULT; +SELECT @@session.max_statement_time; + + +--echo '#--------------------FN_DYNVARS_068_02-------------------------#' +############################################################### +# Check the DEFAULT value of max_statement_time # +############################################################### + +SET @@global.max_statement_time = DEFAULT; +SELECT @@global.max_statement_time = 0; + +SET @@session.max_statement_time = DEFAULT; +SELECT @@session.max_statement_time = 0; + + +--echo '#--------------------FN_DYNVARS_068_03-------------------------#' +######################################################################### +# Change the value of max_statement_time to a valid value for GLOBAL Scope # +######################################################################### + +SET @@global.max_statement_time = 0; +SELECT @@global.max_statement_time; +SET @@global.max_statement_time = 0.123456; +SELECT @@global.max_statement_time; +SET @@global.max_statement_time = 60020; +SELECT @@global.max_statement_time; +SET @@global.max_statement_time = 31536000; +SELECT @@global.max_statement_time; +SET @@global.max_statement_time = 65536; +SELECT @@global.max_statement_time; + + +--echo '#--------------------FN_DYNVARS_068_04-------------------------#' +########################################################################## +# Change the value of max_statement_time to a valid value for SESSION Scope # +########################################################################## + +SET @@session.max_statement_time = 0; +SELECT @@session.max_statement_time; +SET @@session.max_statement_time = 1; +SELECT @@session.max_statement_time; +SET @@session.max_statement_time = 50050; +SELECT @@session.max_statement_time; +SET @@session.max_statement_time = 31536000; +SELECT @@session.max_statement_time; +SET @@session.max_statement_time = 65550; +SELECT @@session.max_statement_time; + + +--echo '#------------------FN_DYNVARS_068_05-----------------------#' +######################################################## +# Change the value of max_statement_time to an invalid value # +######################################################## + +SET @@global.max_statement_time = 100000000000; +SELECT @@global.max_statement_time; +SET @@global.max_statement_time = -1; +SELECT @@global.max_statement_time; +SET @@global.max_statement_time = 65530.34; +SELECT @@global.max_statement_time; +--Error ER_WRONG_TYPE_FOR_VAR +SET @@global.max_statement_time = test; +SELECT @@global.max_statement_time; + +SET @@session.max_statement_time = 100000000000; +SELECT @@session.max_statement_time; +SET @@session.max_statement_time = -2; +SELECT @@session.max_statement_time; +SET @@session.max_statement_time = 65530.34; +SELECT @@session.max_statement_time; + +--Error ER_WRONG_TYPE_FOR_VAR +SET @@session.max_statement_time = test; +SELECT @@session.max_statement_time; + + +--echo '#------------------FN_DYNVARS_068_06-----------------------#' +#################################################################### +# Check if the value in GLOBAL Table matches value in variable # +#################################################################### + + +SELECT @@global.max_statement_time = VARIABLE_VALUE +FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES +WHERE VARIABLE_NAME='max_statement_time'; + +--echo '#------------------FN_DYNVARS_068_07-----------------------#' +#################################################################### +# Check if the value in SESSION Table matches value in variable # +#################################################################### + +SELECT @@session.max_statement_time = VARIABLE_VALUE +FROM INFORMATION_SCHEMA.SESSION_VARIABLES +WHERE VARIABLE_NAME='max_statement_time'; + + +--echo '#------------------FN_DYNVARS_068_08-----------------------#' +#################################################################### +# Check if TRUE and FALSE values can be used on variable # +#################################################################### + +SET @@global.max_statement_time = TRUE; +SELECT @@global.max_statement_time; +SET @@global.max_statement_time = FALSE; +SELECT @@global.max_statement_time; + + +--echo '#---------------------FN_DYNVARS_001_09----------------------#' +################################################################################# +# Check if accessing variable with and without GLOBAL point to same variable # +################################################################################# + +SET @@global.max_statement_time = 10; +SELECT @@max_statement_time = @@global.max_statement_time; + + +--echo '#---------------------FN_DYNVARS_001_10----------------------#' +######################################################################################################## +# Check if accessing variable with SESSION,LOCAL and without SCOPE points to same session variable # +######################################################################################################## + +SET @@max_statement_time = 100; +SELECT @@max_statement_time = @@local.max_statement_time; +SELECT @@local.max_statement_time = @@session.max_statement_time; + + +--echo '#---------------------FN_DYNVARS_001_11----------------------#' +########################################################################## +# Check if max_statement_time can be accessed with and without @@ sign # +########################################################################## + +SET max_statement_time = 1; +SELECT @@max_statement_time; +--Error ER_UNKNOWN_TABLE +SELECT local.max_statement_time; +--Error ER_UNKNOWN_TABLE +SELECT session.max_statement_time; +--Error ER_BAD_FIELD_ERROR +SELECT max_statement_time = @@session.max_statement_time; + +--echo # +--echo # Check that one can use max_statement_time as a field +--echo # + +--disable_warnings +drop table if exists t1; +--enable_warnings +create table t1 (a int, max_statement_time int); +drop table t1; + +#################################### +# Restore initial value # +#################################### + +SET @@global.max_statement_time = @start_global_value; +SELECT @@global.max_statement_time; +SET @@session.max_statement_time = @start_session_value; +SELECT @@session.max_statement_time; + + +#################################################### +# END OF max_statement_time TESTS # +#################################################### + diff --git a/mysql-test/t/grant.test b/mysql-test/t/grant.test index ed7271521c8..20632038273 100644 --- a/mysql-test/t/grant.test +++ b/mysql-test/t/grant.test @@ -47,10 +47,10 @@ flush privileges; # delete from mysql.user where user='mysqltest_1'; flush privileges; -grant usage on *.* to mysqltest_1@localhost with max_queries_per_hour 10; +grant usage on *.* to mysqltest_1@localhost with max_queries_per_hour 10 max_statement_time 60; query_vertical select * from mysql.user where user="mysqltest_1"; show grants for mysqltest_1@localhost; -grant usage on *.* to mysqltest_1@localhost with max_updates_per_hour 20 max_connections_per_hour 30; +grant usage on *.* to mysqltest_1@localhost with max_updates_per_hour 20 max_connections_per_hour 30 max_statement_time 0; query_vertical select * from mysql.user where user="mysqltest_1"; show grants for mysqltest_1@localhost; # This is just to double check that one won't ignore results of selects diff --git a/mysql-test/t/max_statement_time.test b/mysql-test/t/max_statement_time.test new file mode 100644 index 00000000000..0356d3caa49 --- /dev/null +++ b/mysql-test/t/max_statement_time.test @@ -0,0 +1,189 @@ +# +# Test behavior of MAX_STATEMENT_TIME. +# + +--source include/not_embedded.inc +--source include/have_innodb.inc + +--echo +--echo # Test the MAX_STATEMENT_TIME option. +--echo + +SET @@MAX_STATEMENT_TIME=2; +select @@max_statement_time; +SELECT SLEEP(1); +SELECT SLEEP(3); +SET @@MAX_STATEMENT_TIME=0; +SELECT SLEEP(1); +SHOW STATUS LIKE "max_statement_time_exceeded"; + +CREATE TABLE t1 (a INT, b VARCHAR(300)) engine=myisam; + +INSERT INTO t1 VALUES (1, 'string'); + +--disable_result_log +--disable_query_log + +SET @@MAX_STATEMENT_TIME=2; + +SET @@MAX_STATEMENT_TIME=0.1; +WHILE (! $mysql_errno) +{ + SET @@MAX_STATEMENT_TIME=0; + INSERT INTO t1 SELECT * FROM t1; + SET @@MAX_STATEMENT_TIME=0.1; + --error 0,ER_STATEMENT_TIMEOUT + SELECT COUNT(*) FROM t1 WHERE b LIKE '%z%'; +} +SET @@MAX_STATEMENT_TIME=0; + +--enable_query_log +--enable_result_log + +eval SELECT $mysql_errno; + +--echo +--echo # Test the MAX_STATEMENT_TIME option with SF (should have no effect). +--echo + +DELIMITER |; + +CREATE PROCEDURE p1() +BEGIN + declare tmp int; + SET @@MAX_STATEMENT_TIME=0.0001; + SELECT COUNT(*) INTO tmp FROM t1 WHERE b LIKE '%z%'; + SET @@MAX_STATEMENT_TIME=0; +END| + +CREATE PROCEDURE p2() +BEGIN + SET @@MAX_STATEMENT_TIME=5; +END| + +DELIMITER ;| + +SELECT @@MAX_STATEMENT_TIME; +CALL p1(); +CALL p2(); +SELECT @@MAX_STATEMENT_TIME; +SET @@MAX_STATEMENT_TIME=0; + +DROP PROCEDURE p1; +DROP PROCEDURE p2; +DROP TABLE t1; + +--echo +--echo # MAX_STATEMENT_TIME account resource +--echo + +GRANT USAGE ON *.* TO user1@localhost WITH MAX_STATEMENT_TIME 1.005; + +--echo # con1 +connect(con1,localhost,user1,,test,,); +SELECT @@max_statement_time; +disconnect con1; + +--echo # restart and reconnect +connection default; +source include/restart_mysqld.inc; + +set @global.userstat=1; +connect(con1,localhost,user1,,test,,); +SELECT @@global.max_statement_time,@@session.max_statement_time; +select sleep(100); +SHOW STATUS LIKE "max_statement_time_exceeded"; +disconnect con1; + +connection default; +show grants for user1@localhost; +--disable_parsing +select max_user_timeouts from information_schema.user_statistics where user="user1"; +--enable_parsing + +set @global.userstat=0; +DROP USER user1@localhost; + +--echo +--echo # MAX_STATEMENT_TIME status variables. +--echo + +flush status; + +SET @@max_statement_time=0; +SELECT CONVERT(VARIABLE_VALUE, UNSIGNED) INTO @time_exceeded + FROM INFORMATION_SCHEMA.GLOBAL_STATUS + WHERE VARIABLE_NAME = 'max_statement_time_exceeded'; + +SET @@max_statement_time=0.5; +SELECT SLEEP(2); +SHOW STATUS LIKE '%timeout%'; +SET @@max_statement_time=0; + +--echo # Ensure that the counters for: +--echo # - statements that exceeded their maximum execution time +--echo # are incremented. + +SELECT 1 AS STATUS FROM INFORMATION_SCHEMA.GLOBAL_STATUS + WHERE VARIABLE_NAME = 'max_statement_time_exceeded' + AND CONVERT(VARIABLE_VALUE, UNSIGNED) > @time_exceeded; + +--echo +--echo # Check that the appropriate error status is set. +--echo + +CREATE TABLE t1 (a INT) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1); + +START TRANSACTION; +SELECT * FROM t1 FOR UPDATE; + +connect (con1,localhost,root,,test,,); +SET @@SESSION.max_statement_time = 0.5; +--error ER_STATEMENT_TIMEOUT +UPDATE t1 SET a = 2; +SHOW WARNINGS; +disconnect con1; + +connection default; +ROLLBACK; +DROP TABLE t1; + +--echo +--echo # Test interaction with lock waits. +--echo + +CREATE TABLE t1 (a INT) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1); + +connect (con1,localhost,root,,test,,); +SET @@SESSION.max_statement_time= 0.5; + +connection default; +LOCK TABLES t1 WRITE; + +connection con1; +SELECT @@SESSION.max_statement_time; +--error ER_STATEMENT_TIMEOUT +LOCK TABLES t1 READ; + +connection default; +UNLOCK TABLES; +BEGIN; +SELECT * FROM t1; + +connection con1; +--error ER_STATEMENT_TIMEOUT +ALTER TABLE t1 ADD COLUMN b INT; + +connection default; +ROLLBACK; +SELECT GET_LOCK('lock', 1); + +connection con1; +SELECT GET_LOCK('lock', 1); + +disconnect con1; +connection default; +SELECT RELEASE_LOCK('lock'); +DROP TABLE t1; diff --git a/mysys/CMakeLists.txt b/mysys/CMakeLists.txt index f0d25dae6b9..7f076b10e78 100644 --- a/mysys/CMakeLists.txt +++ b/mysys/CMakeLists.txt @@ -33,7 +33,9 @@ SET(MYSYS_SOURCES array.c charset-def.c charset.c checksum.c my_default.c my_basename.c my_write.c ptr_cmp.c queues.c stacktrace.c string.c thr_alarm.c thr_lock.c thr_mutex.c - thr_rwlock.c tree.c typelib.c base64.c my_memmem.c my_getpagesize.c + thr_rwlock.c thr_timer.c + tree.c typelib.c base64.c my_memmem.c + my_getpagesize.c lf_alloc-pin.c lf_dynarray.c lf_hash.c safemalloc.c my_new.cc my_atomic.c my_getncpus.c my_safehash.c my_chmod.c my_rnd.c @@ -89,6 +91,10 @@ ADD_EXECUTABLE(thr_lock thr_lock.c) TARGET_LINK_LIBRARIES(thr_lock mysys) SET_TARGET_PROPERTIES(thr_lock PROPERTIES COMPILE_FLAGS "-DMAIN") +ADD_EXECUTABLE(thr_timer thr_timer.c) +TARGET_LINK_LIBRARIES(thr_timer mysys) +SET_TARGET_PROPERTIES(thr_timer PROPERTIES COMPILE_FLAGS "-DMAIN") + INSTALL_DEBUG_SYMBOLS(mysys) IF(MSVC) INSTALL_DEBUG_TARGET(mysys DESTINATION ${INSTALL_LIBDIR}/debug) diff --git a/mysys/md5.c.THIS b/mysys/md5.c.THIS deleted file mode 100644 index 829eea50d22..00000000000 --- a/mysys/md5.c.THIS +++ /dev/null @@ -1,329 +0,0 @@ -/* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ - -/* - * This code implements the MD5 message-digest algorithm. - * The algorithm is due to Ron Rivest. This code was - * written by Colin Plumb in 1993, no copyright is claimed. - * This code is in the public domain; do with it what you wish. - * - * Equivalent code is available from RSA Data Security, Inc. - * This code has been tested against that, and is equivalent, - * except that you don't need to include two pages of legalese - * with every copy. - * - * To compute the message digest of a chunk of bytes, declare an - * MD5Context structure, pass it to MD5Init, call MD5Update as - * needed on buffers full of bytes, and then call MD5Final, which - * will fill a supplied 16-byte array with the digest. - */ - -/* This code was modified in 1997 by Jim Kingdon of Cyclic Software to - not require an integer type which is exactly 32 bits. This work - draws on the changes for the same purpose by Tatu Ylonen - <ylo@cs.hut.fi> as part of SSH, but since I didn't actually use - that code, there is no copyright issue. I hereby disclaim - copyright in any changes I have made; this code remains in the - public domain. */ - -/* - Skip entirely if built with OpenSSL/YaSSL support. -*/ -#if !defined(HAVE_OPENSSL) && !defined(HAVE_YASSL) - -#include <my_global.h> -#include <m_string.h> -#include "my_md5.h" - -static void -my_MD5Transform (cvs_uint32 buf[4], const unsigned char in[64]); - -/* Little-endian byte-swapping routines. Note that these do not - depend on the size of datatypes such as uint32, nor do they require - us to detect the endianness of the machine we are running on. It - is possible they should be macros for speed, but I would be - surprised if they were a performance bottleneck for MD5. */ - -static uint32 getu32 (const unsigned char *addr) -{ - return (((((unsigned long)addr[3] << 8) | addr[2]) << 8) - | addr[1]) << 8 | addr[0]; -} - -static void -putu32 (uint32 data, unsigned char *addr) -{ - addr[0] = (unsigned char)data; - addr[1] = (unsigned char)(data >> 8); - addr[2] = (unsigned char)(data >> 16); - addr[3] = (unsigned char)(data >> 24); -} - -/* - Start MD5 accumulation. Set bit count to 0 and buffer to mysterious - initialization constants. -*/ -void -my_MD5Init (my_MD5Context *ctx) -{ - ctx->buf[0] = 0x67452301; - ctx->buf[1] = 0xefcdab89; - ctx->buf[2] = 0x98badcfe; - ctx->buf[3] = 0x10325476; - - ctx->bits[0] = 0; - ctx->bits[1] = 0; -} - -/* - Update context to reflect the concatenation of another buffer full - of bytes. -*/ -void -my_MD5Update (my_MD5Context *ctx, unsigned char const *buf, unsigned len) -{ - uint32 t; - - /* Update bitcount */ - - t = ctx->bits[0]; - if ((ctx->bits[0] = (t + ((uint32)len << 3)) & 0xffffffff) < t) - ctx->bits[1]++; /* Carry from low to high */ - ctx->bits[1] += len >> 29; - - t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */ - - /* Handle any leading odd-sized chunks */ - - if ( t ) { - unsigned char *p = ctx->in + t; - - t = 64-t; - if (len < t) { - memcpy(p, buf, len); - return; - } - memcpy(p, buf, t); - my_MD5Transform (ctx->buf, ctx->in); - buf += t; - len -= t; - } - - /* Process data in 64-byte chunks */ - - while (len >= 64) { - memcpy(ctx->in, buf, 64); - my_MD5Transform (ctx->buf, ctx->in); - buf += 64; - len -= 64; - } - - /* Handle any remaining bytes of data. */ - - memcpy(ctx->in, buf, len); -} - -/* - Final wrapup - pad to 64-byte boundary with the bit pattern - 1 0* (64-bit count of bits processed, MSB-first) -*/ -void -my_MD5Final (unsigned char digest[16], my_MD5Context *ctx) -{ - unsigned count; - unsigned char *p; - - /* Compute number of bytes mod 64 */ - count = (ctx->bits[0] >> 3) & 0x3F; - - /* Set the first char of padding to 0x80. This is safe since there is - always at least one byte free */ - p = ctx->in + count; - *p++ = 0x80; - - /* Bytes of padding needed to make 64 bytes */ - count = 64 - 1 - count; - - /* Pad out to 56 mod 64 */ - if (count < 8) { - /* Two lots of padding: Pad the first block to 64 bytes */ - memset(p, 0, count); - my_MD5Transform (ctx->buf, ctx->in); - - /* Now fill the next block with 56 bytes */ - memset(ctx->in, 0, 56); - } else { - /* Pad block to 56 bytes */ - memset(p, 0, count-8); - } - - /* Append length in bits and transform */ - putu32(ctx->bits[0], ctx->in + 56); - putu32(ctx->bits[1], ctx->in + 60); - - my_MD5Transform (ctx->buf, ctx->in); - putu32(ctx->buf[0], digest); - putu32(ctx->buf[1], digest + 4); - putu32(ctx->buf[2], digest + 8); - putu32(ctx->buf[3], digest + 12); - memset(ctx, 0, sizeof(*ctx)); /* In case it's sensitive */ -} - -#ifndef ASM_MD5 - -/* The four core functions - F1 is optimized somewhat */ - -/* #define F1(x, y, z) (x & y | ~x & z) */ -#define F1(x, y, z) (z ^ (x & (y ^ z))) -#define F2(x, y, z) F1(z, x, y) -#define F3(x, y, z) (x ^ y ^ z) -#define F4(x, y, z) (y ^ (x | ~z)) - -/* This is the central step in the MD5 algorithm. */ -#define MD5STEP(f, w, x, y, z, data, s) \ - ( w += f(x, y, z) + data, w &= 0xffffffff, w = w<<s | w>>(32-s), w += x ) - -/* - * The core of the MD5 algorithm, this alters an existing MD5 hash to - * reflect the addition of 16 longwords of new data. MD5Update blocks - * the data and converts bytes into longwords for this routine. - */ -static void -my_MD5Transform (uint32 buf[4], const unsigned char inraw[64]) -{ - register uint32 a, b, c, d; - uint32 in[16]; - int i; - - for (i = 0; i < 16; ++i) - in[i] = getu32 (inraw + 4 * i); - - a = buf[0]; - b = buf[1]; - c = buf[2]; - d = buf[3]; - - MD5STEP(F1, a, b, c, d, in[ 0]+0xd76aa478, 7); - MD5STEP(F1, d, a, b, c, in[ 1]+0xe8c7b756, 12); - MD5STEP(F1, c, d, a, b, in[ 2]+0x242070db, 17); - MD5STEP(F1, b, c, d, a, in[ 3]+0xc1bdceee, 22); - MD5STEP(F1, a, b, c, d, in[ 4]+0xf57c0faf, 7); - MD5STEP(F1, d, a, b, c, in[ 5]+0x4787c62a, 12); - MD5STEP(F1, c, d, a, b, in[ 6]+0xa8304613, 17); - MD5STEP(F1, b, c, d, a, in[ 7]+0xfd469501, 22); - MD5STEP(F1, a, b, c, d, in[ 8]+0x698098d8, 7); - MD5STEP(F1, d, a, b, c, in[ 9]+0x8b44f7af, 12); - MD5STEP(F1, c, d, a, b, in[10]+0xffff5bb1, 17); - MD5STEP(F1, b, c, d, a, in[11]+0x895cd7be, 22); - MD5STEP(F1, a, b, c, d, in[12]+0x6b901122, 7); - MD5STEP(F1, d, a, b, c, in[13]+0xfd987193, 12); - MD5STEP(F1, c, d, a, b, in[14]+0xa679438e, 17); - MD5STEP(F1, b, c, d, a, in[15]+0x49b40821, 22); - - MD5STEP(F2, a, b, c, d, in[ 1]+0xf61e2562, 5); - MD5STEP(F2, d, a, b, c, in[ 6]+0xc040b340, 9); - MD5STEP(F2, c, d, a, b, in[11]+0x265e5a51, 14); - MD5STEP(F2, b, c, d, a, in[ 0]+0xe9b6c7aa, 20); - MD5STEP(F2, a, b, c, d, in[ 5]+0xd62f105d, 5); - MD5STEP(F2, d, a, b, c, in[10]+0x02441453, 9); - MD5STEP(F2, c, d, a, b, in[15]+0xd8a1e681, 14); - MD5STEP(F2, b, c, d, a, in[ 4]+0xe7d3fbc8, 20); - MD5STEP(F2, a, b, c, d, in[ 9]+0x21e1cde6, 5); - MD5STEP(F2, d, a, b, c, in[14]+0xc33707d6, 9); - MD5STEP(F2, c, d, a, b, in[ 3]+0xf4d50d87, 14); - MD5STEP(F2, b, c, d, a, in[ 8]+0x455a14ed, 20); - MD5STEP(F2, a, b, c, d, in[13]+0xa9e3e905, 5); - MD5STEP(F2, d, a, b, c, in[ 2]+0xfcefa3f8, 9); - MD5STEP(F2, c, d, a, b, in[ 7]+0x676f02d9, 14); - MD5STEP(F2, b, c, d, a, in[12]+0x8d2a4c8a, 20); - - MD5STEP(F3, a, b, c, d, in[ 5]+0xfffa3942, 4); - MD5STEP(F3, d, a, b, c, in[ 8]+0x8771f681, 11); - MD5STEP(F3, c, d, a, b, in[11]+0x6d9d6122, 16); - MD5STEP(F3, b, c, d, a, in[14]+0xfde5380c, 23); - MD5STEP(F3, a, b, c, d, in[ 1]+0xa4beea44, 4); - MD5STEP(F3, d, a, b, c, in[ 4]+0x4bdecfa9, 11); - MD5STEP(F3, c, d, a, b, in[ 7]+0xf6bb4b60, 16); - MD5STEP(F3, b, c, d, a, in[10]+0xbebfbc70, 23); - MD5STEP(F3, a, b, c, d, in[13]+0x289b7ec6, 4); - MD5STEP(F3, d, a, b, c, in[ 0]+0xeaa127fa, 11); - MD5STEP(F3, c, d, a, b, in[ 3]+0xd4ef3085, 16); - MD5STEP(F3, b, c, d, a, in[ 6]+0x04881d05, 23); - MD5STEP(F3, a, b, c, d, in[ 9]+0xd9d4d039, 4); - MD5STEP(F3, d, a, b, c, in[12]+0xe6db99e5, 11); - MD5STEP(F3, c, d, a, b, in[15]+0x1fa27cf8, 16); - MD5STEP(F3, b, c, d, a, in[ 2]+0xc4ac5665, 23); - - MD5STEP(F4, a, b, c, d, in[ 0]+0xf4292244, 6); - MD5STEP(F4, d, a, b, c, in[ 7]+0x432aff97, 10); - MD5STEP(F4, c, d, a, b, in[14]+0xab9423a7, 15); - MD5STEP(F4, b, c, d, a, in[ 5]+0xfc93a039, 21); - MD5STEP(F4, a, b, c, d, in[12]+0x655b59c3, 6); - MD5STEP(F4, d, a, b, c, in[ 3]+0x8f0ccc92, 10); - MD5STEP(F4, c, d, a, b, in[10]+0xffeff47d, 15); - MD5STEP(F4, b, c, d, a, in[ 1]+0x85845dd1, 21); - MD5STEP(F4, a, b, c, d, in[ 8]+0x6fa87e4f, 6); - MD5STEP(F4, d, a, b, c, in[15]+0xfe2ce6e0, 10); - MD5STEP(F4, c, d, a, b, in[ 6]+0xa3014314, 15); - MD5STEP(F4, b, c, d, a, in[13]+0x4e0811a1, 21); - MD5STEP(F4, a, b, c, d, in[ 4]+0xf7537e82, 6); - MD5STEP(F4, d, a, b, c, in[11]+0xbd3af235, 10); - MD5STEP(F4, c, d, a, b, in[ 2]+0x2ad7d2bb, 15); - MD5STEP(F4, b, c, d, a, in[ 9]+0xeb86d391, 21); - - buf[0] += a; - buf[1] += b; - buf[2] += c; - buf[3] += d; -} -#endif - -#ifdef TEST -/* - Simple test program. Can use it to manually run the tests from - RFC1321 for example. -*/ -#include <stdio.h> - -int -main (int argc, char **argv) -{ - my_MD5Context context; - unsigned char checksum[16]; - int i; - int j; - - if (argc < 2) - { - fprintf (stderr, "usage: %s string-to-hash\n", argv[0]); - exit (1); - } - for (j = 1; j < argc; ++j) - { - printf ("MD5 (\"%s\") = ", argv[j]); - my_MD5Init (&context); - my_MD5Update (&context, argv[j], strlen (argv[j])); - my_MD5Final (checksum, &context); - for (i = 0; i < 16; i++) - { - printf ("%02x", (unsigned int) checksum[i]); - } - printf ("\n"); - } - return 0; -} -#endif /* TEST */ - -#endif /* !defined(HAVE_OPENSSL) && !defined(HAVE_YASSL) */ diff --git a/mysys/my_aes.c.THIS b/mysys/my_aes.c.THIS deleted file mode 100644 index 7074f700413..00000000000 --- a/mysys/my_aes.c.THIS +++ /dev/null @@ -1,228 +0,0 @@ -/* Copyright (c) 2002, 2006 MySQL AB - Use is subject to license terms - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ - - -/* - Implementation of AES Encryption for MySQL - Initial version by Peter Zaitsev June 2002 -*/ - - -#include <my_global.h> -#include <m_string.h> -#include "my_aes.h" - -enum encrypt_dir { AES_ENCRYPT, AES_DECRYPT }; - -#define AES_BLOCK_SIZE 16 /* Block size in bytes */ - -#define AES_BAD_DATA -1 /* If bad data discovered during decoding */ - - -/* The structure for key information */ -typedef struct { - int nr; /* Number of rounds */ - uint32 rk[4*(AES_MAXNR + 1)]; /* key schedule */ -} KEYINSTANCE; - - -/* - This is internal function just keeps joint code of Key generation - - SYNOPSIS - my_aes_create_key() - aes_key Address of Key Instance to be created - direction Direction (are we encoding or decoding) - key Key to use for real key creation - key_length Length of the key - - DESCRIPTION - - RESULT - 0 ok - -1 Error Note: The current impementation never returns this -*/ - -static int my_aes_create_key(KEYINSTANCE *aes_key, - enum encrypt_dir direction, const char *key, - int key_length) -{ - uint8 rkey[AES_KEY_LENGTH/8]; /* The real key to be used for encryption */ - uint8 *rkey_end=rkey+AES_KEY_LENGTH/8; /* Real key boundary */ - uint8 *ptr; /* Start of the real key*/ - const char *sptr; /* Start of the working key */ - const char *key_end=key+key_length; /* Working key boundary*/ - - bzero((char*) rkey,AES_KEY_LENGTH/8); /* Set initial key */ - - for (ptr= rkey, sptr= key; sptr < key_end; ptr++,sptr++) - { - if (ptr == rkey_end) - ptr= rkey; /* Just loop over tmp_key until we used all key */ - *ptr^= (uint8) *sptr; - } -#ifdef AES_USE_KEY_BITS - /* - This block is intended to allow more weak encryption if application - build with libmysqld needs to correspond to export regulations - It should be never used in normal distribution as does not give - any speed improvement. - To get worse security define AES_USE_KEY_BITS to number of bits - you want key to be. It should be divisible by 8 - - WARNING: Changing this value results in changing of enryption for - all key lengths so altering this value will result in impossibility - to decrypt data encrypted with previous value - */ -#define AES_USE_KEY_BYTES (AES_USE_KEY_BITS/8) - /* - To get weaker key we use first AES_USE_KEY_BYTES bytes of created key - and cyclically copy them until we created all required key length - */ - for (ptr= rkey+AES_USE_KEY_BYTES, sptr=rkey ; ptr < rkey_end; - ptr++,sptr++) - { - if (sptr == rkey+AES_USE_KEY_BYTES) - sptr=rkey; - *ptr=*sptr; - } -#endif - if (direction == AES_DECRYPT) - aes_key->nr = rijndaelKeySetupDec(aes_key->rk, rkey, AES_KEY_LENGTH); - else - aes_key->nr = rijndaelKeySetupEnc(aes_key->rk, rkey, AES_KEY_LENGTH); - return 0; -} - - -/* - Crypt buffer with AES encryption algorithm. - - SYNOPSIS - my_aes_encrypt() - source Pointer to data for encryption - source_length Size of encryption data - dest Buffer to place encrypted data (must be large enough) - key Key to be used for encryption - key_length Length of the key. Will handle keys of any length - - RETURN - >= 0 Size of encrypted data - < 0 Error -*/ - -int my_aes_encrypt(const char* source, int source_length, char* dest, - const char* key, int key_length) -{ - KEYINSTANCE aes_key; - uint8 block[AES_BLOCK_SIZE]; /* 128 bit block used for padding */ - int rc; /* result codes */ - int num_blocks; /* number of complete blocks */ - char pad_len; /* pad size for the last block */ - int i; - - if ((rc= my_aes_create_key(&aes_key,AES_ENCRYPT,key,key_length))) - return rc; - - num_blocks = source_length/AES_BLOCK_SIZE; - - for (i = num_blocks; i > 0; i--) /* Encode complete blocks */ - { - rijndaelEncrypt(aes_key.rk, aes_key.nr, (const uint8*) source, - (uint8*) dest); - source+= AES_BLOCK_SIZE; - dest+= AES_BLOCK_SIZE; - } - - /* Encode the rest. We always have incomplete block */ - pad_len = AES_BLOCK_SIZE - (source_length - AES_BLOCK_SIZE*num_blocks); - memcpy(block, source, 16 - pad_len); - bfill(block + AES_BLOCK_SIZE - pad_len, pad_len, pad_len); - rijndaelEncrypt(aes_key.rk, aes_key.nr, block, (uint8*) dest); - return AES_BLOCK_SIZE*(num_blocks + 1); -} - - -/* - DeCrypt buffer with AES encryption algorithm. - - SYNOPSIS - my_aes_decrypt() - source Pointer to data for decryption - source_length Size of encrypted data - dest Buffer to place decrypted data (must be large enough) - key Key to be used for decryption - key_length Length of the key. Will handle keys of any length - - RETURN - >= 0 Size of encrypted data - < 0 Error -*/ - -int my_aes_decrypt(const char *source, int source_length, char *dest, - const char *key, int key_length) -{ - KEYINSTANCE aes_key; - uint8 block[AES_BLOCK_SIZE]; /* 128 bit block used for padding */ - int rc; /* Result codes */ - int num_blocks; /* Number of complete blocks */ - uint pad_len; /* Pad size for the last block */ - int i; - - if ((rc=my_aes_create_key(&aes_key,AES_DECRYPT,key,key_length))) - return rc; - - num_blocks = source_length/AES_BLOCK_SIZE; - - if ((source_length != num_blocks*AES_BLOCK_SIZE) || num_blocks ==0 ) - return AES_BAD_DATA; /* Input size has to be even and at least one block */ - - for (i = num_blocks-1; i > 0; i--) /* Decode all but last blocks */ - { - rijndaelDecrypt(aes_key.rk, aes_key.nr, (const uint8*) source, - (uint8*) dest); - source+= AES_BLOCK_SIZE; - dest+= AES_BLOCK_SIZE; - } - - rijndaelDecrypt(aes_key.rk, aes_key.nr, (const uint8*) source, block); - /* Use last char in the block as size */ - pad_len = (uint) (uchar) block[AES_BLOCK_SIZE-1]; - - if (pad_len > AES_BLOCK_SIZE) - return AES_BAD_DATA; - /* We could also check whole padding but we do not really need this */ - - memcpy(dest, block, AES_BLOCK_SIZE - pad_len); - return AES_BLOCK_SIZE*num_blocks - pad_len; -} - - -/* - Get size of buffer which will be large enough for encrypted data - - SYNOPSIS - my_aes_get_size() - source_length Length of data to be encrypted - - RETURN - Size of buffer required to store encrypted data -*/ - -int my_aes_get_size(int source_length) -{ - return AES_BLOCK_SIZE*(source_length/AES_BLOCK_SIZE)+AES_BLOCK_SIZE; -} diff --git a/mysys/my_init.c b/mysys/my_init.c index 2c06425f6fb..32289dbed7a 100644 --- a/mysys/my_init.c +++ b/mysys/my_init.c @@ -454,7 +454,8 @@ PSI_mutex_key key_LOCK_localtime_r; #endif /* !defined(HAVE_LOCALTIME_R) || !defined(HAVE_GMTIME_R) */ PSI_mutex_key key_BITMAP_mutex, key_IO_CACHE_append_buffer_lock, - key_IO_CACHE_SHARE_mutex, key_KEY_CACHE_cache_lock, key_LOCK_alarm, + key_IO_CACHE_SHARE_mutex, key_KEY_CACHE_cache_lock, + key_LOCK_alarm, key_LOCK_timer, key_my_thread_var_mutex, key_THR_LOCK_charset, key_THR_LOCK_heap, key_THR_LOCK_lock, key_THR_LOCK_malloc, key_THR_LOCK_mutex, key_THR_LOCK_myisam, key_THR_LOCK_net, @@ -474,6 +475,7 @@ static PSI_mutex_info all_mysys_mutexes[]= { &key_IO_CACHE_SHARE_mutex, "IO_CACHE::SHARE_mutex", 0}, { &key_KEY_CACHE_cache_lock, "KEY_CACHE::cache_lock", 0}, { &key_LOCK_alarm, "LOCK_alarm", PSI_FLAG_GLOBAL}, + { &key_LOCK_timer, "LOCK_timer", PSI_FLAG_GLOBAL}, { &key_my_thread_var_mutex, "my_thread_var::mutex", 0}, { &key_THR_LOCK_charset, "THR_LOCK_charset", PSI_FLAG_GLOBAL}, { &key_THR_LOCK_heap, "THR_LOCK_heap", PSI_FLAG_GLOBAL}, @@ -489,13 +491,14 @@ static PSI_mutex_info all_mysys_mutexes[]= { &key_LOCK_uuid_generator, "LOCK_uuid_generator", PSI_FLAG_GLOBAL } }; -PSI_cond_key key_COND_alarm, key_IO_CACHE_SHARE_cond, +PSI_cond_key key_COND_alarm, key_COND_timer, key_IO_CACHE_SHARE_cond, key_IO_CACHE_SHARE_cond_writer, key_my_thread_var_suspend, key_THR_COND_threads, key_WT_RESOURCE_cond; static PSI_cond_info all_mysys_conds[]= { { &key_COND_alarm, "COND_alarm", PSI_FLAG_GLOBAL}, + { &key_COND_timer, "COND_timer", PSI_FLAG_GLOBAL}, { &key_IO_CACHE_SHARE_cond, "IO_CACHE_SHARE::cond", 0}, { &key_IO_CACHE_SHARE_cond_writer, "IO_CACHE_SHARE::cond_writer", 0}, { &key_my_thread_var_suspend, "my_thread_var::suspend", 0}, @@ -512,12 +515,17 @@ static PSI_rwlock_info all_mysys_rwlocks[]= #ifdef USE_ALARM_THREAD PSI_thread_key key_thread_alarm; +#endif +PSI_thread_key key_thread_timer; static PSI_thread_info all_mysys_threads[]= { - { &key_thread_alarm, "alarm", PSI_FLAG_GLOBAL} +#ifdef USE_ALARM_THREAD + { &key_thread_alarm, "alarm", PSI_FLAG_GLOBAL}, +#endif + { &key_thread_timer, "statement_timer", PSI_FLAG_GLOBAL} }; -#endif /* USE_ALARM_THREAD */ + #ifdef HUGETLB_USE_PROC_MEMINFO PSI_file_key key_file_proc_meminfo; @@ -552,10 +560,8 @@ void my_init_mysys_psi_keys() count= sizeof(all_mysys_rwlocks)/sizeof(all_mysys_rwlocks[0]); mysql_rwlock_register(category, all_mysys_rwlocks, count); -#ifdef USE_ALARM_THREAD count= sizeof(all_mysys_threads)/sizeof(all_mysys_threads[0]); mysql_thread_register(category, all_mysys_threads, count); -#endif /* USE_ALARM_THREAD */ count= sizeof(all_mysys_files)/sizeof(all_mysys_files[0]); mysql_file_register(category, all_mysys_files, count); diff --git a/mysys/mysys_priv.h b/mysys/mysys_priv.h index 80c6a981db2..9b94a5a18ce 100644 --- a/mysys/mysys_priv.h +++ b/mysys/mysys_priv.h @@ -42,16 +42,16 @@ extern PSI_mutex_key key_BITMAP_mutex, key_IO_CACHE_append_buffer_lock, key_THR_LOCK_lock, key_THR_LOCK_malloc, key_THR_LOCK_mutex, key_THR_LOCK_myisam, key_THR_LOCK_net, key_THR_LOCK_open, key_THR_LOCK_threads, key_LOCK_uuid_generator, - key_TMPDIR_mutex, key_THR_LOCK_myisam_mmap; + key_TMPDIR_mutex, key_THR_LOCK_myisam_mmap, key_LOCK_timer; -extern PSI_cond_key key_COND_alarm, key_IO_CACHE_SHARE_cond, +extern PSI_cond_key key_COND_alarm, key_COND_timer, key_IO_CACHE_SHARE_cond, key_IO_CACHE_SHARE_cond_writer, key_my_thread_var_suspend, key_THR_COND_threads; #ifdef USE_ALARM_THREAD extern PSI_thread_key key_thread_alarm; #endif /* USE_ALARM_THREAD */ - +extern PSI_thread_key key_thread_timer; extern PSI_rwlock_key key_SAFEHASH_mutex; #endif /* HAVE_PSI_INTERFACE */ diff --git a/mysys/thr_timer.c b/mysys/thr_timer.c new file mode 100644 index 00000000000..6414ee6f246 --- /dev/null +++ b/mysys/thr_timer.c @@ -0,0 +1,589 @@ +/* + Copyright (c) 2012 Monty Program Ab + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 or later of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + +/* + Implementation if OS independent timers. + This is done based on pthread primitives, especially pthread_cond_timedwait() +*/ + +#include "mysys_priv.h" +#include "thr_timer.h" +#include <m_string.h> +#include <queues.h> +#ifdef HAVE_TIMER_CREATE +#include <sys/syscall.h> +#endif + +enum thread_state +{ + NOT_RUNNING= -1, RUNNING= 0, ABORTING=1 +}; + +static enum thread_state timer_thread_state= NOT_RUNNING; + +volatile my_bool timer_thread_running= 0; +struct timespec next_timer_expire_time; + +static my_bool thr_timer_inited= 0; +static mysql_mutex_t LOCK_timer; +static mysql_cond_t COND_timer; +static QUEUE timer_queue; +pthread_t timer_thread; + +#define set_max_time(abs_time) \ + { (abs_time)->MY_tv_sec= INT_MAX32; (abs_time)->MY_tv_nsec= 0; } + + +static void *timer_handler(void *arg __attribute__((unused))); + +/* + Compare two timespecs +*/ + +static int compare_timespec(void *not_used __attribute__((unused)), + uchar *a_ptr, uchar *b_ptr) +{ + return cmp_timespec((*(struct timespec*) a_ptr), + (*(struct timespec*) b_ptr)); +} + + +/** + Initialize timer variables and create timer thread + + @param alloc_timers Init allocation of timers. Will be autoextended + if needed + @return 0 ok + @return 1 error; Can't create thread +*/ + +static thr_timer_t max_timer_data; + +my_bool init_thr_timer(uint alloc_timers) +{ + pthread_attr_t thr_attr; + my_bool res; + DBUG_ENTER("init_thr_timer"); + + init_queue(&timer_queue, alloc_timers+2, offsetof(thr_timer_t,expire_time), + 0, compare_timespec, NullS, + offsetof(thr_timer_t, index_in_queue)+1, 1); + mysql_mutex_init(key_LOCK_timer, &LOCK_timer, MY_MUTEX_INIT_FAST); + mysql_cond_init(key_COND_timer, &COND_timer, NULL); + + /* Set dummy element with max time into the queue to simplify usage */ + bzero(&max_timer_data, sizeof(max_timer_data)); + set_max_time(&max_timer_data.expire_time); + queue_insert(&timer_queue, (uchar*) &max_timer_data); + next_timer_expire_time= max_timer_data.expire_time; + + /* Create a thread to handle timers */ + pthread_attr_init(&thr_attr); + pthread_attr_setscope(&thr_attr,PTHREAD_SCOPE_PROCESS); + pthread_attr_setdetachstate(&thr_attr,PTHREAD_CREATE_DETACHED); + pthread_attr_setstacksize(&thr_attr,8196); + res= mysql_thread_create(key_thread_timer, + &timer_thread, &thr_attr, timer_handler, NULL) != 0; + pthread_attr_destroy(&thr_attr); + + thr_timer_inited= 1; + DBUG_RETURN(res); +} + + +void end_thr_timer(void) +{ + struct timespec abstime; + DBUG_ENTER("end_thr_timer"); + + if (!thr_timer_inited) + DBUG_VOID_RETURN; + + mysql_mutex_lock(&LOCK_timer); + timer_thread_state= ABORTING; /* Signal abort */ + mysql_cond_signal(&COND_timer); + + /* Wait until timer thread dies */ + set_timespec(abstime, 10*1000); /* Wait up to 10 seconds */ + while (timer_thread_state == ABORTING) + { + int error= mysql_cond_timedwait(&COND_timer, &LOCK_timer, &abstime); + if (error == ETIME || error == ETIMEDOUT) + break; /* Don't wait forever */ + } + mysql_mutex_unlock(&LOCK_timer); + if (timer_thread_state == NOT_RUNNING) + { + mysql_mutex_destroy(&LOCK_timer); + mysql_cond_destroy(&COND_timer); + delete_queue(&timer_queue); + thr_timer_inited= 0; + } + DBUG_VOID_RETURN; +} + + +/* + Initialize a timer object + + @param timer_data Timer structure + @param function Function to be called when getting timeout + @param argument Argument for function +*/ + +void thr_timer_init(thr_timer_t *timer_data, void(*function)(void*), + void *arg) +{ + DBUG_ENTER("thr_timer_init"); + bzero(timer_data, sizeof(*timer_data)); + timer_data->func= function; + timer_data->func_arg= arg; + timer_data->expired= 1; /* Not active */ + DBUG_VOID_RETURN; +} + + +/* + Request timer after X milliseconds + + SYNOPSIS + thr_timer() + timer_data Pointer to timer structure + micro_seconds; Number of microseconds until timer + + RETURN VALUES + 0 ok + 1 If no more timers are allowed (aborted by process) + + Stores in first argument a pointer to a non-zero int which is set to 0 + when the timer has been given +*/ + +my_bool thr_timer_settime(thr_timer_t *timer_data, ulonglong micro_seconds) +{ + int reschedule; + DBUG_ENTER("thr_timer_settime"); + DBUG_PRINT("enter",("thread: %s micro_seconds: %llu",my_thread_name(), + micro_seconds)); + + DBUG_ASSERT(timer_data->expired == 1); + + set_timespec_nsec(timer_data->expire_time, micro_seconds*1000); + timer_data->expired= 0; + + mysql_mutex_lock(&LOCK_timer); /* Lock from threads & timers */ + if (queue_insert_safe(&timer_queue,(uchar*) timer_data)) + { + DBUG_PRINT("info", ("timer queue full")); + fprintf(stderr,"Warning: thr_timer queue is full\n"); + timer_data->expired= 1; + mysql_mutex_unlock(&LOCK_timer); + DBUG_RETURN(1); + } + + /* Reschedule timer if the current one has more time left than new one */ + reschedule= cmp_timespec(next_timer_expire_time, timer_data->expire_time); + mysql_mutex_unlock(&LOCK_timer); + if (reschedule > 0) + { +#if defined(MAIN) + printf("reschedule\n"); fflush(stdout); +#endif + DBUG_PRINT("info", ("reschedule")); + mysql_cond_signal(&COND_timer); + } + + DBUG_RETURN(0); +} + + +/* + Remove timer from list of timers + + notes: Timer will be marked as expired +*/ + +void thr_timer_end(thr_timer_t *timer_data) +{ + DBUG_ENTER("thr_timer_end"); + + mysql_mutex_lock(&LOCK_timer); + if (!timer_data->expired) + { + DBUG_ASSERT(timer_data->index_in_queue != 0); + DBUG_ASSERT(queue_element(&timer_queue, timer_data->index_in_queue) == + (uchar*) timer_data); + queue_remove(&timer_queue, timer_data->index_in_queue); + /* Mark as expired for asserts to work */ + timer_data->expired= 1; + } + mysql_mutex_unlock(&LOCK_timer); + DBUG_VOID_RETURN; +} + + +/* + Come here when some timer in queue is due. +*/ + +static sig_handler process_timers(struct timespec *now) +{ + thr_timer_t *timer_data; + DBUG_ENTER("process_timers"); + DBUG_PRINT("info",("active timers: %d", timer_queue.elements - 1)); + +#if defined(MAIN) + printf("process_timer\n"); fflush(stdout); +#endif + + /* We can safely remove the first one as it has already expired */ + for (;;) + { + void (*function)(void*); + void *func_arg; + + timer_data= (thr_timer_t*) queue_top(&timer_queue); + function= timer_data->func; + func_arg= timer_data->func_arg; + timer_data->expired= 1; /* Mark expired */ + /* + We remove timer before calling timer function to allow thread to + delete it's timer data any time. + */ + queue_remove_top(&timer_queue); /* Remove timer */ + (*function)(func_arg); /* Inform thread of timeout */ + + /* Check if next one has also expired */ + timer_data= (thr_timer_t*) queue_top(&timer_queue); + if (cmp_timespec(timer_data->expire_time, (*now)) > 0) + break; /* All data processed */ + } + DBUG_VOID_RETURN; +} + + +/* + set up a timer thread to handle timeouts + This will be killed when timer_thread_state is set to ABORTING. + At end timer_aborted will be set to NOT_RUNNING +*/ + +static void *timer_handler(void *arg __attribute__((unused))) +{ + my_thread_init(); + + timer_thread_state= RUNNING; + + mysql_mutex_lock(&LOCK_timer); + while (likely(timer_thread_state == RUNNING)) + { + int error; + struct timespec *top_time; + struct timespec now, abstime; + + set_timespec(now, 0); + + top_time= &(((thr_timer_t*) queue_top(&timer_queue))->expire_time); + + if (cmp_timespec((*top_time), now) <= 0) + { + process_timers(&now); + top_time= &(((thr_timer_t*) queue_top(&timer_queue))->expire_time); + } + + abstime= *top_time; + next_timer_expire_time= *top_time; + if ((error= mysql_cond_timedwait(&COND_timer, &LOCK_timer, &abstime)) && + error != ETIME && error != ETIMEDOUT) + { +#ifdef MAIN + printf("Got error: %d from ptread_cond_timedwait (errno: %d)\n", + error,errno); +#endif + } + } + timer_thread_state= NOT_RUNNING; /* Mark thread ended */ + mysql_cond_signal(&COND_timer); /* signal end_thr_timer() */ + mysql_mutex_unlock(&LOCK_timer); + my_thread_end(); + pthread_exit(0); + return 0; /* Impossible */ +} + + +/**************************************************************************** + Testing of thr_timer (when compiled with -DMAIN) +***************************************************************************/ + +#ifdef MAIN + +static mysql_cond_t COND_thread_count; +static mysql_mutex_t LOCK_thread_count; +static uint thread_count, benchmark_runs, test_to_run= 1; + +static void send_signal(void *arg) +{ + struct st_my_thread_var *current_my_thread_var= arg; +#if defined(MAIN) + printf("sending signal\n"); fflush(stdout); +#endif + mysql_mutex_lock(¤t_my_thread_var->mutex); + mysql_cond_signal(¤t_my_thread_var->suspend); + mysql_mutex_unlock(¤t_my_thread_var->mutex); +} + + +static void run_thread_test(int param) +{ + int i,wait_time,retry; + my_hrtime_t start_time; + thr_timer_t timer_data; + struct st_my_thread_var *current_my_thread_var; + DBUG_ENTER("run_thread_test"); + + current_my_thread_var= my_thread_var; + thr_timer_init(&timer_data, send_signal, current_my_thread_var); + + for (i=1 ; i <= 10 ; i++) + { + wait_time=param ? 11-i : i; + start_time= my_hrtime(); + + mysql_mutex_lock(¤t_my_thread_var->mutex); + if (thr_timer_settime(&timer_data, wait_time * 1000000)) + { + printf("Thread: %s timers aborted\n",my_thread_name()); + break; + } + if (wait_time == 3) + { + printf("Thread: %s Simulation of no timer needed\n",my_thread_name()); + fflush(stdout); + } + else + { + for (retry=0 ; !timer_data.expired && retry < 10 ; retry++) + { + printf("Thread: %s Waiting %d sec\n",my_thread_name(),wait_time); + mysql_cond_wait(¤t_my_thread_var->suspend, + ¤t_my_thread_var->mutex); + + } + if (!timer_data.expired) + { + printf("Thread: %s didn't get an timer. Aborting!\n", + my_thread_name()); + break; + } + } + mysql_mutex_unlock(¤t_my_thread_var->mutex); + printf("Thread: %s Slept for %g (%d) sec\n",my_thread_name(), + (int) (my_hrtime().val-start_time.val)/1000000.0, wait_time); + fflush(stdout); + thr_timer_end(&timer_data); + fflush(stdout); + } + DBUG_VOID_RETURN; +} + + +static void run_thread_benchmark(int param) +{ + int i; + struct st_my_thread_var *current_my_thread_var; + thr_timer_t timer_data; + DBUG_ENTER("run_thread_benchmark"); + + current_my_thread_var= my_thread_var; + thr_timer_init(&timer_data, send_signal, current_my_thread_var); + + for (i=1 ; i <= param ; i++) + { + if (thr_timer_settime(&timer_data, 1000000)) + { + printf("Thread: %s timers aborted\n",my_thread_name()); + break; + } + thr_timer_end(&timer_data); + } + DBUG_VOID_RETURN; +} + + +#ifdef HAVE_TIMER_CREATE + +/* Test for benchmarking posix timers against thr_timer */ + +#ifndef sigev_notify_thread_id +#define sigev_notify_thread_id _sigev_un._tid +#endif + +static void run_timer_benchmark(int param) +{ + int i; + timer_t timerid; + struct sigevent sigev; + pid_t thread_id= (pid_t) syscall(SYS_gettid); + DBUG_ENTER("run_timer_benchmark"); + + /* Setup a signal that will never be signaled */ + sigev.sigev_value.sival_ptr= 0; + sigev.sigev_signo= SIGRTMIN; /* First free signal */ + sigev.sigev_notify= SIGEV_SIGNAL | SIGEV_THREAD_ID; + sigev.sigev_notify_thread_id= thread_id; + + if (timer_create(CLOCK_MONOTONIC, &sigev, &timerid)) + { + printf("Could not create timer\n"); + exit(1); + } + + for (i=1 ; i <= param ; i++) + { + struct itimerspec abstime; + abstime.it_interval.tv_sec= 0; + abstime.it_interval.tv_nsec= 0; + abstime.it_value.tv_sec= 1; + abstime.it_value.tv_nsec= 0; + + if (timer_settime(timerid, 0, &abstime, NULL)) + { + printf("Thread: %s timers aborted\n",my_thread_name()); + break; + } + abstime.it_interval.tv_sec= 0; + abstime.it_interval.tv_nsec= 0; + abstime.it_value.tv_sec= 0; + abstime.it_value.tv_nsec= 0; + timer_settime(timerid, 0, &abstime, NULL); + } + timer_delete(timerid); + DBUG_VOID_RETURN; +} +#endif /* HAVE_TIMER_CREATE */ + + +static void *start_thread(void *arg) +{ + my_thread_init(); + printf("Thread %d (%s) started\n",*((int*) arg),my_thread_name()); + fflush(stdout); + + switch (test_to_run) { + case 1: + run_thread_test(*((int*) arg)); + break; + case 2: + run_thread_benchmark(benchmark_runs); + break; + case 3: +#ifdef HAVE_TIMER_CREATE + run_timer_benchmark(benchmark_runs); +#endif + break; + } + free((uchar*) arg); + mysql_mutex_lock(&LOCK_thread_count); + thread_count--; + mysql_cond_signal(&COND_thread_count); /* Tell main we are ready */ + mysql_mutex_unlock(&LOCK_thread_count); + my_thread_end(); + return 0; +} + + +/* Start a lot of threads that will run with timers */ + +static void run_test() +{ + pthread_t tid; + pthread_attr_t thr_attr; + int i,*param,error; + DBUG_ENTER("run_test"); + + if (init_thr_timer(5)) + { + printf("Can't initialize timers\n"); + exit(1); + } + + mysql_mutex_init(0, &LOCK_thread_count, MY_MUTEX_INIT_FAST); + mysql_cond_init(0, &COND_thread_count, NULL); + + thr_setconcurrency(3); + pthread_attr_init(&thr_attr); + pthread_attr_setscope(&thr_attr,PTHREAD_SCOPE_PROCESS); + printf("Main thread: %s\n",my_thread_name()); + for (i=0 ; i < 2 ; i++) + { + param=(int*) malloc(sizeof(int)); + *param= i; + mysql_mutex_lock(&LOCK_thread_count); + if ((error= mysql_thread_create(0, + &tid, &thr_attr, start_thread, + (void*) param))) + { + printf("Can't create thread %d, error: %d\n",i,error); + exit(1); + } + thread_count++; + mysql_mutex_unlock(&LOCK_thread_count); + } + + pthread_attr_destroy(&thr_attr); + mysql_mutex_lock(&LOCK_thread_count); + while (thread_count) + { + mysql_cond_wait(&COND_thread_count, &LOCK_thread_count); + } + mysql_mutex_unlock(&LOCK_thread_count); + DBUG_ASSERT(timer_queue.elements == 1); + end_thr_timer(); + printf("Test succeeded\n"); + DBUG_VOID_RETURN; +} + + +int main(int argc __attribute__((unused)),char **argv __attribute__((unused))) +{ + MY_INIT(argv[0]); + + if (argc > 1 && argv[1][0] == '-') + { + switch (argv[1][1]) { + case '#': + test_to_run= 1; + DBUG_PUSH(argv[1]+2); + break; + case 'b': + test_to_run= 2; + benchmark_runs= atoi(argv[1]+2); + break; + case 't': + test_to_run= 3; + benchmark_runs= atoi(argv[1]+2); + break; + } + } + if (!benchmark_runs) + benchmark_runs= 1000000; + + run_test(); + my_end(1); + return 0; +} + +#endif /* MAIN */ diff --git a/scripts/mysql_system_tables.sql b/scripts/mysql_system_tables.sql index a148e191204..faad08ab6d9 100644 --- a/scripts/mysql_system_tables.sql +++ b/scripts/mysql_system_tables.sql @@ -33,7 +33,7 @@ set @had_db_table= @@warning_count != 0; CREATE TABLE IF NOT EXISTS host ( Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, Select_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Insert_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Update_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Delete_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Drop_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Grant_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, References_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Index_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Alter_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_tmp_table_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Lock_tables_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Show_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Alter_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Execute_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Trigger_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, PRIMARY KEY Host (Host,Db) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Host privileges; Merged with database privileges'; -CREATE TABLE IF NOT EXISTS user ( Host char(60) binary DEFAULT '' NOT NULL, User char(80) binary DEFAULT '' NOT NULL, Password char(41) character set latin1 collate latin1_bin DEFAULT '' NOT NULL, Select_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Insert_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Update_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Delete_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Drop_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Reload_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Shutdown_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Process_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, File_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Grant_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, References_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Index_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Alter_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Show_db_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Super_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_tmp_table_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Lock_tables_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Execute_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Repl_slave_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Repl_client_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Show_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Alter_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_user_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Event_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Trigger_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_tablespace_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, ssl_type enum('','ANY','X509', 'SPECIFIED') COLLATE utf8_general_ci DEFAULT '' NOT NULL, ssl_cipher BLOB NOT NULL, x509_issuer BLOB NOT NULL, x509_subject BLOB NOT NULL, max_questions int(11) unsigned DEFAULT 0 NOT NULL, max_updates int(11) unsigned DEFAULT 0 NOT NULL, max_connections int(11) unsigned DEFAULT 0 NOT NULL, max_user_connections int(11) DEFAULT 0 NOT NULL, plugin char(64) CHARACTER SET latin1 DEFAULT '' NOT NULL, authentication_string TEXT NOT NULL, password_expired ENUM('N', 'Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, is_role enum('N', 'Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, default_role char(80) binary DEFAULT '' NOT NULL, PRIMARY KEY Host (Host,User) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Users and global privileges'; +CREATE TABLE IF NOT EXISTS user ( Host char(60) binary DEFAULT '' NOT NULL, User char(80) binary DEFAULT '' NOT NULL, Password char(41) character set latin1 collate latin1_bin DEFAULT '' NOT NULL, Select_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Insert_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Update_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Delete_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Drop_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Reload_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Shutdown_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Process_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, File_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Grant_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, References_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Index_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Alter_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Show_db_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Super_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_tmp_table_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Lock_tables_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Execute_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Repl_slave_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Repl_client_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Show_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Alter_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_user_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Event_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Trigger_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_tablespace_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, ssl_type enum('','ANY','X509', 'SPECIFIED') COLLATE utf8_general_ci DEFAULT '' NOT NULL, ssl_cipher BLOB NOT NULL, x509_issuer BLOB NOT NULL, x509_subject BLOB NOT NULL, max_questions int(11) unsigned DEFAULT 0 NOT NULL, max_updates int(11) unsigned DEFAULT 0 NOT NULL, max_connections int(11) unsigned DEFAULT 0 NOT NULL, max_user_connections int(11) DEFAULT 0 NOT NULL, plugin char(64) CHARACTER SET latin1 DEFAULT '' NOT NULL, authentication_string TEXT NOT NULL, password_expired ENUM('N', 'Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, is_role enum('N', 'Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, default_role char(80) binary DEFAULT '' NOT NULL, max_statement_time decimal(12,6) DEFAULT 0 NOT NULL, PRIMARY KEY Host (Host,User) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Users and global privileges'; -- Remember for later if user table already existed set @had_user_table= @@warning_count != 0; @@ -80,7 +80,7 @@ CREATE TABLE IF NOT EXISTS time_zone_transition_type ( Time_zone_id int unsign CREATE TABLE IF NOT EXISTS time_zone_leap_second ( Transition_time bigint signed NOT NULL, Correction int signed NOT NULL, PRIMARY KEY TranTime (Transition_time) ) engine=MyISAM CHARACTER SET utf8 comment='Leap seconds information for time zones'; -CREATE TABLE IF NOT EXISTS proc (db char(64) collate utf8_bin DEFAULT '' NOT NULL, name char(64) DEFAULT '' NOT NULL, type enum('FUNCTION','PROCEDURE') NOT NULL, specific_name char(64) DEFAULT '' NOT NULL, language enum('SQL') DEFAULT 'SQL' NOT NULL, sql_data_access enum( 'CONTAINS_SQL', 'NO_SQL', 'READS_SQL_DATA', 'MODIFIES_SQL_DATA') DEFAULT 'CONTAINS_SQL' NOT NULL, is_deterministic enum('YES','NO') DEFAULT 'NO' NOT NULL, security_type enum('INVOKER','DEFINER') DEFAULT 'DEFINER' NOT NULL, param_list blob NOT NULL, returns longblob DEFAULT '' NOT NULL, body longblob NOT NULL, definer char(141) collate utf8_bin DEFAULT '' NOT NULL, created timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, modified timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', sql_mode set( 'REAL_AS_FLOAT', 'PIPES_AS_CONCAT', 'ANSI_QUOTES', 'IGNORE_SPACE', 'IGNORE_BAD_TABLE_OPTIONS', 'ONLY_FULL_GROUP_BY', 'NO_UNSIGNED_SUBTRACTION', 'NO_DIR_IN_CREATE', 'POSTGRESQL', 'ORACLE', 'MSSQL', 'DB2', 'MAXDB', 'NO_KEY_OPTIONS', 'NO_TABLE_OPTIONS', 'NO_FIELD_OPTIONS', 'MYSQL323', 'MYSQL40', 'ANSI', 'NO_AUTO_VALUE_ON_ZERO', 'NO_BACKSLASH_ESCAPES', 'STRICT_TRANS_TABLES', 'STRICT_ALL_TABLES', 'NO_ZERO_IN_DATE', 'NO_ZERO_DATE', 'INVALID_DATES', 'ERROR_FOR_DIVISION_BY_ZERO', 'TRADITIONAL', 'NO_AUTO_CREATE_USER', 'HIGH_NOT_PRECEDENCE', 'NO_ENGINE_SUBSTITUTION', 'PAD_CHAR_TO_FULL_LENGTH') DEFAULT '' NOT NULL, comment text collate utf8_bin NOT NULL, character_set_client char(32) collate utf8_bin, collation_connection char(32) collate utf8_bin, db_collation char(32) collate utf8_bin, body_utf8 longblob, PRIMARY KEY (db,name,type)) engine=MyISAM character set utf8 comment='Stored Procedures'; +CREATE TABLE IF NOT EXISTS proc (db char(64) collate utf8_bin DEFAULT '' NOT NULL, name char(64) DEFAULT '' NOT NULL, type enum('FUNCTION','PROCEDURE') NOT NULL, specific_name char(64) DEFAULT '' NOT NULL, language enum('SQL') DEFAULT 'SQL' NOT NULL, sql_data_access enum( 'CONTAINS_SQL', 'NO_SQL', 'READS_SQL_DATA', 'MODIFIES_SQL_DATA') DEFAULT 'CONTAINS_SQL' NOT NULL, is_deterministic enum('YES','NO') DEFAULT 'NO' NOT NULL, security_type enum('INVOKER','DEFINER') DEFAULT 'DEFINER' NOT NULL, param_list blob NOT NULL, returns longblob NOT NULL, body longblob NOT NULL, definer char(141) collate utf8_bin DEFAULT '' NOT NULL, created timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, modified timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', sql_mode set( 'REAL_AS_FLOAT', 'PIPES_AS_CONCAT', 'ANSI_QUOTES', 'IGNORE_SPACE', 'IGNORE_BAD_TABLE_OPTIONS', 'ONLY_FULL_GROUP_BY', 'NO_UNSIGNED_SUBTRACTION', 'NO_DIR_IN_CREATE', 'POSTGRESQL', 'ORACLE', 'MSSQL', 'DB2', 'MAXDB', 'NO_KEY_OPTIONS', 'NO_TABLE_OPTIONS', 'NO_FIELD_OPTIONS', 'MYSQL323', 'MYSQL40', 'ANSI', 'NO_AUTO_VALUE_ON_ZERO', 'NO_BACKSLASH_ESCAPES', 'STRICT_TRANS_TABLES', 'STRICT_ALL_TABLES', 'NO_ZERO_IN_DATE', 'NO_ZERO_DATE', 'INVALID_DATES', 'ERROR_FOR_DIVISION_BY_ZERO', 'TRADITIONAL', 'NO_AUTO_CREATE_USER', 'HIGH_NOT_PRECEDENCE', 'NO_ENGINE_SUBSTITUTION', 'PAD_CHAR_TO_FULL_LENGTH') DEFAULT '' NOT NULL, comment text collate utf8_bin NOT NULL, character_set_client char(32) collate utf8_bin, collation_connection char(32) collate utf8_bin, db_collation char(32) collate utf8_bin, body_utf8 longblob, PRIMARY KEY (db,name,type)) engine=MyISAM character set utf8 comment='Stored Procedures'; CREATE TABLE IF NOT EXISTS procs_priv ( Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(80) binary DEFAULT '' NOT NULL, Routine_name char(64) COLLATE utf8_general_ci DEFAULT '' NOT NULL, Routine_type enum('FUNCTION','PROCEDURE') NOT NULL, Grantor char(141) DEFAULT '' NOT NULL, Proc_priv set('Execute','Alter Routine','Grant') COLLATE utf8_general_ci DEFAULT '' NOT NULL, Timestamp timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (Host,Db,User,Routine_name,Routine_type), KEY Grantor (Grantor) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Procedure privileges'; diff --git a/scripts/mysql_system_tables_data.sql b/scripts/mysql_system_tables_data.sql index 46c96ef4bb1..075aafd5e3b 100644 --- a/scripts/mysql_system_tables_data.sql +++ b/scripts/mysql_system_tables_data.sql @@ -39,10 +39,10 @@ DROP TABLE tmp_db; -- Fill "user" table with default users allowing root access -- from local machine if "user" table didn't exist before CREATE TEMPORARY TABLE tmp_user LIKE user; -INSERT INTO tmp_user VALUES ('localhost','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0,'','','N', 'N',''); -REPLACE INTO tmp_user SELECT @current_hostname,'root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0,'','','N','N','' FROM dual WHERE @current_hostname != 'localhost'; -REPLACE INTO tmp_user VALUES ('127.0.0.1','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0,'','','N','N', ''); -REPLACE INTO tmp_user VALUES ('::1','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0,'','','N','N', ''); +INSERT INTO tmp_user VALUES ('localhost','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0,'','','N', 'N','', 0); +REPLACE INTO tmp_user SELECT @current_hostname,'root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0,'','','N','N','',0 FROM dual WHERE @current_hostname != 'localhost'; +REPLACE INTO tmp_user VALUES ('127.0.0.1','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0,'','','N','N','',0); +REPLACE INTO tmp_user VALUES ('::1','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0,'','','N','N', '', 0); INSERT INTO tmp_user (host,user) VALUES ('localhost',''); INSERT INTO tmp_user (host,user) SELECT @current_hostname,'' FROM dual WHERE @current_hostname != 'localhost'; INSERT INTO user SELECT * FROM tmp_user WHERE @had_user_table=0; diff --git a/scripts/mysql_system_tables_fix.sql b/scripts/mysql_system_tables_fix.sql index 3ec2d94673a..96e4103b5bd 100644 --- a/scripts/mysql_system_tables_fix.sql +++ b/scripts/mysql_system_tables_fix.sql @@ -632,6 +632,7 @@ ALTER TABLE user ADD plugin char(64) DEFAULT '', ADD authentication_string TEXT ALTER TABLE user ADD password_expired ENUM('N', 'Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL; ALTER TABLE user ADD is_role enum('N', 'Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL; ALTER TABLE user ADD default_role char(80) binary DEFAULT '' NOT NULL; +ALTER TABLE user ADD max_statement_time decimal(12,6) DEFAULT 0 NOT NULL; ALTER TABLE user MODIFY plugin char(64) CHARACTER SET latin1 DEFAULT '' NOT NULL, MODIFY authentication_string TEXT NOT NULL; -- Somewhere above, we ran ALTER TABLE user .... CONVERT TO CHARACTER SET utf8 COLLATE utf8_bin. -- we want password_expired column to have collation utf8_general_ci. diff --git a/sql/events.cc b/sql/events.cc index fa40086c1f7..d42a5d7b0a0 100644 --- a/sql/events.cc +++ b/sql/events.cc @@ -1131,8 +1131,11 @@ Events::load_events_from_db(THD *thd) goto end; } #ifdef WITH_WSREP - // when SST from master node who initials event, the event status is ENABLED - // this is problematic because there are two nodes with same events and both enabled. + /* + When SST from master node who initials event, the event status is ENABLED + this is problematic because there are two nodes with same events and + both enabled. + */ if (WSREP(thd) && et->originator != thd->variables.server_id) { store_record(table, record[1]); diff --git a/sql/lex.h b/sql/lex.h index 10a52160cf0..affb8032193 100644 --- a/sql/lex.h +++ b/sql/lex.h @@ -363,6 +363,7 @@ static SYMBOL symbols[] = { { "MAX_QUERIES_PER_HOUR", SYM(MAX_QUERIES_PER_HOUR)}, { "MAX_ROWS", SYM(MAX_ROWS)}, { "MAX_SIZE", SYM(MAX_SIZE_SYM)}, + { "MAX_STATEMENT_TIME", SYM(MAX_STATEMENT_TIME_SYM)}, { "MAX_UPDATES_PER_HOUR", SYM(MAX_UPDATES_PER_HOUR)}, { "MAX_USER_CONNECTIONS", SYM(MAX_USER_CONNECTIONS_SYM)}, { "MAXVALUE", SYM(MAX_VALUE_SYM)}, diff --git a/sql/log.cc b/sql/log.cc index 9c6de086a13..8ad6556e7c4 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -1910,12 +1910,12 @@ static bool trans_cannot_safely_rollback(THD *thd, bool all) return ((thd->variables.option_bits & OPTION_KEEP_LOG) || (trans_has_updated_non_trans_table(thd) && - WSREP_FORMAT(thd->variables.binlog_format) == BINLOG_FORMAT_STMT) || + WSREP_FORMAT((enum enum_binlog_format) thd->variables.binlog_format) == BINLOG_FORMAT_STMT) || (cache_mngr->trx_cache.changes_to_non_trans_temp_table() && - WSREP_FORMAT(thd->variables.binlog_format) == BINLOG_FORMAT_MIXED) || + WSREP_FORMAT((enum enum_binlog_format) thd->variables.binlog_format) == BINLOG_FORMAT_MIXED) || (trans_has_updated_non_trans_table(thd) && ending_single_stmt_trans(thd,all) && - WSREP_FORMAT(thd->variables.binlog_format) == BINLOG_FORMAT_MIXED)); + WSREP_FORMAT((enum enum_binlog_format) thd->variables.binlog_format) == BINLOG_FORMAT_MIXED)); } @@ -2064,9 +2064,9 @@ static int binlog_rollback(handlerton *hton, THD *thd, bool all) else if (ending_trans(thd, all) || (!(thd->variables.option_bits & OPTION_KEEP_LOG) && (!stmt_has_updated_non_trans_table(thd) || - WSREP_FORMAT(thd->variables.binlog_format) != BINLOG_FORMAT_STMT) && + WSREP_FORMAT((enum enum_binlog_format) thd->variables.binlog_format) != BINLOG_FORMAT_STMT) && (!cache_mngr->trx_cache.changes_to_non_trans_temp_table() || - WSREP_FORMAT(thd->variables.binlog_format) != BINLOG_FORMAT_MIXED))) + WSREP_FORMAT((enum enum_binlog_format) thd->variables.binlog_format) != BINLOG_FORMAT_MIXED))) error= binlog_truncate_trx_cache(thd, cache_mngr, all); } diff --git a/sql/log_event.cc b/sql/log_event.cc index ee35acadd9b..e5183b208b2 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -473,6 +473,7 @@ inline bool unexpected_error_code(int unexpected_error) case ER_NET_READ_ERROR: case ER_NET_ERROR_ON_WRITE: case ER_QUERY_INTERRUPTED: + case ER_STATEMENT_TIMEOUT: case ER_CONNECTION_KILLED: case ER_SERVER_SHUTDOWN: case ER_NEW_ABORTING_CONNECTION: diff --git a/sql/mysqld.cc b/sql/mysqld.cc index d252c33ac53..ec5f66cac45 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -2106,6 +2106,9 @@ void clean_up(bool print_message) sp_cache_end(); free_status_vars(); end_thr_alarm(1); /* Free allocated memory */ +#ifndef EMBEDDED_LIBRARY + end_thr_timer(); +#endif my_free_open_file_info(); if (defaults_argv) free_defaults(defaults_argv); @@ -4746,6 +4749,14 @@ static int init_server_components() my_rnd_init(&sql_rand,(ulong) server_start_time,(ulong) server_start_time/2); setup_fpu(); init_thr_lock(); +#ifndef EMBEDDED_LIBRARY + if (init_thr_timer(thread_scheduler->max_threads + extra_max_connections)) + { + fprintf(stderr, "Can't initialize timers\n"); + unireg_abort(1); + } +#endif + my_uuid_init((ulong) (my_rnd(&sql_rand))*12345,12345); #ifdef HAVE_REPLICATION init_slave_list(); @@ -8077,6 +8088,7 @@ SHOW_VAR status_vars[]= { {"Handler_write", (char*) offsetof(STATUS_VAR, ha_write_count), SHOW_LONG_STATUS}, {"Key", (char*) &show_default_keycache, SHOW_FUNC}, {"Last_query_cost", (char*) offsetof(STATUS_VAR, last_query_cost), SHOW_DOUBLE_STATUS}, + {"max_statement_time_exceeded", (char*) offsetof(STATUS_VAR, max_statement_time_exceeded), SHOW_LONG_STATUS}, {"Max_used_connections", (char*) &max_used_connections, SHOW_LONG}, {"Memory_used", (char*) offsetof(STATUS_VAR, memory_used), SHOW_LONGLONG_STATUS}, {"Not_flushed_delayed_rows", (char*) &delayed_rows_in_use, SHOW_LONG_NOFLUSH}, @@ -9145,7 +9157,9 @@ static int get_options(int *argc_ptr, char ***argv_ptr) debug_assert_if_crashed_table= 1; global_system_variables.long_query_time= (ulonglong) - (global_system_variables.long_query_time_double * 1e6); + (global_system_variables.long_query_time_double * 1e6 + 0.1); + global_system_variables.max_statement_time= (ulonglong) + (global_system_variables.max_statement_time_double * 1e6 + 0.1); if (opt_short_log_format) opt_specialflag|= SPECIAL_SHORT_LOG_FORMAT; diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt index 32cdbe138b2..7042669a363 100644 --- a/sql/share/errmsg-utf8.txt +++ b/sql/share/errmsg-utf8.txt @@ -7110,3 +7110,5 @@ ER_IT_IS_A_VIEW 42S02 eng "'%-.192s' is a view" ER_SLAVE_SKIP_NOT_IN_GTID eng "When using GTID, @@sql_slave_skip_counter can not be used. Instead, setting @@gtid_slave_pos explicitly can be used to skip to after a given GTID position." +ER_STATEMENT_TIMEOUT 70100 + eng "Query execution was interrupted (max_statement_time exceeded)" diff --git a/sql/signal_handler.cc b/sql/signal_handler.cc index 3fadbcd088f..61e2830e82e 100644 --- a/sql/signal_handler.cc +++ b/sql/signal_handler.cc @@ -172,6 +172,10 @@ extern "C" sig_handler handle_fatal_signal(int sig) case KILL_QUERY_HARD: kreason= "KILL_QUERY"; break; + case KILL_TIMEOUT: + case KILL_TIMEOUT_HARD: + kreason= "KILL_TIMEOUT"; + break; case KILL_SYSTEM_THREAD: case KILL_SYSTEM_THREAD_HARD: kreason= "KILL_SYSTEM_THREAD"; diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 5e30b148ad7..8e976f0f579 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -211,8 +211,10 @@ static char *safe_str(char *str) static const char *safe_str(const char *str) { return str ? str : ""; } +#ifndef NO_EMBEDDED_ACCESS_CHECKS static size_t safe_strlen(const char *str) { return str ? strlen(str) : 0; } +#endif /* Classes */ @@ -709,6 +711,8 @@ bool ROLE_GRANT_PAIR::init(MEM_ROOT *mem, char *username, #define ROLE_ASSIGN_COLUMN_IDX 43 #define DEFAULT_ROLE_COLUMN_IDX 44 +#define MAX_STATEMENT_TIME_COLUMN_IDX 45 + /* various flags valid for ACL_USER */ #define IS_ROLE (1L << 0) /* Flag to mark that a ROLE is on the recursive DEPTH_FIRST_SEARCH stack */ @@ -1272,6 +1276,8 @@ static bool acl_load(THD *thd, TABLE_LIST *tables) user.sort= get_sort(2, user.host.hostname, user.user.str); user.hostname_length= safe_strlen(user.host.hostname); + user.user_resource.user_conn= 0; + user.user_resource.max_statement_time= 0.0; /* Starting from 4.0.2 we have more fields */ if (table->s->fields >= 31) @@ -1331,6 +1337,14 @@ static bool acl_load(THD *thd, TABLE_LIST *tables) fix_user_plugin_ptr(&user); } } + + if (table->s->fields > MAX_STATEMENT_TIME_COLUMN_IDX) + { + /* Starting from 10.1.1 we can have max_statement_time */ + ptr= get_field(thd->mem_root, + table->field[MAX_STATEMENT_TIME_COLUMN_IDX]); + user.user_resource.max_statement_time= ptr ? atof(ptr) : 0.0; + } } else { @@ -2041,6 +2055,8 @@ static void acl_update_user(const char *user, const char *host, acl_user->user_resource.conn_per_hour= mqh->conn_per_hour; if (mqh->specified_limits & USER_RESOURCES::USER_CONNECTIONS) acl_user->user_resource.user_conn= mqh->user_conn; + if (mqh->specified_limits & USER_RESOURCES::MAX_STATEMENT_TIME) + acl_user->user_resource.max_statement_time= mqh->max_statement_time; if (ssl_type != SSL_TYPE_NOT_SPECIFIED) { acl_user->ssl_type= ssl_type; @@ -3393,8 +3409,6 @@ static int replace_user_table(THD *thd, TABLE *table, LEX_USER &combo, if (table->s->fields >= 36 && (mqh.specified_limits & USER_RESOURCES::USER_CONNECTIONS)) table->field[next_field+3]->store((longlong) mqh.user_conn, FALSE); - mqh_used= mqh_used || mqh.questions || mqh.updates || mqh.conn_per_hour; - next_field+= 4; if (table->s->fields >= 41) { @@ -3415,7 +3429,16 @@ static int replace_user_table(THD *thd, TABLE *table, LEX_USER &combo, table->field[next_field]->reset(); table->field[next_field + 1]->reset(); } + + if (table->s->fields > MAX_STATEMENT_TIME_COLUMN_IDX) + { + if (mqh.specified_limits & USER_RESOURCES::MAX_STATEMENT_TIME) + table->field[MAX_STATEMENT_TIME_COLUMN_IDX]-> + store(mqh.max_statement_time); + } } + mqh_used= (mqh_used || mqh.questions || mqh.updates || mqh.conn_per_hour || + mqh.user_conn || mqh.max_statement_time != 0.0); /* table format checked earlier */ if (handle_as_role) @@ -7508,6 +7531,21 @@ static void add_user_option(String *grant, long value, const char *name, } } + +static void add_user_option(String *grant, double value, const char *name) +{ + if (value != 0.0 ) + { + char buff[FLOATING_POINT_BUFFER]; + size_t len; + grant->append(' '); + grant->append(name, strlen(name)); + grant->append(' '); + len= my_fcvt(value, 6, buff, NULL); + grant->append(buff, len); + } +} + static const char *command_array[]= { "SELECT", "INSERT", "UPDATE", "DELETE", "CREATE", "DROP", "RELOAD", @@ -7890,7 +7928,8 @@ static bool show_global_privileges(THD *thd, ACL_USER_BASE *acl_entry, (acl_user->user_resource.questions || acl_user->user_resource.updates || acl_user->user_resource.conn_per_hour || - acl_user->user_resource.user_conn)) + acl_user->user_resource.user_conn || + acl_user->user_resource.max_statement_time != 0.0)) { global.append(STRING_WITH_LEN(" WITH")); if (want_access & GRANT_ACL) @@ -7903,6 +7942,8 @@ static bool show_global_privileges(THD *thd, ACL_USER_BASE *acl_entry, "MAX_CONNECTIONS_PER_HOUR", false); add_user_option(&global, acl_user->user_resource.user_conn, "MAX_USER_CONNECTIONS", true); + add_user_option(&global, acl_user->user_resource.max_statement_time, + "MAX_STATEMENT_TIME"); } } @@ -12232,12 +12273,22 @@ bool acl_authenticate(THD *thd, uint com_change_user_pkt_len) if ((acl_user->user_resource.questions || acl_user->user_resource.updates || acl_user->user_resource.conn_per_hour || - acl_user->user_resource.user_conn || max_user_connections_checking) && + acl_user->user_resource.user_conn || + acl_user->user_resource.max_statement_time != 0.0 || + max_user_connections_checking) && get_or_create_user_conn(thd, (opt_old_style_user_limits ? sctx->user : sctx->priv_user), (opt_old_style_user_limits ? sctx->host_or_ip : sctx->priv_host), &acl_user->user_resource)) DBUG_RETURN(1); // The error is set by get_or_create_user_conn() + + if (acl_user->user_resource.max_statement_time != 0.0) + { + thd->variables.max_statement_time_double= + acl_user->user_resource.max_statement_time; + thd->variables.max_statement_time= + (thd->variables.max_statement_time_double * 1e6 + 0.1); + } } else sctx->skip_grants(); diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 356f672657e..a23c71dfc1c 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -3558,7 +3558,7 @@ thr_lock_type read_lock_type_for_table(THD *thd, */ bool log_on= mysql_bin_log.is_open() && thd->variables.sql_log_bin; ulong binlog_format= thd->variables.binlog_format; - if ((log_on == FALSE) || (WSREP_FORMAT(binlog_format) == BINLOG_FORMAT_ROW) || + if ((log_on == FALSE) || (WSREP_FORMAT((enum enum_binlog_format) binlog_format) == BINLOG_FORMAT_ROW) || (table_list->table->s->table_category == TABLE_CATEGORY_LOG) || (table_list->table->s->table_category == TABLE_CATEGORY_PERFORMANCE) || !(is_update_query(prelocking_ctx->sql_command) || @@ -5327,7 +5327,7 @@ bool lock_tables(THD *thd, TABLE_LIST *tables, uint count, We can solve these problems in mixed mode by switching to binlogging if at least one updated table is used by sub-statement */ - if (WSREP_FORMAT(thd->variables.binlog_format) != BINLOG_FORMAT_ROW && tables && + if (WSREP_FORMAT((enum enum_binlog_format) thd->variables.binlog_format) != BINLOG_FORMAT_ROW && tables && has_write_table_with_auto_increment(thd->lex->first_not_own_table())) thd->lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_AUTOINC_COLUMNS); } diff --git a/sql/sql_class.cc b/sql/sql_class.cc index dde0a9a2f7a..c8c03da0471 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -861,9 +861,26 @@ bool Drop_table_error_handler::handle_condition(THD *thd, } +/** + Send timeout to thread. + + Note that this is always safe as the thread will always remove it's + timeouts at end of query (and thus before THD is destroyed) +*/ + +extern "C" void thd_kill_timeout(THD* thd) +{ + thd->status_var.max_statement_time_exceeded++; + mysql_mutex_lock(&thd->LOCK_thd_data); + /* Kill queries that can't cause data corruptions */ + thd->awake(KILL_TIMEOUT); + mysql_mutex_unlock(&thd->LOCK_thd_data); +} + + THD::THD(bool is_wsrep_applier) - :Statement(&main_lex, &main_mem_root, STMT_CONVENTIONAL_EXECUTION, - /* statement id */ 0), + :Statement(&main_lex, &main_mem_root, STMT_CONVENTIONAL_EXECUTION, + /* statement id */ 0), rli_fake(0), rgi_fake(0), rgi_slave(NULL), in_sub_stmt(0), log_all_errors(0), binlog_unsafe_warning_flags(0), @@ -896,16 +913,17 @@ THD::THD(bool is_wsrep_applier) debug_sync_control(0), #endif /* defined(ENABLED_DEBUG_SYNC) */ wait_for_commit_ptr(0), - main_da(0, false, false), + main_da(0, false, false), m_stmt_da(&main_da) #ifdef WITH_WSREP - ,wsrep_applier(is_wsrep_applier) - ,wsrep_applier_closing(false) - ,wsrep_client_thread(false) - ,wsrep_apply_toi(false) - ,wsrep_po_handle(WSREP_PO_INITIALIZER) - ,wsrep_po_cnt(0) - ,wsrep_apply_format(0) + , + wsrep_applier(is_wsrep_applier), + wsrep_applier_closing(false), + wsrep_client_thread(false), + wsrep_apply_toi(false), + wsrep_po_handle(WSREP_PO_INITIALIZER), + wsrep_po_cnt(0), + wsrep_apply_format(0) #endif { ulong tmp; @@ -1058,6 +1076,8 @@ THD::THD(bool is_wsrep_applier) protocol_text.init(this); protocol_binary.init(this); + thr_timer_init(&query_timer, (void (*)(void*)) thd_kill_timeout, this); + tablespace_op=FALSE; /* @@ -1373,6 +1393,7 @@ extern "C" THD *_current_thd_noinline(void) return my_pthread_getspecific_ptr(THD*,THR_THD); } #endif + /* Init common variables that has to be reset on start and on change_user */ @@ -1779,6 +1800,7 @@ void add_diff_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var, This is normally called from another thread's THD object. @note Do always call this while holding LOCK_thd_data. + NOT_KILLED is used to awake a thread for a slave */ void THD::awake(killed_state state_to_set) @@ -1790,6 +1812,13 @@ void THD::awake(killed_state state_to_set) print_aborted_warning(3, "KILLED"); + /* + Don't degrade killed state, for example from a KILL_CONNECTION to + STATEMENT TIMEOUT + */ + if (killed >= KILL_CONNECTION) + state_to_set= killed; + /* Set the 'killed' flag of 'this', which is the target THD object. */ killed= state_to_set; @@ -1821,6 +1850,7 @@ void THD::awake(killed_state state_to_set) mysql_mutex_lock(&mysys_var->mutex); if (!system_thread) // Don't abort locks mysys_var->abort=1; + /* This broadcast could be up in the air if the victim thread exits the cond in the time between read and broadcast, but that is @@ -1989,6 +2019,9 @@ int killed_errno(killed_state killed) case KILL_QUERY: case KILL_QUERY_HARD: DBUG_RETURN(ER_QUERY_INTERRUPTED); + case KILL_TIMEOUT: + case KILL_TIMEOUT_HARD: + DBUG_RETURN(ER_STATEMENT_TIMEOUT); case KILL_SERVER: case KILL_SERVER_HARD: DBUG_RETURN(ER_SERVER_SHUTDOWN); @@ -4317,7 +4350,7 @@ extern "C" int thd_binlog_format(const MYSQL_THD thd) { if (((WSREP(thd) && wsrep_emulate_bin_log) || mysql_bin_log.is_open()) && thd->variables.option_bits & OPTION_BIN_LOG) - return (int) WSREP_FORMAT(thd->variables.binlog_format); + return (int) WSREP_FORMAT((enum enum_binlog_format) thd->variables.binlog_format); else return BINLOG_FORMAT_UNSPEC; } @@ -5047,7 +5080,7 @@ int THD::decide_logging_format(TABLE_LIST *tables) binlog by filtering rules. */ if (mysql_bin_log.is_open() && (variables.option_bits & OPTION_BIN_LOG) && - !(WSREP_FORMAT(variables.binlog_format) == BINLOG_FORMAT_STMT && + !(WSREP_FORMAT((enum enum_binlog_format) variables.binlog_format) == BINLOG_FORMAT_STMT && !binlog_filter->db_ok(db))) { /* @@ -5257,7 +5290,7 @@ int THD::decide_logging_format(TABLE_LIST *tables) */ my_error((error= ER_BINLOG_ROW_INJECTION_AND_STMT_ENGINE), MYF(0)); } - else if (WSREP_FORMAT(variables.binlog_format) == BINLOG_FORMAT_ROW && + else if (WSREP_FORMAT((enum enum_binlog_format) variables.binlog_format) == BINLOG_FORMAT_ROW && sqlcom_can_generate_row_events(this)) { /* @@ -5286,7 +5319,7 @@ int THD::decide_logging_format(TABLE_LIST *tables) else { /* binlog_format = STATEMENT */ - if (WSREP_FORMAT(variables.binlog_format) == BINLOG_FORMAT_STMT) + if (WSREP_FORMAT((enum enum_binlog_format) variables.binlog_format) == BINLOG_FORMAT_STMT) { if (lex->is_stmt_row_injection()) { @@ -5414,11 +5447,11 @@ int THD::decide_logging_format(TABLE_LIST *tables) DBUG_PRINT("info", ("decision: no logging since " "mysql_bin_log.is_open() = %d " "and (options & OPTION_BIN_LOG) = 0x%llx " - "and binlog_format = %lu " + "and binlog_format = %u " "and binlog_filter->db_ok(db) = %d", mysql_bin_log.is_open(), (variables.option_bits & OPTION_BIN_LOG), - WSREP_FORMAT(variables.binlog_format), + (uint) WSREP_FORMAT((enum enum_binlog_format) variables.binlog_format), binlog_filter->db_ok(db))); #endif diff --git a/sql/sql_class.h b/sql/sql_class.h index cab2968a62b..0860b868cd2 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -37,6 +37,7 @@ #include "violite.h" /* vio_is_connected */ #include "thr_lock.h" /* thr_lock_type, THR_LOCK_DATA, THR_LOCK_INFO */ +#include "thr_timer.h" #include <mysql/psi/mysql_stage.h> #include <mysql/psi/mysql_statement.h> #include <mysql/psi/mysql_idle.h> @@ -449,17 +450,19 @@ enum killed_state */ ABORT_QUERY= 6, ABORT_QUERY_HARD= 7, + KILL_TIMEOUT= 8, + KILL_TIMEOUT_HARD= 9, /* All of the following killed states will kill the connection KILL_CONNECTION must be the first of these and it must start with an even number (becasue of HARD bit)! */ - KILL_CONNECTION= 8, - KILL_CONNECTION_HARD= 9, - KILL_SYSTEM_THREAD= 10, - KILL_SYSTEM_THREAD_HARD= 11, - KILL_SERVER= 12, - KILL_SERVER_HARD= 13 + KILL_CONNECTION= 10, + KILL_CONNECTION_HARD= 11, + KILL_SYSTEM_THREAD= 12, + KILL_SYSTEM_THREAD_HARD= 13, + KILL_SERVER= 14, + KILL_SERVER_HARD= 15 }; extern int killed_errno(killed_state killed); @@ -508,6 +511,7 @@ typedef struct system_variables ulonglong max_heap_table_size; ulonglong tmp_table_size; ulonglong long_query_time; + ulonglong max_statement_time; ulonglong optimizer_switch; sql_mode_t sql_mode; ///< which non-standard SQL behaviour should be enabled sql_mode_t old_behavior; ///< which old SQL behaviour should be enabled @@ -644,8 +648,7 @@ typedef struct system_variables my_bool wsrep_causal_reads; uint wsrep_sync_wait; ulong wsrep_retry_autocommit; - - double long_query_time_double; + double long_query_time_double, max_statement_time_double; my_bool pseudo_slave_mode; @@ -734,6 +737,7 @@ typedef struct system_status_var ulong empty_queries; ulong access_denied_errors; ulong lost_connections; + ulong max_statement_time_exceeded; /* Number of statements sent from the client */ @@ -3282,8 +3286,8 @@ public: tests fail and so force them to propagate the lex->binlog_row_based_if_mixed upwards to the caller. */ - if ((WSREP_FORMAT(variables.binlog_format) == BINLOG_FORMAT_MIXED) && - (in_sub_stmt == 0)) + if ((WSREP_FORMAT((enum enum_binlog_format) variables.binlog_format) == + BINLOG_FORMAT_MIXED) && (in_sub_stmt == 0)) set_current_stmt_binlog_format_row(); DBUG_VOID_RETURN; @@ -3334,7 +3338,8 @@ public: show_system_thread(system_thread))); if (in_sub_stmt == 0) { - if (WSREP_FORMAT(variables.binlog_format) == BINLOG_FORMAT_ROW) + if (WSREP_FORMAT((enum enum_binlog_format) variables.binlog_format) == + BINLOG_FORMAT_ROW) set_current_stmt_binlog_format_row(); else if (temporary_tables == NULL) set_current_stmt_binlog_format_stmt(); @@ -3722,8 +3727,8 @@ public: mysql_mutex_t LOCK_wakeup_ready; mysql_cond_t COND_wakeup_ready; /* - The GTID assigned to the last commit. If no GTID was assigned to any commit - so far, this is indicated by last_commit_gtid.seq_no == 0. + The GTID assigned to the last commit. If no GTID was assigned to any commit + so far, this is indicated by last_commit_gtid.seq_no == 0. */ rpl_gtid last_commit_gtid; @@ -3758,27 +3763,55 @@ public: mysql_cond_t COND_wsrep_thd; wsrep_trx_meta_t wsrep_trx_meta; uint32 wsrep_rand; - Relay_log_info* wsrep_rli; - rpl_group_info* wsrep_rgi; + Relay_log_info *wsrep_rli; + rpl_group_info *wsrep_rgi; wsrep_ws_handle_t wsrep_ws_handle; ulong wsrep_retry_counter; // of autocommit - char* wsrep_retry_query; + char *wsrep_retry_query; size_t wsrep_retry_query_len; enum enum_server_command wsrep_retry_command; enum wsrep_consistency_check_mode wsrep_consistency_check; int wsrep_mysql_replicated; - const char* wsrep_TOI_pre_query; /* a query to apply before - the actual TOI query */ + const char *wsrep_TOI_pre_query; /* a query to apply before + the actual TOI query */ size_t wsrep_TOI_pre_query_len; wsrep_po_handle_t wsrep_po_handle; size_t wsrep_po_cnt; #ifdef GTID_SUPPORT rpl_sid wsrep_po_sid; #endif /* GTID_SUPPORT */ - void* wsrep_apply_format; + void *wsrep_apply_format; char wsrep_info[128]; /* string for dynamic proc info */ #endif /* WITH_WSREP */ + + /* Handling of timeouts for commands */ + thr_timer_t query_timer; +public: + void set_query_timer() + { +#ifndef EMBEDDED_LIBRARY + /* + Don't start a query timer if + - If timeouts are not set + - if we are in a stored procedure or sub statement + - If this is a slave thread + - If we already have set a timeout (happens when running prepared + statements that calls mysql_execute_command()) + */ + if (!variables.max_statement_time || spcont || in_sub_stmt || + slave_thread || query_timer.expired == 0) + return; + thr_timer_settime(&query_timer, variables.max_statement_time); +#endif + } + void reset_query_timer() + { +#ifndef EMBEDDED_LIBRARY + if (!query_timer.expired) + thr_timer_end(&query_timer); +#endif + } }; diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc index 0065edcc14d..89a90f41697 100644 --- a/sql/sql_connect.cc +++ b/sql/sql_connect.cc @@ -101,7 +101,6 @@ int get_or_create_user_conn(THD *thd, const char *user, end: mysql_mutex_unlock(&LOCK_user_conn); return return_val; - } @@ -437,6 +436,7 @@ void init_user_stats(USER_STATS *user_stats, ulonglong rollback_trans, ulonglong denied_connections, ulonglong lost_connections, + ulonglong max_statement_time_exceeded, ulonglong access_denied_errors, ulonglong empty_queries) { @@ -467,6 +467,7 @@ void init_user_stats(USER_STATS *user_stats, user_stats->rollback_trans= rollback_trans; user_stats->denied_connections= denied_connections; user_stats->lost_connections= lost_connections; + user_stats->max_statement_time_exceeded= max_statement_time_exceeded; user_stats->access_denied_errors= access_denied_errors; user_stats->empty_queries= empty_queries; DBUG_VOID_RETURN; @@ -496,6 +497,7 @@ void add_user_stats(USER_STATS *user_stats, ulonglong rollback_trans, ulonglong denied_connections, ulonglong lost_connections, + ulonglong max_statement_time_exceeded, ulonglong access_denied_errors, ulonglong empty_queries) { @@ -519,6 +521,7 @@ void add_user_stats(USER_STATS *user_stats, user_stats->rollback_trans+= rollback_trans; user_stats->denied_connections+= denied_connections; user_stats->lost_connections+= lost_connections; + user_stats->max_statement_time_exceeded+= max_statement_time_exceeded; user_stats->access_denied_errors+= access_denied_errors; user_stats->empty_queries+= empty_queries; } @@ -644,6 +647,7 @@ static bool increment_count_by_name(const char *name, size_t name_length, 0, 0, // commit and rollback trans thd->status_var.access_denied_errors, 0, // lost connections + 0, // max query timeouts 0, // access denied errors 0); // empty queries @@ -756,6 +760,7 @@ static void update_global_user_stats_with_user(THD *thd, /* The following can only contain 0 or 1 and then connection ends */ user_stats->denied_connections+= thd->status_var.access_denied_errors; user_stats->lost_connections+= thd->status_var.lost_connections; + user_stats->max_statement_time_exceeded+= thd->status_var.max_statement_time_exceeded; } diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 6aa76ebf9c7..0788c233508 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2697,6 +2697,9 @@ mysql_execute_command(THD *thd) goto error; } + /* Start timeouts */ + thd->set_query_timer(); + switch (lex->sql_command) { case SQLCOM_SHOW_EVENTS: @@ -2778,10 +2781,9 @@ mysql_execute_command(THD *thd) else res= check_access(thd, privileges_requested, any_db, NULL, NULL, 0, 0); - if (res) - break; + if (!res) + res= execute_sqlcom_select(thd, all_tables); - res= execute_sqlcom_select(thd, all_tables); break; } case SQLCOM_PREPARE: @@ -3132,7 +3134,7 @@ mysql_execute_command(THD *thd) */ if (thd->query_name_consts && mysql_bin_log.is_open() && - WSREP_FORMAT(thd->variables.binlog_format) == BINLOG_FORMAT_STMT && + WSREP_FORMAT((enum enum_binlog_format) thd->variables.binlog_format) == BINLOG_FORMAT_STMT && !mysql_bin_log.is_query_in_union(thd, thd->query_id)) { List_iterator_fast<Item> it(select_lex->item_list); @@ -5492,6 +5494,7 @@ error: finish: + thd->reset_query_timer(); DBUG_ASSERT(!thd->in_active_multi_stmt_transaction() || thd->in_multi_stmt_transaction_mode()); diff --git a/sql/sql_show.cc b/sql/sql_show.cc index ec7d4979a4e..a5c305f9448 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -3198,6 +3198,7 @@ static int aggregate_user_stats(HASH *all_user_stats, HASH *agg_user_stats) user->other_commands, user->commit_trans, user->rollback_trans, user->denied_connections, user->lost_connections, + user->max_statement_time_exceeded, user->access_denied_errors, user->empty_queries); if (my_hash_insert(agg_user_stats, (uchar*) agg_user)) @@ -3223,6 +3224,7 @@ static int aggregate_user_stats(HASH *all_user_stats, HASH *agg_user_stats) user->other_commands, user->commit_trans, user->rollback_trans, user->denied_connections, user->lost_connections, + user->max_statement_time_exceeded, user->access_denied_errors, user->empty_queries); } } @@ -3278,6 +3280,7 @@ int send_user_stats(THD* thd, HASH *all_user_stats, TABLE *table) table->field[j++]->store((longlong)user_stats->lost_connections, TRUE); table->field[j++]->store((longlong)user_stats->access_denied_errors, TRUE); table->field[j++]->store((longlong)user_stats->empty_queries, TRUE); + table->field[j++]->store((longlong)user_stats->max_statement_time_exceeded, TRUE); if (schema_table_store_record(thd, table)) { DBUG_PRINT("error", ("store record error")); @@ -7410,6 +7413,7 @@ ST_FIELD_INFO user_stats_fields_info[]= {"LOST_CONNECTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, 0, "Lost_connections",SKIP_OPEN_TABLE}, {"ACCESS_DENIED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, 0, "Access_denied",SKIP_OPEN_TABLE}, {"EMPTY_QUERIES", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, 0, "Empty_queries",SKIP_OPEN_TABLE}, + {"MAX_STATEMENT_TIME_EXCEEDED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, 0, "Max_statement_time_exceeded",SKIP_OPEN_TABLE}, {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, 0} }; @@ -7438,6 +7442,7 @@ ST_FIELD_INFO client_stats_fields_info[]= {"LOST_CONNECTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, 0, "Lost_connections",SKIP_OPEN_TABLE}, {"ACCESS_DENIED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, 0, "Access_denied",SKIP_OPEN_TABLE}, {"EMPTY_QUERIES", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, 0, "Empty_queries",SKIP_OPEN_TABLE}, + {"MAX_STATEMENT_TIME_EXCEEDED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, 0, "Max_statement_time_exceeded",SKIP_OPEN_TABLE}, {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, 0} }; diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 78a0eff935a..df9c59e5deb 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1304,6 +1304,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token MAX_SIZE_SYM %token MAX_SYM /* SQL-2003-N */ %token MAX_UPDATES_PER_HOUR +%token MAX_STATEMENT_TIME_SYM %token MAX_USER_CONNECTIONS_SYM %token MAX_VALUE_SYM /* SQL-2003-N */ %token MEDIUMBLOB @@ -14266,6 +14267,7 @@ keyword_sp: | MAX_CONNECTIONS_PER_HOUR {} | MAX_QUERIES_PER_HOUR {} | MAX_SIZE_SYM {} + | MAX_STATEMENT_TIME_SYM {} | MAX_UPDATES_PER_HOUR {} | MAX_USER_CONNECTIONS_SYM {} | MEDIUM_SYM {} @@ -15620,6 +15622,12 @@ grant_option: lex->mqh.user_conn= $2; lex->mqh.specified_limits|= USER_RESOURCES::USER_CONNECTIONS; } + | MAX_STATEMENT_TIME_SYM NUM_literal + { + LEX *lex=Lex; + lex->mqh.max_statement_time= $2->val_real(); + lex->mqh.specified_limits|= USER_RESOURCES::MAX_STATEMENT_TIME; + } ; begin: diff --git a/sql/structs.h b/sql/structs.h index da8d4beb754..d02301e4350 100644 --- a/sql/structs.h +++ b/sql/structs.h @@ -232,12 +232,15 @@ typedef struct user_resources { connections allowed */ int user_conn; + /* Max query timeout */ + double max_statement_time; + /* Values of this enum and specified_limits member are used by the parser to store which user limits were specified in GRANT statement. */ enum {QUERIES_PER_HOUR= 1, UPDATES_PER_HOUR= 2, CONNECTIONS_PER_HOUR= 4, - USER_CONNECTIONS= 8}; + USER_CONNECTIONS= 8, MAX_STATEMENT_TIME= 16}; uint specified_limits; } USER_RESOURCES; @@ -293,7 +296,7 @@ typedef struct st_user_stats ha_rows rows_updated, rows_deleted, rows_inserted; ulonglong select_commands, update_commands, other_commands; ulonglong commit_trans, rollback_trans; - ulonglong denied_connections, lost_connections; + ulonglong denied_connections, lost_connections, max_statement_time_exceeded; ulonglong access_denied_errors; ulonglong empty_queries; } USER_STATS; @@ -331,6 +334,7 @@ init_user_stats(USER_STATS *user_stats, ulonglong rollback_trans, ulonglong denied_connections, ulonglong lost_connections, + ulonglong max_statement_time_exceeded, ulonglong access_denied_errors, ulonglong empty_queries); @@ -357,6 +361,7 @@ add_user_stats(USER_STATS *user_stats, ulonglong rollback_trans, ulonglong denied_connections, ulonglong lost_connections, + ulonglong max_statement_time_exceeded, ulonglong access_denied_errors, ulonglong empty_queries); diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index 0fab83be90d..b9304403ee5 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -1176,6 +1176,29 @@ static Sys_var_double Sys_long_query_time( NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0), ON_UPDATE(update_cached_long_query_time)); + +static bool update_cached_max_statement_time(sys_var *self, THD *thd, + enum_var_type type) +{ + if (type == OPT_SESSION) + thd->variables.max_statement_time= + double2ulonglong(thd->variables.max_statement_time_double * 1e6); + else + global_system_variables.max_statement_time= + double2ulonglong(global_system_variables.max_statement_time_double * 1e6); + return false; +} + +static Sys_var_double Sys_max_statement_time( + "max_statement_time", + "A SELECT query that have taken more than max_statement_time seconds " + "will be aborted. The argument will be treated as a decimal value " + "with microsecond precision. A value of 0 (default) means no timeout", + SESSION_VAR(max_statement_time_double), + CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, LONG_TIMEOUT), DEFAULT(0), + NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0), + ON_UPDATE(update_cached_max_statement_time)); + static bool fix_low_prio_updates(sys_var *self, THD *thd, enum_var_type type) { if (type == OPT_SESSION) diff --git a/sql/wsrep_thd.cc b/sql/wsrep_thd.cc index b9ff0ecf8a8..b65eead817d 100644 --- a/sql/wsrep_thd.cc +++ b/sql/wsrep_thd.cc @@ -90,7 +90,7 @@ void wsrep_client_rollback(THD *thd) #define NUMBER_OF_FIELDS_TO_IDENTIFY_WORKER 2 //#include "rpl_info_factory.h" -#if 0 +#ifdef NOT_USED static Relay_log_info* wsrep_relay_log_init(const char* log_fname) { diff --git a/storage/innobase/fil/fil0pagecompress.cc b/storage/innobase/fil/fil0pagecompress.cc index b6eb2e73b30..77efd250fa0 100644 --- a/storage/innobase/fil/fil0pagecompress.cc +++ b/storage/innobase/fil/fil0pagecompress.cc @@ -99,7 +99,6 @@ fil_decompress_page_2( return; } - ulint olen = 0; byte* ptr = buf + FIL_PAGE_DATA; ulint version = mach_read_from_1(buf + FIL_PAGE_VERSION); int err = 0; @@ -206,6 +205,7 @@ fil_decompress_page_2( #ifdef HAVE_LZO case PAGE_LZO_ALGORITHM: { + ulint olen = 0; fprintf(stderr, "InnoDB: [Note]: lzo \n"); err = lzo1x_decompress((const unsigned char *)ptr, original_len,(unsigned char *)(page_buf), &olen, NULL); @@ -493,7 +493,6 @@ fil_decompress_page( ulint actual_size = 0; ulint compression_alg = 0; byte *in_buf; - ulint olen=0; ulint ptype; ut_ad(buf); @@ -607,6 +606,8 @@ fil_decompress_page( #endif /* HAVE_LZ4 */ #ifdef HAVE_LZO case PAGE_LZO_ALGORITHM: + { + ulint olen=0; err = lzo1x_decompress((const unsigned char *)buf+FIL_PAGE_DATA+FIL_PAGE_COMPRESSED_SIZE, actual_size,(unsigned char *)in_buf, &olen, NULL); @@ -621,6 +622,7 @@ fil_decompress_page( ut_error; } break; + } #endif /* HAVE_LZO */ #ifdef HAVE_LZMA case PAGE_LZMA_ALGORITHM: { diff --git a/storage/oqgraph/mysql-test/oqgraph/regression_mdev5996.result b/storage/oqgraph/mysql-test/oqgraph/regression_mdev5996.result index a639a185ec2..39e476b2403 100644 --- a/storage/oqgraph/mysql-test/oqgraph/regression_mdev5996.result +++ b/storage/oqgraph/mysql-test/oqgraph/regression_mdev5996.result @@ -1,3 +1,4 @@ +call mtr.add_suppression("99999999 is open on delete"); Performing OQGraph regression test mdev5996 - using db=``, table=`999999999` use test; drop table if exists `999999999` ; diff --git a/storage/oqgraph/mysql-test/oqgraph/regression_mdev5996.test b/storage/oqgraph/mysql-test/oqgraph/regression_mdev5996.test index e5d04ef357d..cb4563a5759 100644 --- a/storage/oqgraph/mysql-test/oqgraph/regression_mdev5996.test +++ b/storage/oqgraph/mysql-test/oqgraph/regression_mdev5996.test @@ -2,6 +2,8 @@ # MidSchipDB_unstable --let $oqgraph_table_name= 999999999 +call mtr.add_suppression("99999999 is open on delete"); + --let $oqgraph_database_name= --source regression_mdev5996.inc diff --git a/storage/xtradb/fil/fil0pagecompress.cc b/storage/xtradb/fil/fil0pagecompress.cc index e92f3587236..d7bc0ff62e7 100644 --- a/storage/xtradb/fil/fil0pagecompress.cc +++ b/storage/xtradb/fil/fil0pagecompress.cc @@ -99,7 +99,6 @@ fil_decompress_page_2( return; } - ulint olen = 0; byte* ptr = buf + FIL_PAGE_DATA; ulint version = mach_read_from_1(buf + FIL_PAGE_VERSION); int err = 0; @@ -206,6 +205,7 @@ fil_decompress_page_2( #ifdef HAVE_LZO case PAGE_LZO_ALGORITHM: { + ulint olen = 0; fprintf(stderr, "InnoDB: [Note]: lzo \n"); err = lzo1x_decompress((const unsigned char *)ptr, original_len,(unsigned char *)(page_buf), &olen, NULL); @@ -490,7 +490,6 @@ fil_decompress_page( ulint actual_size = 0; ulint compression_alg = 0; byte *in_buf; - ulint olen=0; ulint ptype; ut_ad(buf); @@ -603,7 +602,8 @@ fil_decompress_page( break; #endif /* HAVE_LZ4 */ #ifdef HAVE_LZO - case PAGE_LZO_ALGORITHM: + case PAGE_LZO_ALGORITHM: { + ulint olen=0; err = lzo1x_decompress((const unsigned char *)buf+FIL_PAGE_DATA+FIL_PAGE_COMPRESSED_SIZE, actual_size,(unsigned char *)in_buf, &olen, NULL); @@ -618,6 +618,7 @@ fil_decompress_page( ut_error; } break; + } #endif /* HAVE_LZO */ #ifdef HAVE_LZMA case PAGE_LZMA_ALGORITHM: { diff --git a/storage/xtradb/os/os0file.cc b/storage/xtradb/os/os0file.cc index d67573d14aa..a7a5d5f32c0 100644 --- a/storage/xtradb/os/os0file.cc +++ b/storage/xtradb/os/os0file.cc @@ -6404,7 +6404,7 @@ os_file_trim( #define SECT_SIZE 512 size_t trim_len = UNIV_PAGE_SIZE - len; - os_offset_t off = slot->offset + len; + os_offset_t off __attribute__((unused)) = slot->offset + len; // len here should be alligned to sector size ut_a((trim_len % SECT_SIZE) == 0); ut_a((len % SECT_SIZE) == 0); |