List:Commits« Previous MessageNext Message »
From:Tomas Ulin Date:October 29 2008 1:10pm
Subject:bzr push into mysql-5.1 branch (tomas.ulin:2708 to 2710) Bug#40246
View as plain text  
 2710 Tomas Ulin	2008-10-29
      Bug#40246 - alter when table is locked does not work
added:
  mysql-test/suite/ndb/r/ndb_dbug_lock.result
  mysql-test/suite/ndb/t/ndb_dbug_lock.test
modified:
  sql/ha_ndbcluster.cc
  sql/ha_ndbcluster_binlog.cc
  sql/ha_ndbcluster_binlog.h
  sql/handler.cc
  sql/handler.h
  sql/sql_table.cc

 2709 Tomas Ulin	2008-10-28 [merge]
      merge
modified:
  storage/ndb/src/cw/cpcd/main.cpp

 2708 Tomas Ulin	2008-10-28 [merge]
      merge
removed:
  extra/yassl/taocrypt/taocrypt.vcproj
  extra/yassl/yassl.vcproj
  include/mysql_h.ic
  mysql-test/suite/funcs_1/r/memory_storedproc.result
  mysql-test/suite/funcs_1/r/myisam_storedproc.result
  mysql-test/suite/funcs_1/r/ndb_storedproc.result
  mysql-test/suite/funcs_1/t/innodb_storedproc.test
  mysql-test/suite/funcs_1/t/memory_storedproc.test
  mysql-test/suite/funcs_1/t/myisam_storedproc.test
  mysql-test/suite/parts/t/partition_alter2_ndb.test
  mysql-test/suite/rpl/t/rpl_view-slave.opt
  server-tools/instance-manager/mysqlmanager.vcproj
added:
  include/mysql.h.pp
  include/mysql/plugin.h.pp
  mysql-test/extra/rpl_tests/rpl_blackhole.test
  mysql-test/r/skip_log_bin.result
  mysql-test/suite/binlog/r/binlog_grant.result
  mysql-test/suite/binlog/r/binlog_mix_innodb_stat.result
  mysql-test/suite/binlog/r/binlog_stm_row.result
  mysql-test/suite/binlog/t/binlog_grant.test
  mysql-test/suite/binlog/t/binlog_mix_innodb_stat.test
  mysql-test/suite/binlog/t/binlog_stm_row.test
  mysql-test/suite/funcs_1/storedproc/param_check.inc
  mysql-test/suite/parts/inc/partition_alter2_2.inc
  mysql-test/suite/parts/inc/partition_auto_increment.inc
  mysql-test/suite/parts/r/partition_alter2_2_innodb.result
  mysql-test/suite/parts/r/partition_alter2_2_myisam.result
  mysql-test/suite/parts/r/partition_auto_increment_archive.result
  mysql-test/suite/parts/r/partition_auto_increment_blackhole.result
  mysql-test/suite/parts/r/partition_auto_increment_innodb.result
  mysql-test/suite/parts/r/partition_auto_increment_memory.result
  mysql-test/suite/parts/r/partition_auto_increment_myisam.result
  mysql-test/suite/parts/r/partition_auto_increment_ndb.result
  mysql-test/suite/parts/t/partition_alter2_2_innodb.test
  mysql-test/suite/parts/t/partition_alter2_2_myisam.test
  mysql-test/suite/parts/t/partition_auto_increment_archive.test
  mysql-test/suite/parts/t/partition_auto_increment_blackhole.test
  mysql-test/suite/parts/t/partition_auto_increment_innodb.test
  mysql-test/suite/parts/t/partition_auto_increment_memory.test
  mysql-test/suite/parts/t/partition_auto_increment_myisam.test
  mysql-test/suite/parts/t/partition_auto_increment_ndb.test
  mysql-test/suite/rpl/r/rpl_binlog_query_filter_rules.result
  mysql-test/suite/rpl/r/rpl_blackhole.result
  mysql-test/suite/rpl/t/rpl_binlog_query_filter_rules-master.opt
  mysql-test/suite/rpl/t/rpl_binlog_query_filter_rules.test
  mysql-test/suite/rpl/t/rpl_blackhole.test
  mysql-test/t/skip_log_bin-master.opt
  mysql-test/t/skip_log_bin.test
  sql/mysql_priv.h.pp
  win/build-vs9.bat
  win/build-vs9_x64.bat
