List:Commits« Previous MessageNext Message »
From:jonas oreland Date:July 5 2011 5:10am
Subject:bzr push into mysql-5.1-telco-6.3 branch (jonas.oreland:3443 to 3444)
View as plain text  
 3444 jonas oreland	2011-07-05
      ndb - The hunt for the trailing share - part I

    added:
      mysql-test/suite/ndb/t/ndb_share.cnf
      mysql-test/suite/ndb/t/ndb_share.test
    modified:
      mysql-test/suite/ndb/t/ndb_basic.test
      sql/ha_ndbcluster.cc
      sql/ha_ndbcluster.h
      sql/ha_ndbcluster_binlog.cc
 3443 Kent Boortz	2011-07-04 [merge]
      Updated/added copyright headers

    added:
      storage/ndb/compile-cluster
    modified:
      configure.in
      mysql-test/include/mtr_check.sql
      mysql-test/include/mtr_warnings.sql
      mysql-test/t/ctype_cp932_binlog_stm.test
      sql/ha_ndbcluster_binlog.cc
      storage/ndb/Makefile.am
      storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp
      storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp
      storage/ndb/src/kernel/blocks/suma/Suma.cpp
      storage/ndb/src/ndbapi/NdbTransaction.cpp
      storage/ndb/test/ndbapi/testScan.cpp
      storage/ndb/test/run-test/daily-basic-tests.txt
=== modified file 'mysql-test/suite/ndb/t/ndb_basic.test'
--- a/mysql-test/suite/ndb/t/ndb_basic.test	2011-04-08 13:23:36 +0000
+++ b/mysql-test/suite/ndb/t/ndb_basic.test	2011-07-05 05:09:35 +0000
@@ -16,7 +16,7 @@ drop database if exists mysqltest;
 --replace_column 2 #
 SHOW GLOBAL STATUS LIKE 'ndb%';
 --replace_column 2 #
-SHOW GLOBAL VARIABLES LIKE 'ndb%';
+SHOW GLOBAL VARIABLES LIKE 'ndb\_%';
 
 #
 # Create a normal table with primary key

=== added file 'mysql-test/suite/ndb/t/ndb_share.cnf'
--- a/mysql-test/suite/ndb/t/ndb_share.cnf	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/ndb/t/ndb_share.cnf	2011-07-05 05:09:35 +0000
@@ -0,0 +1,28 @@
+!include ../my.cnf
+
+[cluster_config.1]
+mysqld=,,,
+
+[mysqld.1.1]
+log-bin=mysqld-bin
+
+[mysqld.2.1]
+log-bin=mysqld-bin
+
+[mysqld.3.1]
+skip-log-bin
+
+[mysqld.4.1]
+skip-log-bin
+
+[ENV]
+
+NDB_CONNECTSTRING=             @mysql_cluster.1.ndb_connectstring
+MYSQLD1_SOCK=                  @mysqld.1.1.socket
+MYSQLD1_PORT=                  @mysqld.1.1.port
+MYSQLD2_SOCK=                  @mysqld.2.1.socket
+MYSQLD2_PORT=                  @mysqld.2.1.port
+MYSQLD3_SOCK=                  @mysqld.3.1.socket
+MYSQLD3_PORT=                  @mysqld.3.1.port
+MYSQLD4_SOCK=                  @mysqld.4.1.socket
+MYSQLD4_PORT=                  @mysqld.4.1.port

