List:Commits« Previous MessageNext Message »
From:Ingo Struewing Date:April 7 2009 7:05pm
Subject:bzr commit into mysql-6.0-backup branch (ingo.struewing:2810) Bug#44068
View as plain text  
#At file:///home2/mydev/bzrroot/mysql-6.0-keycache-1/ based on revid:jorgen.loland@stripped

 2810 Ingo Struewing	2009-04-07
      Bug#44068 - RESTORE can disable the MyISAM Key Cache
      
      The test case myisam_keycache_coverage used to fail if it ran
      after backup_myisam_sync.
      
      The reason was that the latter test case disabled the key cache
      during RESTORE. The error injection in myisam_keycache_coverage
      became void as the key cache wasn't used any more. Reads of the
      index file bypassed the cache, and the statements succeeded.
      
      Fixed by moving initialization and de-initialization of the key
      cache from mi_examine_log() to myisamlog. In the server, the
      initialization is already done.
      
      Additional change: To make the state of the key cache visible,
      I added cleanup for the status variables blocks_used and
      blocks_unused. This improves the testability.
     @ mysql-test/r/myisam_keycache_coverage.result
        Bug#44068 - RESTORE can disable the MyISAM Key Cache
        Updated test result.
     @ mysql-test/suite/backup/r/backup_myisam_sync.result
        Bug#44068 - RESTORE can disable the MyISAM Key Cache
        Updated test result.
     @ mysql-test/suite/backup/t/backup_myisam_sync.test
        Bug#44068 - RESTORE can disable the MyISAM Key Cache
        Added checks for the state of the key cache.
     @ mysql-test/t/myisam_keycache_coverage.test
        Bug#44068 - RESTORE can disable the MyISAM Key Cache
        Added FORCE INDEX to the reference statement to make it
        equal to the tested statement.
        Removed old attempts to stabilize the test case.
        Added proper set and unset of the debug variable
        to disturb debugging as little as possible.
     @ mysys/mf_keycache.c
        Bug#44068 - RESTORE can disable the MyISAM Key Cache
        Added cleanup for blocks_used and blocks_unused.
        Added DBUG.
     @ storage/myisam/mi_examine_log.c
        Bug#44068 - RESTORE can disable the MyISAM Key Cache
        Moved calls to init_key_cache() and end_key_cache()
        from here to myisamlog.c
     @ storage/myisam/myisamlog.c
        Bug#44068 - RESTORE can disable the MyISAM Key Cache
        Moved calls to init_key_cache() and end_key_cache()
        from mi_examine_log.c to here.

    modified:
      mysql-test/r/myisam_keycache_coverage.result
      mysql-test/suite/backup/r/backup_myisam_sync.result
      mysql-test/suite/backup/t/backup_myisam_sync.test
      mysql-test/t/myisam_keycache_coverage.test
      mysys/mf_keycache.c
      storage/myisam/mi_examine_log.c
      storage/myisam/myisamlog.c
=== modified file 'mysql-test/r/myisam_keycache_coverage.result'
--- a/mysql-test/r/myisam_keycache_coverage.result	2009-03-30 16:47:55 +0000
+++ b/mysql-test/r/myisam_keycache_coverage.result	2009-04-07 19:05:08 +0000
@@ -11,7 +11,7 @@ INSERT INTO t1 SELECT * FROM t1;
 #
 # Positive tests.
 #
-SELECT COUNT(*) FROM t1 WHERE c2 < 5;
+SELECT COUNT(*) FROM t1 FORCE INDEX(i1) WHERE c2 < 5;
 COUNT(*)
 8
 LOAD INDEX INTO CACHE t1;
@@ -25,33 +25,30 @@ FLUSH TABLE t1;
 #
 # Inject error key_cache_read_block_error
 #
-EXPLAIN SELECT COUNT(*) FROM t1 WHERE c2 < 5;
-id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	SIMPLE	t1	index	NULL	i1	13	NULL	8	Using where; Using index
 SET debug='+d,key_cache_read_block_error';
-FLUSH TABLES;
-SELECT COUNT(*) FROM t1 FORCE INDEX(i1) WHERE c2 < 5;
 SELECT COUNT(*) FROM t1 FORCE INDEX(i1) WHERE c2 < 5;
 ERROR HY000: Incorrect key file for table 't1.MYI'; try to repair it
+SET debug='-d,key_cache_read_block_error';
 FLUSH TABLE t1;
 #
 # Inject error key_cache_insert_block_error
 #
-SET debug='d,key_cache_insert_block_error';
+SET debug='+d,key_cache_insert_block_error';
 LOAD INDEX INTO CACHE t1;
 Table	Op	Msg_type	Msg_text
 test.t1	preload_keys	error	Failed to read from index file (errno: 5)
 test.t1	preload_keys	status	Operation failed