renamed:
  mysql-test/suite/funcs_1/r/innodb_storedproc.result => mysql-test/suite/funcs_1/r/storedproc.result
  mysql-test/suite/funcs_1/storedproc/storedproc_master.inc => mysql-test/suite/funcs_1/t/storedproc.test
  mysql-test/suite/parts/inc/partition_alter2.inc => mysql-test/suite/parts/inc/partition_alter2_1.inc
  mysql-test/suite/parts/r/partition_alter2_innodb.result => mysql-test/suite/parts/r/partition_alter2_1_innodb.result
  mysql-test/suite/parts/r/partition_alter2_myisam.result => mysql-test/suite/parts/r/partition_alter2_1_myisam.result
  mysql-test/suite/parts/t/partition_alter2_innodb.test => mysql-test/suite/parts/t/partition_alter2_1_innodb.test
  mysql-test/suite/parts/t/partition_alter2_myisam.test => mysql-test/suite/parts/t/partition_alter2_1_myisam.test
  mysql-test/suite/rpl/r/rpl_truncate_7ndb_2.result => mysql-test/suite/rpl_ndb/r/rpl_truncate_7ndb_2.result
  mysql-test/suite/rpl/t/rpl_truncate_7ndb_2-master.opt => mysql-test/suite/rpl_ndb/t/rpl_truncate_7ndb_2-master.opt
  mysql-test/suite/rpl/t/rpl_truncate_7ndb_2.test => mysql-test/suite/rpl_ndb/t/rpl_truncate_7ndb_2.test
