From 3c614245633d4a736d8910b86520a562e62e2f8a Mon Sep 17 00:00:00 2001 From: "mskold/marty@mysql.com/linux.site" <> Date: Mon, 7 Aug 2006 13:51:20 +0200 Subject: [PATCH 1/9] Fix for bug #21059 Server crashes on join query with large dataset with NDB tables: Releasing operation for each intermediate batch, before next call to trans->execute(NoCommit); --- ndb/include/ndbapi/NdbConnection.hpp | 3 ++- sql/ha_ndbcluster.cc | 8 ++++++++ sql/ha_ndbcluster.h | 2 ++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/ndb/include/ndbapi/NdbConnection.hpp b/ndb/include/ndbapi/NdbConnection.hpp index 75c3f80121d..8d7735c9300 100644 --- a/ndb/include/ndbapi/NdbConnection.hpp +++ b/ndb/include/ndbapi/NdbConnection.hpp @@ -163,7 +163,8 @@ class NdbConnection friend class NdbIndexOperation; friend class NdbIndexScanOperation; friend class NdbBlob; - + friend class ha_ndbcluster; + public: /** diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 1031c4f635c..f508e3cc339 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -161,6 +161,7 @@ int execute_no_commit(ha_ndbcluster *h, NdbConnection *trans) if (m_batch_execute) return 0; #endif + h->release_completed_operations(trans); return trans->execute(NoCommit,AbortOnError,h->m_force_send); } @@ -194,6 +195,7 @@ int execute_no_commit_ie(ha_ndbcluster *h, NdbConnection *trans) if (m_batch_execute) return 0; #endif + h->release_completed_operations(trans); return trans->execute(NoCommit, AO_IgnoreError,h->m_force_send); } @@ -5269,6 +5271,12 @@ int ha_ndbcluster::write_ndb_file() DBUG_RETURN(error); } +void +ha_ndbcluster::release_completed_operations(NdbConnection *trans) +{ + trans->releaseCompletedOperations(); +} + int ndbcluster_show_status(THD* thd) { diff --git a/sql/ha_ndbcluster.h b/sql/ha_ndbcluster.h index 313e497f9b5..4a53b4007fe 100644 --- a/sql/ha_ndbcluster.h +++ b/sql/ha_ndbcluster.h @@ -262,6 +262,8 @@ class ha_ndbcluster: public handler void no_uncommitted_rows_init(THD *); void no_uncommitted_rows_reset(THD *); + void release_completed_operations(NdbConnection*); + friend int execute_no_commit(ha_ndbcluster*, NdbConnection*); friend int execute_commit(ha_ndbcluster*, NdbConnection*); friend int execute_no_commit_ie(ha_ndbcluster*, NdbConnection*); From d7f8c331e1cb36499056a962e4f6453cc0f932a7 Mon Sep 17 00:00:00 2001 From: "mskold/marty@mysql.com/linux.site" <> Date: Mon, 7 Aug 2006 14:48:54 +0200 Subject: [PATCH 2/9] Fix for bug #21059 Server crashes on join query with large dataset with NDB tables: Releasing operation for each intermediate batch, before next call to trans->execute(NoCommit); --- sql/ha_ndbcluster.cc | 61 ++++++++++++++++++++++++++++++++------------ sql/ha_ndbcluster.h | 13 ++++++++-- 2 files changed, 55 insertions(+), 19 deletions(-) diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 46ab5b88624..0b31b41fa38 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -228,13 +228,15 @@ static int ndb_to_mysql_error(const NdbError *err) inline -int execute_no_commit(ha_ndbcluster *h, NdbTransaction *trans) +int execute_no_commit(ha_ndbcluster *h, NdbTransaction *trans, + bool force_release) { #ifdef NOT_USED int m_batch_execute= 0; if (m_batch_execute) return 0; #endif + h->release_completed_operations(trans, force_release); return trans->execute(NdbTransaction::NoCommit, NdbTransaction::AbortOnError, h->m_force_send); @@ -267,13 +269,15 @@ int execute_commit(THD *thd, NdbTransaction *trans) } inline -int execute_no_commit_ie(ha_ndbcluster *h, NdbTransaction *trans) +int execute_no_commit_ie(ha_ndbcluster *h, NdbTransaction *trans, + bool force_release) { #ifdef NOT_USED int m_batch_execute= 0; if (m_batch_execute) return 0; #endif + h->release_completed_operations(trans, force_release); return trans->execute(NdbTransaction::NoCommit, NdbTransaction::AO_IgnoreError, h->m_force_send); @@ -290,6 +294,7 @@ Thd_ndb::Thd_ndb() all= NULL; stmt= NULL; error= 0; + query_state&= NDB_QUERY_NORMAL; } Thd_ndb::~Thd_ndb() @@ -1442,7 +1447,7 @@ int ha_ndbcluster::pk_read(const byte *key, uint key_len, byte *buf) if ((res= define_read_attrs(buf, op))) DBUG_RETURN(res); - if (execute_no_commit_ie(this,trans) != 0) + if (execute_no_commit_ie(this,trans,false) != 0) { table->status= STATUS_NOT_FOUND; DBUG_RETURN(ndb_err(trans)); @@ -1489,7 +1494,7 @@ int ha_ndbcluster::complemented_pk_read(const byte *old_data, byte *new_data) ERR_RETURN(trans->getNdbError()); } } - if (execute_no_commit(this,trans) != 0) + if (execute_no_commit(this,trans,false) != 0) { table->status= STATUS_NOT_FOUND; DBUG_RETURN(ndb_err(trans)); @@ -1629,7 +1634,7 @@ int ha_ndbcluster::peek_indexed_rows(const byte *record) } last= trans->getLastDefinedOperation(); if (first) - res= execute_no_commit_ie(this,trans); + res= execute_no_commit_ie(this,trans,false); else { // Table has no keys @@ -1678,7 +1683,7 @@ int ha_ndbcluster::unique_index_read(const byte *key, if ((res= define_read_attrs(buf, op))) DBUG_RETURN(res); - if (execute_no_commit_ie(this,trans) != 0) + if (execute_no_commit_ie(this,trans,false) != 0) { table->status= STATUS_NOT_FOUND; DBUG_RETURN(ndb_err(trans)); @@ -1726,7 +1731,7 @@ inline int ha_ndbcluster::fetch_next(NdbScanOperation* cursor) */ if (m_ops_pending && m_blobs_pending) { - if (execute_no_commit(this,trans) != 0) + if (execute_no_commit(this,trans,false) != 0) DBUG_RETURN(ndb_err(trans)); m_ops_pending= 0; m_blobs_pending= FALSE; @@ -1758,7 +1763,7 @@ inline int ha_ndbcluster::fetch_next(NdbScanOperation* cursor) { if (m_transaction_on) { - if (execute_no_commit(this,trans) != 0) + if (execute_no_commit(this,trans,false) != 0) DBUG_RETURN(-1); } else @@ -2062,7 +2067,7 @@ int ha_ndbcluster::ordered_index_scan(const key_range *start_key, DBUG_RETURN(res); } - if (execute_no_commit(this,trans) != 0) + if (execute_no_commit(this,trans,false) != 0) DBUG_RETURN(ndb_err(trans)); DBUG_RETURN(next_result(buf)); @@ -2095,7 +2100,7 @@ int ha_ndbcluster::full_table_scan(byte *buf) if ((res= define_read_attrs(buf, op))) DBUG_RETURN(res); - if (execute_no_commit(this,trans) != 0) + if (execute_no_commit(this,trans,false) != 0) DBUG_RETURN(ndb_err(trans)); DBUG_PRINT("exit", ("Scan started successfully")); DBUG_RETURN(next_result(buf)); @@ -2227,7 +2232,7 @@ int ha_ndbcluster::write_row(byte *record) m_bulk_insert_not_flushed= FALSE; if (m_transaction_on) { - if (execute_no_commit(this,trans) != 0) + if (execute_no_commit(this,trans,false) != 0) { m_skip_auto_increment= TRUE; no_uncommitted_rows_execute_failure(); @@ -2426,7 +2431,7 @@ int ha_ndbcluster::update_row(const byte *old_data, byte *new_data) } // Execute update operation - if (!cursor && execute_no_commit(this,trans) != 0) { + if (!cursor && execute_no_commit(this,trans,false) != 0) { no_uncommitted_rows_execute_failure(); DBUG_RETURN(ndb_err(trans)); } @@ -2497,7 +2502,7 @@ int ha_ndbcluster::delete_row(const byte *record) } // Execute delete operation - if (execute_no_commit(this,trans) != 0) { + if (execute_no_commit(this,trans,false) != 0) { no_uncommitted_rows_execute_failure(); DBUG_RETURN(ndb_err(trans)); } @@ -2931,7 +2936,7 @@ int ha_ndbcluster::close_scan() deleteing/updating transaction before closing the scan */ DBUG_PRINT("info", ("ops_pending: %d", m_ops_pending)); - if (execute_no_commit(this,trans) != 0) { + if (execute_no_commit(this,trans,false) != 0) { no_uncommitted_rows_execute_failure(); DBUG_RETURN(ndb_err(trans)); } @@ -3337,7 +3342,7 @@ int ha_ndbcluster::end_bulk_insert() m_bulk_insert_not_flushed= FALSE; if (m_transaction_on) { - if (execute_no_commit(this, trans) != 0) + if (execute_no_commit(this, trans,false) != 0) { no_uncommitted_rows_execute_failure(); my_errno= error= ndb_err(trans); @@ -3510,6 +3515,7 @@ int ha_ndbcluster::external_lock(THD *thd, int lock_type) ERR_RETURN(ndb->getNdbError()); no_uncommitted_rows_reset(thd); thd_ndb->stmt= trans; + thd_ndb->query_state&= NDB_QUERY_NORMAL; trans_register_ha(thd, FALSE, &ndbcluster_hton); } else @@ -3525,6 +3531,7 @@ int ha_ndbcluster::external_lock(THD *thd, int lock_type) ERR_RETURN(ndb->getNdbError()); no_uncommitted_rows_reset(thd); thd_ndb->all= trans; + thd_ndb->query_state&= NDB_QUERY_NORMAL; trans_register_ha(thd, TRUE, &ndbcluster_hton); /* @@ -3731,6 +3738,7 @@ int ha_ndbcluster::start_stmt(THD *thd, thr_lock_type lock_type) thd_ndb->stmt= trans; trans_register_ha(thd, FALSE, &ndbcluster_hton); } + thd_ndb->query_state&= NDB_QUERY_NORMAL; m_active_trans= trans; // Start of statement @@ -5969,6 +5977,7 @@ ha_ndbcluster::read_multi_range_first(KEY_MULTI_RANGE **found_range_p, NDB_INDEX_TYPE index_type= get_index_type(active_index); ulong reclength= table->s->reclength; NdbOperation* op; + Thd_ndb *thd_ndb= get_thd_ndb(current_thd); if (uses_blob_value(m_retrieve_all_fields)) { @@ -5982,7 +5991,7 @@ ha_ndbcluster::read_multi_range_first(KEY_MULTI_RANGE **found_range_p, sorted, buffer)); } - + thd_ndb->query_state|= NDB_QUERY_MULTI_READ_RANGE; m_disable_multi_read= FALSE; /** @@ -6129,7 +6138,7 @@ ha_ndbcluster::read_multi_range_first(KEY_MULTI_RANGE **found_range_p, */ m_current_multi_operation= lastOp ? lastOp->next() : m_active_trans->getFirstDefinedOperation(); - if (!(res= execute_no_commit_ie(this, m_active_trans))) + if (!(res= execute_no_commit_ie(this, m_active_trans,true))) { m_multi_range_defined= multi_range_curr; multi_range_curr= ranges; @@ -7831,6 +7840,24 @@ ha_ndbcluster::generate_scan_filter(Ndb_cond_stack *ndb_cond_stack, DBUG_RETURN(0); } + +void +ha_ndbcluster::release_completed_operations(NdbTransaction *trans, + bool force_release) +{ + if (!force_release) + { + if (get_thd_ndb(current_thd)->query_state & NDB_QUERY_MULTI_READ_RANGE) + { + /* We are batching reads and have not consumed all fetched + rows yet, releasing operation records is unsafe + */ + return; + } + } + trans->releaseCompletedOperations(); +} + int ndbcluster_show_status(THD* thd) { diff --git a/sql/ha_ndbcluster.h b/sql/ha_ndbcluster.h index 01950c2b00f..d098a5f77aa 100644 --- a/sql/ha_ndbcluster.h +++ b/sql/ha_ndbcluster.h @@ -435,6 +435,12 @@ class Ndb_cond_traverse_context Ndb_rewrite_context *rewrite_stack; }; + +typedef enum ndb_query_state_bits { + NDB_QUERY_NORMAL = 0, + NDB_QUERY_MULTI_READ_RANGE = 1 +} NDB_QUERY_STATE_BITS; + /* Place holder for ha_ndbcluster thread specific data */ @@ -451,6 +457,7 @@ class Thd_ndb NdbTransaction *stmt; int error; List changed_tables; + uint query_state; }; class ha_ndbcluster: public handler @@ -657,6 +664,8 @@ private: void no_uncommitted_rows_init(THD *); void no_uncommitted_rows_reset(THD *); + void release_completed_operations(NdbTransaction*, bool); + /* Condition pushdown */ @@ -672,8 +681,8 @@ private: NdbScanOperation* op); friend int execute_commit(ha_ndbcluster*, NdbTransaction*); - friend int execute_no_commit(ha_ndbcluster*, NdbTransaction*); - friend int execute_no_commit_ie(ha_ndbcluster*, NdbTransaction*); + friend int execute_no_commit(ha_ndbcluster*, NdbTransaction*, bool); + friend int execute_no_commit_ie(ha_ndbcluster*, NdbTransaction*, bool); NdbTransaction *m_active_trans; NdbScanOperation *m_active_cursor; From a51106f00346c6f5edb47e2b270fd3a98d878bf2 Mon Sep 17 00:00:00 2001 From: "mskold/marty@mysql.com/linux.site" <> Date: Mon, 7 Aug 2006 15:58:43 +0200 Subject: [PATCH 3/9] Fix for bug #21059 Server crashes on join query with large dataset with NDB tables: missing friend declaration in change set --- ndb/include/ndbapi/NdbTransaction.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/ndb/include/ndbapi/NdbTransaction.hpp b/ndb/include/ndbapi/NdbTransaction.hpp index a6ba6a11c4d..8e4d8d9ea7f 100644 --- a/ndb/include/ndbapi/NdbTransaction.hpp +++ b/ndb/include/ndbapi/NdbTransaction.hpp @@ -140,6 +140,7 @@ class NdbTransaction friend class NdbIndexOperation; friend class NdbIndexScanOperation; friend class NdbBlob; + friend class ha_ndbcluster; #endif public: From a922e328af088936d849a94fda0d8351a746d9ec Mon Sep 17 00:00:00 2001 From: "mskold/marty@mysql.com/linux.site" <> Date: Tue, 8 Aug 2006 12:22:23 +0200 Subject: [PATCH 4/9] bug #18184 SELECT ... FOR UPDATE does not work..: Added lockTuple call in close_scan --- mysql-test/r/ndb_lock.result | 15 ++++++++++++--- mysql-test/t/ndb_lock.test | 15 +++++++++++++-- sql/ha_ndbcluster.cc | 19 +++++++++++++++++++ 3 files changed, 44 insertions(+), 5 deletions(-) diff --git a/mysql-test/r/ndb_lock.result b/mysql-test/r/ndb_lock.result index 875dcd775e6..c7413949f42 100644 --- a/mysql-test/r/ndb_lock.result +++ b/mysql-test/r/ndb_lock.result @@ -64,17 +64,26 @@ pk u o insert into t1 values (1,1,1); drop table t1; create table t1 (x integer not null primary key, y varchar(32), z integer, key(z)) engine = ndb; -insert into t1 values (1,'one',1), (2,'two',2),(3,"three",3); +insert into t1 values (1,'one',1); begin; select * from t1 where x = 1 for update; x y z 1 one 1 begin; +select * from t1 where x = 1 for update; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +rollback; +rollback; +insert into t1 values (2,'two',2),(3,"three",3); +begin; +select * from t1 where x = 1 for update; +x y z +1 one 1 +select * from t1 where x = 1 for update; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction select * from t1 where x = 2 for update; x y z 2 two 2 -select * from t1 where x = 1 for update; -ERROR HY000: Lock wait timeout exceeded; try restarting transaction rollback; commit; begin; diff --git a/mysql-test/t/ndb_lock.test b/mysql-test/t/ndb_lock.test index e8f7c57ac96..3804782b150 100644 --- a/mysql-test/t/ndb_lock.test +++ b/mysql-test/t/ndb_lock.test @@ -73,7 +73,7 @@ drop table t1; create table t1 (x integer not null primary key, y varchar(32), z integer, key(z)) engine = ndb; -insert into t1 values (1,'one',1), (2,'two',2),(3,"three",3); +insert into t1 values (1,'one',1); # PK access connection con1; @@ -82,11 +82,22 @@ select * from t1 where x = 1 for update; connection con2; begin; -select * from t1 where x = 2 for update; --error 1205 select * from t1 where x = 1 for update; rollback; +connection con1; +rollback; +insert into t1 values (2,'two',2),(3,"three",3); +begin; +select * from t1 where x = 1 for update; + +connection con2; +--error 1205 +select * from t1 where x = 1 for update; +select * from t1 where x = 2 for update; +rollback; + connection con1; commit; diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index f508e3cc339..df4043ff3f2 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -2735,6 +2735,25 @@ int ha_ndbcluster::close_scan() if (!cursor) DBUG_RETURN(1); + if (m_lock_tuple) + { + /* + Lock level m_lock.type either TL_WRITE_ALLOW_WRITE + (SELECT FOR UPDATE) or TL_READ_WITH_SHARED_LOCKS (SELECT + LOCK WITH SHARE MODE) and row was not explictly unlocked + with unlock_row() call + */ + NdbOperation *op; + // Lock row + DBUG_PRINT("info", ("Keeping lock on scanned row")); + + if (!(op= m_active_cursor->lockTuple())) + { + m_lock_tuple= false; + ERR_RETURN(trans->getNdbError()); + } + m_ops_pending++; + } m_lock_tuple= false; if (m_ops_pending) { From 3a7d3f20f1f1286289909f8b460b9ebb4e7fd6c0 Mon Sep 17 00:00:00 2001 From: "jonas@perch.ndb.mysql.com" <> Date: Wed, 9 Aug 2006 10:22:09 +0200 Subject: [PATCH 5/9] ndb - bug#21363 Add extra sleeps (conditionally) if user-ndb-object still exists during shutdown Note: This is not in anyway optimal, but i dont't really know in which order should be shutdown but it fixes problem... --- sql/ha_ndbcluster_binlog.cc | 27 ++++++++++++++++++- .../include/ndbapi/ndb_cluster_connection.hpp | 1 + storage/ndb/src/ndbapi/Ndbif.cpp | 5 +++- storage/ndb/src/ndbapi/TransporterFacade.cpp | 10 +++++++ .../ndb/src/ndbapi/ndb_cluster_connection.cpp | 5 ++++ 5 files changed, 46 insertions(+), 2 deletions(-) diff --git a/sql/ha_ndbcluster_binlog.cc b/sql/ha_ndbcluster_binlog.cc index 8e9f0077dd0..3b72b4f1be6 100644 --- a/sql/ha_ndbcluster_binlog.cc +++ b/sql/ha_ndbcluster_binlog.cc @@ -3858,13 +3858,38 @@ err: close_thread_tables(thd); pthread_mutex_lock(&injector_mutex); /* don't mess with the injector_ndb anymore from other threads */ + int ndb_obj_cnt= 1; // g_ndb + ndb_obj_cnt+= injector_ndb == 0 ? 0 : 1; + ndb_obj_cnt+= schema_ndb == 0 ? 0 : 1; + ndb_obj_cnt+= ndbcluster_util_inited ? 1 : 0; injector_thd= 0; injector_ndb= 0; schema_ndb= 0; pthread_mutex_unlock(&injector_mutex); thd->db= 0; // as not to try to free memory - sql_print_information("Stopping Cluster Binlog"); + if (!ndb_extra_logging) + sql_print_information("Stopping Cluster Binlog"); + else + sql_print_information("Stopping Cluster Binlog: %u(%u)", + g_ndb_cluster_connection->get_active_ndb_objects(), + ndb_obj_cnt); + + /** + * Add extra wait loop to make user "user" ndb-object go away... + * otherwise user thread can have ongoing SUB_DATA + */ + int sleep_cnt= 0; + while (sleep_cnt < 300 && g_ndb_cluster_connection->get_active_ndb_objects() > ndb_obj_cnt) + { + my_sleep(10000); // 10ms + sleep_cnt++; + } + if (ndb_extra_logging) + sql_print_information("Stopping Cluster Binlog: waited %ums %u(%u)", + 10*sleep_cnt, g_ndb_cluster_connection->get_active_ndb_objects(), + ndb_obj_cnt); + if (apply_status_share) { free_share(&apply_status_share); diff --git a/storage/ndb/include/ndbapi/ndb_cluster_connection.hpp b/storage/ndb/include/ndbapi/ndb_cluster_connection.hpp index a803d010e61..8c8155d80ab 100644 --- a/storage/ndb/include/ndbapi/ndb_cluster_connection.hpp +++ b/storage/ndb/include/ndbapi/ndb_cluster_connection.hpp @@ -114,6 +114,7 @@ public: void init_get_next_node(Ndb_cluster_connection_node_iter &iter); unsigned int get_next_node(Ndb_cluster_connection_node_iter &iter); + unsigned get_active_ndb_objects() const; #endif private: diff --git a/storage/ndb/src/ndbapi/Ndbif.cpp b/storage/ndb/src/ndbapi/Ndbif.cpp index 0527744afe1..179e0a1247b 100644 --- a/storage/ndb/src/ndbapi/Ndbif.cpp +++ b/storage/ndb/src/ndbapi/Ndbif.cpp @@ -742,9 +742,12 @@ Ndb::handleReceivedSignal(NdbApiSignal* aSignal, LinearSectionPtr ptr[3]) const Uint32 oid = sdata->senderData; NdbEventOperationImpl *op= (NdbEventOperationImpl*)int2void(oid); - if (op->m_magic_number != NDB_EVENT_OP_MAGIC_NUMBER) + if (unlikely(op == 0 || op->m_magic_number != NDB_EVENT_OP_MAGIC_NUMBER)) + { g_eventLogger.error("dropped GSN_SUB_TABLE_DATA due to wrong magic " "number"); + return ; + } // Accumulate DIC_TAB_INFO for TE_ALTER events if (sdata->operation == NdbDictionary::Event::_TE_ALTER && diff --git a/storage/ndb/src/ndbapi/TransporterFacade.cpp b/storage/ndb/src/ndbapi/TransporterFacade.cpp index 2f421271e91..8d0693f17a7 100644 --- a/storage/ndb/src/ndbapi/TransporterFacade.cpp +++ b/storage/ndb/src/ndbapi/TransporterFacade.cpp @@ -1265,6 +1265,7 @@ TransporterFacade::get_an_alive_node() } TransporterFacade::ThreadData::ThreadData(Uint32 size){ + m_use_cnt = 0; m_firstFree = END_OF_LIST; expand(size); } @@ -1302,6 +1303,7 @@ TransporterFacade::ThreadData::open(void* objRef, nextFree = m_firstFree; } + m_use_cnt++; m_firstFree = m_statusNext[nextFree]; Object_Execute oe = { objRef , fun }; @@ -1318,6 +1320,8 @@ TransporterFacade::ThreadData::close(int number){ number= numberToIndex(number); assert(getInUse(number)); m_statusNext[number] = m_firstFree; + assert(m_use_cnt); + m_use_cnt--; m_firstFree = number; Object_Execute oe = { 0, 0 }; m_objectExecute[number] = oe; @@ -1325,6 +1329,12 @@ TransporterFacade::ThreadData::close(int number){ return 0; } +Uint32 +TransporterFacade::get_active_ndb_objects() const +{ + return m_threads.m_use_cnt; +} + PollGuard::PollGuard(TransporterFacade *tp, NdbWaiter *aWaiter, Uint32 block_no) { diff --git a/storage/ndb/src/ndbapi/ndb_cluster_connection.cpp b/storage/ndb/src/ndbapi/ndb_cluster_connection.cpp index a7e645f5100..97af326d95c 100644 --- a/storage/ndb/src/ndbapi/ndb_cluster_connection.cpp +++ b/storage/ndb/src/ndbapi/ndb_cluster_connection.cpp @@ -599,5 +599,10 @@ Ndb_cluster_connection::get_next_node(Ndb_cluster_connection_node_iter &iter) return m_impl.get_next_node(iter); } +unsigned +Ndb_cluster_connection::get_active_ndb_objects() const +{ + return m_impl.m_transporter_facade->get_active_ndb_objects(); +} template class Vector; From f6772782a64c17d368694c49033ce334c5b7ce7f Mon Sep 17 00:00:00 2001 From: "jonas@perch.ndb.mysql.com" <> Date: Wed, 9 Aug 2006 10:41:22 +0200 Subject: [PATCH 6/9] ndb - bug#21363 add file that got missing from last changset --- storage/ndb/src/ndbapi/TransporterFacade.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/storage/ndb/src/ndbapi/TransporterFacade.hpp b/storage/ndb/src/ndbapi/TransporterFacade.hpp index 2d47a2febf8..e444b7e77bb 100644 --- a/storage/ndb/src/ndbapi/TransporterFacade.hpp +++ b/storage/ndb/src/ndbapi/TransporterFacade.hpp @@ -68,6 +68,7 @@ public: // Close this block number int close(BlockNumber blockNumber, Uint64 trans_id); + Uint32 get_active_ndb_objects() const; // Only sends to nodes which are alive int sendSignal(NdbApiSignal * signal, NodeId nodeId); @@ -240,6 +241,7 @@ private: NodeStatusFunction m_statusFunction; }; + Uint32 m_use_cnt; Uint32 m_firstFree; Vector m_statusNext; Vector m_objectExecute; From b36bcc316ac3a2fdf6ecfda4127f6eeb167dc9b5 Mon Sep 17 00:00:00 2001 From: "mskold/marty@mysql.com/linux.site" <> Date: Wed, 9 Aug 2006 14:32:56 +0200 Subject: [PATCH 7/9] Fix for bug #21059 Server crashes on join query with large dataset with NDB tables: added more tests --- mysql-test/r/ndb_read_multi_range.result | 67 ++++++++++++++++++++++-- mysql-test/t/ndb_read_multi_range.test | 25 +++++++-- 2 files changed, 86 insertions(+), 6 deletions(-) diff --git a/mysql-test/r/ndb_read_multi_range.result b/mysql-test/r/ndb_read_multi_range.result index 9941d2b28a3..53c10552668 100644 --- a/mysql-test/r/ndb_read_multi_range.result +++ b/mysql-test/r/ndb_read_multi_range.result @@ -286,10 +286,10 @@ INSERT INTO t1 VALUES (406990,67,'2006-02-23 18:01:45'),(148815,67,'2005-10-25 15:34:17'), (148812,67,'2005-10-25 15:30:01'),(245651,67,'2005-12-08 15:58:27'), (154503,67,'2005-10-28 11:52:38'); -create table t11 select * from t1 where b = 67 AND (c IS NULL OR c > NOW()) order by 3 asc; -create table t12 select * from t1 where b = 67 AND (c IS NULL OR c > NOW()) order by 3 desc; +create table t11 engine = ndbcluster select * from t1 where b = 67 AND (c IS NULL OR c > NOW()) order by 3 asc; +create table t12 engine = ndbcluster select * from t1 where b = 67 AND (c IS NULL OR c > NOW()) order by 3 desc; create table t21 select * from t1 where b = 67 AND (c IS NULL OR c > '2005-12-08') order by 3 asc; -create table t22 select * from t1 where b = 67 AND (c IS NULL OR c > '2005-12-08') order by 3 desc; +create table t22 engine = ndbcluster select * from t1 where b = 67 AND (c IS NULL OR c > '2005-12-08') order by 3 desc; select * from t11 order by 1,2,3; a b c 254 67 NULL @@ -366,4 +366,65 @@ a b c 406993 67 2006-02-27 11:20:57 406994 67 2006-02-27 11:26:46 406995 67 2006-02-28 11:55:00 +select t12.a from t11, t12 where t11.a in(255,256) and t11.a = t12.a and t11.c is null order by t12.a; +a +255 +256 +update t22 set c = '2005-12-08 15:58:27' where a = 255; +select * from t22 order by 1,2,3; +a b c +1 67 2006-02-23 15:01:35 +254 67 NULL +255 67 2005-12-08 15:58:27 +256 67 NULL +1120 67 NULL +1133 67 NULL +4101 67 NULL +9199 67 NULL +223456 67 NULL +245651 67 2005-12-08 15:58:27 +245652 67 2005-12-08 15:58:27 +245653 67 2005-12-08 15:59:07 +245654 67 2005-12-08 15:59:08 +245655 67 2005-12-08 15:59:08 +398340 67 2006-02-20 04:38:53 +398341 67 2006-02-20 04:48:44 +398545 67 2006-02-20 04:53:13 +406631 67 2006-02-23 10:49:42 +406988 67 2006-02-23 17:07:22 +406989 67 2006-02-23 17:08:46 +406990 67 2006-02-23 18:01:45 +406991 67 2006-02-24 16:42:32 +406992 67 2006-02-24 16:47:18 +406993 67 2006-02-27 11:20:57 +406994 67 2006-02-27 11:26:46 +406995 67 2006-02-28 11:55:00 +select t21.* from t21,t22 where t21.a = t22.a and +t22.a in (select t12.a from t11, t12 where t11.a in(255,256) and t11.a = t12.a and t11.c is null) and t22.c is null order by t21.a; +a b c +256 67 NULL +delete from t22 where a > 245651; +update t22 set b = a + 1; +select * from t22 order by 1,2,3; +a b c +1 2 2006-02-23 15:01:35 +254 255 NULL +255 256 2005-12-08 15:58:27 +256 257 NULL +1120 1121 NULL +1133 1134 NULL +4101 4102 NULL +9199 9200 NULL +223456 223457 NULL +245651 245652 2005-12-08 15:58:27 +select c, count(*) +from t21 +inner join t22 using (a) +where t22.b in (2,256,257,1121,1134,4102,9200,223457,245652) +group by c +order by c; +c count(*) +NULL 7 +2005-12-08 15:58:27 1 +2006-02-23 15:01:35 1 DROP TABLE t1, t11, t12, t21, t22; diff --git a/mysql-test/t/ndb_read_multi_range.test b/mysql-test/t/ndb_read_multi_range.test index 855f7789032..8cdba49fb92 100644 --- a/mysql-test/t/ndb_read_multi_range.test +++ b/mysql-test/t/ndb_read_multi_range.test @@ -228,13 +228,32 @@ INSERT INTO t1 VALUES (148812,67,'2005-10-25 15:30:01'),(245651,67,'2005-12-08 15:58:27'), (154503,67,'2005-10-28 11:52:38'); -create table t11 select * from t1 where b = 67 AND (c IS NULL OR c > NOW()) order by 3 asc; -create table t12 select * from t1 where b = 67 AND (c IS NULL OR c > NOW()) order by 3 desc; +create table t11 engine = ndbcluster select * from t1 where b = 67 AND (c IS NULL OR c > NOW()) order by 3 asc; +create table t12 engine = ndbcluster select * from t1 where b = 67 AND (c IS NULL OR c > NOW()) order by 3 desc; create table t21 select * from t1 where b = 67 AND (c IS NULL OR c > '2005-12-08') order by 3 asc; -create table t22 select * from t1 where b = 67 AND (c IS NULL OR c > '2005-12-08') order by 3 desc; +create table t22 engine = ndbcluster select * from t1 where b = 67 AND (c IS NULL OR c > '2005-12-08') order by 3 desc; select * from t11 order by 1,2,3; select * from t12 order by 1,2,3; select * from t21 order by 1,2,3; select * from t22 order by 1,2,3; + +# join tests +select t12.a from t11, t12 where t11.a in(255,256) and t11.a = t12.a and t11.c is null order by t12.a; + +update t22 set c = '2005-12-08 15:58:27' where a = 255; +select * from t22 order by 1,2,3; +select t21.* from t21,t22 where t21.a = t22.a and +t22.a in (select t12.a from t11, t12 where t11.a in(255,256) and t11.a = t12.a and t11.c is null) and t22.c is null order by t21.a; + +delete from t22 where a > 245651; +update t22 set b = a + 1; +select * from t22 order by 1,2,3; +select c, count(*) +from t21 +inner join t22 using (a) +where t22.b in (2,256,257,1121,1134,4102,9200,223457,245652) +group by c +order by c; + DROP TABLE t1, t11, t12, t21, t22; From 794c87485319fa250c62ae408375fb8c7c638b25 Mon Sep 17 00:00:00 2001 From: "mskold/marty@mysql.com/linux.site" <> Date: Wed, 9 Aug 2006 16:12:24 +0200 Subject: [PATCH 8/9] bug #18184 SELECT ... FOR UPDATE does not work..: Updated result file --- mysql-test/r/ndb_lock.result | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/ndb_lock.result b/mysql-test/r/ndb_lock.result index 197995505a1..668c26aad03 100644 --- a/mysql-test/r/ndb_lock.result +++ b/mysql-test/r/ndb_lock.result @@ -64,17 +64,26 @@ pk u o insert into t1 values (1,1,1); drop table t1; create table t1 (x integer not null primary key, y varchar(32), z integer, key(z)) engine = ndb; -insert into t1 values (1,'one',1), (2,'two',2),(3,"three",3); +insert into t1 values (1,'one',1); begin; select * from t1 where x = 1 for update; x y z 1 one 1 begin; +select * from t1 where x = 1 for update; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +rollback; +rollback; +insert into t1 values (2,'two',2),(3,"three",3); +begin; +select * from t1 where x = 1 for update; +x y z +1 one 1 +select * from t1 where x = 1 for update; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction select * from t1 where x = 2 for update; x y z 2 two 2 -select * from t1 where x = 1 for update; -ERROR HY000: Lock wait timeout exceeded; try restarting transaction rollback; commit; begin; From 732f9f6843281b9cdbb5ce2823221dde0202007d Mon Sep 17 00:00:00 2001 From: "jonas@perch.ndb.mysql.com" <> Date: Thu, 10 Aug 2006 13:33:49 +0200 Subject: [PATCH 9/9] ndb - bug#21283 this test in its current form depend on binlog format row --- mysql-test/t/ndb_autodiscover3.test | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mysql-test/t/ndb_autodiscover3.test b/mysql-test/t/ndb_autodiscover3.test index 5f6d457d140..df31398d414 100644 --- a/mysql-test/t/ndb_autodiscover3.test +++ b/mysql-test/t/ndb_autodiscover3.test @@ -2,6 +2,9 @@ -- source include/have_multi_ndb.inc -- source include/not_embedded.inc +# see bug#21563 +-- source include/have_binlog_format_row.inc + --disable_warnings drop table if exists t1, t2; --enable_warnings