diff options
-rw-r--r-- | mysql-test/r/mysqld--help-notwin.result | 4 | ||||
-rw-r--r-- | mysql-test/r/mysqld--help-win.result | 4 | ||||
-rw-r--r-- | mysql-test/suite/sys_vars/r/stored_program_cache_basic.result | 59 | ||||
-rw-r--r-- | mysql-test/suite/sys_vars/t/stored_program_cache_basic.test | 59 | ||||
-rw-r--r-- | sql/mysqld.cc | 5 | ||||
-rw-r--r-- | sql/mysqld.h | 1 | ||||
-rw-r--r-- | sql/sp_cache.cc | 29 | ||||
-rw-r--r-- | sql/sp_cache.h | 1 | ||||
-rw-r--r-- | sql/sql_parse.cc | 2 | ||||
-rw-r--r-- | sql/sql_prepare.cc | 6 | ||||
-rw-r--r-- | sql/sys_vars.cc | 7 |
11 files changed, 177 insertions, 0 deletions
diff --git a/mysql-test/r/mysqld--help-notwin.result b/mysql-test/r/mysqld--help-notwin.result index cb727984ec0..8dacb035f36 100644 --- a/mysql-test/r/mysqld--help-notwin.result +++ b/mysql-test/r/mysqld--help-notwin.result @@ -671,6 +671,9 @@ The following options may be given as the first argument: replication. --sql-mode=name Syntax: sql-mode=mode[,mode[,mode...]]. See the manual for the complete list of valid sql modes + --stored-program-cache=# + The soft upper limit for number of cached stored routines + for one connection. -s, --symbolic-links Enable symbolic link support. --sync-binlog=# Synchronously flush binary log to disk after every #th @@ -935,6 +938,7 @@ slow-query-log FALSE sort-buffer-size 2097152 sporadic-binlog-dump-fail FALSE sql-mode +stored-program-cache 256 symbolic-links FALSE sync-binlog 0 sync-frm TRUE diff --git a/mysql-test/r/mysqld--help-win.result b/mysql-test/r/mysqld--help-win.result index 2ef52355f90..1e7e877e29f 100644 --- a/mysql-test/r/mysqld--help-win.result +++ b/mysql-test/r/mysqld--help-win.result @@ -679,6 +679,9 @@ The following options may be given as the first argument: --sql-mode=name Syntax: sql-mode=mode[,mode[,mode...]]. See the manual for the complete list of valid sql modes --standalone Dummy option to start as a standalone program (NT). + --stored-program-cache=# + The soft upper limit for number of cached stored routines + for one connection. -s, --symbolic-links Enable symbolic link support. --sync-binlog=# Synchronously flush binary log to disk after every #th @@ -946,6 +949,7 @@ slow-start-timeout 15000 sort-buffer-size 2097152 sporadic-binlog-dump-fail FALSE sql-mode +stored-program-cache 256 symbolic-links FALSE sync-binlog 0 sync-frm TRUE diff --git a/mysql-test/suite/sys_vars/r/stored_program_cache_basic.result b/mysql-test/suite/sys_vars/r/stored_program_cache_basic.result new file mode 100644 index 00000000000..f1638520f72 --- /dev/null +++ b/mysql-test/suite/sys_vars/r/stored_program_cache_basic.result @@ -0,0 +1,59 @@ +# Saving initial value of stored_program_cache in a temporary variable +SET @start_value = @@global.stored_program_cache; +SELECT @start_value; +@start_value +256 +# Display the DEFAULT value of stored_program_cache +SET @@global.stored_program_cache = DEFAULT; +SELECT @@global.stored_program_cache; +@@global.stored_program_cache +256 +# Verify default value of variable +SELECT @@global.stored_program_cache = 256; +@@global.stored_program_cache = 256 +1 +# Change the value of stored_program_cache to a valid value +SET @@global.stored_program_cache = 512; +SELECT @@global.stored_program_cache; +@@global.stored_program_cache +512 +# Change the value of stored_program_cache to invalid value +SET @@global.stored_program_cache = -1; +Warnings: +Warning 1292 Truncated incorrect stored_program_cache value: '-1' +SELECT @@global.stored_program_cache; +@@global.stored_program_cache +256 +SET @@global.stored_program_cache =100000000000; +Warnings: +Warning 1292 Truncated incorrect stored_program_cache value: '100000000000' +SELECT @@global.stored_program_cache; +@@global.stored_program_cache +524288 +SET @@global.stored_program_cache = 0; +Warnings: +Warning 1292 Truncated incorrect stored_program_cache value: '0' +SELECT @@global.stored_program_cache; +@@global.stored_program_cache +256 +SET @@global.stored_program_cache = 10000.01; +ERROR 42000: Incorrect argument type to variable 'stored_program_cache' +SET @@global.stored_program_cache = ON; +ERROR 42000: Incorrect argument type to variable 'stored_program_cache' +SET @@global.stored_program_cache= 'test'; +ERROR 42000: Incorrect argument type to variable 'stored_program_cache' +SET @@global.stored_program_cache = ''; +ERROR 42000: Incorrect argument type to variable 'stored_program_cache' +# Test if accessing session stored_program_cache gives error +SET @@session.stored_program_cache = 0; +ERROR HY000: Variable 'stored_program_cache' is a GLOBAL variable and should be set with SET GLOBAL +# Check if accessing variable without SCOPE points to same global variable +SET @@global.stored_program_cache = 512; +SELECT @@stored_program_cache = @@global.stored_program_cache; +@@stored_program_cache = @@global.stored_program_cache +1 +# Restore initial value +SET @@global.stored_program_cache = @start_value; +SELECT @@global.stored_program_cache; +@@global.stored_program_cache +256 diff --git a/mysql-test/suite/sys_vars/t/stored_program_cache_basic.test b/mysql-test/suite/sys_vars/t/stored_program_cache_basic.test new file mode 100644 index 00000000000..9a9ba2ebf81 --- /dev/null +++ b/mysql-test/suite/sys_vars/t/stored_program_cache_basic.test @@ -0,0 +1,59 @@ +# Variable Name: stored_program_cache +# Scope: GLOBAL +# Access Type: Dynamic +# Data Type: numeric +# Default Value: 256 +# Range: 256-524288 + +--source include/load_sysvars.inc + +--echo # Saving initial value of stored_program_cache in a temporary variable +SET @start_value = @@global.stored_program_cache; +SELECT @start_value; + +--echo # Display the DEFAULT value of stored_program_cache +SET @@global.stored_program_cache = DEFAULT; +SELECT @@global.stored_program_cache; + +--echo # Verify default value of variable +SELECT @@global.stored_program_cache = 256; + +--echo # Change the value of stored_program_cache to a valid value +SET @@global.stored_program_cache = 512; +SELECT @@global.stored_program_cache; + +--echo # Change the value of stored_program_cache to invalid value +SET @@global.stored_program_cache = -1; +SELECT @@global.stored_program_cache; + +SET @@global.stored_program_cache =100000000000; +SELECT @@global.stored_program_cache; + +SET @@global.stored_program_cache = 0; +SELECT @@global.stored_program_cache; + +--Error ER_WRONG_TYPE_FOR_VAR +SET @@global.stored_program_cache = 10000.01; + +--Error ER_WRONG_TYPE_FOR_VAR +SET @@global.stored_program_cache = ON; +--Error ER_WRONG_TYPE_FOR_VAR +SET @@global.stored_program_cache= 'test'; + +--Error ER_WRONG_TYPE_FOR_VAR +SET @@global.stored_program_cache = ''; + +--echo # Test if accessing session stored_program_cache gives error + +--Error ER_GLOBAL_VARIABLE +SET @@session.stored_program_cache = 0; + +--echo # Check if accessing variable without SCOPE points to same global variable + +SET @@global.stored_program_cache = 512; +SELECT @@stored_program_cache = @@global.stored_program_cache; + +--echo # Restore initial value + +SET @@global.stored_program_cache = @start_value; +SELECT @@global.stored_program_cache; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 74c5c23aaa2..5e347959d9b 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -511,6 +511,11 @@ uint sync_binlog_period= 0, sync_relaylog_period= 0, sync_relayloginfo_period= 0, sync_masterinfo_period= 0; ulong expire_logs_days = 0; ulong rpl_recovery_rank=0; +/** + Soft upper limit for number of sp_head objects that can be stored + in the sp_cache for one connection. +*/ +ulong stored_program_cache_size= 0; const double log_10[] = { 1e000, 1e001, 1e002, 1e003, 1e004, 1e005, 1e006, 1e007, 1e008, 1e009, diff --git a/sql/mysqld.h b/sql/mysqld.h index eb885417da3..67e39b6a46b 100644 --- a/sql/mysqld.h +++ b/sql/mysqld.h @@ -181,6 +181,7 @@ extern ulonglong max_binlog_cache_size, max_binlog_stmt_cache_size; extern ulong max_binlog_size, max_relay_log_size; extern ulong opt_binlog_rows_event_max_size; extern ulong rpl_recovery_rank, thread_cache_size; +extern ulong stored_program_cache_size; extern ulong back_log; extern char language[FN_REFLEN]; extern "C" MYSQL_PLUGIN_IMPORT ulong server_id; diff --git a/sql/sp_cache.cc b/sql/sp_cache.cc index 8972303ef03..d6445799a36 100644 --- a/sql/sp_cache.cc +++ b/sql/sp_cache.cc @@ -57,6 +57,20 @@ public: { my_hash_delete(&m_hashtable, (uchar *)sp); } + + /** + Remove all elements from a stored routine cache if the current + number of elements exceeds the argument value. + + @param[in] upper_limit_for_elements Soft upper limit of elements that + can be stored in the cache. + */ + void enforce_limit(ulong upper_limit_for_elements) + { + if (m_hashtable.records > upper_limit_for_elements) + my_hash_reset(&m_hashtable); + } + private: void init(); void cleanup(); @@ -228,6 +242,21 @@ ulong sp_cache_version() } +/** + Enforce that the current number of elements in the cache don't exceed + the argument value by flushing the cache if necessary. + + @param[in] c Cache to check + @param[in] upper_limit_for_elements Soft upper limit for number of sp_head + objects that can be stored in the cache. +*/ +void +sp_cache_enforce_limit(sp_cache *c, ulong upper_limit_for_elements) +{ + if (c) + c->enforce_limit(upper_limit_for_elements); +} + /************************************************************************* Internal functions *************************************************************************/ diff --git a/sql/sp_cache.h b/sql/sp_cache.h index 39448568a76..db70066587a 100644 --- a/sql/sp_cache.h +++ b/sql/sp_cache.h @@ -62,5 +62,6 @@ sp_head *sp_cache_lookup(sp_cache **cp, sp_name *name); void sp_cache_invalidate(); void sp_cache_flush_obsolete(sp_cache **cp, sp_head **sp); ulong sp_cache_version(); +void sp_cache_enforce_limit(sp_cache *cp, ulong upper_limit_for_elements); #endif /* _SP_CACHE_H_ */ diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 32ccb8f2c5f..a5d23858a8d 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -5632,6 +5632,8 @@ void mysql_parse(THD *thd, char *rawbuf, uint length, query_cache_abort(&thd->query_cache_tls); } thd_proc_info(thd, "freeing items"); + sp_cache_enforce_limit(thd->sp_proc_cache, stored_program_cache_size); + sp_cache_enforce_limit(thd->sp_func_cache, stored_program_cache_size); thd->end_statement(); thd->cleanup_after_query(); DBUG_ASSERT(thd->change_list.is_empty()); diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 48b6886f6f2..cfdf7d27e58 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -2195,6 +2195,9 @@ void mysqld_stmt_prepare(THD *thd, const char *packet, uint packet_length) thd->protocol= save_protocol; + sp_cache_enforce_limit(thd->sp_proc_cache, stored_program_cache_size); + sp_cache_enforce_limit(thd->sp_func_cache, stored_program_cache_size); + /* check_prepared_statemnt sends the metadata packet in case of success */ DBUG_VOID_RETURN; } @@ -2560,6 +2563,9 @@ void mysqld_stmt_execute(THD *thd, char *packet_arg, uint packet_length) stmt->execute_loop(&expanded_query, open_cursor, packet, packet_end); thd->protocol= save_protocol; + sp_cache_enforce_limit(thd->sp_proc_cache, stored_program_cache_size); + sp_cache_enforce_limit(thd->sp_func_cache, stored_program_cache_size); + /* Close connection socket; for use with client testing (Bug#43560). */ DBUG_EXECUTE_IF("close_conn_after_stmt_execute", vio_close(thd->net.vio);); diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index f5a9ab3b55c..b640bdba491 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -3253,6 +3253,13 @@ static Sys_var_tz Sys_time_zone( SESSION_VAR(time_zone), NO_CMD_LINE, DEFAULT(&default_tz), NO_MUTEX_GUARD, IN_BINLOG); +static Sys_var_ulong Sys_sp_cache_size( + "stored_program_cache", + "The soft upper limit for number of cached stored routines for " + "one connection.", + GLOBAL_VAR(stored_program_cache_size), CMD_LINE(REQUIRED_ARG), + VALID_RANGE(256, 512 * 1024), DEFAULT(256), BLOCK_SIZE(1)); + /**************************************************************************** Used templates |