List:Commits« Previous MessageNext Message »
From:Magne Mahre Date:April 21 2010 9:56pm
Subject:bzr commit into mysql-trunk-runtime branch (magne.mahre:3007) Bug#49177
View as plain text  
#At file:///data/z/mysql-trunk-runtime-49177/ based on revid:jon.hauglid@stripped

 3007 Magne Mahre	2010-04-21
      Bug#49177 table_cache scalability problems
      
      (Note: MyISAM issue only)
      
      As the table cache size is increased, cache lookups and 
      (in particular) misses became increasingly more expensive.
      
      The problem was caused by the cache lookup mechanism, which
      was based on traversing a linked list, of <table cache size>
      length, comparing the file names. 
      
      A hash table has been introduced to reduce the lookup time.
      The linked list and the hash table are used in parallel, with
      the linked list used for implementing LRU functionality, and
      for operations that need to iterate through the entire cache.
      The hash table is only used for lookup.

    modified:
      storage/myisam/mi_close.c
      storage/myisam/mi_open.c
      storage/myisam/mi_static.c
      storage/myisam/myisamdef.h
=== modified file 'storage/myisam/mi_close.c'
--- a/storage/myisam/mi_close.c	2009-12-05 01:26:15 +0000
+++ b/storage/myisam/mi_close.c	2010-04-21 21:56:05 +0000
@@ -54,7 +54,11 @@ int mi_close(register MI_INFO *info)
     info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED);
   }
   flag= !--share->reopen;
-  myisam_open_list=list_delete(myisam_open_list,&info->open_list);
+
+  /* delete from both the hash and the list */
+  my_hash_delete(&myisam_open_hash, info);
+  myisam_open_list= list_delete(myisam_open_list, &info->open_list);
+
   mysql_mutex_unlock(&share->intern_lock);
 
   my_free(mi_get_rec_buff_ptr(info, info->rec_buff), MYF(MY_ALLOW_ZERO_PTR));

=== modified file 'storage/myisam/mi_open.c'
--- a/storage/myisam/mi_open.c	2009-12-05 01:26:15 +0000
+++ b/storage/myisam/mi_open.c	2010-04-21 21:56:05 +0000
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000-2006 MySQL AB, 2008-2009 Sun Microsystems, Inc
+/* Copyright (c) 2000, 2010, 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
@@ -18,6 +18,7 @@
 #include "fulltext.h"
 #include "sp_defs.h"
 #include "rt_index.h"
+#include <hash.h>
 #include <m_ctype.h>
 
 #if defined(MSDOS) || defined(__WIN__)
@@ -44,6 +45,19 @@ if (pos > end_pos)             \
 }
 
 
+static const int myisam_open_hash_size= 32;
+
+/* retrieve the field used as hash key from the MI_INFO record */
+uchar *mi_info_hash_get_key(const uchar *record, size_t *length,
+                            my_bool not_used __attribute__ ((unused)))
+{
+  MI_INFO *info= (MI_INFO *) record;
+  *length= strlen(info->filename);
+  return (uchar *) info->filename;
+}
+
+
+
 /******************************************************************************
 ** Return the shared struct if the table is already open.
 ** In MySQL the server will handle version issues.
@@ -51,15 +65,22 @@ if (pos > end_pos)             \
 
 MI_INFO *test_if_reopen(char *filename)
 {
-  LIST *pos;
+  HASH_SEARCH_STATE current_record;
+  int flen= strlen(filename);
 
-  for (pos=myisam_open_list ; pos ; pos=pos->next)
+  for (info= (MI_INFO *) my_hash_first(&myisam_open_hash, 
+                                      (uchar *) filename, flen,
+                                      &current_record);
+       info;
+       info= (MI_INFO *) my_hash_next(&myisam_open_hash,
+                                      (uchar *) filename, flen,
+                                      &current_record))
   {
-    MI_INFO *info=(MI_INFO*) pos->data;
     MYISAM_SHARE *share=info->s;
-    if (!strcmp(share->unique_file_name,filename) && share->last_version)
+    if (share->last_version)
       return info;
   }
+    
   return 0;
 }
 
@@ -104,6 +125,17 @@ MI_INFO *mi_open(const char *name, int m
   }
 
   mysql_mutex_lock(&THR_LOCK_myisam);
+
+  /* create hash table on the first call to mi_open */
+  if (my_hash_init_opt(&myisam_open_hash, &my_charset_bin, 
+                       myisam_open_hash_size, 0, 0,
+                       mi_info_hash_get_key, 0, 0))
+  {
+    my_errno= ENOMEM;
+    goto err;
+  }
+      
+
   if (!(old_info=test_if_reopen(name_buff)))
   {
     share= &share_buff;
@@ -655,7 +687,9 @@ MI_INFO *mi_open(const char *name, int m
   thr_lock_data_init(&share->lock,&m_info->lock,(void*) m_info);
 #endif
   m_info->open_list.data=(void*) m_info;
-  myisam_open_list=list_add(myisam_open_list,&m_info->open_list);
+  /* Add record to both the list and the hash */
+  myisam_open_list= list_add(myisam_open_list,&m_info->open_list);
+  my_hash_insert(&myisam_open_hash, m_info);
 
   mysql_mutex_unlock(&THR_LOCK_myisam);
   if (myisam_log_file >= 0)

=== modified file 'storage/myisam/mi_static.c'
--- a/storage/myisam/mi_static.c	2010-02-06 16:13:42 +0000
+++ b/storage/myisam/mi_static.c	2010-04-21 21:56:05 +0000
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000-2002, 2004-2005 MySQL AB, 2008-2009 Sun Microsystems, Inc
+/* Copyright (c) 2000, 2010, 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
@@ -22,7 +22,9 @@
 #include "myisamdef.h"
 #endif
 
-LIST	*myisam_open_list=0;
+LIST    *myisam_open_list=0;
+HASH    myisam_open_hash= {.blength= 0 };
+
 uchar	NEAR myisam_file_magic[]=
 { (uchar) 254, (uchar) 254,'\007', '\001', };
 uchar	NEAR myisam_pack_file_magic[]=

=== modified file 'storage/myisam/myisamdef.h'
--- a/storage/myisam/myisamdef.h	2009-12-17 19:16:54 +0000
+++ b/storage/myisam/myisamdef.h	2010-04-21 21:56:05 +0000
@@ -18,6 +18,7 @@
 #include "myisam.h"			/* Structs & some defines */
 #include "myisampack.h"			/* packing of keys */
 #include <my_tree.h>
+#include <hash.h>
 #ifdef THREAD
 #include <my_pthread.h>
 #include <thr_lock.h>
@@ -475,6 +476,7 @@ extern mysql_mutex_t THR_LOCK_myisam;
 	/* Some extern variables */
 
 extern LIST *myisam_open_list;
+extern HASH myisam_open_hash;
 extern uchar NEAR myisam_file_magic[],NEAR myisam_pack_file_magic[];
 extern uint NEAR myisam_read_vec[],NEAR myisam_readnext_vec[];
 extern uint myisam_quick_table_bits;


Attachment: [text/bzr-bundle] bzr/magne.mahre@sun.com-20100421215605-pr3exr4znpfx4w5p.bundle
Thread
bzr commit into mysql-trunk-runtime branch (magne.mahre:3007) Bug#49177Magne Mahre22 Apr