+SET debug='-d,key_cache_insert_block_error';
 FLUSH TABLE t1;
 #
 # Inject error key_cache_write_block_error
 #
-SET debug='d,key_cache_write_block_error';
+SET debug='+d,key_cache_write_block_error';
 UPDATE t1 SET c2=1;
 ERROR HY000: Incorrect key file for table 't1.MYI'; try to repair it
+SET debug='-d,key_cache_write_block_error';
 FLUSH TABLE t1;
 #
 # Cleanup
 #
-SET debug='';
 DROP TABLE t1;

=== modified file 'mysql-test/suite/backup/r/backup_myisam_sync.result'
--- a/mysql-test/suite/backup/r/backup_myisam_sync.result	2009-02-13 12:40:13 +0000
+++ b/mysql-test/suite/backup/r/backup_myisam_sync.result	2009-04-07 19:05:08 +0000
@@ -36,6 +36,15 @@ LENGTH(c1)
 CHECKSUM TABLE t1;
 Table	Checksum
 mysqltest.t1	1728069308
+
+# Verify that the MyISAM Key Cache is enabled.
+# See Bug#44068 (RESTORE can disable the MyISAM Key Cache).
+SELECT SUM(VARIABLE_VALUE) > 0 AS key_cache_is_enabled
+FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE
+VARIABLE_NAME LIKE 'Key_blocks_%used';
+key_cache_is_enabled
+1
+
 Signal BACKUP to finish
 SET DEBUG_SYNC= 'now SIGNAL bup_finish';
 
@@ -59,6 +68,14 @@ mysqltest.t1	check	status	OK
 connection default: cleanup
 SET DEBUG_SYNC= 'RESET';
 
+# Verify that the MyISAM Key Cache is still enabled.
+# See Bug#44068 (RESTORE can disable the MyISAM Key Cache).
+SELECT SUM(VARIABLE_VALUE) > 0 AS key_cache_is_enabled
+FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE
+VARIABLE_NAME LIKE 'Key_blocks_%used';
+key_cache_is_enabled
+1
+
 # final cleanup
 USE test;
 DROP DATABASE mysqltest;

=== modified file 'mysql-test/suite/backup/t/backup_myisam_sync.test'
--- a/mysql-test/suite/backup/t/backup_myisam_sync.test	2009-02-24 20:57:21 +0000
+++ b/mysql-test/suite/backup/t/backup_myisam_sync.test	2009-04-07 19:05:08 +0000
@@ -59,6 +59,14 @@ while ($1)
 SELECT LENGTH(c1) FROM t1;
 CHECKSUM TABLE t1;
 
+--echo
+--echo # Verify that the MyISAM Key Cache is enabled.
+--echo # See Bug#44068 (RESTORE can disable the MyISAM Key Cache).
+SELECT SUM(VARIABLE_VALUE) > 0 AS key_cache_is_enabled
+  FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE
+  VARIABLE_NAME LIKE 'Key_blocks_%used';
+--echo
+
 --echo Signal BACKUP to finish
 SET DEBUG_SYNC= 'now SIGNAL bup_finish';
 
@@ -84,10 +92,17 @@ connection default;
 remove_file $MYSQLD_BACKUPDIR/bup_myisam_sync.bak;
 SET DEBUG_SYNC= 'RESET';
 
+--echo
+--echo # Verify that the MyISAM Key Cache is still enabled.
+--echo # See Bug#44068 (RESTORE can disable the MyISAM Key Cache).
+SELECT SUM(VARIABLE_VALUE) > 0 AS key_cache_is_enabled
+  FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE
+  VARIABLE_NAME LIKE 'Key_blocks_%used';
+--echo
+
 #
 # Cleanup from this test case
 #
---echo
 --echo # final cleanup
 USE test;
 DROP DATABASE mysqltest;

=== modified file 'mysql-test/t/myisam_keycache_coverage.test'
--- a/mysql-test/t/myisam_keycache_coverage.test	2009-03-30 16:47:55 +0000
+++ b/mysql-test/t/myisam_keycache_coverage.test	2009-04-07 19:05:08 +0000
@@ -18,7 +18,7 @@ INSERT INTO t1 SELECT * FROM t1;
 --echo #
 --echo # Positive tests.
 --echo #
-SELECT COUNT(*) FROM t1 WHERE c2 < 5;
+SELECT COUNT(*) FROM t1 FORCE INDEX(i1) WHERE c2 < 5;
 LOAD INDEX INTO CACHE t1;
 UPDATE t1 SET c2=2;
 