=== added file 'mysql-test/suite/ndb/t/ndb_share.test'
--- a/mysql-test/suite/ndb/t/ndb_share.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/ndb/t/ndb_share.test	2011-07-05 05:09:35 +0000
@@ -0,0 +1,346 @@
+-- source include/not_embedded.inc
+-- source include/have_ndb.inc
+-- source include/have_log_bin.inc
+
+connect (server1,127.0.0.1,root,,test,$MYSQLD1_PORT,);
+connect (server2,127.0.0.1,root,,test,$MYSQLD2_PORT,);
+connect (server3,127.0.0.1,root,,test,$MYSQLD3_PORT,);
+connect (server4,127.0.0.1,root,,test,$MYSQLD4_PORT,);
+
+connection server1;
+show variables like 'log_bin';
+connection server2;
+show variables like 'log_bin';
+connection server3;
+show variables like 'log_bin';
+connection server4;
+show variables like 'log_bin';
+
+#
+# Basic create+drop (from with and without log-bin)
+#   no share should be present
+#
+connection server1;
+create table t1 (a int) engine=ndbcluster;
+drop table t1;
+--source include/ndb_share_check_shares.inc
+
+connection server3;
+create table t1 (a int) engine=ndbcluster;
+drop table t1;
+--source include/ndb_share_check_shares.inc
+
+#
+# Basic create+rename+drop (from with and without log-bin)
+#   no share should be present
+#
+connection server1;
+create table t1 (a int) engine=ndbcluster;
+rename table t1 to t2;
+drop table t2;
+--source include/ndb_share_check_shares.inc
+
+connection server2;
+create table t1 (a int) engine=ndbcluster;
+rename table t1 to t2;
+drop table t2;
+--source include/ndb_share_check_shares.inc
+
+#
+# Basic create+offline-alter+drop (from with and without log-bin)
+#   no share should be present
+#
+connection server1;
+create table t1 (a int) engine=ndbcluster;
+alter offline table t1 add column b int default 77;
+drop table t1;
+--source include/ndb_share_check_shares.inc
+
+connection server2;
+create table t1 (a int) engine=ndbcluster;
+alter offline table t1 add column b int default 77;
+drop table t1;
+--source include/ndb_share_check_shares.inc
+
+#
+# Basic create+online-alter+drop (from with and without log-bin)
+#   no share should be present
+#
+connection server1;
+create table t1 (a int primary key) engine=ndbcluster;
+alter online table t1 add column b int column_format dynamic;
+drop table t1;
+--source include/ndb_share_check_shares.inc
+
+connection server2;
+create table t1 (a int primary key) engine=ndbcluster;
+alter offline table t1 add column b int column_format dynamic;
+drop table t1;
+--source include/ndb_share_check_shares.inc
+
+#
+# Basic create+multi-rename+drop (from with and without log-bin)
+#   no share should be present
+#
+connection server1;
+create table t1 (a int) engine=ndbcluster;
+create table t2 (a int) engine=ndbcluster;
+rename table t1 to tmp, t2 to t1, tmp to t2;
+drop table t1, t2;
+--source include/ndb_share_check_shares.inc
+
+connection server2;
+create table t1 (a int) engine=ndbcluster;
+create table t2 (a int) engine=ndbcluster;
+rename table t1 to tmp, t2 to t1, tmp to t2;
+drop table t1, t2;
+--source include/ndb_share_check_shares.inc
+
+#
+# Now...lets get nastier 1
+#   create myisam tables on other servers...and then create ndb table
+#
+connection server2;
+create table t1 (a int) engine=myisam;
+connection server4;
+create table t1 (a int) engine=myisam;
+
+connection server1;
+create table t1 (a int) engine = ndb;
+drop table t1;
+--source include/ndb_share_check_shares.inc
+
+connection server3;
+create table t1 (a int) engine = ndb;
+drop table t1;
+--source include/ndb_share_check_shares.inc
+
+connection server1;
+create table t1 (a int) engine = ndb;
+
+connection server2;
+drop table t1;
+desc t1; # force discovery
+
+connection server4;
+drop table t1;
+desc t1; # force discovery
+
+connection server1;
+drop table t1;
+--source include/ndb_share_check_shares.inc
+
+#
+# Now...lets get nastier 2
+#   create myisam tables on other servers...and then create ndb table
+#   and off-line alter them
+connection server2;
+create table t1 (a int) engine=myisam;
+connection server4;
+create table t1 (a int) engine=myisam;
+
+connection server1;
+create table t1 (a int) engine = ndb;
+alter offline table t1 add column b int column_format dynamic;
+
+connection server2;
+drop table t1;
+desc t1; # force discovery
+
+connection server4;
+drop table t1;
+desc t1; # force discovery
+
+connection server1;
+drop table t1;
+--source include/ndb_share_check_shares.inc
+
+#
+# Now...lets get nastier 3
+#   create myisam tables on other servers...and then create ndb table
+#   and online alter them
+connection server2;
+create table t1 (a int) engine=myisam;
+connection server4;
+create table t1 (a int) engine=myisam;
+
+connection server1;
+create table t1 (a int primary key) engine = ndb;
+alter online table t1 add column b int column_format dynamic;
+
+connection server2;
+drop table t1;
+desc t1; # force discovery
+
+connection server4;
+drop table t1;
+desc t1; # force discovery
+
+connection server1;
+drop table t1;
+--source include/ndb_share_check_shares.inc
+
+#
+# Now...lets get nastier 4
+#   create myisam tables on other servers...and then create ndb table
+#   and rename them
+connection server2;
+create table t1 (a int) engine=myisam;
+connection server4;
+create table t1 (a int) engine=myisam;
+
+connection server1;
+create table t1 (a int) engine = ndb;
+rename table t1 to t2;
+
+connection server2;
+desc t2; # force discovery
+
+connection server4;
+desc t2; # force discovery
+
+connection server1;
+drop table t2;
+--source include/ndb_share_check_shares.inc
+
+connection server2;
+drop table t1;
+
+connection server4;
+drop table t1;
+--source include/ndb_share_check_shares.inc
+
+#
+# Now...create table if not exists
+#
+--disable_warnings
+let $1=5;
+while ($1)
+{
+  dec $1;
+  connection server1;
+  --send create table if not exists t1 (a int) engine=ndbcluster
+  connection server2;
+  --send create table if not exists t1 (a int) engine=ndbcluster
+  connection server3;
+  --send create table if not exists t1 (a int) engine=ndbcluster
+  connection server4;
+  --send create table if not exists t1 (a int) engine=ndbcluster
+  connection server1;
+  --reap
+  connection server2;
+  --reap
+  connection server3;
+  --reap
+  connection server4;
+  --reap
+  connection server1;
+  drop table t1;
+  --source include/ndb_share_check_shares.inc
+}
+--enable_warnings
+
+#
+# Now...drop table if exists
+#
+--disable_warnings
+let $1=5;
+while ($1)
+{
+  dec $1;
+  connection server1;
+  create table t1 (a int) engine=ndbcluster;
+
+  connection server1;
+  --send drop table if exists t1
+  connection server2;
+  --send drop table if exists t1
+  connection server3;
+  --send drop table if exists t1
+  connection server4;
+  --send drop table if exists t1
+  connection server1;
+  --reap
+  connection server2;
+  --reap
+  connection server3;
+  --reap
+  connection server4;
+  --reap
+  --source include/ndb_share_check_shares.inc
+}
+--enable_warnings
+
+#
+# Now...restart
+#
+connection server1;
+create table t1 (a int) engine=ndbcluster;
+
+--exec $NDB_MGM --no-defaults -e "all restart -n" >> $NDB_TOOLS_OUTPUT
+--exec $NDB_TOOLS_DIR/ndb_waiter --no-defaults --ndb-connectstring="$NDB_CONNECTSTRING" --not-started >> $NDB_TOOLS_OUTPUT
+--exec $NDB_MGM --no-defaults -e "all start" >> $NDB_TOOLS_OUTPUT
+--exec $NDB_TOOLS_DIR/ndb_waiter --no-defaults --ndb-connectstring="$NDB_CONNECTSTRING" >> $NDB_TOOLS_OUTPUT
+
+# Wait for mysqld to reconnect and exit from readonly mode
+--disable_query_log
+connection server1;
+--source include/ndb_not_readonly.inc
+connection server2;
+--source include/ndb_not_readonly.inc
+connection server3;
+--source include/ndb_not_readonly.inc
+connection server4;
+--source include/ndb_not_readonly.inc
+--enable_query_log
+
+connection server1;
+desc t1;
+connection server2;
+desc t1;
+connection server3;
+desc t1;
+connection server4;
+desc t1;
+
+connection server1;
+drop table t1;
+--source include/ndb_share_check_shares.inc
+
+#
+# Now...restart -i
+#
+connection server1;
+create table t1 (a int) engine=ndbcluster;
+
+--exec $NDB_MGM --no-defaults -e "all restart -i -n" >> $NDB_TOOLS_OUTPUT
+--exec $NDB_TOOLS_DIR/ndb_waiter --no-defaults --ndb-connectstring="$NDB_CONNECTSTRING" --not-started >> $NDB_TOOLS_OUTPUT
+--exec $NDB_MGM --no-defaults -e "all start" >> $NDB_TOOLS_OUTPUT
+--exec $NDB_TOOLS_DIR/ndb_waiter --no-defaults --ndb-connectstring="$NDB_CONNECTSTRING" >> $NDB_TOOLS_OUTPUT
+
+# Wait for mysqld to reconnect and exit from readonly mode
+--disable_query_log
+connection server1;
+--source include/ndb_not_readonly.inc
+connection server2;
+--source include/ndb_not_readonly.inc
+connection server3;
+--source include/ndb_not_readonly.inc
+connection server4;
+--source include/ndb_not_readonly.inc
+--enable_query_log
+
+connection server1;
+--error 1146
+desc t1;
+connection server2;
+--error 1146
+desc t1;
+connection server3;
+--error 1146
+desc t1;
+connection server4;
+--error 1146
+desc t1;
+
+--source include/ndb_share_check_shares.inc

