diff options
author | unknown <konstantin@mysql.com> | 2006-04-07 23:37:06 +0400 |
---|---|---|
committer | unknown <konstantin@mysql.com> | 2006-04-07 23:37:06 +0400 |
commit | 5b5530daa5c0f5fb20121ab9ce5a159fce900101 (patch) | |
tree | 8f4f2952727fffa7429bb8deb43a9a72dc7bf4e0 /mysql-test/r/ps.result | |
parent | 5aa14b983277d45ca55bea8f5fcdf5229f054bec (diff) | |
download | mariadb-git-5b5530daa5c0f5fb20121ab9ce5a159fce900101.tar.gz |
A fix and a test case for Bug#16365 "Prepared Statements: DoS with
too many open statements". The patch adds a new global variable
@@max_prepared_stmt_count. This variable limits the total number
of prepared statements in the server. The default value of
@@max_prepared_stmt_count is 16382. 16382 small statements
(a select against 3 tables with GROUP, ORDER and LIMIT) consume
100MB of RAM. Once this limit has been reached, the server will
refuse to prepare a new statement and return ER_UNKNOWN_ERROR
(unfortunately, we can't add new errors to 4.1 without breaking 5.0). The limit is changeable after startup
and can accept any value from 0 to 1 million. In case
the new value of the limit is less than the current
statement count, no new statements can be added, while the old
still can be used. Additionally, the current count of prepared
statements is now available through a global read-only variable
@@prepared_stmt_count.
mysql-test/r/ps.result:
Test results fixed (a test case for Bug#16365)
mysql-test/t/ps.test:
A test case for Bug#16365 "Prepared Statements: DoS with too many
open statements". Also fix statement leaks in other tests.
sql/mysql_priv.h:
Add declarations for new global variables.
sql/mysqld.cc:
Add definitions of max_prepared_stmt_count, prepared_stmt_count.
sql/set_var.cc:
Implement support for @@prepared_stmt_count and
@@max_prepared_stmt_count. Currently these variables are queried
without acquiring LOCK_prepared_stmt_count due to limitations of
the set_var/sys_var class design. Updates are, however, protected
with a lock.
sql/set_var.h:
New declarations to add support for @@max_prepared_stmt_count.
Implement a new class, where the lock to be used when updating
a variable is a parameter.
sql/sql_class.cc:
Add accounting of the total number of prepared statements in the
server to the methods of Statement_map.
sql/sql_class.h:
Add accounting of the total number of prepared statements in the
server to the methods of Statement_map.
sql/sql_prepare.cc:
Statement_map::insert will now send a message in case of an
error.
Diffstat (limited to 'mysql-test/r/ps.result')
-rw-r--r-- | mysql-test/r/ps.result | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result index e94c2952893..f9ecd28fb32 100644 --- a/mysql-test/r/ps.result +++ b/mysql-test/r/ps.result @@ -107,6 +107,9 @@ set @fvar= 123.4567; prepare stmt1 from @fvar; ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '123.4567' at line 1 drop table t1,t2; +deallocate prepare stmt3; +deallocate prepare stmt4; +deallocate prepare stmt5; PREPARE stmt1 FROM "select _utf8 'A' collate utf8_bin = ?"; set @var='A'; EXECUTE stmt1 USING @var; @@ -252,6 +255,7 @@ set names latin1; execute `ü`; 1234 1234 +deallocate prepare `ü`; set names default; create table t1 (a varchar(10)) charset=utf8; insert into t1 (a) values ('yahoo'); @@ -747,3 +751,107 @@ length(a) 10 drop table t1; deallocate prepare stmt; +set @old_max_prepared_stmt_count= @@max_prepared_stmt_count; +show variables like 'max_prepared_stmt_count'; +Variable_name Value +max_prepared_stmt_count 16382 +show variables like 'prepared_stmt_count'; +Variable_name Value +prepared_stmt_count 0 +select @@max_prepared_stmt_count, @@prepared_stmt_count; +@@max_prepared_stmt_count @@prepared_stmt_count +16382 0 +set global max_prepared_stmt_count=-1; +select @@max_prepared_stmt_count; +@@max_prepared_stmt_count +0 +set global max_prepared_stmt_count=10000000000000000; +select @@max_prepared_stmt_count; +@@max_prepared_stmt_count +1048576 +set global max_prepared_stmt_count=default; +select @@max_prepared_stmt_count; +@@max_prepared_stmt_count +16382 +set @@max_prepared_stmt_count=1; +ERROR HY000: Variable 'max_prepared_stmt_count' is a GLOBAL variable and should be set with SET GLOBAL +set max_prepared_stmt_count=1; +ERROR HY000: Variable 'max_prepared_stmt_count' is a GLOBAL variable and should be set with SET GLOBAL +set local max_prepared_stmt_count=1; +ERROR HY000: Variable 'max_prepared_stmt_count' is a GLOBAL variable and should be set with SET GLOBAL +set local prepared_stmt_count=0; +ERROR HY000: Variable 'prepared_stmt_count' is a GLOBAL variable and should be set with SET GLOBAL +set @@prepared_stmt_count=0; +ERROR HY000: Variable 'prepared_stmt_count' is a GLOBAL variable and should be set with SET GLOBAL +set global prepared_stmt_count=1; +ERROR 42000: Incorrect argument type to variable 'prepared_stmt_count' +set global max_prepared_stmt_count=1; +select @@max_prepared_stmt_count; +@@max_prepared_stmt_count +1 +set global max_prepared_stmt_count=0; +select @@max_prepared_stmt_count, @@prepared_stmt_count; +@@max_prepared_stmt_count @@prepared_stmt_count +0 0 +prepare stmt from "select 1"; +ERROR HY000: Unknown error +select @@prepared_stmt_count; +@@prepared_stmt_count +0 +set global max_prepared_stmt_count=1; +prepare stmt from "select 1"; +select @@prepared_stmt_count; +@@prepared_stmt_count +1 +prepare stmt1 from "select 1"; +ERROR HY000: Unknown error +select @@prepared_stmt_count; +@@prepared_stmt_count +1 +deallocate prepare stmt; +select @@prepared_stmt_count; +@@prepared_stmt_count +0 +prepare stmt from "select 1"; +select @@prepared_stmt_count; +@@prepared_stmt_count +1 +prepare stmt from "select 2"; +select @@prepared_stmt_count; +@@prepared_stmt_count +1 +select @@prepared_stmt_count, @@max_prepared_stmt_count; +@@prepared_stmt_count @@max_prepared_stmt_count +1 1 +set global max_prepared_stmt_count=0; +prepare stmt from "select 1"; +ERROR HY000: Unknown error +execute stmt; +ERROR HY000: Unknown prepared statement handler (stmt) given to EXECUTE +select @@prepared_stmt_count; +@@prepared_stmt_count +0 +prepare stmt from "select 1"; +ERROR HY000: Unknown error +select @@prepared_stmt_count; +@@prepared_stmt_count +0 +set global max_prepared_stmt_count=3; +select @@max_prepared_stmt_count, @@prepared_stmt_count; +@@max_prepared_stmt_count @@prepared_stmt_count +3 0 +prepare stmt from "select 1"; +prepare stmt from "select 2"; +prepare stmt1 from "select 3"; +prepare stmt2 from "select 4"; +ERROR HY000: Unknown error +prepare stmt2 from "select 4"; +ERROR HY000: Unknown error +select @@max_prepared_stmt_count, @@prepared_stmt_count; +@@max_prepared_stmt_count @@prepared_stmt_count +3 3 +deallocate prepare stmt; +select @@max_prepared_stmt_count, @@prepared_stmt_count; +@@max_prepared_stmt_count @@prepared_stmt_count +3 0 +set global max_prepared_stmt_count= @old_max_prepared_stmt_count; |