@@ -30,66 +30,33 @@ FLUSH TABLE t1;
 --echo #
 --echo # Inject error key_cache_read_block_error
 --echo #
-#
-# I have seen the below SELECT to succeed from time to time,
-# though it shall fail due to the injected error. As far as I undestand,
-# the only way for this to happen is that SELECT does not use the index.
-# Since the problem is random, I add an EXPLAIN here, to see if this
-# does indeed happen. If it shows a result difference from time to time,
-# then perhaps FLUSH TABLE t1 does not always work reliably.
-# In addition to the EXPLAIN, which is here to prove the assumption,
-# I add FORCE INDEX to keep the SELECT failing, which is the whole
-# purpose of this test.
-#
-EXPLAIN SELECT COUNT(*) FROM t1 WHERE c2 < 5;
-#
-# The EXPLAIN shows that the index is used. It fails sporadically anyway.
-# It fails frequently on my machine, but curiously on the first attempt.
-# Both retries were always successful. Running the test stand alone or
-# in a small group does never fail. So I wonder if the setting of the
-# 'debug' server variable might fail. I had "SET debug='d,..." here.
-# Perhaps this is vulnerable to some preset of the variable.
-# So I set it with "+d" as we do at many other places.
-#
 SET debug='+d,key_cache_read_block_error';
-#
-# Changing to "+d" did not help. Trying a full flush of all tables.
-# This shouldn't make a difference, but...
-# Flushing shouldn't play a role since the error injection happens
-# after the copy from cache block to MyISAM buffer.
-#
-FLUSH TABLES;
-#
-# As expected FLUSH TABLES didn't help either.
-# Now duplicating the offending SELECT, ignoring success on the first attempt.
-#
---replace_regex /'.*[\/\\]/'/
---error 0,126
-SELECT COUNT(*) FROM t1 FORCE INDEX(i1) WHERE c2 < 5;
 --replace_regex /'.*[\/\\]/'/
 --error 126
 SELECT COUNT(*) FROM t1 FORCE INDEX(i1) WHERE c2 < 5;
+SET debug='-d,key_cache_read_block_error';
 FLUSH TABLE t1;
 
 --echo #
 --echo # Inject error key_cache_insert_block_error
 --echo #
-SET debug='d,key_cache_insert_block_error';
+SET debug='+d,key_cache_insert_block_error';
 LOAD INDEX INTO CACHE t1;
+SET debug='-d,key_cache_insert_block_error';
 FLUSH TABLE t1;
 
 --echo #
 --echo # Inject error key_cache_write_block_error
 --echo #
-SET debug='d,key_cache_write_block_error';
+SET debug='+d,key_cache_write_block_error';
 --replace_regex /'.*[\/\\]/'/
 --error 126
 UPDATE t1 SET c2=1;
+SET debug='-d,key_cache_write_block_error';
 FLUSH TABLE t1;
 
 --echo #
 --echo # Cleanup
 --echo #
-SET debug='';
 DROP TABLE t1;
 

=== modified file 'mysys/mf_keycache.c'
--- a/mysys/mf_keycache.c	2009-01-29 21:17:59 +0000
+++ b/mysys/mf_keycache.c	2009-04-07 19:05:08 +0000
@@ -765,6 +765,13 @@ void end_key_cache(KEY_CACHE *keycache, 
                         (ulong) keycache->global_cache_r_requests,
                         (ulong) keycache->global_cache_read));
 
+  /*
+    Reset these values to be able to detect a disabled key cache.
+    See Bug#44068 (RESTORE can disable the MyISAM Key Cache).
+  */
+  keycache->blocks_used= 0;
+  keycache->blocks_unused= 0;
+
   if (cleanup)
   {
     pthread_mutex_destroy(&keycache->cache_lock);
@@ -2606,7 +2613,10 @@ uchar *key_cache_read(KEY_CACHE *keycach
       /* Cache could be disabled in a later iteration. */
       
       if (!keycache->can_be_used)
-	goto no_key_cache;
+      {
+        KEYCACHE_DBUG_PRINT("key_cache_read", ("keycache cannot be used"));
+        goto no_key_cache;
+      }
       /* Start reading at the beginning of the cache block. */
       filepos-= offset;
       /* Do not read beyond the end of the cache block. */
@@ -2726,6 +2736,7 @@ uchar *key_cache_read(KEY_CACHE *keycach
     } while ((length-= read_length));
     goto end;
   }
+  KEYCACHE_DBUG_PRINT("key_cache_read", ("keycache not initialized"));
 
 no_key_cache:
   /* Key cache is not used */
@@ -2746,6 +2757,7 @@ end:
     dec_counter_for_resize_op(keycache);
     keycache_pthread_mutex_unlock(&keycache->cache_lock);
   }