=== modified file 'sql/ha_ndbcluster.cc'
--- a/sql/ha_ndbcluster.cc	2011-06-30 15:55:35 +0000
+++ b/sql/ha_ndbcluster.cc	2011-07-05 05:09:35 +0000
@@ -7829,13 +7829,50 @@ int ha_ndbcluster::rename_table(const ch
   Delete table from NDB Cluster.
 */
 
+static
+void
+delete_table_drop_share(NDB_SHARE* share, const char * path)
+{
+  if (share)
+  {
+    pthread_mutex_lock(&ndbcluster_mutex);
+do_drop:
+    if (share->state != NSS_DROPPED)
+    {
+      /*
+        The share kept by the server has not been freed, free it
+      */
+      share->state= NSS_DROPPED;
+      /* ndb_share reference create free */
+      DBUG_PRINT("NDB_SHARE", ("%s create free  use_count: %u",
+                               share->key, share->use_count));
+      free_share(&share, TRUE);
+    }
+    /* ndb_share reference temporary free */
+    DBUG_PRINT("NDB_SHARE", ("%s temporary free  use_count: %u",
+                             share->key, share->use_count));
+    free_share(&share, TRUE);
+    pthread_mutex_unlock(&ndbcluster_mutex);
+  }
+  else if (path)
+  {
+    pthread_mutex_lock(&ndbcluster_mutex);
+    share= get_share(path, 0, FALSE, TRUE);
+    if (share)
+    {
+      goto do_drop;
+    }
+    pthread_mutex_unlock(&ndbcluster_mutex);
+  }
+}
+
 /* static version which does not need a handler */
 
 int
-ha_ndbcluster::delete_table(THD *thd, ha_ndbcluster *h, Ndb *ndb,
-                            const char *path,
-                            const char *db,
-                            const char *table_name)
+ha_ndbcluster::drop_table(THD *thd, ha_ndbcluster *h, Ndb *ndb,
+                          const char *path,
+                          const char *db,
+                          const char *table_name)
 {
   DBUG_ENTER("ha_ndbcluster::ndbcluster_delete_table");
   NDBDICT *dict= ndb->getDictionary();
@@ -7931,26 +7968,7 @@ retry_temporary_error1:
   if (res)
   {
     /* the drop table failed for some reason, drop the share anyways */
-    if (share)
-    {
-      pthread_mutex_lock(&ndbcluster_mutex);
-      if (share->state != NSS_DROPPED)
-      {
-        /*
-          The share kept by the server has not been freed, free it
-        */
-        share->state= NSS_DROPPED;
-        /* ndb_share reference create free */
-        DBUG_PRINT("NDB_SHARE", ("%s create free  use_count: %u",
-                                 share->key, share->use_count));
-        free_share(&share, TRUE);
-      }
-      /* ndb_share reference temporary free */
-      DBUG_PRINT("NDB_SHARE", ("%s temporary free  use_count: %u",
-                               share->key, share->use_count));
-      free_share(&share, TRUE);
-      pthread_mutex_unlock(&ndbcluster_mutex);
-    }
+    delete_table_drop_share(share, 0);
     DBUG_RETURN(res);
   }
 
@@ -7990,26 +8008,7 @@ retry_temporary_error1:
                              SOT_DROP_TABLE, 0, 0, 1);
   }
 
