List:Commits« Previous MessageNext Message »
From:gluh Date:November 9 2007 8:02am
Subject:bk commit into 5.0 tree (gluh:1.2554) BUG#30294
View as plain text  
Below is the list of changes that have just been committed into a local
5.0 repository of gluh. When gluh does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet@stripped, 2007-11-09 11:02:05+04:00, gluh@stripped +3 -0
  Bug#30294 blackhole engine causes 100% with 2 alter table statements running
  Implement neccessary shared lock structure for table locks.
  This is the backport of bug26241 fix.

  sql/ha_blackhole.cc@stripped, 2007-11-09 11:02:03+04:00, gluh@stripped +112 -10
    Implement neccessary shared lock structure for table locks.

  sql/ha_blackhole.h@stripped, 2007-11-09 11:02:03+04:00, gluh@stripped +16 -2
    Declare shared structure for table locks

  sql/handler.cc@stripped, 2007-11-09 11:02:03+04:00, gluh@stripped +4 -0
    added BLACKHOLE_DB case

diff -Nrup a/sql/ha_blackhole.cc b/sql/ha_blackhole.cc
--- a/sql/ha_blackhole.cc	2007-02-14 20:35:54 +04:00
+++ b/sql/ha_blackhole.cc	2007-11-09 11:02:03 +04:00
@@ -22,6 +22,14 @@
 #ifdef HAVE_BLACKHOLE_DB
 #include "ha_blackhole.h"
 
+/* Static declarations for shared structures */
+
+static pthread_mutex_t blackhole_mutex;
+static HASH blackhole_open_tables;
+static int blackhole_init= FALSE;
+
+static st_blackhole_share *get_share(const char *table_name);
+static void free_share(st_blackhole_share *share);
 
 /* Blackhole storage engine handlerton */
 
