List:Commits« Previous MessageNext Message »
From:Dmitry Lenev Date:May 12 2012 2:54pm
Subject:bzr push into mysql-trunk branch (Dmitry.Lenev:3892 to 3893) WL#5772
View as plain text  
 3893 Dmitry Lenev	2012-05-12
      WL#5772 "Add partitioned Table Definition Cache to avoid
      using LOCK_open and its derivatives in DML queries".
      
      Review changes #5:
      - Made status variables for table cache visible in SHOW STATUS.
      - Added test coverage for them.
      - Fixed setting of @@table_open_cache size at runtime.

    modified:
      mysql-test/r/status.result
      mysql-test/t/status.test
      sql/mysqld.cc
      sql/sys_vars.cc
 3892 Dmitry Lenev	2012-05-11
      WL#5772 "Add partitioned Table Definition Cache to avoid
      using LOCK_open and its derivatives in DML queries".
      
      Review changes #4:
      - Make Table_cache API object-oriented.
      - Get rid of hash look-ups when iterating over
        all used TABLE instances for the TABLE_SHARE.
      - Improve comments.

    modified:
      sql/mysqld.cc
      sql/sql_base.cc
      sql/sql_base.h
      sql/sql_const.h
      sql/sql_handler.cc
      sql/sql_parse.cc
      sql/sql_table.cc
      sql/sql_test.cc
      sql/sys_vars.cc
      sql/table.cc
      sql/table.h
=== modified file 'mysql-test/r/status.result'
--- a/mysql-test/r/status.result	2012-03-06 14:29:42 +0000
+++ b/mysql-test/r/status.result	2012-05-12 14:54:12 +0000
@@ -238,5 +238,104 @@ SELECT 9;
 9
 DROP PROCEDURE p1;
 DROP FUNCTION f1;
+#
+# Test coverage for status variables which were introduced by
+# WL#5772 "Add partitioned Table Definition Cache to avoid
+# using LOCK_open and its derivatives in DML queries".
+#
+create table t1 (i int);
+create table t2 (j int);
+create table t3 (k int);
+# Flush table cache to ensure that it is empty and reset status
+# variables. Since to test cache overflow we will need to reduce
+# its size, also save original table cache size.
+flush tables;
+flush status;
+set @old_table_open_cache= @@table_open_cache;
+# Check that after reset all status variables are zero.
+show status like 'table_open_cache_%';
+Variable_name	Value
+Table_open_cache_hits	0
+Table_open_cache_misses	0
+Table_open_cache_overflows	0
+# The first statement accessing t1 after flush should result
+# in table cache miss.
+select * from t1;
+i
+show status like 'table_open_cache_%';
+Variable_name	Value
+Table_open_cache_hits	0
+Table_open_cache_misses	1
+Table_open_cache_overflows	0
+# The second statement accessing the same table should
+# result in table cache hit.
+select * from t1;
+i
+show status like 'table_open_cache_%';
+Variable_name	Value
+Table_open_cache_hits	1
+Table_open_cache_misses	1
+Table_open_cache_overflows	0
+# Again table cache miss if accessing different table.
+select * from t2;
+j
+show status like 'table_open_cache_%';
+Variable_name	Value
+Table_open_cache_hits	1
+Table_open_cache_misses	2
+Table_open_cache_overflows	0
+# And cache hit then accessing it second time.
+select * from t2;
+j
+show status like 'table_open_cache_%';
+Variable_name	Value
+Table_open_cache_hits	2
+Table_open_cache_misses	2
+Table_open_cache_overflows	0
+# The below statement should result in 2 cache hits and 
+# 4 cache misses since it needs 6 table instances in total.
+select * from t1 as a, t2 as b, t1 as c, t2 as d, t1 as e, t2 as f;
+i	j	i	j	i	j
+show status like 'table_open_cache_%';
+Variable_name	Value
+Table_open_cache_hits	4
+Table_open_cache_misses	6
+Table_open_cache_overflows	0
+# Reduce size of table cache to check that status
+# variable tracking cache overflows works.
+set @@global.table_open_cache= 4;
+# The below statement should result in table cache hit, but
+# as a side effect it should result in trimming of table
+# cache by 2 TABLE instances, meaning that overflow counter
+# will get increased by 2.
+select * from t1;
+i
+show status like 'table_open_cache_%';
+Variable_name	Value
+Table_open_cache_hits	5
+Table_open_cache_misses	6
+Table_open_cache_overflows	2
+# This statement should result in 4 cache hits, 2 cache misses/
+# overflows.
+select * from t1 as a, t2 as b, t1 as c, t2 as d, t1 as e, t2 as f;
+i	j	i	j	i	j
+show status like 'table_open_cache_%';
+Variable_name	Value
+Table_open_cache_hits	9
+Table_open_cache_misses	8
+Table_open_cache_overflows	4
+# Finally, the below statement should result in 1 cache miss
+# and 1 overflow since it accesses table which is not yet in
+# cache and table cache is full.
+select * from t3;
+k
+show status like 'table_open_cache_%';
+Variable_name	Value
+Table_open_cache_hits	9
+Table_open_cache_misses	9
+Table_open_cache_overflows	5
+# Cleanup
+set @@global.table_open_cache= @old_table_open_cache;
+drop tables t1, t2, t3;
 set @@global.concurrent_insert= @old_concurrent_insert;
 SET GLOBAL log_output = @old_log_output;

=== modified file 'mysql-test/t/status.test'
--- a/mysql-test/t/status.test	2011-09-07 10:08:09 +0000
+++ b/mysql-test/t/status.test	2012-05-12 14:54:12 +0000
@@ -354,6 +354,75 @@ DROP FUNCTION f1;
 
 # End of 5.1 tests
 