modified:
  BUILD/compile-dist
  BUILD/compile-solaris-amd64-forte*
  BUILD/compile-solaris-amd64-forte-debug
  BUILD/compile-solaris-sparc
  BUILD/compile-solaris-sparc-forte
  CMakeLists.txt
  Makefile.am
  client/mysqldump.c
  configure.in
  extra/Makefile.am
  extra/yassl/Makefile.am
  extra/yassl/taocrypt/Makefile.am
  include/Makefile.am
  include/hash.h
  include/thr_lock.h
  libmysql/dll.c
  man/Makefile.am
  mysql-test/extra/binlog_tests/binlog.test
  mysql-test/extra/binlog_tests/blackhole.test
  mysql-test/extra/binlog_tests/innodb_stat.test
  mysql-test/extra/rpl_tests/rpl_EE_err.test
  mysql-test/extra/rpl_tests/rpl_ddl.test
  mysql-test/extra/rpl_tests/rpl_log.test
  mysql-test/extra/rpl_tests/rpl_row_basic.test
  mysql-test/include/grant_cache.inc
  mysql-test/include/index_merge1.inc
  mysql-test/include/mix1.inc
  mysql-test/include/ndb_backup_print.inc
  mysql-test/lib/mtr_cases.pl
  mysql-test/lib/mtr_report.pl
  mysql-test/mysql-test-run.pl
  mysql-test/r/auto_increment.result
  mysql-test/r/compare.result
  mysql-test/r/create.result
  mysql-test/r/ctype_cp932_binlog_stm.result
  mysql-test/r/ctype_ucs.result
  mysql-test/r/default.result
  mysql-test/r/distinct.result
  mysql-test/r/events_2.result
  mysql-test/r/federated.result
  mysql-test/r/federated_bug_25714.result
  mysql-test/r/func_group.result
  mysql-test/r/func_regexp.result
  mysql-test/r/grant2.result
  mysql-test/r/grant_cache_no_prot.result
  mysql-test/r/grant_cache_ps_prot.result
  mysql-test/r/index_merge_myisam.result
  mysql-test/r/information_schema_db.result
  mysql-test/r/innodb-semi-consistent.result
  mysql-test/r/innodb.result
  mysql-test/r/innodb_mysql.result
  mysql-test/r/join.result
  mysql-test/r/loaddata.result
  mysql-test/r/lock_multi.result
  mysql-test/r/log_basic.result
  mysql-test/r/log_bin_trust_routine_creators_basic.result
  mysql-test/r/log_state.result
  mysql-test/r/log_tables.result
  mysql-test/r/mysqldump-max.result
  mysql-test/r/mysqldump.result
  mysql-test/r/partition.result
  mysql-test/r/partition_range.result
  mysql-test/r/slow_launch_time_func.result
  mysql-test/r/sp-error.result
  mysql-test/r/sp.result
  mysql-test/r/status.result
  mysql-test/r/trigger-trans.result
  mysql-test/r/tx_isolation_func.result
  mysql-test/r/type_datetime.result
  mysql-test/r/type_set.result
  mysql-test/r/user_var.result
  mysql-test/r/view_grant.result
  mysql-test/r/warnings.result
  mysql-test/suite/binlog/r/binlog_multi_engine.result
  mysql-test/suite/binlog/r/binlog_row_binlog.result
  mysql-test/suite/binlog/r/binlog_row_innodb_stat.result
  mysql-test/suite/binlog/r/binlog_stm_binlog.result
  mysql-test/suite/binlog/r/binlog_stm_blackhole.result
  mysql-test/suite/binlog/r/binlog_stm_innodb_stat.result
  mysql-test/suite/binlog/t/binlog_killed.test
  mysql-test/suite/binlog/t/binlog_killed_simulate.test
  mysql-test/suite/binlog/t/binlog_multi_engine.test
  mysql-test/suite/binlog/t/binlog_start_comment.test
  mysql-test/suite/binlog/t/binlog_stm_innodb_stat.test
  mysql-test/suite/funcs_1/datadict/processlist_priv.inc
  mysql-test/suite/funcs_1/r/processlist_priv_no_prot.result
  mysql-test/suite/funcs_1/r/processlist_priv_ps.result
  mysql-test/suite/funcs_1/views/func_view.inc
  mysql-test/suite/ndb/t/ndb_restore_print.test
  mysql-test/suite/ndb_team/t/ndb_autodiscover.test
  mysql-test/suite/parts/t/disabled.def
  mysql-test/suite/rpl/r/rpl_row_basic_2myisam.result
  mysql-test/suite/rpl/r/rpl_row_basic_3innodb.result
  mysql-test/suite/rpl/r/rpl_row_create_table.result
  mysql-test/suite/rpl/r/rpl_row_log.result
  mysql-test/suite/rpl/r/rpl_row_log_innodb.result
  mysql-test/suite/rpl/r/rpl_sp.result
  mysql-test/suite/rpl/r/rpl_stm_log.result
  mysql-test/suite/rpl/r/rpl_temporary.result
  mysql-test/suite/rpl/t/disabled.def
  mysql-test/suite/rpl/t/rpl_row_create_table.test
  mysql-test/suite/rpl/t/rpl_stm_log-slave.opt
  mysql-test/suite/rpl/t/rpl_temporary.test
  mysql-test/suite/rpl_ndb/r/rpl_row_basic_7ndb.result
  mysql-test/t/auto_increment.test
  mysql-test/t/compare.test
  mysql-test/t/create.test
  mysql-test/t/ctype_big5.test
  mysql-test/t/ctype_ucs.test
  mysql-test/t/default.test
  mysql-test/t/disabled.def
  mysql-test/t/distinct.test
  mysql-test/t/events_2.test
  mysql-test/t/federated.test
  mysql-test/t/federated_bug_25714.test
  mysql-test/t/func_group.test
  mysql-test/t/func_regexp.test
  mysql-test/t/grant2.test
  mysql-test/t/information_schema_db.test
  mysql-test/t/innodb-semi-consistent.test
  mysql-test/t/innodb.test
  mysql-test/t/join.test
  mysql-test/t/loaddata.test
  mysql-test/t/lock_multi.test
  mysql-test/t/log_basic.test
  mysql-test/t/log_state.test
  mysql-test/t/log_tables.test
  mysql-test/t/mysqldump-max.test
  mysql-test/t/mysqldump.test
  mysql-test/t/outfile.test
  mysql-test/t/partition.test
  mysql-test/t/partition_range.test
  mysql-test/t/slow_launch_time_func.test
  mysql-test/t/sp-error.test
  mysql-test/t/sp.test
  mysql-test/t/status.test
  mysql-test/t/symlink.test
  mysql-test/t/trigger-trans.test
  mysql-test/t/tx_isolation_func.test
  mysql-test/t/type_datetime.test
  mysql-test/t/type_set.test
  mysql-test/t/user_var.test
  mysql-test/t/view_grant.test
  mysys/hash.c
  mysys/stacktrace.c
  scripts/make_binary_distribution.sh
  scripts/mysql_system_tables_data.sql
  sql/event_db_repository.cc
  sql/event_parse_data.cc
  sql/event_parse_data.h
  sql/field.cc
  sql/field.h
  sql/ha_partition.cc
  sql/ha_partition.h
  sql/handler.cc
  sql/handler.h
  sql/item.cc
  sql/item.h
  sql/item_cmpfunc.cc
  sql/item_cmpfunc.h
  sql/item_func.cc
  sql/item_func.h
  sql/lock.cc
  sql/log.cc
  sql/log.h
  sql/log_event.cc
  sql/mysql_priv.h
  sql/mysqld.cc
  sql/opt_range.cc
  sql/parse_file.cc
  sql/parse_file.h
  sql/partition_info.h
  sql/set_var.cc
  sql/set_var.h
  sql/sp_head.cc
  sql/sql_acl.cc
  sql/sql_base.cc
  sql/sql_cache.cc
  sql/sql_class.cc
  sql/sql_class.h
  sql/sql_db.cc
  sql/sql_derived.cc
  sql/sql_insert.cc
  sql/sql_lex.cc
  sql/sql_lex.h
  sql/sql_load.cc
  sql/sql_parse.cc
  sql/sql_partition.cc
  sql/sql_select.cc
  sql/sql_show.cc
  sql/sql_show.h
  sql/sql_table.cc
  sql/sql_union.cc
  sql/sql_update.cc
  sql/sql_view.cc
  sql/sql_yacc.yy
  sql/table.cc
  sql/table.h
  storage/blackhole/ha_blackhole.cc
  storage/blackhole/ha_blackhole.h
  support-files/my-huge.cnf.sh
  support-files/my-innodb-heavy-4G.cnf.sh
  support-files/my-large.cnf.sh
  support-files/my-medium.cnf.sh
  support-files/my-small.cnf.sh
  support-files/mysql.spec.sh
  win/create_manifest.js
  zlib/gzio.c
  zlib/zutil.h
  mysql-test/suite/funcs_1/r/storedproc.result
  mysql-test/suite/funcs_1/t/storedproc.test
  mysql-test/suite/parts/inc/partition_alter2_1.inc
  mysql-test/suite/parts/r/partition_alter2_1_innodb.result
  mysql-test/suite/parts/r/partition_alter2_1_myisam.result
  mysql-test/suite/parts/t/partition_alter2_1_innodb.test
  mysql-test/suite/parts/t/partition_alter2_1_myisam.test
  mysql-test/suite/rpl_ndb/r/rpl_truncate_7ndb_2.result
  mysql-test/suite/rpl_ndb/t/rpl_truncate_7ndb_2.test