@@ -30,7 +38,7 @@ handlerton blackhole_hton= {
   SHOW_OPTION_YES,
   "/dev/null storage engine (anything you write to it disappears)",
   DB_TYPE_BLACKHOLE_DB,
-  NULL,
+  blackhole_db_init,
   0,       /* slot */
   0,       /* savepoint size. */
   NULL,    /* close_connection */
@@ -70,15 +78,18 @@ const char **ha_blackhole::bas_ext() con
 int ha_blackhole::open(const char *name, int mode, uint test_if_locked)
 {
   DBUG_ENTER("ha_blackhole::open");
-  thr_lock_init(&thr_lock);
-  thr_lock_data_init(&thr_lock,&lock,NULL);
+
+  if (!(share= get_share(name)))
+    DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+
+  thr_lock_data_init(&share->lock, &lock, NULL);
   DBUG_RETURN(0);
 }
 
 int ha_blackhole::close(void)
 {
   DBUG_ENTER("ha_blackhole::close");
-  thr_lock_delete(&thr_lock);
+  free_share(share);
   DBUG_RETURN(0);
 }
 
@@ -161,17 +172,23 @@ int ha_blackhole::external_lock(THD *thd
 }
 
 
-uint ha_blackhole::lock_count(void) const
-{
-  DBUG_ENTER("ha_blackhole::lock_count");
-  DBUG_RETURN(0);
-}
-
 THR_LOCK_DATA **ha_blackhole::store_lock(THD *thd,
                                          THR_LOCK_DATA **to,
                                          enum thr_lock_type lock_type)
 {
   DBUG_ENTER("ha_blackhole::store_lock");
+  if (lock_type != TL_IGNORE && lock.type == TL_UNLOCK)
+  {
+    if ((lock_type >= TL_WRITE_CONCURRENT_INSERT &&
+         lock_type <= TL_WRITE) && !thd->in_lock_tables)
+      lock_type = TL_WRITE_ALLOW_WRITE;
+
+    if (lock_type == TL_READ_NO_INSERT && !thd->in_lock_tables)
+      lock_type = TL_READ;
+
+    lock.type= lock_type;
+  }
+  *to++= &lock;
   DBUG_RETURN(to);
 }
 
@@ -224,6 +241,91 @@ int ha_blackhole::index_last(byte * buf)
 {
   DBUG_ENTER("ha_blackhole::index_last");
   DBUG_RETURN(HA_ERR_END_OF_FILE);
+}
+
+
+static st_blackhole_share *get_share(const char *table_name)
+{
+  st_blackhole_share *share;
+  uint length;
+
+  length= (uint) strlen(table_name);
+  pthread_mutex_lock(&blackhole_mutex);
+    
+  if (!(share= (st_blackhole_share*) hash_search(&blackhole_open_tables,
+                                                 (byte*) table_name, length)))
+  {
+    if (!(share= (st_blackhole_share*) my_malloc(sizeof(st_blackhole_share) +
+                                                 length,
+                                                 MYF(MY_WME | MY_ZEROFILL))))
+      goto error;
+
+    share->table_name_length= length;
+    strmov(share->table_name, table_name);
+    
+    if (my_hash_insert(&blackhole_open_tables, (byte*) share))
+    {
+      my_free((gptr) share, MYF(0));
+      share= NULL;
+      goto error;
+    }
+    
+    thr_lock_init(&share->lock);
+  }
+  share->use_count++;
+  
+error:
+  pthread_mutex_unlock(&blackhole_mutex);
+  return share;
+}
+
+static void free_share(st_blackhole_share *share)
+{
+  pthread_mutex_lock(&blackhole_mutex);
+  if (!--share->use_count)
+    hash_delete(&blackhole_open_tables, (byte*) share);
+  pthread_mutex_unlock(&blackhole_mutex);
+}
+
+
+static byte* blackhole_get_key(st_blackhole_share *share, uint *length,
+                               my_bool not_used __attribute__((unused)))
+{
+  *length= share->table_name_length;
+  return (byte*) share->table_name;
+}
+
+
+bool blackhole_db_init()
+{
+  DBUG_ENTER("blackhole_db_init");
+  if (pthread_mutex_init(&blackhole_mutex, MY_MUTEX_INIT_FAST))
+    goto error;
+  if (hash_init(&blackhole_open_tables, &my_charset_bin, 32, 0, 0,
+                    (hash_get_key) blackhole_get_key, 0, 0))
+  {
+    VOID(pthread_mutex_destroy(&blackhole_mutex));
+  }
+  else
+  {
+    blackhole_init= TRUE;
+    DBUG_RETURN(FALSE);
+  }
+error:
+  have_blackhole_db= SHOW_OPTION_DISABLED;	// If we couldn't use handler
+  DBUG_RETURN(TRUE);
+}
+
+
+bool blackhole_db_end()
+{
+  if (blackhole_init)
+  {
+    hash_free(&blackhole_open_tables);
+    VOID(pthread_mutex_destroy(&blackhole_mutex));
+  }
+  blackhole_init= 0;
+  return FALSE;
 }
 
 #endif /* HAVE_BLACKHOLE_DB */
diff -Nrup a/sql/ha_blackhole.h b/sql/ha_blackhole.h
--- a/sql/ha_blackhole.h	2007-05-10 18:07:45 +05:00
+++ b/sql/ha_blackhole.h	2007-11-09 11:02:03 +04:00
@@ -17,6 +17,18 @@
 #pragma interface			/* gcc class implementation */
 #endif
 
+
+/*
+  Shared structure for correct LOCK operation
+*/
+struct st_blackhole_share {
+  THR_LOCK lock;
+  uint use_count;
+  uint table_name_length;
+  char table_name[1];
+};
+
+
 /*
   Class definition for the blackhole storage engine
   "Dumbest named feature ever"
@@ -24,7 +36,7 @@
 class ha_blackhole: public handler
 {
   THR_LOCK_DATA lock;      /* MySQL lock */
-  THR_LOCK thr_lock;
+  st_blackhole_share *share;
 
 public:
   ha_blackhole(TABLE *table_arg);
@@ -76,10 +88,12 @@ public:
   void position(const byte *record);
   int info(uint flag);
   int external_lock(THD *thd, int lock_type);
-  uint lock_count(void) const;
   int create(const char *name, TABLE *table_arg,
              HA_CREATE_INFO *create_info);
   THR_LOCK_DATA **store_lock(THD *thd,
                              THR_LOCK_DATA **to,
                              enum thr_lock_type lock_type);
 };
+
+bool blackhole_db_init(void);
+bool blackhole_db_end(void);
diff -Nrup a/sql/handler.cc b/sql/handler.cc
--- a/sql/handler.cc	2007-08-15 12:23:42 +05:00
+++ b/sql/handler.cc	2007-11-09 11:02:03 +04:00
@@ -515,6 +515,10 @@ int ha_panic(enum ha_panic_function flag
   if (have_berkeley_db == SHOW_OPTION_YES)
     error|=berkeley_end();
 #endif
+#ifdef HAVE_BLACKHOLE_DB
+  if (have_blackhole_db == SHOW_OPTION_YES)
+    error|= blackhole_db_end();
+#endif
 #ifdef HAVE_INNOBASE_DB
   if (have_innodb == SHOW_OPTION_YES)
     error|=innobase_end();
Thread
bk commit into 5.0 tree (gluh:1.2554) BUG#30294gluh9 Nov