+
+--echo #
+--echo # Test coverage for status variables which were introduced by
+--echo # WL#5772 "Add partitioned Table Definition Cache to avoid
+--echo # using LOCK_open and its derivatives in DML queries".
+--echo #
+create table t1 (i int);
+create table t2 (j int);
+create table t3 (k int);
+--echo # Flush table cache to ensure that it is empty and reset status
+--echo # variables. Since to test cache overflow we will need to reduce
+--echo # its size, also save original table cache size.
+flush tables;
+flush status;
+set @old_table_open_cache= @@table_open_cache;
+
+--echo # Check that after reset all status variables are zero.
+show status like 'table_open_cache_%';
+
+--echo # The first statement accessing t1 after flush should result
+--echo # in table cache miss.
+select * from t1;
+show status like 'table_open_cache_%';
+
+--echo # The second statement accessing the same table should
+--echo # result in table cache hit.
+select * from t1;
+show status like 'table_open_cache_%';
+
+--echo # Again table cache miss if accessing different table.
+select * from t2;
+show status like 'table_open_cache_%';
+
+--echo # And cache hit then accessing it second time.
+select * from t2;
+show status like 'table_open_cache_%';
+
+--echo # The below statement should result in 2 cache hits and 
+--echo # 4 cache misses since it needs 6 table instances in total.
+select * from t1 as a, t2 as b, t1 as c, t2 as d, t1 as e, t2 as f;
+show status like 'table_open_cache_%';
+
+--echo # Reduce size of table cache to check that status
+--echo # variable tracking cache overflows works.
+set @@global.table_open_cache= 4;
+
+--echo # The below statement should result in table cache hit, but
+--echo # as a side effect it should result in trimming of table
+--echo # cache by 2 TABLE instances, meaning that overflow counter
+--echo # will get increased by 2.
+select * from t1;
+show status like 'table_open_cache_%';
+
+--echo # This statement should result in 4 cache hits, 2 cache misses/
+--echo # overflows.
+select * from t1 as a, t2 as b, t1 as c, t2 as d, t1 as e, t2 as f;
+show status like 'table_open_cache_%';
+
+--echo # Finally, the below statement should result in 1 cache miss
+--echo # and 1 overflow since it accesses table which is not yet in
+--echo # cache and table cache is full.
+select * from t3;
+show status like 'table_open_cache_%';
+
+--echo # Cleanup
+set @@global.table_open_cache= @old_table_open_cache;
+drop tables t1, t2, t3;
+
+
 # Restore global concurrent_insert value. Keep in the end of the test file.
 --connection default
 set @@global.concurrent_insert= @old_concurrent_insert;

=== modified file 'sql/mysqld.cc'
--- a/sql/mysqld.cc	2012-05-11 16:05:27 +0000
+++ b/sql/mysqld.cc	2012-05-12 14:54:12 +0000
@@ -7433,6 +7433,9 @@ SHOW_VAR status_vars[]= {
 #endif /* HAVE_OPENSSL */
   {"Table_locks_immediate",    (char*) &locks_immediate,        SHOW_LONG},
   {"Table_locks_waited",       (char*) &locks_waited,           SHOW_LONG},
+  {"Table_open_cache_hits",    (char*) offsetof(STATUS_VAR, table_open_cache_hits), SHOW_LONGLONG_STATUS},
+  {"Table_open_cache_misses",  (char*) offsetof(STATUS_VAR, table_open_cache_misses), SHOW_LONGLONG_STATUS},
+  {"Table_open_cache_overflows",(char*) offsetof(STATUS_VAR, table_open_cache_overflows), SHOW_LONGLONG_STATUS},
 #ifdef HAVE_MMAP
   {"Tc_log_max_pages_used",    (char*) &tc_log_max_pages_used,  SHOW_LONG},
   {"Tc_log_page_size",         (char*) &tc_log_page_size,       SHOW_LONG},

=== modified file 'sql/sys_vars.cc'
--- a/sql/sys_vars.cc	2012-05-11 16:05:27 +0000
+++ b/sql/sys_vars.cc	2012-05-12 14:54:12 +0000
@@ -2713,16 +2713,18 @@ static Sys_var_ulong Sys_table_def_size(
        VALID_RANGE(TABLE_DEF_CACHE_MIN, 512*1024),
        DEFAULT(TABLE_DEF_CACHE_DEFAULT), BLOCK_SIZE(1));
 
-/*
-  TODO/FIXME: Ensure that table_cache_size_per_instance is properly
-              updated when table_cache_size is changed dynamically.
-*/
+static bool fix_table_cache_size(sys_var *self, THD *thd, enum_var_type type)
+{
+  table_cache_size_per_instance= table_cache_size / table_cache_instances;
+  return false;
+}
 
 static Sys_var_ulong Sys_table_cache_size(
        "table_open_cache", "The number of cached open tables",
        GLOBAL_VAR(table_cache_size), CMD_LINE(REQUIRED_ARG),
        VALID_RANGE(1, 512*1024), DEFAULT(TABLE_OPEN_CACHE_DEFAULT),
-       BLOCK_SIZE(1));
+       BLOCK_SIZE(1), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(NULL),
+       ON_UPDATE(fix_table_cache_size));
 
 static Sys_var_ulong Sys_table_cache_instances(
        "table_open_cache_instances", "The number of table cache instances",

No bundle (reason: useless for push emails).
Thread
bzr push into mysql-trunk branch (Dmitry.Lenev:3892 to 3893) WL#5772Dmitry Lenev16 May