-  if (share)
-  {
-    pthread_mutex_lock(&ndbcluster_mutex);
-    if (share->state != NSS_DROPPED)
-    {
-      /*
-        The share kept by the server has not been freed, free it
-      */
-      share->state= NSS_DROPPED;
-      /* ndb_share reference create free */
-      DBUG_PRINT("NDB_SHARE", ("%s create free  use_count: %u",
-                               share->key, share->use_count));
-      free_share(&share, TRUE);
-    }
-    /* ndb_share reference temporary free */
-    DBUG_PRINT("NDB_SHARE", ("%s temporary free  use_count: %u",
-                             share->key, share->use_count));
-    free_share(&share, TRUE);
-    pthread_mutex_unlock(&ndbcluster_mutex);
-  }
+  delete_table_drop_share(share, 0);
   DBUG_RETURN(0);
 }
 
@@ -8030,6 +8029,7 @@ int ha_ndbcluster::delete_table(const ch
       dropped inside ndb.
       Just drop local files.
     */
+    delete_table_drop_share(0, name);
     DBUG_RETURN(handler::delete_table(name));
   }
 
@@ -8064,8 +8064,8 @@ int ha_ndbcluster::delete_table(const ch
     If it was already gone it might have been dropped
     remotely, give a warning and then drop .ndb file.
    */
-  if (!(error= delete_table(thd, this, ndb, name,
-                            m_dbname, m_tabname)) ||
+  if (!(error= drop_table(thd, this, ndb, name,
+                          m_dbname, m_tabname)) ||
       error == HA_ERR_NO_SUCH_TABLE)
   {
     /* Call ancestor function to delete .ndb file */
@@ -8986,7 +8986,7 @@ int ndbcluster_drop_database_impl(THD *t
   {
     tablename_to_filename(tabname, tmp, FN_REFLEN - (tmp - full_path)-1);
     pthread_mutex_lock(&LOCK_open);
-    if (ha_ndbcluster::delete_table(thd, 0, ndb, full_path, dbname, tabname))
+    if (ha_ndbcluster::drop_table(thd, 0, ndb, full_path, dbname, tabname))
     {
       const NdbError err= dict->getNdbError();
       if (err.code != 709 && err.code != 723)
@@ -13716,6 +13716,70 @@ SHOW_VAR ndb_status_variables_export[]=
   {NullS, NullS, SHOW_LONG}
 };
 
+
+#ifndef DBUG_OFF
+static
+const char*
+get_share_state_string(NDB_SHARE_STATE s)
+{
+  switch(s) {
+  case NSS_INITIAL:
+    return "NSS_INITIAL";
+  case NSS_ALTERED:
+    return "NSS_ALTERED";
+  case NSS_DROPPED:
+    return "NSS_DROPPED";
+  }
+  assert(false);
+  return "<unknown>";
+}
+
+static
+void
+dbug_check_shares(THD*, st_mysql_sys_var*, void*, const void*)
+{
+  sql_print_information("dbug_check_shares");
+  for (uint i= 0; i < ndbcluster_open_tables.records; i++)
+  {
+    NDB_SHARE * share = (NDB_SHARE*)my_hash_element(&ndbcluster_open_tables, i);
+    sql_print_information("  %s.%s: state: %s(%u) use_count: %u",
+                          share->db, share->table_name,
+                          get_share_state_string(share->state),
+                          (unsigned)share->state,
+                          share->use_count);
+  }
+
+  /**
+   * Only shares in mysql database may be open...
+   */
+  for (uint i= 0; i < ndbcluster_open_tables.records; i++)
+  {
+    NDB_SHARE * share = (NDB_SHARE*)my_hash_element(&ndbcluster_open_tables, i);
+    DBUG_ASSERT(strcmp(share->db, "mysql") == 0);
+  }
+}
+
+static MYSQL_THDVAR_UINT(
+  check_shares,              /* name */
+  PLUGIN_VAR_RQCMDARG,
+  "Debug, only...check that no shares are lingering...",
+  NULL,                              /* check func */
+  dbug_check_shares,                 /* update func */
+  0,                                 /* default */
+  0,                                 /* min */
+  1,                                 /* max */
+  0                                  /* block */
+);
+
+#endif
+
+static struct st_mysql_sys_var* system_variables[]= {
+#ifndef DBUG_OFF
+  MYSQL_SYSVAR(check_shares),
+#endif
+  NULL
+};
+
 struct st_mysql_storage_engine ndbcluster_storage_engine=
 { MYSQL_HANDLERTON_INTERFACE_VERSION };
 
@@ -13731,7 +13795,7 @@ mysql_declare_plugin(ndbcluster)
   NULL, /* Plugin Deinit */
   0x0100 /* 1.0 */,
   ndb_status_variables_export,/* status variables                */
-  NULL,                       /* system variables                */
+  system_variables,           /* system variables                */
   NULL                        /* config options                  */
 }
 mysql_declare_plugin_end;

=== modified file 'sql/ha_ndbcluster.h'
--- a/sql/ha_ndbcluster.h	2011-06-30 15:55:35 +0000
+++ b/sql/ha_ndbcluster.h	2011-07-05 05:09:35 +0000
@@ -608,10 +608,11 @@ private:
                                       NDB_SHARE *share);
 
   void check_read_before_write_removal();
-  static int delete_table(THD *thd, ha_ndbcluster *h, Ndb *ndb,
-			  const char *path,
-			  const char *db,
-			  const char *table_name);
+  static int drop_table(THD *thd, ha_ndbcluster *h, Ndb *ndb,
+                        const char *path,
+                        const char *db,
+                        const char *table_name);
+
   int add_index_impl(THD *thd, TABLE *table_arg,
                      KEY *key_info, uint num_of_keys);
   int create_ndb_index(THD *thd, const char *name, KEY *key_info, bool unique);

=== modified file 'sql/ha_ndbcluster_binlog.cc'
--- a/sql/ha_ndbcluster_binlog.cc	2011-07-04 12:36:04 +0000
+++ b/sql/ha_ndbcluster_binlog.cc	2011-07-05 05:09:35 +0000
@@ -6628,6 +6628,30 @@ restart_cluster_failure:
     thd_ndb= NULL;
   }
 
+  /**
+   * release all extra references from tables
+   */
+  {
+    pthread_mutex_lock(&ndbcluster_mutex);
+    for (uint i= 0; i < ndbcluster_open_tables.records; i++)
+    {
+      NDB_SHARE * share = (NDB_SHARE*)my_hash_element(&ndbcluster_open_tables,
+                                                      i);
+      if (share->state != NSS_DROPPED)
+      {
+        /*
+          The share kept by the server has not been freed, free it
+        */
+        share->state= NSS_DROPPED;
+        /* ndb_share reference create free */
+        DBUG_PRINT("NDB_SHARE", ("%s create free  use_count: %u",
+                                 share->key, share->use_count));
+        free_share(&share, TRUE);
+      }
+    }
+    pthread_mutex_unlock(&ndbcluster_mutex);
+  }
+
   if (do_ndbcluster_binlog_close_connection == BCCC_restart)
   {
     pthread_mutex_lock(&injector_mutex);

No bundle (reason: useless for push emails).
Thread
bzr push into mysql-5.1-telco-6.3 branch (jonas.oreland:3443 to 3444) jonas oreland5 Jul