=== added file 'mysql-test/suite/ndb/r/ndb_dbug_lock.result'
--- a/mysql-test/suite/ndb/r/ndb_dbug_lock.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/ndb/r/ndb_dbug_lock.result	2008-10-29 13:09:15 +0000
@@ -0,0 +1,44 @@
+drop table if exists t1;
+#
+# Test that alter during lock table aborts with error if
+# global schema lock already exists
+#
+create table t1 (a int key) engine ndb row_format dynamic;
+set session debug="+d,sleep_after_global_schema_lock";
+alter table t1 add column (b int);
+lock tables t1 write;
+alter table t1 add column (c int);
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
+alter table t1 add column (c int);
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
+alter table t1 add column (c int);
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
+unlock tables;
+#
+# Test that alter during lock works without global schema lock
+# and that an alter done in parallell test serialized
+#
+lock tables t1 write;
+# delay is still set after lock
+alter table t1 add column (c int);
+# issue alter in parallell, which should be hanging waiting on
+alter table t1 add column (d int);
+# check thread state which should be:
+# "Waiting for allowed to take ndbcluster global schema lock"
+# _not_ "Waiting for ndbcluster global schema lock"
+select state from information_schema.processlist where info = "alter table t1 add column (d int)";
+state
+Waiting for allowed to take ndbcluster global schema lock
+unlock tables;
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) NOT NULL,
+  `b` int(11) DEFAULT NULL,
+  `c` int(11) DEFAULT NULL,
+  `d` int(11) DEFAULT NULL,
+  PRIMARY KEY (`a`)
+) ENGINE=ndbcluster DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC
+# Cleanup
+set session debug="-d,sleep_after_global_schema_lock";
+drop table t1;