+  DBUG_PRINT("exit", ("error: %d", error ));
   DBUG_RETURN(error ? (uchar*) 0 : start);
 }
 

=== modified file 'storage/myisam/mi_examine_log.c'
--- a/storage/myisam/mi_examine_log.c	2009-02-22 18:02:16 +0000
+++ b/storage/myisam/mi_examine_log.c	2009-04-07 19:05:08 +0000
@@ -145,6 +145,9 @@ void mi_examine_log_param_init(MI_EXAMIN
   them.
   Is used both by the standalone program myisamlog and by the restore
   code of the MyISAM online backup driver.
+  An initialized key cache may accelerate this function. The MySQL server
+  has a key cache initialized anyway. For other programs it is recommended
+  to set up a key cache before calling this function.
 
   @param  mi_exl           Parameters of the applying
 
@@ -208,8 +211,6 @@ int mi_examine_log(MI_EXAMINE_LOG_PARAM 
   bzero(mi_exl->com_count,sizeof(mi_exl->com_count));
   init_tree(&tree,0,0,sizeof(file_info),(qsort_cmp2) file_info_compare,1,
 	    (tree_element_free) file_info_free, NULL);
-  (void) init_key_cache(dflt_key_cache,KEY_CACHE_BLOCK_SIZE,KEY_CACHE_SIZE,
-                        0, 0);
 
   /*
     Initialize members of file_info that are used for pointing to
@@ -778,7 +779,6 @@ int mi_examine_log(MI_EXAMINE_LOG_PARAM 
   }
   DBUG_PRINT("myisamlog", ("end loop access_time: %lu  cmd_cnt: %lu",
                            access_time, mi_exl->number_of_commands));
-  end_key_cache(dflt_key_cache,1);
   delete_tree(&tree);
   (void) end_io_cache(&cache);
   (void) my_close(log_file,MYF(0));
@@ -803,7 +803,6 @@ int mi_examine_log(MI_EXAMINE_LOG_PARAM 
   fflush(stderr);
  end:
   DBUG_PRINT("myisamlog", ("end label"));
-  end_key_cache(dflt_key_cache, 1);
   delete_tree(&tree);
   (void) end_io_cache(&cache);
   (void) my_close(log_file,MYF(0));

=== modified file 'storage/myisam/myisamlog.c'
--- a/storage/myisam/myisamlog.c	2009-02-22 18:02:16 +0000
+++ b/storage/myisam/myisamlog.c	2009-04-07 19:05:08 +0000
@@ -80,9 +80,19 @@ int main(int argc, char **argv)
     printf("Trying to %s MyISAM files according to log '%s'\n",
 	   (mi_exl.recover ? "recover" : "update"),mi_exl.log_filename);
 
+  /*
+    mi_examine_log() may work faster with an initialized key cache.
+    But it works also if the initialization fails.
+  */
+  (void) init_key_cache(dflt_key_cache, KEY_CACHE_BLOCK_SIZE,
+                        KEY_CACHE_SIZE, 0, 0);
+
   error= mi_examine_log(&mi_exl);
   DBUG_PRINT("myisamlog", ("error from mi_examine_log: %d", error));
 
+  /* Free resources that might be used by the key cache. */
+  end_key_cache(dflt_key_cache, 1);
+
   if (mi_exl.update && ! error)
     puts("Tables updated successfully");
   total_count=total_error=total_recover=0;


Attachment: [text/bzr-bundle] bzr/ingo.struewing@sun.com-20090407190508-0q6fnba2hiwzmy1i.bundle
Thread
bzr commit into mysql-6.0-backup branch (ingo.struewing:2810) Bug#44068Ingo Struewing7 Apr
  • Re: bzr commit into mysql-6.0-backup branch (ingo.struewing:2810)Bug#44068Guilhem Bichot7 Apr
    • Re: bzr commit into mysql-6.0-backup branch (ingo.struewing:2810)Bug#44068Ingo Strüwing8 Apr
      • Re: bzr commit into mysql-6.0-backup branch (ingo.struewing:2810)Bug#44068Guilhem Bichot8 Apr
        • Re: bzr commit into mysql-6.0-backup branch (ingo.struewing:2810)Bug#44068Ingo Strüwing8 Apr
          • Re: bzr commit into mysql-6.0-backup branch (ingo.struewing:2810)Bug#44068Guilhem Bichot8 Apr
            • Re: bzr commit into mysql-6.0-backup branch (ingo.struewing:2810)Bug#44068Ingo Strüwing9 Apr