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 oreland | 5 Jul |