=== added file 'mysql-test/suite/ndb/t/ndb_dbug_lock.test'
--- a/mysql-test/suite/ndb/t/ndb_dbug_lock.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/ndb/t/ndb_dbug_lock.test	2008-10-29 13:09:15 +0000
@@ -0,0 +1,70 @@
+-- source include/have_ndb.inc
+# We are using some debug-only features in this test
+--source include/have_debug.inc
+
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+
+--connect (another_con, localhost, root,,)
+--connect (yet_another_con, localhost, root,,)
+
+--echo #
+--echo # Test that alter during lock table aborts with error if
+--echo # global schema lock already exists
+--echo #
+--connection default
+create table t1 (a int key) engine ndb row_format dynamic;
+# delay after lock
+set session debug="+d,sleep_after_global_schema_lock";
+--send alter table t1 add column (b int)
+--sleep 2
+
+--connection another_con
+lock tables t1 write;
+--error ER_LOCK_OR_ACTIVE_TRANSACTION
+alter table t1 add column (c int);
+# make sure it continues to block
+--error ER_LOCK_OR_ACTIVE_TRANSACTION
+alter table t1 add column (c int);
+--error ER_LOCK_OR_ACTIVE_TRANSACTION
+alter table t1 add column (c int);
+unlock tables;
+
+--connection default
+--reap
+
+--echo #
+--echo # Test that alter during lock works without global schema lock
+--echo # and that an alter done in parallell test serialized
+--echo #
+--connection default
+lock tables t1 write;
+--echo # delay is still set after lock
+--send alter table t1 add column (c int)
+--sleep 2
+
+--echo # issue alter in parallell, which should be hanging waiting on
+--connection another_con
+--send alter table t1 add column (d int)
+
+--echo # check thread state which should be:
+--echo # "Waiting for allowed to take ndbcluster global schema lock"
+--echo # _not_ "Waiting for ndbcluster global schema lock"
+--connection yet_another_con
+select state from information_schema.processlist where info = "alter table t1 add column (d int)";
+
+# wait for alter to complete
+--connection default
+--reap
+unlock tables;
+
+--connection another_con
+--reap
+
+show create table t1;
+
+--echo # Cleanup
+--connection default
+set session debug="-d,sleep_after_global_schema_lock";
+drop table t1;

=== modified file 'sql/ha_ndbcluster.cc'
--- a/sql/ha_ndbcluster.cc	2008-10-28 14:02:09 +0000
+++ b/sql/ha_ndbcluster.cc	2008-10-29 13:09:15 +0000
@@ -7615,6 +7615,7 @@ static int ndbcluster_init(void *p)
   ndbcluster_terminating= 0;
   ndb_dictionary_is_mysqld= 1;
   ndbcluster_hton= (handlerton *)p;
+  ndbcluster_global_schema_lock_init();
 
   {
     handlerton *h= ndbcluster_hton;
@@ -7667,6 +7668,7 @@ static int ndbcluster_init(void *p)
     pthread_mutex_destroy(&LOCK_ndb_util_thread);
     pthread_cond_destroy(&COND_ndb_util_thread);
     pthread_cond_destroy(&COND_ndb_util_ready);
+    ndbcluster_global_schema_lock_deinit();
     goto ndbcluster_init_error;
   }
 
@@ -7684,6 +7686,7 @@ static int ndbcluster_init(void *p)
     pthread_mutex_destroy(&LOCK_ndb_util_thread);
     pthread_cond_destroy(&COND_ndb_util_thread);
     pthread_cond_destroy(&COND_ndb_util_ready);
+    ndbcluster_global_schema_lock_deinit();
     goto ndbcluster_init_error;
   }
 
@@ -7747,6 +7750,7 @@ static int ndbcluster_end(handlerton *ht
   pthread_mutex_destroy(&LOCK_ndb_util_thread);
   pthread_cond_destroy(&COND_ndb_util_thread);
   pthread_cond_destroy(&COND_ndb_util_ready);
+  ndbcluster_global_schema_lock_deinit();
   DBUG_RETURN(0);
 }
 

=== modified file 'sql/ha_ndbcluster_binlog.cc'
--- a/sql/ha_ndbcluster_binlog.cc	2008-10-09 09:10:50 +0000
+++ b/sql/ha_ndbcluster_binlog.cc	2008-10-29 13:09:15 +0000
@@ -767,7 +767,19 @@ int ndbcluster_no_global_schema_lock_abo
   lock/unlock calls are reference counted, so calls to lock
   must be matched to a call to unlock even if the lock call fails
 */
-static int ndbcluster_global_schema_lock(THD *thd,
+static int ndbcluster_global_schema_lock_is_locked_or_queued= 0;
+static int ndbcluster_global_schema_lock_no_locking_allowed= 0;
+static pthread_mutex_t ndbcluster_global_schema_lock_mutex;
+void ndbcluster_global_schema_lock_init()
+{
+  pthread_mutex_init(&ndbcluster_global_schema_lock_mutex, MY_MUTEX_INIT_FAST);
+}
+void ndbcluster_global_schema_lock_deinit()
+{
+  pthread_mutex_destroy(&ndbcluster_global_schema_lock_mutex);
+}
+
+static int ndbcluster_global_schema_lock(THD *thd, int no_lock_queue,
                                          int report_cluster_disconnected)
 {
   Ndb *ndb= check_ndb_in_thd(thd);
@@ -776,7 +788,8 @@ static int ndbcluster_global_schema_lock
   if (thd_ndb->options & TNO_NO_LOCK_SCHEMA_OP)
     return 0;
   DBUG_ENTER("ndbcluster_global_schema_lock");
-  DBUG_PRINT("enter", ("query: %s", thd->query));
+  DBUG_PRINT("enter", ("query: %s, no_lock_queue: %d",
+                       thd->query, no_lock_queue));
   if (thd_ndb->global_schema_lock_count)
   {
     if (thd_ndb->global_schema_lock_trans)
@@ -794,8 +807,65 @@ static int ndbcluster_global_schema_lock
   DBUG_PRINT("exit", ("global_schema_lock_count: %d",
                       thd_ndb->global_schema_lock_count));
 
-  if ((thd_ndb->global_schema_lock_trans=
-       ndbcluster_global_schema_lock_ext(thd, ndb, ndb_error, -1)) != NULL)
+  /*
+    Check that taking the lock is allowed
+    - if not allowed to enter lock queue, return if lock exists
+    - wait until allowed
+    - increase global lock count
+  */
+  Thd_proc_info_guard thd_proc_info_guard(thd);
+  pthread_mutex_lock(&ndbcluster_global_schema_lock_mutex);
+  /* increase global lock count */
+  ndbcluster_global_schema_lock_is_locked_or_queued++;
+  if (no_lock_queue)
+  {
+    if (ndbcluster_global_schema_lock_is_locked_or_queued != 1)
+    {
+      /* Other thread has lock and this thread may not enter lock queue */
+      pthread_mutex_unlock(&ndbcluster_global_schema_lock_mutex);
+      thd_ndb->global_schema_lock_error= -1;
+      DBUG_PRINT("exit", ("aborting as lock exists"));
+      DBUG_RETURN(-1);
+    }
+    /* Mark that no other thread may be take lock */
+    ndbcluster_global_schema_lock_no_locking_allowed= 1;
+  }
+  else
+  {
+    while (ndbcluster_global_schema_lock_no_locking_allowed)
+    {
+      thd_proc_info(thd, "Waiting for allowed to take ndbcluster global schema lock");
+      /* Wait until locking is allowed */
+      pthread_mutex_unlock(&ndbcluster_global_schema_lock_mutex);
+      do_retry_sleep(50);
+      if (thd->killed)
+      {
+        thd_ndb->global_schema_lock_error= -1;
+        DBUG_RETURN(-1);
+      }
+      pthread_mutex_lock(&ndbcluster_global_schema_lock_mutex);
+    }
+  }
+  pthread_mutex_unlock(&ndbcluster_global_schema_lock_mutex);
+
+  /*
+    Take the lock
+  */
+  thd_proc_info(thd, "Waiting for ndbcluster global schema lock");
+  thd_ndb->global_schema_lock_trans=
+    ndbcluster_global_schema_lock_ext(thd, ndb, ndb_error, -1);
+
+  DBUG_EXECUTE_IF("sleep_after_global_schema_lock", my_sleep(6000000););
+
+  if (no_lock_queue)
+  {
+    pthread_mutex_lock(&ndbcluster_global_schema_lock_mutex);
+    /* Mark that other thread may be take lock */
+    ndbcluster_global_schema_lock_no_locking_allowed= 0;
+    pthread_mutex_unlock(&ndbcluster_global_schema_lock_mutex);
+  }
+
+  if (thd_ndb->global_schema_lock_trans)
   {
     DBUG_RETURN(0);
   }
@@ -838,6 +908,14 @@ static int ndbcluster_global_schema_unlo
     DBUG_RETURN(0);
   }
   thd_ndb->global_schema_lock_error= 0;
+
+  /*
+    Decrease global lock count
+  */
+  pthread_mutex_lock(&ndbcluster_global_schema_lock_mutex);
+  ndbcluster_global_schema_lock_is_locked_or_queued--;
+  pthread_mutex_unlock(&ndbcluster_global_schema_lock_mutex);
+
   if (trans)
   {
     thd_ndb->global_schema_lock_trans= NULL;
@@ -879,7 +957,7 @@ static int ndbcluster_binlog_func(handle
     ndbcluster_binlog_index_purge_file(thd, (const char *)arg);
     break;
   case BFN_GLOBAL_SCHEMA_LOCK:
-    DBUG_RETURN(ndbcluster_global_schema_lock(thd, 1));
+    DBUG_RETURN(ndbcluster_global_schema_lock(thd, *(int*)arg, 1));
     break;
   case BFN_GLOBAL_SCHEMA_UNLOCK:
     ndbcluster_global_schema_unlock(thd);
@@ -906,7 +984,7 @@ int Ndbcluster_global_schema_lock_guard:
     of calls to lock and unlock need to match up.
   */
   m_lock= 1;
-  return ndbcluster_global_schema_lock(m_thd, 0);
+  return ndbcluster_global_schema_lock(m_thd, 0, 0);
 }
 
 void ndbcluster_binlog_init_handlerton()

=== modified file 'sql/ha_ndbcluster_binlog.h'
--- a/sql/ha_ndbcluster_binlog.h	2008-10-07 08:19:31 +0000
+++ b/sql/ha_ndbcluster_binlog.h	2008-10-29 13:09:15 +0000
@@ -135,7 +135,20 @@ private:
   int m_invalidate;
 };
 
+class Thd_proc_info_guard
+{
+public:
+  Thd_proc_info_guard(THD *thd)
+   : m_thd(thd), m_proc_info(thd->proc_info) {}
+  ~Thd_proc_info_guard() { m_thd->proc_info= m_proc_info; }
+private:
+  THD *m_thd;
+  const char *m_proc_info;
+};
+
 extern Ndb_cluster_connection* g_ndb_cluster_connection;
+void ndbcluster_global_schema_lock_init();
+void ndbcluster_global_schema_lock_deinit();
 
 #ifdef HAVE_NDB_BINLOG
 extern pthread_t ndb_binlog_thread;

=== modified file 'sql/handler.cc'
--- a/sql/handler.cc	2008-10-28 14:02:09 +0000
+++ b/sql/handler.cc	2008-10-29 13:09:15 +0000
@@ -3891,14 +3891,15 @@ static my_bool binlog_func_foreach(THD *
 {
   hton_list_st hton_list;
   uint i, sz;
+  int res= 0;
 
   hton_list.sz= 0;
   plugin_foreach(thd, binlog_func_list,
                  MYSQL_STORAGE_ENGINE_PLUGIN, &hton_list);
 
   for (i= 0, sz= hton_list.sz; i < sz ; i++)
-    hton_list.hton[i]->binlog_func(hton_list.hton[i], thd, bfn->fn, bfn->arg);
-  return FALSE;
+    res|= hton_list.hton[i]->binlog_func(hton_list.hton[i], thd, bfn->fn, bfn->arg);
+  return res != 0;
 }
 
 int ha_reset_logs(THD *thd)
@@ -3941,11 +3942,11 @@ int ha_binlog_index_purge_file(THD *thd,
   return 0;
 }
 
-static int ha_global_schema_lock(THD *thd)
+static int ha_global_schema_lock(THD *thd, int no_queue)
 {
-  binlog_func_st bfn= {BFN_GLOBAL_SCHEMA_LOCK, 0};
-  binlog_func_foreach(thd, &bfn);
-  if (thd->main_da.is_error())
+  binlog_func_st bfn= {BFN_GLOBAL_SCHEMA_LOCK, (void *)&no_queue};
+  int res= binlog_func_foreach(thd, &bfn);
+  if (res || thd->main_da.is_error())
     return 1;
   return 0;
 }
@@ -3970,11 +3971,11 @@ Ha_global_schema_lock_guard::~Ha_global_
     ha_global_schema_unlock(m_thd);
 }
 
-int Ha_global_schema_lock_guard::lock()
+int Ha_global_schema_lock_guard::lock(int no_queue)
 {
   DBUG_ASSERT(m_lock == 0);
   m_lock= 1;
-  return ha_global_schema_lock(m_thd);
+  return ha_global_schema_lock(m_thd, no_queue);
 }
 
 struct binlog_log_query_st

=== modified file 'sql/handler.h'
--- a/sql/handler.h	2008-10-28 14:02:09 +0000
+++ b/sql/handler.h	2008-10-29 13:09:15 +0000
@@ -2198,7 +2198,7 @@ class Ha_global_schema_lock_guard
 public:
   Ha_global_schema_lock_guard(THD *thd);
   ~Ha_global_schema_lock_guard();
-  int lock();
+  int lock(int no_queue= 0);
 private:
   THD *m_thd;
   int m_lock;
@@ -2216,6 +2216,6 @@ class Ha_global_schema_lock_guard
 public:
   Ha_global_schema_lock_guard(THD *thd) {}
   ~Ha_global_schema_lock_guard() {}
-  int lock() { return 0; }
+  int lock(int no_queue= 0) { return 0; }
 };
 #endif

=== modified file 'sql/sql_table.cc'
--- a/sql/sql_table.cc	2008-10-28 14:02:09 +0000
+++ b/sql/sql_table.cc	2008-10-29 13:09:15 +0000
@@ -6639,16 +6639,24 @@ view_err:
   if (table_type == DB_TYPE_NDBCLUSTER ||
       (create_info->db_type && create_info->db_type->db_type == DB_TYPE_NDBCLUSTER))
   {
-    /*
-      To avoid deadlock in this situation
-    */
     if (thd->locked_tables)
     {
-      my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
-                 ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
-      DBUG_RETURN(TRUE);
+      /*
+        To avoid deadlock in this situation:
+        - if other thread has lock do not enter lock queue
+        and report an error instead
+      */
+      if (global_schema_lock_guard.lock(1))
+      {
+        my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
+                   ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
+        DBUG_RETURN(TRUE);
+      }
+    }
+    else
+    {
+      global_schema_lock_guard.lock();
     }
-    global_schema_lock_guard.lock();
   }
   if (!(table= open_n_lock_single_table(thd, table_list, TL_WRITE_ALLOW_READ)))
     DBUG_RETURN(TRUE);

=== modified file 'storage/ndb/src/cw/cpcd/main.cpp'
--- a/storage/ndb/src/cw/cpcd/main.cpp	2007-05-10 09:59:39 +0000
+++ b/storage/ndb/src/cw/cpcd/main.cpp	2008-10-28 15:16:07 +0000
@@ -75,7 +75,7 @@ const char *progname = "ndb_cpcd";
 
 int main(int argc, char** argv){
   const char *load_default_groups[]= { "ndb_cpcd",0 };
-  MY_INIT(argv[0]);
+  NDB_INIT(argv[0]);
 
   load_defaults("ndb_cpcd",load_default_groups,&argc,&argv);
   if (handle_options(&argc, &argv, my_long_options, get_one_option)) {

Thread
bzr push into mysql-5.1 branch (tomas.ulin:2708 to 2710) Bug#40246Tomas Ulin29 Oct