diff options
Diffstat (limited to 'ndb')
168 files changed, 1960 insertions, 783 deletions
diff --git a/ndb/examples/ndbapi_async_example/ndbapi_async.cpp b/ndb/examples/ndbapi_async_example/ndbapi_async.cpp index 7abebcc832d..76ce1a8efe3 100644 --- a/ndb/examples/ndbapi_async_example/ndbapi_async.cpp +++ b/ndb/examples/ndbapi_async_example/ndbapi_async.cpp @@ -46,9 +46,9 @@ * * NdbDictionary::Column * setName() - * setPrimaryKey() * setType() * setLength() + * setPrimaryKey() * setNullable() * * NdbDictionary::Table @@ -234,9 +234,9 @@ int create_table(Ndb * myNdb) * Column REG_NO */ myColumn.setName("REG_NO"); - myColumn.setPrimaryKey(true); myColumn.setType(NdbDictionary::Column::Unsigned); myColumn.setLength(1); + myColumn.setPrimaryKey(true); myColumn.setNullable(false); myTable.addColumn(myColumn); @@ -244,9 +244,9 @@ int create_table(Ndb * myNdb) * Column BRAND */ myColumn.setName("BRAND"); - myColumn.setPrimaryKey(false); myColumn.setType(NdbDictionary::Column::Char); myColumn.setLength(20); + myColumn.setPrimaryKey(false); myColumn.setNullable(false); myTable.addColumn(myColumn); @@ -254,9 +254,9 @@ int create_table(Ndb * myNdb) * Column COLOR */ myColumn.setName("COLOR"); - myColumn.setPrimaryKey(false); myColumn.setType(NdbDictionary::Column::Char); myColumn.setLength(20); + myColumn.setPrimaryKey(false); myColumn.setNullable(false); myTable.addColumn(myColumn); @@ -454,6 +454,7 @@ int populate(Ndb * myNdb, int data, async_callback_t * cbData) int main() { + ndb_init(); Ndb* myNdb = new Ndb( "TEST_DB" ); // Object representing the database /******************************************* @@ -493,5 +494,3 @@ int main() std::cout << "Number of temporary errors: " << tempErrors << std::endl; delete myNdb; } - - diff --git a/ndb/examples/ndbapi_example1/ndbapi_example1.cpp b/ndb/examples/ndbapi_example1/ndbapi_example1.cpp index 879d86de824..03a84aa249b 100644 --- a/ndb/examples/ndbapi_example1/ndbapi_example1.cpp +++ b/ndb/examples/ndbapi_example1/ndbapi_example1.cpp @@ -44,6 +44,7 @@ int main() { + ndb_init(); Ndb* myNdb = new Ndb( "TEST_DB_1" ); // Object representing the database NdbDictionary::Table myTable; NdbDictionary::Column myColumn; @@ -78,16 +79,16 @@ int main() myTable.setName("MYTABLENAME"); myColumn.setName("ATTR1"); - myColumn.setPrimaryKey(true); myColumn.setType(NdbDictionary::Column::Unsigned); myColumn.setLength(1); + myColumn.setPrimaryKey(true); myColumn.setNullable(false); myTable.addColumn(myColumn); myColumn.setName("ATTR2"); - myColumn.setPrimaryKey(false); myColumn.setType(NdbDictionary::Column::Unsigned); myColumn.setLength(1); + myColumn.setPrimaryKey(false); myColumn.setNullable(false); myTable.addColumn(myColumn); diff --git a/ndb/examples/ndbapi_example2/ndbapi_example2.cpp b/ndb/examples/ndbapi_example2/ndbapi_example2.cpp index 1c61721c037..95a7bae66b8 100644 --- a/ndb/examples/ndbapi_example2/ndbapi_example2.cpp +++ b/ndb/examples/ndbapi_example2/ndbapi_example2.cpp @@ -39,6 +39,7 @@ static void callback(int result, NdbConnection* NdbObject, void* aObject); int main() { + ndb_init(); Ndb* myNdb = new Ndb( "TEST_DB_2" ); // Object representing the database NdbConnection* myNdbConnection[2]; // For transactions diff --git a/ndb/examples/ndbapi_example3/ndbapi_example3.cpp b/ndb/examples/ndbapi_example3/ndbapi_example3.cpp index 36d2cf1608c..91d9ff122ba 100644 --- a/ndb/examples/ndbapi_example3/ndbapi_example3.cpp +++ b/ndb/examples/ndbapi_example3/ndbapi_example3.cpp @@ -176,6 +176,7 @@ int executeInsertTransaction(int transactionId, Ndb* myNdb) { int main() { + ndb_init(); Ndb* myNdb = new Ndb( "TEST_DB_1" ); // Object representing the database /******************************************* diff --git a/ndb/examples/ndbapi_example4/ndbapi_example4.cpp b/ndb/examples/ndbapi_example4/ndbapi_example4.cpp index 520172b9b0c..fcb770d49e9 100644 --- a/ndb/examples/ndbapi_example4/ndbapi_example4.cpp +++ b/ndb/examples/ndbapi_example4/ndbapi_example4.cpp @@ -44,6 +44,7 @@ int main() { + ndb_init(); Ndb* myNdb = new Ndb( "TEST_DB_1" ); // Object representing the database NdbDictionary::Table myTable; NdbDictionary::Column myColumn; @@ -79,16 +80,16 @@ int main() myTable.setName("MYTABLENAME"); myColumn.setName("ATTR1"); - myColumn.setPrimaryKey(true); myColumn.setType(NdbDictionary::Column::Unsigned); myColumn.setLength(1); + myColumn.setPrimaryKey(true); myColumn.setNullable(false); myTable.addColumn(myColumn); myColumn.setName("ATTR2"); - myColumn.setPrimaryKey(false); myColumn.setType(NdbDictionary::Column::Unsigned); myColumn.setLength(1); + myColumn.setPrimaryKey(false); myColumn.setNullable(false); myTable.addColumn(myColumn); diff --git a/ndb/examples/ndbapi_example5/ndbapi_example5.cpp b/ndb/examples/ndbapi_example5/ndbapi_example5.cpp index a9d3099883c..77f74e7bb63 100644 --- a/ndb/examples/ndbapi_example5/ndbapi_example5.cpp +++ b/ndb/examples/ndbapi_example5/ndbapi_example5.cpp @@ -65,6 +65,7 @@ int myCreateEvent(Ndb* myNdb, int main() { + ndb_init(); Ndb* myNdb = myCreateNdb(); NdbDictionary::Dictionary *myDict; diff --git a/ndb/examples/ndbapi_scan_example/ndbapi_scan.cpp b/ndb/examples/ndbapi_scan_example/ndbapi_scan.cpp index 7c3a66326c6..22641bc5b57 100644 --- a/ndb/examples/ndbapi_scan_example/ndbapi_scan.cpp +++ b/ndb/examples/ndbapi_scan_example/ndbapi_scan.cpp @@ -47,9 +47,9 @@ * * NdbDictionary::Column * setName() - * setPrimaryKey() * setType() * setLength() + * setPrimaryKey() * setNullable() * * NdbDictionary::Table @@ -165,24 +165,24 @@ int create_table(Ndb * myNdb) myTable.setName("GARAGE"); myColumn.setName("REG_NO"); - myColumn.setPrimaryKey(true); myColumn.setType(NdbDictionary::Column::Unsigned); myColumn.setLength(1); + myColumn.setPrimaryKey(true); myColumn.setNullable(false); myTable.addColumn(myColumn); myColumn.setName("BRAND"); - myColumn.setPrimaryKey(false); myColumn.setType(NdbDictionary::Column::Char); myColumn.setLength(20); + myColumn.setPrimaryKey(false); myColumn.setNullable(false); myTable.addColumn(myColumn); myColumn.setName("COLOR"); - myColumn.setPrimaryKey(false); myColumn.setType(NdbDictionary::Column::Char); myColumn.setLength(20); + myColumn.setPrimaryKey(false); myColumn.setNullable(false); myTable.addColumn(myColumn); @@ -761,6 +761,7 @@ int scan_print(Ndb * myNdb, int parallelism, int main() { + ndb_init(); Ndb* myNdb = new Ndb( "TEST_DB" ); // Object representing the database @@ -813,4 +814,3 @@ int main() delete myNdb; } - diff --git a/ndb/examples/select_all/select_all.cpp b/ndb/examples/select_all/select_all.cpp index 3cdbdc47e62..bd25fb60128 100644 --- a/ndb/examples/select_all/select_all.cpp +++ b/ndb/examples/select_all/select_all.cpp @@ -112,6 +112,7 @@ const char* ResultSetContainer::getAttrName(int i) const {return m_names[i];} int main(int argc, const char** argv) { + ndb_init(); Ndb* myNdb = new Ndb("ndbapi_example4"); // Object representing the database NdbConnection* myNdbConnection; // For transactions NdbOperation* myNdbOperation; // For operations diff --git a/ndb/include/kernel/signaldata/DictTabInfo.hpp b/ndb/include/kernel/signaldata/DictTabInfo.hpp index dec7145c897..a9a50f19fbc 100644 --- a/ndb/include/kernel/signaldata/DictTabInfo.hpp +++ b/ndb/include/kernel/signaldata/DictTabInfo.hpp @@ -438,8 +438,8 @@ public: case DictTabInfo::ExtText: AttributeType = DictTabInfo::StringType; AttributeSize = DictTabInfo::an8Bit; - // head + inline part [ attr precision ] - AttributeArraySize = (NDB_BLOB_HEAD_SIZE << 2) + AttributeExtPrecision; + // head + inline part [ attr precision lower half ] + AttributeArraySize = (NDB_BLOB_HEAD_SIZE << 2) + (AttributeExtPrecision & 0xFFFF); return true; }; return false; diff --git a/ndb/include/mgmapi/mgmapi.h b/ndb/include/mgmapi/mgmapi.h index a745688561c..929f4b0833b 100644 --- a/ndb/include/mgmapi/mgmapi.h +++ b/ndb/include/mgmapi/mgmapi.h @@ -204,6 +204,7 @@ extern "C" { int version; ///< Internal version number int connect_count; ///< No of times node has connected ///< or disconnected to the mgm srv + char connect_address[sizeof("000.000.000.000")+1]; }; /** @@ -214,6 +215,7 @@ extern "C" { ///< node_states array struct ndb_mgm_node_state ///< An array with node_states node_states[1]; + const char *hostname; }; /** @@ -395,6 +397,14 @@ extern "C" { const char * ndb_mgm_get_node_type_string(enum ndb_mgm_node_type type); /** + * Convert an ndb_mgm_node_type to a alias string + * + * @param type Node type. + * @return NULL if invalid id. + */ + const char * ndb_mgm_get_node_type_alias_string(enum ndb_mgm_node_type type, const char **str); + + /** * Convert a string to a ndb_mgm_node_status * * @param status NDB node status string. diff --git a/ndb/include/ndb_global.h b/ndb/include/ndb_global.h index 0ae781ba5c2..19bd387c457 100644 --- a/ndb/include/ndb_global.h +++ b/ndb/include/ndb_global.h @@ -76,6 +76,9 @@ extern "C" { #include <assert.h> +/* call in main() - does not return on error */ +extern int ndb_init(void); + #ifndef HAVE_STRDUP extern char * strdup(const char *s); #endif diff --git a/ndb/include/ndbapi/Ndb.hpp b/ndb/include/ndbapi/Ndb.hpp index 387447f00f4..9d0e9714eef 100644 --- a/ndb/include/ndbapi/Ndb.hpp +++ b/ndb/include/ndbapi/Ndb.hpp @@ -1363,15 +1363,6 @@ public: */ static void setConnectString(const char * connectString); - /** - * useFullyQualifiedNames - * Enables unique name space for different databases and schemas - * by defining table names as DATABASENAME/SCHEMANAME/TABLENAME and - * index names as DATABASENAME/SCHEMANAME/TABLENAME/INDEXNAME - * @param turnNamingOn bool true - turn naming on, false - turn naming off - */ - void useFullyQualifiedNames(bool turnNamingOn = true); - bool usingFullyQualifiedNames(); /** @} *********************************************************************/ @@ -1422,13 +1413,13 @@ public: */ Uint64 getAutoIncrementValue(const char* aTableName, Uint32 cacheSize = 1); - Uint64 getAutoIncrementValue(NdbDictionary::Table * aTable, + Uint64 getAutoIncrementValue(const NdbDictionary::Table * aTable, Uint32 cacheSize = 1); Uint64 readAutoIncrementValue(const char* aTableName); - Uint64 readAutoIncrementValue(NdbDictionary::Table * aTable); + Uint64 readAutoIncrementValue(const NdbDictionary::Table * aTable); bool setAutoIncrementValue(const char* aTableName, Uint64 val, bool increase = false); - bool setAutoIncrementValue(NdbDictionary::Table * aTable, Uint64 val, + bool setAutoIncrementValue(const NdbDictionary::Table * aTable, Uint64 val, bool increase = false); Uint64 getTupleIdFromNdb(const char* aTableName, Uint32 cacheSize = 1000); diff --git a/ndb/include/ndbapi/NdbBlob.hpp b/ndb/include/ndbapi/NdbBlob.hpp index dc47115d16f..22e393b6c5d 100644 --- a/ndb/include/ndbapi/NdbBlob.hpp +++ b/ndb/include/ndbapi/NdbBlob.hpp @@ -238,9 +238,9 @@ private: Ndb* theNdb; NdbConnection* theNdbCon; NdbOperation* theNdbOp; - NdbTableImpl* theTable; - NdbTableImpl* theAccessTable; - NdbTableImpl* theBlobTable; + const NdbTableImpl* theTable; + const NdbTableImpl* theAccessTable; + const NdbTableImpl* theBlobTable; const NdbColumnImpl* theColumn; char theFillChar; // sizes diff --git a/ndb/include/ndbapi/NdbConnection.hpp b/ndb/include/ndbapi/NdbConnection.hpp index c268f9aab04..ef4972f205b 100644 --- a/ndb/include/ndbapi/NdbConnection.hpp +++ b/ndb/include/ndbapi/NdbConnection.hpp @@ -442,13 +442,13 @@ public: int executePendingBlobOps(Uint8 flags = 0xFF); // Fast path calls for MySQL ha_ndbcluster - NdbOperation* getNdbOperation(NdbDictionary::Table * table); - NdbIndexOperation* getNdbIndexOperation(NdbDictionary::Index * index, - NdbDictionary::Table * table); - NdbScanOperation* getNdbScanOperation(NdbDictionary::Table * table); - NdbIndexScanOperation* getNdbIndexScanOperation(NdbDictionary::Index * index, - NdbDictionary::Table * table); - + NdbOperation* getNdbOperation(const NdbDictionary::Table * table); + NdbIndexOperation* getNdbIndexOperation(const NdbDictionary::Index *, + const NdbDictionary::Table * table); + NdbScanOperation* getNdbScanOperation(const NdbDictionary::Table * table); + NdbIndexScanOperation* getNdbIndexScanOperation(const NdbDictionary::Index * index, + const NdbDictionary::Table * table); + private: /** * Release completed operations @@ -556,14 +556,14 @@ private: void setOperationErrorCodeAbort(int anErrorCode); int checkMagicNumber(); // Verify correct object - NdbOperation* getNdbOperation(class NdbTableImpl* aTable, + NdbOperation* getNdbOperation(const class NdbTableImpl* aTable, NdbOperation* aNextOp = 0); - NdbIndexScanOperation* getNdbScanOperation(class NdbTableImpl* aTable); - NdbIndexOperation* getNdbIndexOperation(class NdbIndexImpl* anIndex, - class NdbTableImpl* aTable, + NdbIndexScanOperation* getNdbScanOperation(const class NdbTableImpl* aTable); + NdbIndexOperation* getNdbIndexOperation(const class NdbIndexImpl* anIndex, + const class NdbTableImpl* aTable, NdbOperation* aNextOp = 0); - NdbIndexScanOperation* getNdbIndexScanOperation(NdbIndexImpl* index, - NdbTableImpl* table); + NdbIndexScanOperation* getNdbIndexScanOperation(const NdbIndexImpl* index, + const NdbTableImpl* table); void handleExecuteCompletion(); diff --git a/ndb/include/ndbapi/NdbDictionary.hpp b/ndb/include/ndbapi/NdbDictionary.hpp index 71ef5dbf630..51a6895648f 100644 --- a/ndb/include/ndbapi/NdbDictionary.hpp +++ b/ndb/include/ndbapi/NdbDictionary.hpp @@ -32,6 +32,8 @@ #include <ndb_types.h> class Ndb; +struct charset_info_st; +typedef struct charset_info_st CHARSET_INFO; /** * @class NdbDictionary @@ -257,6 +259,10 @@ public: /** * Set type of column * @param type Type of column + * + * @note setType resets <em>all</em> column attributes + * to (type dependent) defaults and should be the first + * method to call. Default type is Unsigned. */ void setType(Type type); @@ -302,27 +308,35 @@ public: int getLength() const; /** + * For Char or Varchar or Text, set or get MySQL CHARSET_INFO. This + * specifies both character set and collation. See get_charset() + * etc in MySQL. (The cs is not "const" in MySQL). + */ + void setCharset(CHARSET_INFO* cs); + CHARSET_INFO* getCharset() const; + + /** * For blob, set or get "inline size" i.e. number of initial bytes * to store in table's blob attribute. This part is normally in * main memory and can be indexed and interpreted. */ - void setInlineSize(int size) { setPrecision(size); } - int getInlineSize() const { return getPrecision(); } + void setInlineSize(int size); + int getInlineSize() const; /** * For blob, set or get "part size" i.e. number of bytes to store in * each tuple of the "blob table". Can be set to zero to omit parts * and to allow only inline bytes ("tinyblob"). */ - void setPartSize(int size) { setScale(size); } - int getPartSize() const { return getScale(); } + void setPartSize(int size); + int getPartSize() const; /** * For blob, set or get "stripe size" i.e. number of consecutive * <em>parts</em> to store in each node group. */ - void setStripeSize(int size) { setLength(size); } - int getStripeSize() const { return getLength(); } + void setStripeSize(int size); + int getStripeSize() const; /** * Get size of element @@ -1066,6 +1080,9 @@ public: Dictionary(NdbDictionaryImpl&); const Table * getIndexTable(const char * indexName, const char * tableName); + public: + const Table * getTable(const char * name, void **data); + void set_local_table_data_size(unsigned sz); }; }; diff --git a/ndb/include/ndbapi/NdbIndexOperation.hpp b/ndb/include/ndbapi/NdbIndexOperation.hpp index 2d873c52e56..36c3c73db2d 100644 --- a/ndb/include/ndbapi/NdbIndexOperation.hpp +++ b/ndb/include/ndbapi/NdbIndexOperation.hpp @@ -175,15 +175,15 @@ private: int executeCursor(int ProcessorId); // Overloaded methods from NdbCursorOperation - int indxInit(class NdbIndexImpl* anIndex, - class NdbTableImpl* aTable, + int indxInit(const class NdbIndexImpl* anIndex, + const class NdbTableImpl* aTable, NdbConnection* myConnection); int equal_impl(const class NdbColumnImpl*, const char* aValue, Uint32 len); int prepareSend(Uint32 TC_ConnectPtr, Uint64 TransactionId); // Private attributes - NdbIndexImpl* m_theIndex; + const NdbIndexImpl* m_theIndex; Uint32 m_theIndexDefined[NDB_MAX_ATTRIBUTES_IN_INDEX][3]; Uint32 m_theIndexLen; // Length of the index in words Uint32 m_theNoOfIndexDefined; // The number of index attributes diff --git a/ndb/include/ndbapi/NdbOperation.hpp b/ndb/include/ndbapi/NdbOperation.hpp index 3ece6be8c68..2d08fa57aae 100644 --- a/ndb/include/ndbapi/NdbOperation.hpp +++ b/ndb/include/ndbapi/NdbOperation.hpp @@ -709,7 +709,7 @@ protected: //-------------------------------------------------------------- // Initialise after allocating operation to a transaction //-------------------------------------------------------------- - int init(class NdbTableImpl*, NdbConnection* aCon); + int init(const class NdbTableImpl*, NdbConnection* aCon); void initInterpreter(); void next(NdbOperation*); // Set next pointer @@ -858,8 +858,8 @@ protected: Uint32* theKEYINFOptr; // Pointer to where to write KEYINFO Uint32* theATTRINFOptr; // Pointer to where to write ATTRINFO - class NdbTableImpl* m_currentTable; // The current table - class NdbTableImpl* m_accessTable; + const class NdbTableImpl* m_currentTable; // The current table + const class NdbTableImpl* m_accessTable; // Set to TRUE when a tuple key attribute has been defined. Uint32 theTupleKeyDefined[NDB_MAX_NO_OF_ATTRIBUTES_IN_KEY][3]; diff --git a/ndb/include/ndbapi/NdbScanOperation.hpp b/ndb/include/ndbapi/NdbScanOperation.hpp index 638ca39409a..6ae71ef5aef 100644 --- a/ndb/include/ndbapi/NdbScanOperation.hpp +++ b/ndb/include/ndbapi/NdbScanOperation.hpp @@ -110,7 +110,7 @@ protected: int executeCursor(int ProcessorId); // Overloaded private methods from NdbOperation - int init(NdbTableImpl* tab, NdbConnection* myConnection); + int init(const NdbTableImpl* tab, NdbConnection* myConnection); int prepareSend(Uint32 TC_ConnectPtr, Uint64 TransactionId); int doSend(int ProcessorId); diff --git a/ndb/include/util/NdbSqlUtil.hpp b/ndb/include/util/NdbSqlUtil.hpp index 1d3e96d5c7e..df1cb716f93 100644 --- a/ndb/include/util/NdbSqlUtil.hpp +++ b/ndb/include/util/NdbSqlUtil.hpp @@ -90,6 +90,13 @@ public: */ static const Type& getType(Uint32 typeId); + /** + * Check character set. + */ + static bool usable_in_pk(Uint32 typeId, const void* cs); + static bool usable_in_hash_index(Uint32 typeId, const void* cs); + static bool usable_in_ordered_index(Uint32 typeId, const void* cs); + private: /** * List of all types. Must match Type::Enum. diff --git a/ndb/src/common/mgmcommon/ConfigRetriever.cpp b/ndb/src/common/mgmcommon/ConfigRetriever.cpp index 26bac2cf10b..c0e2c1a793a 100644 --- a/ndb/src/common/mgmcommon/ConfigRetriever.cpp +++ b/ndb/src/common/mgmcommon/ConfigRetriever.cpp @@ -102,14 +102,13 @@ ConfigRetriever::do_connect(int exit_on_connect_failure){ if (ndb_mgm_connect(m_handle, tmp.c_str()) == 0) { return 0; } - if (exit_on_connect_failure) - return 1; setError(CR_RETRY, ndb_mgm_get_latest_error_desc(m_handle)); case MgmId_File: break; } } - + if (exit_on_connect_failure) + return 1; if(latestErrorType == CR_RETRY){ REPORT_WARNING("Failed to retrieve cluster configuration"); ndbout << "(Cause of failure: " << getErrorString() << ")" << endl; diff --git a/ndb/src/common/mgmcommon/LocalConfig.cpp b/ndb/src/common/mgmcommon/LocalConfig.cpp index 71d06c29135..e4e87b250fe 100644 --- a/ndb/src/common/mgmcommon/LocalConfig.cpp +++ b/ndb/src/common/mgmcommon/LocalConfig.cpp @@ -200,9 +200,8 @@ LocalConfig::parseString(const char * connectString, char *line){ bool b_nodeId = false; bool found_other = false; - for (char *tok = strtok_r(copy,";",&for_strtok); tok != 0; - tok = strtok_r(NULL, ";", &for_strtok)) { - + for (char *tok = strtok_r(copy,";,",&for_strtok); tok != 0; + tok = strtok_r(NULL, ";,", &for_strtok)) { if (tok[0] == '#') continue; if (!b_nodeId) // only one nodeid definition allowed diff --git a/ndb/src/common/mgmcommon/NdbConfig.c b/ndb/src/common/mgmcommon/NdbConfig.c index 6c93f9fc7cf..e92f8fa8392 100644 --- a/ndb/src/common/mgmcommon/NdbConfig.c +++ b/ndb/src/common/mgmcommon/NdbConfig.c @@ -19,7 +19,7 @@ #include <NdbEnv.h> #include <NdbMem.h> -static char *datadir_path= 0; +static const char *datadir_path= 0; const char * NdbConfig_get_path(int *_len) @@ -71,58 +71,74 @@ NdbConfig_NdbCfgName(int with_ndb_home){ return buf; } +static +char *get_prefix_buf(int len, int node_id) +{ + char tmp_buf[sizeof("ndb_pid#########")+1]; + char *buf; + if (node_id > 0) + snprintf(tmp_buf, sizeof(tmp_buf), "ndb_%u", node_id); + else + snprintf(tmp_buf, sizeof(tmp_buf), "ndb_pid%u", getpid()); + tmp_buf[sizeof(tmp_buf)-1]= 0; + + buf= NdbConfig_AllocHomePath(len+strlen(tmp_buf)); + strcat(buf, tmp_buf); + return buf; +} + char* NdbConfig_ErrorFileName(int node_id){ - char *buf= NdbConfig_AllocHomePath(128); + char *buf= get_prefix_buf(128, node_id); int len= strlen(buf); - snprintf(buf+len, 128, "ndb_%u_error.log", node_id); + snprintf(buf+len, 128, "_error.log"); return buf; } char* NdbConfig_ClusterLogFileName(int node_id){ - char *buf= NdbConfig_AllocHomePath(128); + char *buf= get_prefix_buf(128, node_id); int len= strlen(buf); - snprintf(buf+len, 128, "ndb_%u_cluster.log", node_id); + snprintf(buf+len, 128, "_cluster.log"); return buf; } char* NdbConfig_SignalLogFileName(int node_id){ - char *buf= NdbConfig_AllocHomePath(128); + char *buf= get_prefix_buf(128, node_id); int len= strlen(buf); - snprintf(buf+len, 128, "ndb_%u_signal.log", node_id); + snprintf(buf+len, 128, "_signal.log"); return buf; } char* NdbConfig_TraceFileName(int node_id, int file_no){ - char *buf= NdbConfig_AllocHomePath(128); + char *buf= get_prefix_buf(128, node_id); int len= strlen(buf); - snprintf(buf+len, 128, "ndb_%u_trace.log.%u", node_id, file_no); + snprintf(buf+len, 128, "_trace.log.%u", file_no); return buf; } char* NdbConfig_NextTraceFileName(int node_id){ - char *buf= NdbConfig_AllocHomePath(128); + char *buf= get_prefix_buf(128, node_id); int len= strlen(buf); - snprintf(buf+len, 128, "ndb_%u_trace.log.next", node_id); + snprintf(buf+len, 128, "_trace.log.next"); return buf; } char* NdbConfig_PidFileName(int node_id){ - char *buf= NdbConfig_AllocHomePath(128); + char *buf= get_prefix_buf(128, node_id); int len= strlen(buf); - snprintf(buf+len, 128, "ndb_%u.pid", node_id); + snprintf(buf+len, 128, ".pid"); return buf; } char* NdbConfig_StdoutFileName(int node_id){ - char *buf= NdbConfig_AllocHomePath(128); + char *buf= get_prefix_buf(128, node_id); int len= strlen(buf); - snprintf(buf+len, 128, "ndb_%u_out.log", node_id); + snprintf(buf+len, 128, "_out.log"); return buf; } diff --git a/ndb/src/common/transporter/TransporterRegistry.cpp b/ndb/src/common/transporter/TransporterRegistry.cpp index ad8a2729c26..ca574b19dbc 100644 --- a/ndb/src/common/transporter/TransporterRegistry.cpp +++ b/ndb/src/common/transporter/TransporterRegistry.cpp @@ -1184,7 +1184,7 @@ TransporterRegistry::start_service(SocketServer& socket_server) { ndbout_c("Unable to setup transporter service port: %d!\n" "Please check if the port is already used,\n" - "(perhaps a mgmtsrvrserver is already running)", + "(perhaps a mgmt server is already running)", m_service_port); delete t->m_service; return false; @@ -1209,7 +1209,7 @@ TransporterRegistry::start_service(SocketServer& socket_server) { ndbout_c("Unable to setup transporter service port: %d!\n" "Please check if the port is already used,\n" - "(perhaps a mgmtsrvrserver is already running)", + "(perhaps a mgmt server is already running)", m_service_port); delete m_transporter_service; return false; diff --git a/ndb/src/common/util/Makefile.am b/ndb/src/common/util/Makefile.am index 678added01e..efb249dd330 100644 --- a/ndb/src/common/util/Makefile.am +++ b/ndb/src/common/util/Makefile.am @@ -9,7 +9,7 @@ libgeneral_la_SOURCES = \ NdbSqlUtil.cpp new.cpp \ uucode.c random.c getarg.c version.c \ strdup.c strlcat.c strlcpy.c \ - ConfigValues.cpp + ConfigValues.cpp ndb_init.c include $(top_srcdir)/ndb/config/common.mk.am include $(top_srcdir)/ndb/config/type_util.mk.am diff --git a/ndb/src/common/util/NdbSqlUtil.cpp b/ndb/src/common/util/NdbSqlUtil.cpp index 84a6f6e6c21..afb9bcfff62 100644 --- a/ndb/src/common/util/NdbSqlUtil.cpp +++ b/ndb/src/common/util/NdbSqlUtil.cpp @@ -529,6 +529,83 @@ NdbSqlUtil::cmpText(const Uint32* p1, const Uint32* p2, Uint32 full, Uint32 size return CmpUnknown; } +// check charset + +bool +NdbSqlUtil::usable_in_pk(Uint32 typeId, const void* info) +{ + const Type& type = getType(typeId); + switch (type.m_typeId) { + case Type::Undefined: + break; + case Type::Char: + { + const CHARSET_INFO *cs = (const CHARSET_INFO*)info; + return + cs != 0 && + cs->cset != 0 && + cs->coll != 0 && + cs->coll->strnxfrm != 0 && + cs->strxfrm_multiply == 1; // current limitation + } + break; + case Type::Varchar: + return true; // Varchar not used via MySQL + case Type::Blob: + case Type::Text: + break; + default: + return true; + } + return false; +} + +bool +NdbSqlUtil::usable_in_hash_index(Uint32 typeId, const void* info) +{ + return usable_in_pk(typeId, info); +} + +bool +NdbSqlUtil::usable_in_ordered_index(Uint32 typeId, const void* info) +{ + const Type& type = getType(typeId); + switch (type.m_typeId) { + case Type::Undefined: + break; + case Type::Char: + { + const CHARSET_INFO *cs = (const CHARSET_INFO*)info; + return + cs != 0 && + cs->cset != 0 && + cs->coll != 0 && + cs->coll->strnxfrm != 0 && + cs->coll->strnncollsp != 0 && + cs->strxfrm_multiply == 1; // current limitation + } + break; + case Type::Varchar: + return true; // Varchar not used via MySQL + case Type::Text: + { + const CHARSET_INFO *cs = (const CHARSET_INFO*)info; + return + cs != 0 && + cs->mbmaxlen == 1 && // extra limitation + cs->cset != 0 && + cs->coll != 0 && + cs->coll->strnxfrm != 0 && + cs->coll->strnncollsp != 0 && + cs->strxfrm_multiply == 1; // current limitation + } + break; + default: + return true; + } + return false; +} + #ifdef NDB_SQL_UTIL_TEST #include <NdbTick.h> diff --git a/ndb/src/common/util/ndb_init.c b/ndb/src/common/util/ndb_init.c new file mode 100644 index 00000000000..b160ed3636b --- /dev/null +++ b/ndb/src/common/util/ndb_init.c @@ -0,0 +1,29 @@ +/* Copyright (C) 2003 MySQL AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#include <ndb_global.h> +#include <my_sys.h> + +int +ndb_init() +{ + if (my_init()) { + const char* err = "my_init() failed - exit\n"; + write(2, err, strlen(err)); + exit(1); + } + return 0; +} diff --git a/ndb/src/cw/cpcd/Process.cpp b/ndb/src/cw/cpcd/Process.cpp index 0a986f63fda..c38b2a45145 100644 --- a/ndb/src/cw/cpcd/Process.cpp +++ b/ndb/src/cw/cpcd/Process.cpp @@ -353,6 +353,7 @@ CPCD::Process::start() { setsid(); writePid(getpgrp()); if(runas(m_runas.c_str()) == 0){ + signal(SIGCHLD, SIG_DFL); do_exec(); } _exit(1); @@ -383,6 +384,7 @@ CPCD::Process::start() { if(runas(m_runas.c_str()) != 0){ _exit(1); } + signal(SIGCHLD, SIG_DFL); do_exec(); _exit(1); /* NOTREACHED */ diff --git a/ndb/src/kernel/blocks/backup/Backup.cpp b/ndb/src/kernel/blocks/backup/Backup.cpp index 1690712d48c..b3e9ff735ac 100644 --- a/ndb/src/kernel/blocks/backup/Backup.cpp +++ b/ndb/src/kernel/blocks/backup/Backup.cpp @@ -885,7 +885,7 @@ Backup::execBACKUP_REQ(Signal* signal) }//if ndbrequire(ptr.p->pages.empty()); - ndbrequire(ptr.p->tables.empty()); + ndbrequire(ptr.p->tables.isEmpty()); ptr.p->masterData.state.forceState(INITIAL); ptr.p->masterData.state.setState(DEFINING); @@ -2484,8 +2484,7 @@ Backup::execLIST_TABLES_CONF(Signal* signal) jam(); Uint32 tableId = ListTablesConf::getTableId(conf->tableData[i]); Uint32 tableType = ListTablesConf::getTableType(conf->tableData[i]); - if (tableType != DictTabInfo::SystemTable && - tableType != DictTabInfo::UserTable) { + if (!DictTabInfo::isTable(tableType) && !DictTabInfo::isIndex(tableType)){ jam(); continue; }//if @@ -2864,7 +2863,12 @@ Backup::execGET_TABINFO_CONF(Signal* signal) return; }//if + TablePtr tmp = tabPtr; ptr.p->tables.next(tabPtr); + if(DictTabInfo::isIndex(tmp.p->tableType)){ + ptr.p->tables.release(tmp); + } + if(tabPtr.i == RNIL) { jam(); @@ -2906,7 +2910,11 @@ Backup::parseTableDescription(Signal* signal, BackupRecordPtr ptr, Uint32 len) TablePtr tabPtr; ndbrequire(findTable(ptr, tabPtr, tmpTab.TableId)); - + if(DictTabInfo::isIndex(tabPtr.p->tableType)){ + jam(); + return tabPtr; + } + /** * Initialize table object */ diff --git a/ndb/src/kernel/blocks/backup/Backup.hpp b/ndb/src/kernel/blocks/backup/Backup.hpp index ed01331fe15..4dc2cd13ae0 100644 --- a/ndb/src/kernel/blocks/backup/Backup.hpp +++ b/ndb/src/kernel/blocks/backup/Backup.hpp @@ -441,7 +441,7 @@ public: Uint32 startGCP; Uint32 currGCP; Uint32 stopGCP; - SLList<Table> tables; + DLList<Table> tables; SLList<TriggerRecord> triggers; SLList<BackupFile> files; diff --git a/ndb/src/kernel/blocks/backup/read.cpp b/ndb/src/kernel/blocks/backup/read.cpp index 921c352ea13..89cc08ee9de 100644 --- a/ndb/src/kernel/blocks/backup/read.cpp +++ b/ndb/src/kernel/blocks/backup/read.cpp @@ -48,6 +48,7 @@ static Uint32 logEntryNo; int main(int argc, const char * argv[]){ + ndb_init(); if(argc <= 1){ printf("Usage: %s <filename>", argv[0]); exit(1); diff --git a/ndb/src/kernel/blocks/backup/restore/Restore.cpp b/ndb/src/kernel/blocks/backup/restore/Restore.cpp index f0ca54884be..f60480ad7bf 100644 --- a/ndb/src/kernel/blocks/backup/restore/Restore.cpp +++ b/ndb/src/kernel/blocks/backup/restore/Restore.cpp @@ -240,6 +240,7 @@ RestoreMetaData::parseTableDescriptor(const Uint32 * data, Uint32 len) debug << "Pushing table " << table->getTableName() << endl; debug << " with " << table->getNoOfAttributes() << " attributes" << endl; + allTables.push_back(table); return true; @@ -683,8 +684,8 @@ RestoreDataIterator::validateFragmentFooter() { AttributeDesc::AttributeDesc(NdbDictionary::Column *c) : m_column(c) { - size = c->getSize()*8; - arraySize = c->getLength(); + size = 8*NdbColumnImpl::getImpl(* c).m_attrSize; + arraySize = NdbColumnImpl::getImpl(* c).m_arraySize; } void TableS::createAttr(NdbDictionary::Column *column) diff --git a/ndb/src/kernel/blocks/backup/restore/consumer.hpp b/ndb/src/kernel/blocks/backup/restore/consumer.hpp index e3ba2041a22..0b7b517c666 100644 --- a/ndb/src/kernel/blocks/backup/restore/consumer.hpp +++ b/ndb/src/kernel/blocks/backup/restore/consumer.hpp @@ -24,6 +24,7 @@ public: virtual ~BackupConsumer() { } virtual bool init() { return true;} virtual bool table(const TableS &){return true;} + virtual bool endOfTables() { return true; } virtual void tuple(const TupleS &){} virtual void tuple_free(){} virtual void endOfTuples(){} diff --git a/ndb/src/kernel/blocks/backup/restore/consumer_restore.cpp b/ndb/src/kernel/blocks/backup/restore/consumer_restore.cpp index 5731a9a3883..c132bccee75 100644 --- a/ndb/src/kernel/blocks/backup/restore/consumer_restore.cpp +++ b/ndb/src/kernel/blocks/backup/restore/consumer_restore.cpp @@ -16,6 +16,7 @@ #include "consumer_restore.hpp" #include <NdbSleep.h> +#include <NdbDictionaryImpl.hpp> extern FilteredNdbOut err; extern FilteredNdbOut info; @@ -36,9 +37,6 @@ BackupRestore::init() if (m_ndb == NULL) return false; - // Turn off table name completion - m_ndb->useFullyQualifiedNames(false); - m_ndb->init(1024); if (m_ndb->waitUntilReady(30) != 0) { @@ -102,19 +100,147 @@ BackupRestore::~BackupRestore() release(); } +static +int +match_blob(const char * name){ + int cnt, id1, id2; + char buf[256]; + if((cnt = sscanf(name, "%[^/]/%[^/]/NDB$BLOB_%d_%d", buf, buf, &id1, &id2)) == 4){ + return id1; + } + + return -1; +} + +const NdbDictionary::Table* +BackupRestore::get_table(const NdbDictionary::Table* tab){ + if(m_cache.m_old_table == tab) + return m_cache.m_new_table; + m_cache.m_old_table = tab; + + int cnt, id1, id2; + char buf[256]; + if((cnt = sscanf(tab->getName(), "%[^/]/%[^/]/NDB$BLOB_%d_%d", buf, buf, &id1, &id2)) == 4){ + snprintf(buf, sizeof(buf), "NDB$BLOB_%d_%d", m_new_tables[id1]->getTableId(), id2); + m_cache.m_new_table = m_ndb->getDictionary()->getTable(buf); + } else { + m_cache.m_new_table = m_new_tables[tab->getTableId()]; + } + + return m_cache.m_new_table; +} + bool BackupRestore::table(const TableS & table){ - if (!m_restore_meta) + if (!m_restore && !m_restore_meta) + return true; + + const char * name = table.getTableName(); + + /** + * Ignore blob tables + */ + if(match_blob(name) >= 0) return true; + + const NdbTableImpl & tmptab = NdbTableImpl::getImpl(* table.m_dictTable); + if(tmptab.m_indexType != NdbDictionary::Index::Undefined){ + m_indexes.push_back(table.m_dictTable); + return true; + } + + BaseString tmp(name); + Vector<BaseString> split; + if(tmp.split(split, "/") != 3){ + err << "Invalid table name format " << name << endl; + return false; + } + m_ndb->setDatabaseName(split[0].c_str()); + m_ndb->setSchemaName(split[1].c_str()); + NdbDictionary::Dictionary* dict = m_ndb->getDictionary(); - if (dict->createTable(*table.m_dictTable) == -1) - { - err << "Create table " << table.getTableName() << " failed: " - << dict->getNdbError() << endl; + if(m_restore_meta){ + NdbDictionary::Table copy(*table.m_dictTable); + + copy.setName(split[2].c_str()); + + if (dict->createTable(copy) == -1) + { + err << "Create table " << table.getTableName() << " failed: " + << dict->getNdbError() << endl; + return false; + } + info << "Successfully restored table " << table.getTableName()<< endl ; + } + + const NdbDictionary::Table* tab = dict->getTable(split[2].c_str()); + if(tab == 0){ + err << "Unable to find table: " << split[2].c_str() << endl; return false; } - info << "Successfully restored table " << table.getTableName()<< endl ; + const NdbDictionary::Table* null = 0; + m_new_tables.fill(table.m_dictTable->getTableId(), null); + m_new_tables[table.m_dictTable->getTableId()] = tab; + return true; +} + +bool +BackupRestore::endOfTables(){ + if(!m_restore_meta) + return true; + + NdbDictionary::Dictionary* dict = m_ndb->getDictionary(); + for(size_t i = 0; i<m_indexes.size(); i++){ + const NdbTableImpl & indtab = NdbTableImpl::getImpl(* m_indexes[i]); + + BaseString tmp(indtab.m_primaryTable.c_str()); + Vector<BaseString> split; + if(tmp.split(split, "/") != 3){ + err << "Invalid table name format " << indtab.m_primaryTable.c_str() + << endl; + return false; + } + + m_ndb->setDatabaseName(split[0].c_str()); + m_ndb->setSchemaName(split[1].c_str()); + + const NdbDictionary::Table * prim = dict->getTable(split[2].c_str()); + if(prim == 0){ + err << "Unable to find base table \"" << split[2].c_str() + << "\" for index " + << indtab.getName() << endl; + return false; + } + NdbTableImpl& base = NdbTableImpl::getImpl(*prim); + NdbIndexImpl* idx; + int id; + char idxName[255], buf[255]; + if(sscanf(indtab.getName(), "%[^/]/%[^/]/%d/%s", + buf, buf, &id, idxName) != 4){ + err << "Invalid index name format " << indtab.getName() << endl; + return false; + } + if(NdbDictInterface::create_index_obj_from_table(&idx, &indtab, &base)) + { + err << "Failed to create index " << idxName + << " on " << split[2].c_str() << endl; + return false; + } + idx->setName(idxName); + if(dict->createIndex(* idx) != 0) + { + delete idx; + err << "Failed to create index " << idxName + << " on " << split[2].c_str() << endl + << dict->getNdbError() << endl; + + return false; + } + delete idx; + info << "Successfully created index " << idxName + << " on " << split[2].c_str() << endl; + } return true; } @@ -161,8 +287,9 @@ void BackupRestore::tuple_a(restore_callback_t *cb) } // if const TupleS &tup = *(cb->tup); - const TableS * table = tup.getTable(); - NdbOperation * op = cb->connection->getNdbOperation(table->getTableName()); + const NdbDictionary::Table * table = get_table(tup.getTable()->m_dictTable); + + NdbOperation * op = cb->connection->getNdbOperation(table); if (op == NULL) { @@ -203,8 +330,9 @@ void BackupRestore::tuple_a(restore_callback_t *cb) ret = op->setValue(i, dataPtr, length); } if (ret < 0) { - ndbout_c("Column: %d type %d",i, - attr_desc->m_column->getType()); + ndbout_c("Column: %d type %d %d %d %d",i, + attr_desc->m_column->getType(), + size, arraySize, attr_data->size); break; } } @@ -349,8 +477,8 @@ BackupRestore::logEntry(const LogEntry & tup) exit(-1); } // if - const TableS * table = tup.m_table; - NdbOperation * op = trans->getNdbOperation(table->getTableName()); + const NdbDictionary::Table * table = get_table(tup.m_table->m_dictTable); + NdbOperation * op = trans->getNdbOperation(table); if (op == NULL) { err << "Cannot get operation: " << trans->getNdbError() << endl; @@ -514,3 +642,6 @@ BackupRestore::tuple(const TupleS & tup) m_dataCount++; } #endif + +template class Vector<NdbDictionary::Table*>; +template class Vector<const NdbDictionary::Table*>; diff --git a/ndb/src/kernel/blocks/backup/restore/consumer_restore.hpp b/ndb/src/kernel/blocks/backup/restore/consumer_restore.hpp index 2d36501bf40..ca336eeea4f 100644 --- a/ndb/src/kernel/blocks/backup/restore/consumer_restore.hpp +++ b/ndb/src/kernel/blocks/backup/restore/consumer_restore.hpp @@ -42,12 +42,14 @@ public: m_tuples = 0; m_free_callback = 0; m_transactions = 0; + m_cache.m_old_table = 0; } virtual ~BackupRestore(); virtual bool init(); virtual void release(); virtual bool table(const TableS &); + virtual bool endOfTables(); virtual void tuple(const TupleS &); virtual void tuple_free(); virtual void tuple_a(restore_callback_t *cb); @@ -70,6 +72,20 @@ public: TupleS *m_tuples; restore_callback_t *m_callback; restore_callback_t *m_free_callback; + + /** + * m_new_table_ids[X] = Y; + * X - old table id + * Y != 0 - new table + */ + Vector<const NdbDictionary::Table*> m_new_tables; + struct { + const NdbDictionary::Table* m_old_table; + const NdbDictionary::Table* m_new_table; + } m_cache; + const NdbDictionary::Table* get_table(const NdbDictionary::Table* ); + + Vector<const NdbDictionary::Table*> m_indexes; }; #endif diff --git a/ndb/src/kernel/blocks/backup/restore/main.cpp b/ndb/src/kernel/blocks/backup/restore/main.cpp index 23805173484..5708415c61e 100644 --- a/ndb/src/kernel/blocks/backup/restore/main.cpp +++ b/ndb/src/kernel/blocks/backup/restore/main.cpp @@ -206,6 +206,7 @@ free_data_callback() int main(int argc, const char** argv) { + ndb_init(); if (!readArguments(argc, argv)) { return -1; @@ -276,81 +277,88 @@ main(int argc, const char** argv) } } + for(i= 0; i < g_consumers.size(); i++) + if (!g_consumers[i]->endOfTables()) + { + ndbout_c("Restore: Failed while closing tables"); + return -11; + } + if (ga_restore || ga_print) { - if (ga_restore) + if (ga_restore) + { + RestoreDataIterator dataIter(metaData, &free_data_callback); + + // Read data file header + if (!dataIter.readHeader()) { - RestoreDataIterator dataIter(metaData, &free_data_callback); - - // Read data file header - if (!dataIter.readHeader()) - { - ndbout << "Failed to read header of data file. Exiting..." ; - return -11; - } - - - while (dataIter.readFragmentHeader(res= 0)) + ndbout << "Failed to read header of data file. Exiting..." ; + return -11; + } + + + while (dataIter.readFragmentHeader(res= 0)) + { + const TupleS* tuple; + while ((tuple = dataIter.getNextTuple(res= 1)) != 0) { - const TupleS* tuple; - while ((tuple = dataIter.getNextTuple(res= 1)) != 0) - { - if (checkSysTable(tuple->getTable()->getTableName())) - for(Uint32 i= 0; i < g_consumers.size(); i++) - g_consumers[i]->tuple(* tuple); - } // while (tuple != NULL); - - if (res < 0) - { - ndbout_c("Restore: An error occured while restoring data. " - "Exiting..."); - return -1; - } - if (!dataIter.validateFragmentFooter()) { - ndbout_c("Restore: Error validating fragment footer. " - "Exiting..."); - return -1; - } - } // while (dataIter.readFragmentHeader(res)) + if (checkSysTable(tuple->getTable()->getTableName())) + for(Uint32 i= 0; i < g_consumers.size(); i++) + g_consumers[i]->tuple(* tuple); + } // while (tuple != NULL); if (res < 0) { - err << "Restore: An error occured while restoring data. Exiting... res=" << res << endl; + ndbout_c("Restore: An error occured while restoring data. " + "Exiting..."); return -1; } - - - dataIter.validateFooter(); //not implemented - - for (Uint32 i= 0; i < g_consumers.size(); i++) - g_consumers[i]->endOfTuples(); - - RestoreLogIterator logIter(metaData); - if (!logIter.readHeader()) - { - err << "Failed to read header of data file. Exiting..." << endl; - return -1; - } - - const LogEntry * logEntry = 0; - while ((logEntry = logIter.getNextLogEntry(res= 0)) != 0) - { - if (checkSysTable(logEntry->m_table->getTableName())) - for(Uint32 i= 0; i < g_consumers.size(); i++) - g_consumers[i]->logEntry(* logEntry); - } - if (res < 0) - { - err << "Restore: An restoring the data log. Exiting... res=" << res << endl; + if (!dataIter.validateFragmentFooter()) { + ndbout_c("Restore: Error validating fragment footer. " + "Exiting..."); return -1; } - logIter.validateFooter(); //not implemented - for (i= 0; i < g_consumers.size(); i++) - g_consumers[i]->endOfLogEntrys(); + } // while (dataIter.readFragmentHeader(res)) + + if (res < 0) + { + err << "Restore: An error occured while restoring data. Exiting... res=" << res << endl; + return -1; + } + + + dataIter.validateFooter(); //not implemented + + for (i= 0; i < g_consumers.size(); i++) + g_consumers[i]->endOfTuples(); + + RestoreLogIterator logIter(metaData); + if (!logIter.readHeader()) + { + err << "Failed to read header of data file. Exiting..." << endl; + return -1; + } + + const LogEntry * logEntry = 0; + while ((logEntry = logIter.getNextLogEntry(res= 0)) != 0) + { + if (checkSysTable(logEntry->m_table->getTableName())) + for(Uint32 i= 0; i < g_consumers.size(); i++) + g_consumers[i]->logEntry(* logEntry); + } + if (res < 0) + { + err << "Restore: An restoring the data log. Exiting... res=" << res << endl; + return -1; } + logIter.validateFooter(); //not implemented + for (i= 0; i < g_consumers.size(); i++) + g_consumers[i]->endOfLogEntrys(); + } } clearConsumers(); - return 1; + return 0; } // main template class Vector<BackupConsumer*>; diff --git a/ndb/src/kernel/blocks/dbdict/Dbdict.cpp b/ndb/src/kernel/blocks/dbdict/Dbdict.cpp index 7126842459e..d82083684b7 100644 --- a/ndb/src/kernel/blocks/dbdict/Dbdict.cpp +++ b/ndb/src/kernel/blocks/dbdict/Dbdict.cpp @@ -6317,6 +6317,8 @@ Dbdict::createIndex_toCreateTable(Signal* signal, OpCreateIndexPtr opPtr) w.add(DictTabInfo::AttributeStoredInd, (Uint32)DictTabInfo::Stored); // ext type overrides w.add(DictTabInfo::AttributeExtType, aRec->extType); + w.add(DictTabInfo::AttributeExtPrecision, aRec->extPrecision); + w.add(DictTabInfo::AttributeExtScale, aRec->extScale); w.add(DictTabInfo::AttributeExtLength, aRec->extLength); w.add(DictTabInfo::AttributeEnd, (Uint32)true); } diff --git a/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp b/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp index 71d5dd8e193..3b05a133bbb 100644 --- a/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp +++ b/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp @@ -8134,8 +8134,8 @@ void Dblqh::scanTupkeyConfLab(Signal* signal) ndbrequire(scanptr.p->m_curr_batch_size_rows < MAX_PARALLEL_OP_PER_SCAN); scanptr.p->m_curr_batch_size_bytes+= tdata4; scanptr.p->m_curr_batch_size_rows++; - scanptr.p->m_last_row = conf->lastRow; - if (scanptr.p->check_scan_batch_completed() | conf->lastRow){ + scanptr.p->m_last_row = tdata5; + if (scanptr.p->check_scan_batch_completed() | tdata5){ if (scanptr.p->scanLockHold == ZTRUE) { jam(); scanptr.p->scanState = ScanRecord::WAIT_SCAN_NEXTREQ; diff --git a/ndb/src/kernel/blocks/dbtup/DbtupBuffer.cpp b/ndb/src/kernel/blocks/dbtup/DbtupBuffer.cpp index ea46ee94fdc..6527864135b 100644 --- a/ndb/src/kernel/blocks/dbtup/DbtupBuffer.cpp +++ b/ndb/src/kernel/blocks/dbtup/DbtupBuffer.cpp @@ -134,6 +134,10 @@ void Dbtup::sendReadAttrinfo(Signal* signal, const Operationrec * const regOperPtr) { const BlockReference recBlockref = regOperPtr->recBlockref; + const Uint32 sig0 = regOperPtr->tcOperationPtr; + const Uint32 sig1 = regOperPtr->transid1; + const Uint32 sig2 = regOperPtr->transid2; + const Uint32 block = refToBlock(recBlockref); const Uint32 nodeId = refToNode(recBlockref); @@ -141,6 +145,8 @@ void Dbtup::sendReadAttrinfo(Signal* signal, const Uint32 type = getNodeInfo(nodeId).m_type; bool is_api = (type >= NodeInfo::API && type <= NodeInfo::REP); bool old_dest = (getNodeInfo(nodeId).m_version < MAKE_VERSION(3,5,0)); + const Uint32 TpacketTA = hostBuffer[nodeId].noOfPacketsTA; + const Uint32 TpacketLen = hostBuffer[nodeId].packetLenTA; if (ERROR_INSERTED(4006) && (nodeId != getOwnNodeId())){ // Use error insert to turn routing on @@ -148,15 +154,11 @@ void Dbtup::sendReadAttrinfo(Signal* signal, connectedToNode = false; } - Uint32 sig0 = regOperPtr->tcOperationPtr; - Uint32 sig1 = regOperPtr->transid1; - Uint32 sig2 = regOperPtr->transid2; - TransIdAI * transIdAI = (TransIdAI *)signal->getDataPtrSend(); transIdAI->connectPtr = sig0; transIdAI->transId[0] = sig1; transIdAI->transId[1] = sig2; - + if (connectedToNode){ /** * Own node -> execute direct @@ -169,6 +171,22 @@ void Dbtup::sendReadAttrinfo(Signal* signal, */ if(ToutBufIndex >= 22 && is_api && !old_dest) { ljam(); + /** + * Flush buffer so that order is maintained + */ + if (TpacketTA != 0) { + ljam(); + BlockReference TBref = numberToRef(API_PACKED, nodeId); + MEMCOPY_NO_WORDS(&signal->theData[0], + &hostBuffer[nodeId].packetBufferTA[0], + TpacketLen); + sendSignal(TBref, GSN_TRANSID_AI, signal, TpacketLen, JBB); + hostBuffer[nodeId].noOfPacketsTA = 0; + hostBuffer[nodeId].packetLenTA = 0; + transIdAI->connectPtr = sig0; + transIdAI->transId[0] = sig1; + transIdAI->transId[1] = sig2; + }//if LinearSectionPtr ptr[3]; ptr[0].p = &signal->theData[25]; ptr[0].sz = ToutBufIndex; diff --git a/ndb/src/kernel/error/ErrorReporter.cpp b/ndb/src/kernel/error/ErrorReporter.cpp index f1320c44e09..d43001ef1f5 100644 --- a/ndb/src/kernel/error/ErrorReporter.cpp +++ b/ndb/src/kernel/error/ErrorReporter.cpp @@ -139,7 +139,7 @@ ErrorReporter::formatMessage(ErrorCategory type, objRef, programName, processId, - theNameOfTheTraceFile); + theNameOfTheTraceFile ? theNameOfTheTraceFile : "<no tracefile>"); // Add trailing blanks to get a fixed lenght of the message while (strlen(messptr) <= MESSAGE_LENGTH-3){ @@ -217,8 +217,10 @@ WriteMessage(ErrorCategory thrdType, int thrdMessageID, /** * Format trace file name */ - int file_no= ErrorReporter::get_trace_no(); - char *theTraceFileName= NdbConfig_TraceFileName(globalData.ownId, file_no); + char *theTraceFileName= 0; + if (globalData.ownId > 0) + theTraceFileName= NdbConfig_TraceFileName(globalData.ownId, + ErrorReporter::get_trace_no()); NdbAutoPtr<char> tmp_aptr1(theTraceFileName); // The first 69 bytes is info about the current offset @@ -291,26 +293,28 @@ WriteMessage(ErrorCategory thrdType, int thrdMessageID, fflush(stream); fclose(stream); - // Open the tracefile... - FILE *jamStream = fopen(theTraceFileName, "w"); + if (theTraceFileName) { + // Open the tracefile... + FILE *jamStream = fopen(theTraceFileName, "w"); - // ...and "dump the jam" there. - // ErrorReporter::dumpJam(jamStream); - if(thrdTheEmulatedJam != 0){ - dumpJam(jamStream, thrdTheEmulatedJamIndex, thrdTheEmulatedJam); - } - - /* Dont print the jobBuffers until a way to copy them, - like the other variables, - is implemented. Otherwise when NDB keeps running, - with this function running - in the background, the jobBuffers will change during runtime. And when - they're printed here, they will not be correct anymore. - */ - globalScheduler.dumpSignalMemory(jamStream); + // ...and "dump the jam" there. + // ErrorReporter::dumpJam(jamStream); + if(thrdTheEmulatedJam != 0){ + dumpJam(jamStream, thrdTheEmulatedJamIndex, thrdTheEmulatedJam); + } - fclose(jamStream); + /* Dont print the jobBuffers until a way to copy them, + like the other variables, + is implemented. Otherwise when NDB keeps running, + with this function running + in the background, the jobBuffers will change during runtime. And when + they're printed here, they will not be correct anymore. + */ + globalScheduler.dumpSignalMemory(jamStream); + fclose(jamStream); + } + return 0; } diff --git a/ndb/src/kernel/main.cpp b/ndb/src/kernel/main.cpp index 491733975a8..20844db75b6 100644 --- a/ndb/src/kernel/main.cpp +++ b/ndb/src/kernel/main.cpp @@ -56,6 +56,7 @@ const char programName[] = "NDB Kernel"; NDB_MAIN(ndb_kernel){ + ndb_init(); // Print to stdout/console g_eventLogger.createConsoleHandler(); g_eventLogger.setCategory("NDB"); diff --git a/ndb/src/kernel/vm/Configuration.cpp b/ndb/src/kernel/vm/Configuration.cpp index 8907cb9f640..c0015172512 100644 --- a/ndb/src/kernel/vm/Configuration.cpp +++ b/ndb/src/kernel/vm/Configuration.cpp @@ -15,7 +15,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include <ndb_global.h> -#include <my_sys.h> #include "Configuration.hpp" #include <ErrorHandlingMacros.hpp> @@ -105,7 +104,6 @@ Configuration::init(int argc, const char** argv){ } // check for depricated flag '-i' - my_init(); #ifndef DBUG_OFF if (debug_option) DBUG_PUSH(debug_option); diff --git a/ndb/src/mgmapi/mgmapi.cpp b/ndb/src/mgmapi/mgmapi.cpp index 0f65d9425ae..08b83a8d750 100644 --- a/ndb/src/mgmapi/mgmapi.cpp +++ b/ndb/src/mgmapi/mgmapi.cpp @@ -403,14 +403,15 @@ ndb_mgm_disconnect(NdbMgmHandle handle) struct ndb_mgm_type_atoi { const char * str; + const char * alias; enum ndb_mgm_node_type value; }; static struct ndb_mgm_type_atoi type_values[] = { - { "NDB", NDB_MGM_NODE_TYPE_NDB}, - { "API", NDB_MGM_NODE_TYPE_API }, - { "MGM", NDB_MGM_NODE_TYPE_MGM } + { "NDB", "ndbd", NDB_MGM_NODE_TYPE_NDB}, + { "API", "mysqld", NDB_MGM_NODE_TYPE_API }, + { "MGM", "ndb_mgmd", NDB_MGM_NODE_TYPE_MGM } }; const int no_of_type_values = (sizeof(type_values) / @@ -440,6 +441,20 @@ ndb_mgm_get_node_type_string(enum ndb_mgm_node_type type) return 0; } +extern "C" +const char * +ndb_mgm_get_node_type_alias_string(enum ndb_mgm_node_type type, const char** str) +{ + for(int i = 0; i<no_of_type_values; i++) + if(type_values[i].value == type) + { + if (str) + *str= type_values[i].str; + return type_values[i].alias; + } + return 0; +} + struct ndb_mgm_status_atoi { const char * str; enum ndb_mgm_node_status value; @@ -509,6 +524,9 @@ status_ackumulate(struct ndb_mgm_node_state * state, state->version = atoi(value); } else if(strcmp("connect_count", field) == 0){ state->connect_count = atoi(value); + } else if(strcmp("address", field) == 0){ + strncpy(state->connect_address, value, sizeof(state->connect_address)); + state->connect_address[sizeof(state->connect_address)-1]= 0; } else { ndbout_c("Unknown field: %s", field); } @@ -575,22 +593,27 @@ ndb_mgm_get_status(NdbMgmHandle handle) ndb_mgm_cluster_state *state = (ndb_mgm_cluster_state*) malloc(sizeof(ndb_mgm_cluster_state)+ - noOfNodes*sizeof(ndb_mgm_node_state)); + noOfNodes*(sizeof(ndb_mgm_node_state)+sizeof("000.000.000.000#"))); - state->no_of_nodes = noOfNodes; + state->hostname= 0; + state->no_of_nodes= noOfNodes; ndb_mgm_node_state * ptr = &state->node_states[0]; int nodeId = 0; - int i = -1; ptr--; + int i; + for (i= 0; i < noOfNodes; i++) { + state->node_states[i].connect_address[0]= 0; + } + i = -1; ptr--; for(; i<noOfNodes; ){ in.gets(buf, sizeof(buf)); tmp.assign(buf); - + if(tmp.trim() == ""){ break; } Vector<BaseString> split; - tmp.split(split, ":."); + tmp.split(split, ":.", 4); if(split.size() != 4) break; @@ -1512,8 +1535,10 @@ extern "C" void ndb_mgm_destroy_configuration(struct ndb_mgm_configuration *cfg) { - if (cfg) - delete (ConfigValues *)cfg; + if (cfg) { + ((ConfigValues *)cfg)->~ConfigValues(); + free((void *)cfg); + } } extern "C" diff --git a/ndb/src/mgmclient/CommandInterpreter.cpp b/ndb/src/mgmclient/CommandInterpreter.cpp index 5496f18bd2a..91d057f8c30 100644 --- a/ndb/src/mgmclient/CommandInterpreter.cpp +++ b/ndb/src/mgmclient/CommandInterpreter.cpp @@ -19,6 +19,7 @@ #include <mgmapi.h> #include <mgmapi_debug.h> #include <version.h> +#include <NdbAutoPtr.hpp> #include <NdbOut.hpp> #include <NdbSleep.h> #include <EventLogger.hpp> @@ -53,7 +54,7 @@ static const char* helpText = #endif "START BACKUP Start backup\n" "ABORT BACKUP <backup id> Abort backup\n" -"SHUTDOWN Shutdown all processed in cluster and quit\n" +"SHUTDOWN Shutdown all processes in cluster and quit\n" "CLUSTERLOG ON Enable Cluster logging\n" "CLUSTERLOG OFF Disable Cluster logging\n" "CLUSTERLOG FILTER <severity> Toggle severity filter on/off\n" @@ -77,8 +78,10 @@ static const char* helpTextShow = "---------------------------------------------------------------------------\n" "SHOW prints NDB Cluster information\n\n" "SHOW Print information about cluster\n" +#if 0 "SHOW CONFIG Print configuration (in initial config file format)\n" "SHOW PARAMETERS Print information about configuration parameters\n\n" +#endif ; #ifdef HAVE_GLOBAL_REPLICATION @@ -692,6 +695,79 @@ CommandInterpreter::executeShutdown(char* parameters) * SHOW *****************************************************************************/ + +static +const char *status_string(ndb_mgm_node_status status) +{ + switch(status){ + case NDB_MGM_NODE_STATUS_NO_CONTACT: + return "not connected"; + case NDB_MGM_NODE_STATUS_NOT_STARTED: + return "not started"; + case NDB_MGM_NODE_STATUS_STARTING: + return "starting"; + case NDB_MGM_NODE_STATUS_STARTED: + return "started"; + case NDB_MGM_NODE_STATUS_SHUTTING_DOWN: + return "shutting down"; + case NDB_MGM_NODE_STATUS_RESTARTING: + return "restarting"; + case NDB_MGM_NODE_STATUS_SINGLEUSER: + return "single user mode"; + default: + return "unknown state"; + } +} + +static void +print_nodes(ndb_mgm_cluster_state *state, ndb_mgm_configuration_iterator *it, + const char *proc_name, int no_proc, ndb_mgm_node_type type, int master_id) +{ + int i; + ndbout << "[" << proc_name + << "(" << ndb_mgm_get_node_type_string(type) << ")]\t" << no_proc << " node(s)" << endl; + for(i=0; i < state->no_of_nodes; i++) { + struct ndb_mgm_node_state *node_state= &(state->node_states[i]); + if(node_state->node_type == type) { + int node_id= node_state->node_id; + ndbout << "id=" << node_id; + if(node_state->version != 0) { + const char *hostname= node_state->connect_address; + if (hostname == 0 || strlen(hostname) == 0 || strcmp(hostname,"0.0.0.0") == 0) + ndbout << " "; + else + ndbout << "\t@" << hostname; + ndbout << " (Version: " + << getMajor(node_state->version) << "." + << getMinor(node_state->version) << "." + << getBuild(node_state->version); + if (type == NDB_MGM_NODE_TYPE_NDB) { + if (node_state->node_status != NDB_MGM_NODE_STATUS_STARTED) { + ndbout << ", " << status_string(node_state->node_status); + } + if (node_state->node_group >= 0) { + ndbout << ", Nodegroup: " << node_state->node_group; + if (node_state->dynamic_id == master_id) + ndbout << ", Master"; + } + } + ndbout << ")" << endl; + } else { + if(ndb_mgm_find(it, CFG_NODE_ID, node_id) != 0){ + ndbout_c("Unable to find node with id: %d", node_id); + return; + } + const char *config_hostname= 0; + ndb_mgm_get_string_parameter(it, CFG_NODE_HOST, &config_hostname); + if (config_hostname == 0 || config_hostname[0] == 0) + config_hostname= "any host"; + ndbout << " (not connected, accepting connect from " << config_hostname << ")" << endl; + } + } + } + ndbout << endl; +} + void CommandInterpreter::executeShow(char* parameters) { @@ -708,6 +784,22 @@ CommandInterpreter::executeShow(char* parameters) return; } + ndb_mgm_configuration * conf = ndb_mgm_get_configuration(m_mgmsrv,0); + if(conf == 0){ + ndbout_c("Could not get configuration"); + printError(); + return; + } + + ndb_mgm_configuration_iterator * it; + it = ndb_mgm_create_configuration_iterator((struct ndb_mgm_configuration *)conf, CFG_SECTION_NODE); + + if(it == 0){ + ndbout_c("Unable to create config iterator"); + return; + } + NdbAutoPtr<ndb_mgm_configuration_iterator> ptr(it); + int master_id= 0, ndb_nodes= 0, @@ -741,73 +833,9 @@ CommandInterpreter::executeShow(char* parameters) } } - ndbout << ndb_nodes - << " [ndbd] node(s)" - << endl; - - for(i=0; i < state->no_of_nodes; i++) { - if(state->node_states[i].node_type == NDB_MGM_NODE_TYPE_NDB) { - ndbout << "[ndbd]\t\tid=" << state->node_states[i].node_id; - if(state->node_states[i].version != 0) { - ndbout << " (Version: " - << getMajor(state->node_states[i].version) << "." - << getMinor(state->node_states[i].version) << "." - << getBuild(state->node_states[i].version) << "," - << " Nodegroup: " << state->node_states[i].node_group; - if (state->node_states[i].dynamic_id == master_id) - ndbout << ", Master"; - ndbout << ")" << endl; - } else - { - ndbout << " (not connected) " << endl; - } - - } - } - ndbout << endl; - - ndbout << mgm_nodes - << " [ndb_mgmd] node(s)" - << endl; - - for(i=0; i < state->no_of_nodes; i++) { - if(state->node_states[i].node_type == NDB_MGM_NODE_TYPE_MGM) { - ndbout << "[ndb_mgmd]\tid=" << state->node_states[i].node_id; - if(state->node_states[i].version != 0) { - ndbout << " (Version: " - << getMajor(state->node_states[i].version) << "." - << getMinor(state->node_states[i].version) << "." - << getBuild(state->node_states[i].version) << ")" << endl; - - } else - { - ndbout << " (no version information available) " << endl; - } - } - } - ndbout << endl; - - ndbout << api_nodes - << " [mysqld] node(s)" - << endl; - - for(i=0; i < state->no_of_nodes; i++) { - if(state->node_states[i].node_type == NDB_MGM_NODE_TYPE_API) { - ndbout << "[mysqld]\tid=" << state->node_states[i].node_id; - if(state->node_states[i].version != 0) { - ndbout << " (Version: " - << getMajor(state->node_states[i].version) << "." - << getMinor(state->node_states[i].version) << "." - << getBuild(state->node_states[i].version) << ")" << endl; - - } else - { - ndbout << " (not connected) " << endl; - } - } - } - ndbout << endl; - + print_nodes(state, it, "ndbd", ndb_nodes, NDB_MGM_NODE_TYPE_NDB, master_id); + print_nodes(state, it, "ndb_mgmd", mgm_nodes, NDB_MGM_NODE_TYPE_MGM, 0); + print_nodes(state, it, "mysqld", api_nodes, NDB_MGM_NODE_TYPE_API, 0); // ndbout << helpTextShow; return; } else if (strcmp(parameters, "PROPERTIES") == 0 || @@ -1184,33 +1212,15 @@ CommandInterpreter::executeStatus(int processId, startPhase = cl->node_states[i].start_phase; version = cl->node_states[i].version; - ndbout << "Node " << processId << ": "; + ndbout << "Node " << processId << ": " << status_string(status); switch(status){ - case NDB_MGM_NODE_STATUS_NO_CONTACT: - ndbout << "No contact" << endl; - break; - case NDB_MGM_NODE_STATUS_NOT_STARTED: - ndbout << "Not started" ; - break; case NDB_MGM_NODE_STATUS_STARTING: - ndbout << "Starting (Start phase " << startPhase << ")" ; - break; - case NDB_MGM_NODE_STATUS_STARTED: - ndbout << "Started" ; + ndbout << " (Phase " << startPhase << ")" ; break; case NDB_MGM_NODE_STATUS_SHUTTING_DOWN: - ndbout << "Shutting down " << (system == false ? "node" : "system") - << " (Phase " << startPhase << ")" - ; - break; - case NDB_MGM_NODE_STATUS_RESTARTING: - ndbout << "Restarting" ; - break; - case NDB_MGM_NODE_STATUS_SINGLEUSER: - ndbout << "Single user mode" ; + ndbout << " (Phase " << startPhase << ")"; break; default: - ndbout << "Unknown state" ; break; } if(status != NDB_MGM_NODE_STATUS_NO_CONTACT) diff --git a/ndb/src/mgmclient/main.cpp b/ndb/src/mgmclient/main.cpp index df6659df0b1..69f968677cd 100644 --- a/ndb/src/mgmclient/main.cpp +++ b/ndb/src/mgmclient/main.cpp @@ -44,6 +44,7 @@ handler(int sig){ } int main(int argc, const char** argv){ + ndb_init(); int optind = 0; const char *_host = 0; int _port = 0; diff --git a/ndb/src/mgmsrv/ConfigInfo.cpp b/ndb/src/mgmsrv/ConfigInfo.cpp index b3afd57f6cd..7cb438bd2dd 100644 --- a/ndb/src/mgmsrv/ConfigInfo.cpp +++ b/ndb/src/mgmsrv/ConfigInfo.cpp @@ -33,6 +33,10 @@ * Section names ****************************************************************************/ +#define DB_TOKEN_PRINT "ndbd(DB)" +#define MGM_TOKEN_PRINT "ndb_mgmd(MGM)" +#define API_TOKEN_PRINT "mysqld(API)" + #define DB_TOKEN "DB" #define MGM_TOKEN "MGM" #define API_TOKEN "API" @@ -182,9 +186,12 @@ const int ConfigInfo::m_NoOfRules = sizeof(m_SectionRules)/sizeof(SectionRule); /**************************************************************************** * Config Rules declarations ****************************************************************************/ -static bool add_node_connections(Vector<ConfigInfo::ConfigRuleSection>§ions, +static bool sanity_checks(Vector<ConfigInfo::ConfigRuleSection>§ions, struct InitConfigFileParser::Context &ctx, const char * rule_data); +static bool add_node_connections(Vector<ConfigInfo::ConfigRuleSection>§ions, + struct InitConfigFileParser::Context &ctx, + const char * rule_data); static bool add_server_ports(Vector<ConfigInfo::ConfigRuleSection>§ions, struct InitConfigFileParser::Context &ctx, const char * rule_data); @@ -194,6 +201,7 @@ static bool check_node_vs_replicas(Vector<ConfigInfo::ConfigRuleSection>§ion const ConfigInfo::ConfigRule ConfigInfo::m_ConfigRules[] = { + { sanity_checks, 0 }, { add_node_connections, 0 }, { add_server_ports, 0 }, { check_node_vs_replicas, 0 }, @@ -275,6 +283,18 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = { ConfigInfo::STRING, MANDATORY, 0, 0 }, + + { + KEY_INTERNAL, + "ByteOrder", + "COMPUTER", + 0, + ConfigInfo::DEPRICATED, + false, + ConfigInfo::STRING, + UNDEFINED, + 0, + 0 }, /**************************************************************************** * SYSTEM @@ -316,7 +336,7 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = { CFG_SYS_PRIMARY_MGM_NODE, "PrimaryMGMNode", "SYSTEM", - "Node id of Primary "MGM_TOKEN" node", + "Node id of Primary "MGM_TOKEN_PRINT" node", ConfigInfo::USED, false, ConfigInfo::INT, @@ -377,7 +397,7 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = { CFG_NODE_ID, "Id", DB_TOKEN, - "Number identifying the database node ("DB_TOKEN")", + "Number identifying the database node ("DB_TOKEN_PRINT")", ConfigInfo::USED, false, ConfigInfo::INT, @@ -473,7 +493,7 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = { CFG_DB_NO_INDEX_OPS, "MaxNoOfConcurrentIndexOperations", DB_TOKEN, - "Total number of index operations that can execute simultaneously on one "DB_TOKEN" node", + "Total number of index operations that can execute simultaneously on one "DB_TOKEN_PRINT" node", ConfigInfo::USED, false, ConfigInfo::INT, @@ -498,7 +518,7 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = { CFG_DB_NO_TRIGGER_OPS, "MaxNoOfFiredTriggers", DB_TOKEN, - "Total number of triggers that can fire simultaneously in one "DB_TOKEN" node", + "Total number of triggers that can fire simultaneously in one "DB_TOKEN_PRINT" node", ConfigInfo::USED, false, ConfigInfo::INT, @@ -557,7 +577,7 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = { CFG_DB_STOP_ON_ERROR, "StopOnError", DB_TOKEN, - "If set to N, "DB_TOKEN" automatically restarts/recovers in case of node failure", + "If set to N, "DB_TOKEN_PRINT" automatically restarts/recovers in case of node failure", ConfigInfo::USED, true, ConfigInfo::BOOL, @@ -629,7 +649,7 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = { CFG_DB_NO_TRANSACTIONS, "MaxNoOfConcurrentTransactions", DB_TOKEN, - "Max number of transaction executing concurrently on the "DB_TOKEN" node", + "Max number of transaction executing concurrently on the "DB_TOKEN_PRINT" node", ConfigInfo::USED, false, ConfigInfo::INT, @@ -641,7 +661,7 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = { CFG_DB_NO_SCANS, "MaxNoOfConcurrentScans", DB_TOKEN, - "Max number of scans executing concurrently on the "DB_TOKEN" node", + "Max number of scans executing concurrently on the "DB_TOKEN_PRINT" node", ConfigInfo::USED, false, ConfigInfo::INT, @@ -653,7 +673,7 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = { CFG_DB_TRANS_BUFFER_MEM, "TransactionBufferMemory", DB_TOKEN, - "Dynamic buffer space (in bytes) for key and attribute data allocated for each "DB_TOKEN" node", + "Dynamic buffer space (in bytes) for key and attribute data allocated for each "DB_TOKEN_PRINT" node", ConfigInfo::USED, false, ConfigInfo::INT, @@ -665,7 +685,7 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = { CFG_DB_INDEX_MEM, "IndexMemory", DB_TOKEN, - "Number bytes on each "DB_TOKEN" node allocated for storing indexes", + "Number bytes on each "DB_TOKEN_PRINT" node allocated for storing indexes", ConfigInfo::USED, false, ConfigInfo::INT64, @@ -677,7 +697,7 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = { CFG_DB_DATA_MEM, "DataMemory", DB_TOKEN, - "Number bytes on each "DB_TOKEN" node allocated for storing data", + "Number bytes on each "DB_TOKEN_PRINT" node allocated for storing data", ConfigInfo::USED, false, ConfigInfo::INT64, @@ -689,7 +709,7 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = { CFG_DB_UNDO_INDEX_BUFFER, "UndoIndexBuffer", DB_TOKEN, - "Number bytes on each "DB_TOKEN" node allocated for writing UNDO logs for index part", + "Number bytes on each "DB_TOKEN_PRINT" node allocated for writing UNDO logs for index part", ConfigInfo::USED, false, ConfigInfo::INT, @@ -701,7 +721,7 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = { CFG_DB_UNDO_DATA_BUFFER, "UndoDataBuffer", DB_TOKEN, - "Number bytes on each "DB_TOKEN" node allocated for writing UNDO logs for data part", + "Number bytes on each "DB_TOKEN_PRINT" node allocated for writing UNDO logs for data part", ConfigInfo::USED, false, ConfigInfo::INT, @@ -713,7 +733,7 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = { CFG_DB_REDO_BUFFER, "RedoBuffer", DB_TOKEN, - "Number bytes on each "DB_TOKEN" node allocated for writing REDO logs", + "Number bytes on each "DB_TOKEN_PRINT" node allocated for writing REDO logs", ConfigInfo::USED, false, ConfigInfo::INT, @@ -725,7 +745,7 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = { CFG_DB_LONG_SIGNAL_BUFFER, "LongMessageBuffer", DB_TOKEN, - "Number bytes on each "DB_TOKEN" node allocated for internal long messages", + "Number bytes on each "DB_TOKEN_PRINT" node allocated for internal long messages", ConfigInfo::USED, false, ConfigInfo::INT, @@ -773,7 +793,7 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = { CFG_DB_HEARTBEAT_INTERVAL, "HeartbeatIntervalDbDb", DB_TOKEN, - "Time between "DB_TOKEN"-"DB_TOKEN" heartbeats. "DB_TOKEN" considered dead after 3 missed HBs", + "Time between "DB_TOKEN_PRINT"-"DB_TOKEN_PRINT" heartbeats. "DB_TOKEN_PRINT" considered dead after 3 missed HBs", ConfigInfo::USED, true, ConfigInfo::INT, @@ -785,7 +805,7 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = { CFG_DB_API_HEARTBEAT_INTERVAL, "HeartbeatIntervalDbApi", DB_TOKEN, - "Time between "API_TOKEN"-"DB_TOKEN" heartbeats. "API_TOKEN" connection closed after 3 missed HBs", + "Time between "API_TOKEN_PRINT"-"DB_TOKEN_PRINT" heartbeats. "API_TOKEN_PRINT" connection closed after 3 missed HBs", ConfigInfo::USED, true, ConfigInfo::INT, @@ -821,7 +841,7 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = { CFG_DB_NO_REDOLOG_FILES, "NoOfFragmentLogFiles", DB_TOKEN, - "No of 16 Mbyte Redo log files in each of 4 file sets belonging to "DB_TOKEN" node", + "No of 16 Mbyte Redo log files in each of 4 file sets belonging to "DB_TOKEN_PRINT" node", ConfigInfo::USED, false, ConfigInfo::INT, @@ -833,7 +853,7 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = { KEY_INTERNAL, "MaxNoOfOpenFiles", DB_TOKEN, - "Max number of files open per "DB_TOKEN" node.(One thread is created per file)", + "Max number of files open per "DB_TOKEN_PRINT" node.(One thread is created per file)", ConfigInfo::USED, false, ConfigInfo::INT, @@ -987,7 +1007,7 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = { CFG_DB_FILESYSTEM_PATH, "FileSystemPath", DB_TOKEN, - "Path to directory where the "DB_TOKEN" node stores its data (directory must exist)", + "Path to directory where the "DB_TOKEN_PRINT" node stores its data (directory must exist)", ConfigInfo::USED, false, ConfigInfo::STRING, @@ -1277,7 +1297,7 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = { CFG_NODE_ID, "Id", API_TOKEN, - "Number identifying application node ("API_TOKEN")", + "Number identifying application node ("API_TOKEN_PRINT")", ConfigInfo::USED, false, ConfigInfo::INT, @@ -1300,7 +1320,7 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = { CFG_NODE_ARBIT_RANK, "ArbitrationRank", API_TOKEN, - "If 0, then "API_TOKEN" is not arbitrator. Kernel selects arbitrators in order 1, 2", + "If 0, then "API_TOKEN_PRINT" is not arbitrator. Kernel selects arbitrators in order 1, 2", ConfigInfo::USED, false, ConfigInfo::INT, @@ -1408,7 +1428,7 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = { CFG_NODE_ID, "Id", MGM_TOKEN, - "Number identifying the management server node ("MGM_TOKEN")", + "Number identifying the management server node ("MGM_TOKEN_PRINT")", ConfigInfo::USED, false, ConfigInfo::INT, @@ -1478,7 +1498,7 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = { CFG_NODE_ARBIT_RANK, "ArbitrationRank", MGM_TOKEN, - "If 0, then "MGM_TOKEN" is not arbitrator. Kernel selects arbitrators in order 1, 2", + "If 0, then "MGM_TOKEN_PRINT" is not arbitrator. Kernel selects arbitrators in order 1, 2", ConfigInfo::USED, false, ConfigInfo::INT, @@ -1539,7 +1559,7 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = { CFG_CONNECTION_NODE_1, "NodeId1", "TCP", - "Id of node ("DB_TOKEN", "API_TOKEN" or "MGM_TOKEN") on one side of the connection", + "Id of node ("DB_TOKEN_PRINT", "API_TOKEN_PRINT" or "MGM_TOKEN_PRINT") on one side of the connection", ConfigInfo::USED, false, ConfigInfo::STRING, @@ -1550,7 +1570,7 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = { CFG_CONNECTION_NODE_2, "NodeId2", "TCP", - "Id of node ("DB_TOKEN", "API_TOKEN" or "MGM_TOKEN") on one side of the connection", + "Id of node ("DB_TOKEN_PRINT", "API_TOKEN_PRINT" or "MGM_TOKEN_PRINT") on one side of the connection", ConfigInfo::USED, false, ConfigInfo::STRING, @@ -1670,7 +1690,7 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = { CFG_CONNECTION_NODE_1, "NodeId1", "SHM", - "Id of node ("DB_TOKEN", "API_TOKEN" or "MGM_TOKEN") on one side of the connection", + "Id of node ("DB_TOKEN_PRINT", "API_TOKEN_PRINT" or "MGM_TOKEN_PRINT") on one side of the connection", ConfigInfo::USED, false, ConfigInfo::STRING, @@ -1693,7 +1713,7 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = { CFG_CONNECTION_NODE_2, "NodeId2", "SHM", - "Id of node ("DB_TOKEN", "API_TOKEN" or "MGM_TOKEN") on one side of the connection", + "Id of node ("DB_TOKEN_PRINT", "API_TOKEN_PRINT" or "MGM_TOKEN_PRINT") on one side of the connection", ConfigInfo::USED, false, ConfigInfo::STRING, @@ -1790,7 +1810,7 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = { CFG_CONNECTION_NODE_1, "NodeId1", "SCI", - "Id of node ("DB_TOKEN", "API_TOKEN" or "MGM_TOKEN") on one side of the connection", + "Id of node ("DB_TOKEN_PRINT", "API_TOKEN_PRINT" or "MGM_TOKEN_PRINT") on one side of the connection", ConfigInfo::USED, false, ConfigInfo::STRING, @@ -1802,7 +1822,7 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = { CFG_CONNECTION_NODE_2, "NodeId2", "SCI", - "Id of node ("DB_TOKEN", "API_TOKEN" or "MGM_TOKEN") on one side of the connection", + "Id of node ("DB_TOKEN_PRINT", "API_TOKEN_PRINT" or "MGM_TOKEN_PRINT") on one side of the connection", ConfigInfo::USED, false, ConfigInfo::STRING, @@ -2003,7 +2023,7 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = { CFG_CONNECTION_NODE_1, "NodeId1", "OSE", - "Id of node ("DB_TOKEN", "API_TOKEN" or "MGM_TOKEN") on one side of the connection", + "Id of node ("DB_TOKEN_PRINT", "API_TOKEN_PRINT" or "MGM_TOKEN_PRINT") on one side of the connection", ConfigInfo::USED, false, ConfigInfo::INT, @@ -2015,7 +2035,7 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = { CFG_CONNECTION_NODE_2, "NodeId2", "OSE", - "Id of node ("DB_TOKEN", "API_TOKEN" or "MGM_TOKEN") on one side of the connection", + "Id of node ("DB_TOKEN_PRINT", "API_TOKEN_PRINT" or "MGM_TOKEN_PRINT") on one side of the connection", ConfigInfo::USED, false, ConfigInfo::INT, @@ -3290,6 +3310,29 @@ saveInConfigValues(InitConfigFileParser::Context & ctx, const char * data){ } static bool +sanity_checks(Vector<ConfigInfo::ConfigRuleSection>§ions, + struct InitConfigFileParser::Context &ctx, + const char * rule_data) +{ + Uint32 db_nodes = 0; + Uint32 mgm_nodes = 0; + Uint32 api_nodes = 0; + if (!ctx.m_userProperties.get("DB", &db_nodes)) { + ctx.reportError("At least one database node should be defined in config file"); + return false; + } + if (!ctx.m_userProperties.get("MGM", &mgm_nodes)) { + ctx.reportError("At least one management server node should be defined in config file"); + return false; + } + if (!ctx.m_userProperties.get("API", &api_nodes)) { + ctx.reportError("At least one application node (for the mysqld) should be defined in config file"); + return false; + } + return true; +} + +static bool add_node_connections(Vector<ConfigInfo::ConfigRuleSection>§ions, struct InitConfigFileParser::Context &ctx, const char * rule_data) diff --git a/ndb/src/mgmsrv/MgmtSrvr.cpp b/ndb/src/mgmsrv/MgmtSrvr.cpp index 0f50fd6c596..8380f3fd86a 100644 --- a/ndb/src/mgmsrv/MgmtSrvr.cpp +++ b/ndb/src/mgmsrv/MgmtSrvr.cpp @@ -61,6 +61,8 @@ #define DEBUG(x) #endif +extern int global_flag_send_heartbeat_now; + static void CmdBackupCallback(const MgmtSrvr::BackupEvent & event) @@ -543,9 +545,10 @@ MgmtSrvr::MgmtSrvr(NodeId nodeId, /** * Fill the nodeTypes array */ - for(Uint32 i = 0; i<MAX_NODES; i++) + for(Uint32 i = 0; i<MAX_NODES; i++) { nodeTypes[i] = (enum ndb_mgm_node_type)-1; - + m_connect_address[i].s_addr= 0; + } { ndb_mgm_configuration_iterator * iter = ndb_mgm_create_configuration_iterator (config->m_configValues, CFG_SECTION_NODE); @@ -589,8 +592,10 @@ MgmtSrvr::MgmtSrvr(NodeId nodeId, _ownNodeId= 0; NodeId tmp= nodeId; - if (!alloc_node_id(&tmp, NDB_MGM_NODE_TYPE_MGM, 0, 0)){ - ndbout << "Unable to obtain requested nodeid " << nodeId; + BaseString error_string; + if (!alloc_node_id(&tmp, NDB_MGM_NODE_TYPE_MGM, 0, 0, error_string)){ + ndbout << "Unable to obtain requested nodeid: " + << error_string.c_str() << endl; exit(-1); } _ownNodeId = tmp; @@ -623,15 +628,19 @@ MgmtSrvr::check_start() } bool -MgmtSrvr::start() +MgmtSrvr::start(BaseString &error_string) { if (_props == NULL) { - if (!check_start()) + if (!check_start()) { + error_string.append("MgmtSrvr.cpp: check_start() failed."); return false; + } } - theFacade= TransporterFacade::theFacadeInstance = new TransporterFacade(); + theFacade= TransporterFacade::theFacadeInstance= new TransporterFacade(); + if(theFacade == 0) { - DEBUG("MgmtSrvr.cpp: theFacade == 0."); + DEBUG("MgmtSrvr.cpp: theFacade is NULL."); + error_string.append("MgmtSrvr.cpp: theFacade is NULL."); return false; } if ( theFacade->start_instance @@ -650,6 +659,7 @@ MgmtSrvr::start() if(_blockNumber == -1){ DEBUG("MgmtSrvr.cpp: _blockNumber is -1."); + error_string.append("MgmtSrvr.cpp: _blockNumber is -1."); theFacade->stop_instance(); theFacade = 0; return false; @@ -2324,7 +2334,8 @@ bool MgmtSrvr::alloc_node_id(NodeId * nodeId, enum ndb_mgm_node_type type, struct sockaddr *client_addr, - SOCKET_SIZE_TYPE *client_addr_len) + SOCKET_SIZE_TYPE *client_addr_len, + BaseString &error_string) { Guard g(&f_node_id_mutex); #if 0 @@ -2342,31 +2353,39 @@ MgmtSrvr::alloc_node_id(NodeId * nodeId, } } + bool found_matching_id= false; + bool found_matching_type= false; + bool found_free_node= false; + const char *config_hostname = 0; + struct in_addr config_addr= {0}; + int r_config_addr= -1; + unsigned type_c= 0; + ndb_mgm_configuration_iterator iter(*(ndb_mgm_configuration *)_config->m_configValues, CFG_SECTION_NODE); for(iter.first(); iter.valid(); iter.next()) { unsigned tmp= 0; if(iter.get(CFG_NODE_ID, &tmp)) abort(); - if (connected_nodes.get(tmp)) - continue; if (*nodeId && *nodeId != tmp) continue; - unsigned type_c; + found_matching_id= true; if(iter.get(CFG_TYPE_OF_SECTION, &type_c)) abort(); if(type_c != type) continue; - const char *config_hostname = 0; + found_matching_type= true; + if (connected_nodes.get(tmp)) + continue; + found_free_node= true; if(iter.get(CFG_NODE_HOST, &config_hostname)) abort(); if (config_hostname && config_hostname[0] != 0 && client_addr) { // check hostname compatability - struct in_addr config_addr; - const void *tmp= &(((sockaddr_in*)client_addr)->sin_addr); - if(Ndb_getInAddr(&config_addr, config_hostname) != 0 - || memcmp(&config_addr, tmp, sizeof(config_addr)) != 0) { + const void *tmp_in= &(((sockaddr_in*)client_addr)->sin_addr); + if((r_config_addr= Ndb_getInAddr(&config_addr, config_hostname)) != 0 + || memcmp(&config_addr, tmp_in, sizeof(config_addr)) != 0) { struct in_addr tmp_addr; if(Ndb_getInAddr(&tmp_addr, "localhost") != 0 - || memcmp(&tmp_addr, tmp, sizeof(config_addr)) != 0) { + || memcmp(&tmp_addr, tmp_in, sizeof(config_addr)) != 0) { // not localhost #if 0 ndbout << "MgmtSrvr::getFreeNodeId compare failed for \"" << config_hostname @@ -2387,6 +2406,10 @@ MgmtSrvr::alloc_node_id(NodeId * nodeId, } } *nodeId= tmp; + if (client_addr) + m_connect_address[tmp]= ((struct sockaddr_in *)client_addr)->sin_addr; + else + Ndb_getInAddr(&(m_connect_address[tmp]), "localhost"); m_reserved_nodes.set(tmp); #if 0 ndbout << "MgmtSrvr::getFreeNodeId found type=" << type @@ -2394,6 +2417,52 @@ MgmtSrvr::alloc_node_id(NodeId * nodeId, #endif return true; } + + if (found_matching_type && !found_free_node) { + // we have a temporary error which might be due to that we have got the latest + // connect status from db-nodes. Force update. + global_flag_send_heartbeat_now= 1; + } + + BaseString type_string, type_c_string; + { + const char *alias, *str; + alias= ndb_mgm_get_node_type_alias_string(type, &str); + type_string.assfmt("%s(%s)", alias, str); + alias= ndb_mgm_get_node_type_alias_string((enum ndb_mgm_node_type)type_c, &str); + type_c_string.assfmt("%s(%s)", alias, str); + } + + if (*nodeId == 0) { + if (found_matching_id) + if (found_matching_type) + if (found_free_node) + error_string.appfmt("Connection done from wrong host ip %s.", + inet_ntoa(((struct sockaddr_in *)(client_addr))->sin_addr)); + else + error_string.appfmt("No free node id found for %s.", type_string.c_str()); + else + error_string.appfmt("No %s node defined in config file.", type_string.c_str()); + else + error_string.append("No nodes defined in config file."); + } else { + if (found_matching_id) + if (found_matching_type) + if (found_free_node) { + // have to split these into two since inet_ntoa overwrites itself + error_string.appfmt("Connection with id %d done from wrong host ip %s,", + *nodeId, inet_ntoa(((struct sockaddr_in *)(client_addr))->sin_addr)); + error_string.appfmt(" expected %s(%s).", config_hostname, + r_config_addr ? "lookup failed" : inet_ntoa(config_addr)); + } else + error_string.appfmt("Id %d already allocated by another node.", *nodeId); + else + error_string.appfmt("Id %d configured as %s, connect attempted as %s.", + *nodeId, type_c_string.c_str(), type_string.c_str()); + else + error_string.appfmt("No node defined with id=%d in config file.", *nodeId); + } + return false; } @@ -2793,6 +2862,10 @@ MgmtSrvr::Allocated_resources::Allocated_resources(MgmtSrvr &m) MgmtSrvr::Allocated_resources::~Allocated_resources() { Guard g(&f_node_id_mutex); + if (!m_reserved_nodes.isclear()) { + // node has been reserved, force update signal to ndb nodes + global_flag_send_heartbeat_now= 1; + } m_mgmsrv.m_reserved_nodes.bitANDC(m_reserved_nodes); } diff --git a/ndb/src/mgmsrv/MgmtSrvr.hpp b/ndb/src/mgmsrv/MgmtSrvr.hpp index e910fb67449..d7f9f7a1af3 100644 --- a/ndb/src/mgmsrv/MgmtSrvr.hpp +++ b/ndb/src/mgmsrv/MgmtSrvr.hpp @@ -179,7 +179,7 @@ public: * @return true if succeeded, otherwise false */ bool check_start(); // may be run before start to check that some things are ok - bool start(); + bool start(BaseString &error_string); ~MgmtSrvr(); @@ -467,7 +467,8 @@ public: */ bool getNextNodeId(NodeId * _nodeId, enum ndb_mgm_node_type type) const ; bool alloc_node_id(NodeId * _nodeId, enum ndb_mgm_node_type type, - struct sockaddr *client_addr, SOCKET_SIZE_TYPE *client_addr_len); + struct sockaddr *client_addr, SOCKET_SIZE_TYPE *client_addr_len, + BaseString &error_string); /** * @@ -520,6 +521,7 @@ public: int setDbParameter(int node, int parameter, const char * value, BaseString&); + const char *get_connect_address(Uint32 node_id) { return inet_ntoa(m_connect_address[node_id]); } //************************************************************************** private: //************************************************************************** @@ -559,6 +561,7 @@ private: NodeBitmask m_reserved_nodes; Allocated_resources m_allocated_resources; + struct in_addr m_connect_address[MAX_NODES]; int _setVarReqResult; // The result of the SET_VAR_REQ response Statistics _statistics; // handleSTATISTICS_CONF store the result here, diff --git a/ndb/src/mgmsrv/Services.cpp b/ndb/src/mgmsrv/Services.cpp index 0f54a15c20c..c529e277e0e 100644 --- a/ndb/src/mgmsrv/Services.cpp +++ b/ndb/src/mgmsrv/Services.cpp @@ -413,11 +413,14 @@ MgmApiSession::get_nodeid(Parser_t::Context &, NodeId tmp= nodeid; if(tmp == 0 || !m_allocated_resources->is_reserved(tmp)){ + BaseString error_string; if (!m_mgmsrv.alloc_node_id(&tmp, (enum ndb_mgm_node_type)nodetype, - &addr, &addrlen)){ + &addr, &addrlen, error_string)){ + const char *alias; + const char *str; + alias= ndb_mgm_get_node_type_alias_string((enum ndb_mgm_node_type)nodetype, &str); m_output->println(cmd); - m_output->println("result: no free nodeid %d for nodetype %d", - nodeid, nodetype); + m_output->println("result: %s", error_string.c_str()); m_output->println(""); return; } @@ -943,6 +946,7 @@ printNodeStatus(OutputStream *output, output->println("node.%d.dynamic_id: %d", nodeId, dynamicId); output->println("node.%d.node_group: %d", nodeId, nodeGroup); output->println("node.%d.connect_count: %d", nodeId, connectCount); + output->println("node.%d.address: %s", nodeId, mgmsrv.get_connect_address(nodeId)); } } diff --git a/ndb/src/mgmsrv/main.cpp b/ndb/src/mgmsrv/main.cpp index b671a4d8590..40385219faf 100644 --- a/ndb/src/mgmsrv/main.cpp +++ b/ndb/src/mgmsrv/main.cpp @@ -15,7 +15,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include <ndb_global.h> -#include <my_sys.h> #include "MgmtSrvr.hpp" #include "EventLogger.hpp" @@ -107,7 +106,7 @@ struct getargs args[] = { { "version", 'v', arg_flag, &_print_version, "Print ndb_mgmd version"}, { "config-file", 'c', arg_string, &glob.config_filename, - "Specify cluster configuration file", "filename" }, + "Specify cluster configuration file (will default use config.ini if available)", "filename" }, #ifndef DBUG_OFF { "debug", 0, arg_string, &debug_option, "Specify debug options e.g. d:t:i:o,out.trace", "options" }, @@ -119,7 +118,7 @@ struct getargs args[] = { "filename" }, { "interactive", 0, arg_flag, &glob.interactive, "Run interactive. Not supported but provided for testing purposes", "" }, - { "nodaemon", 'n', arg_flag, &glob.non_interactive, + { "nodaemon", 0, arg_flag, &glob.non_interactive, "Don't run as daemon, but don't read from stdin", "non-interactive" } }; @@ -129,6 +128,7 @@ int num_args = sizeof(args) / sizeof(args[0]); * MAIN */ NDB_MAIN(mgmsrv){ + ndb_init(); /** * OSE specific. Enable shared ownership of file system resources. * This is needed in order to use the cluster log since the events @@ -152,7 +152,6 @@ NDB_MAIN(mgmsrv){ } #ifndef DBUG_OFF - my_init(); if (debug_option) DBUG_PUSH(debug_option); #endif @@ -203,10 +202,15 @@ NDB_MAIN(mgmsrv){ glob.use_specific_ip = false; if(!glob.use_specific_ip){ - if(!glob.socketServer->tryBind(glob.port, glob.interface_name)){ + int count= 5; // no of retries for tryBind + while(!glob.socketServer->tryBind(glob.port, glob.interface_name)){ + if (--count > 0) { + NdbSleep_MilliSleep(1000); + continue; + } ndbout_c("Unable to setup port: %s:%d!\n" "Please check if the port is already used,\n" - "(perhaps a mgmtsrvr is already running),\n" + "(perhaps a ndb_mgmd is already running),\n" "and if you are executing on the correct computer", (glob.interface_name ? glob.interface_name : "*"), glob.port); goto error_end; @@ -218,7 +222,7 @@ NDB_MAIN(mgmsrv){ if(!glob.socketServer->setup(mapi, glob.port, glob.interface_name)){ ndbout_c("Unable to setup management port: %d!\n" "Please check if the port is already used,\n" - "(perhaps a mgmtsrvr is already running),\n" + "(perhaps a ndb_mgmd is already running),\n" "and if you are executing on the correct computer", glob.port); delete mapi; @@ -251,10 +255,14 @@ NDB_MAIN(mgmsrv){ } signal(SIGPIPE, SIG_IGN); - if(!glob.mgmObject->start()){ - ndbout_c("Unable to start management server."); - ndbout_c("Probably caused by illegal initial configuration file."); - goto error_end; + { + BaseString error_string; + if(!glob.mgmObject->start(error_string)){ + ndbout_c("Unable to start management server."); + ndbout_c("Probably caused by illegal initial configuration file."); + ndbout_c(error_string.c_str()); + goto error_end; + } } //glob.mgmObject->saveConfig(); diff --git a/ndb/src/mgmsrv/mkconfig/mkconfig.cpp b/ndb/src/mgmsrv/mkconfig/mkconfig.cpp index 3b2046d7b49..28823aaa35e 100644 --- a/ndb/src/mgmsrv/mkconfig/mkconfig.cpp +++ b/ndb/src/mgmsrv/mkconfig/mkconfig.cpp @@ -32,6 +32,7 @@ void usage(const char * prg){ NDB_COMMAND(mkconfig, "mkconfig", "mkconfig", "Make a binary configuration from a config file", 16384){ + ndb_init(); if(argc < 3){ usage(argv[0]); return 0; diff --git a/ndb/src/ndbapi/ClusterMgr.cpp b/ndb/src/ndbapi/ClusterMgr.cpp index 17a0e443b48..e10b2e1d82c 100644 --- a/ndb/src/ndbapi/ClusterMgr.cpp +++ b/ndb/src/ndbapi/ClusterMgr.cpp @@ -37,6 +37,8 @@ #include <mgmapi_configuration.hpp> #include <mgmapi_config_parameters.h> +int global_flag_send_heartbeat_now= 0; + // Just a C wrapper for threadMain extern "C" void* @@ -177,6 +179,9 @@ ClusterMgr::threadMain( ){ /** * Start of Secure area for use of Transporter */ + int send_heartbeat_now= global_flag_send_heartbeat_now; + global_flag_send_heartbeat_now= 0; + theFacade.lock_mutex(); for (int i = 1; i < MAX_NODES; i++){ /** @@ -199,12 +204,16 @@ ClusterMgr::threadMain( ){ } theNode.hbCounter += timeSlept; - if (theNode.hbCounter >= theNode.hbFrequency){ + if (theNode.hbCounter >= theNode.hbFrequency || + send_heartbeat_now) { /** * It is now time to send a new Heartbeat */ - theNode.hbSent++; - theNode.hbCounter = 0; + if (theNode.hbCounter >= theNode.hbFrequency) { + theNode.hbSent++; + theNode.hbCounter = 0; + } + /** * If the node is of type REP, * then the receiver of the signal should be API_CLUSTERMGR @@ -443,13 +452,11 @@ ClusterMgr::reportNodeFailed(NodeId nodeId){ theNode.nfCompleteRep = false; if(noOfConnectedNodes == 0){ - Uint32 theData[1]; - NFCompleteRep * rep = (NFCompleteRep *)&theData[0]; - + NFCompleteRep rep; for(Uint32 i = 1; i<MAX_NODES; i++){ if(theNodes[i].defined && theNodes[i].nfCompleteRep == false){ - rep->failedNodeId = i; - execNF_COMPLETEREP(theData); + rep.failedNodeId = i; + execNF_COMPLETEREP((Uint32*)&rep); } } } diff --git a/ndb/src/ndbapi/DictCache.cpp b/ndb/src/ndbapi/DictCache.cpp index 5f620f77906..12300ce216f 100644 --- a/ndb/src/ndbapi/DictCache.cpp +++ b/ndb/src/ndbapi/DictCache.cpp @@ -21,6 +21,31 @@ #include <NdbCondition.h> #include <NdbSleep.h> +Ndb_local_table_info * +Ndb_local_table_info::create(NdbTableImpl *table_impl, Uint32 sz) +{ + void *data= malloc(sizeof(NdbTableImpl)+sz-1); + if (data == 0) + return 0; + memset(data,0,sizeof(NdbTableImpl)+sz-1); + new (data) Ndb_local_table_info(table_impl); + return (Ndb_local_table_info *) data; +} + +void Ndb_local_table_info::destroy(Ndb_local_table_info *info) +{ + free((void *)info); +} + +Ndb_local_table_info::Ndb_local_table_info(NdbTableImpl *table_impl) +{ + m_table_impl= table_impl; +} + +Ndb_local_table_info::~Ndb_local_table_info() +{ +} + LocalDictCache::LocalDictCache(){ m_tableHash.createHashTable(); } @@ -29,22 +54,24 @@ LocalDictCache::~LocalDictCache(){ m_tableHash.releaseHashTable(); } -NdbTableImpl * +Ndb_local_table_info * LocalDictCache::get(const char * name){ const Uint32 len = strlen(name); return m_tableHash.getData(name, len); } void -LocalDictCache::put(const char * name, NdbTableImpl * tab){ - const Uint32 id = tab->m_tableId; +LocalDictCache::put(const char * name, Ndb_local_table_info * tab_info){ + const Uint32 id = tab_info->m_table_impl->m_tableId; - m_tableHash.insertKey(name, strlen(name), id, tab); + m_tableHash.insertKey(name, strlen(name), id, tab_info); } void LocalDictCache::drop(const char * name){ - m_tableHash.deleteKey(name, strlen(name)); + Ndb_local_table_info *info= m_tableHash.deleteKey(name, strlen(name)); + DBUG_ASSERT(info != 0); + Ndb_local_table_info::destroy(info); } /***************************************************************** diff --git a/ndb/src/ndbapi/DictCache.hpp b/ndb/src/ndbapi/DictCache.hpp index 098acc9006a..0dc853306fa 100644 --- a/ndb/src/ndbapi/DictCache.hpp +++ b/ndb/src/ndbapi/DictCache.hpp @@ -27,6 +27,17 @@ #include <Ndb.hpp> #include "NdbLinHash.hpp" +class Ndb_local_table_info { +public: + static Ndb_local_table_info *create(NdbTableImpl *table_impl, Uint32 sz=0); + static void destroy(Ndb_local_table_info *); + NdbTableImpl *m_table_impl; + char m_local_data[1]; +private: + Ndb_local_table_info(NdbTableImpl *table_impl); + ~Ndb_local_table_info(); +}; + /** * A non thread safe dict cache */ @@ -35,12 +46,12 @@ public: LocalDictCache(); ~LocalDictCache(); - NdbTableImpl * get(const char * name); + Ndb_local_table_info * get(const char * name); - void put(const char * name, NdbTableImpl *); + void put(const char * name, Ndb_local_table_info *); void drop(const char * name); - NdbLinHash<NdbTableImpl> m_tableHash; // On name + NdbLinHash<Ndb_local_table_info> m_tableHash; // On name }; /** diff --git a/ndb/src/ndbapi/Ndb.cpp b/ndb/src/ndbapi/Ndb.cpp index 2b95384324d..74e4c2a0c84 100644 --- a/ndb/src/ndbapi/Ndb.cpp +++ b/ndb/src/ndbapi/Ndb.cpp @@ -753,15 +753,17 @@ Uint64 Ndb::getAutoIncrementValue(const char* aTableName, Uint32 cacheSize) { DEBUG_TRACE("getAutoIncrementValue"); - const NdbTableImpl* table = theDictionary->getTable(aTableName); - if (table == 0) + const char * internalTableName = internalizeTableName(aTableName); + Ndb_local_table_info *info= theDictionary->get_local_table_info(internalTableName); + if (info == 0) return ~0; + const NdbTableImpl *table= info->m_table_impl; Uint64 tupleId = getTupleIdFromNdb(table->m_tableId, cacheSize); return tupleId; } Uint64 -Ndb::getAutoIncrementValue(NdbDictionary::Table * aTable, Uint32 cacheSize) +Ndb::getAutoIncrementValue(const NdbDictionary::Table * aTable, Uint32 cacheSize) { DEBUG_TRACE("getAutoIncrementValue"); if (aTable == 0) @@ -808,7 +810,7 @@ Ndb::readAutoIncrementValue(const char* aTableName) } Uint64 -Ndb::readAutoIncrementValue(NdbDictionary::Table * aTable) +Ndb::readAutoIncrementValue(const NdbDictionary::Table * aTable) { DEBUG_TRACE("readtAutoIncrementValue"); if (aTable == 0) @@ -832,16 +834,18 @@ bool Ndb::setAutoIncrementValue(const char* aTableName, Uint64 val, bool increase) { DEBUG_TRACE("setAutoIncrementValue " << val); - const NdbTableImpl* table = theDictionary->getTable(aTableName); - if (table == 0) { + const char * internalTableName= internalizeTableName(aTableName); + Ndb_local_table_info *info= theDictionary->get_local_table_info(internalTableName); + if (info == 0) { theError= theDictionary->getNdbError(); return false; } + const NdbTableImpl* table= info->m_table_impl; return setTupleIdInNdb(table->m_tableId, val, increase); } bool -Ndb::setAutoIncrementValue(NdbDictionary::Table * aTable, Uint64 val, bool increase) +Ndb::setAutoIncrementValue(const NdbDictionary::Table * aTable, Uint64 val, bool increase) { DEBUG_TRACE("setAutoIncrementValue " << val); if (aTable == 0) @@ -1137,7 +1141,7 @@ void Ndb::setCatalogName(const char * a_catalog_name) if (a_catalog_name) { snprintf(theDataBase, sizeof(theDataBase), "%s", a_catalog_name ? a_catalog_name : ""); - + int len = snprintf(prefixName, sizeof(prefixName), "%s%c%s%c", theDataBase, table_name_separator, theDataBaseSchema, table_name_separator); @@ -1188,11 +1192,6 @@ void Ndb::setDatabaseSchemaName(const char * a_schema_name) setSchemaName(a_schema_name); } -void Ndb::useFullyQualifiedNames(bool turnNamingOn) -{ - fullyQualifiedNames = turnNamingOn; -} - bool Ndb::usingFullyQualifiedNames() { return fullyQualifiedNames; diff --git a/ndb/src/ndbapi/NdbConnection.cpp b/ndb/src/ndbapi/NdbConnection.cpp index 1b4f1f1f75c..2da8e2f07d3 100644 --- a/ndb/src/ndbapi/NdbConnection.cpp +++ b/ndb/src/ndbapi/NdbConnection.cpp @@ -201,7 +201,9 @@ NdbConnection::restart(){ } else { theNdb->theFirstTransId = tTransid + 1; } + theCommitStatus = Started; theCompletionStatus = NotCompleted; + theTransactionIsStarted = false; DBUG_RETURN(0); } DBUG_PRINT("error",("theCompletionStatus != CompletedSuccess")); @@ -941,7 +943,7 @@ Remark: Get an operation from NdbOperation object idlelist and object, synchronous. *****************************************************************************/ NdbOperation* -NdbConnection::getNdbOperation(NdbTableImpl * tab, NdbOperation* aNextOp) +NdbConnection::getNdbOperation(const NdbTableImpl * tab, NdbOperation* aNextOp) { NdbOperation* tOp; @@ -987,7 +989,7 @@ NdbConnection::getNdbOperation(NdbTableImpl * tab, NdbOperation* aNextOp) return NULL; }//NdbConnection::getNdbOperation() -NdbOperation* NdbConnection::getNdbOperation(NdbDictionary::Table * table) +NdbOperation* NdbConnection::getNdbOperation(const NdbDictionary::Table * table) { if (table) return getNdbOperation(& NdbTableImpl::getImpl(*table)); @@ -1046,8 +1048,8 @@ NdbConnection::getNdbIndexScanOperation(const char* anIndexName, } NdbIndexScanOperation* -NdbConnection::getNdbIndexScanOperation(NdbIndexImpl* index, - NdbTableImpl* table) +NdbConnection::getNdbIndexScanOperation(const NdbIndexImpl* index, + const NdbTableImpl* table) { if (theCommitStatus == Started){ const NdbTableImpl * indexTable = index->getIndexTable(); @@ -1068,8 +1070,8 @@ NdbConnection::getNdbIndexScanOperation(NdbIndexImpl* index, }//NdbConnection::getNdbIndexScanOperation() NdbIndexScanOperation* -NdbConnection::getNdbIndexScanOperation(NdbDictionary::Index * index, - NdbDictionary::Table * table) +NdbConnection::getNdbIndexScanOperation(const NdbDictionary::Index * index, + const NdbDictionary::Table * table) { if (index && table) return getNdbIndexScanOperation(& NdbIndexImpl::getImpl(*index), @@ -1089,7 +1091,7 @@ Remark: Get an operation from NdbScanOperation object idlelist and get t getOperation will set the theTableId in the NdbOperation object, synchronous. *****************************************************************************/ NdbIndexScanOperation* -NdbConnection::getNdbScanOperation(NdbTableImpl * tab) +NdbConnection::getNdbScanOperation(const NdbTableImpl * tab) { NdbIndexScanOperation* tOp; @@ -1118,7 +1120,7 @@ getNdbOp_error1: }//NdbConnection::getNdbScanOperation() NdbScanOperation* -NdbConnection::getNdbScanOperation(NdbDictionary::Table * table) +NdbConnection::getNdbScanOperation(const NdbDictionary::Table * table) { if (table) return getNdbScanOperation(& NdbTableImpl::getImpl(*table)); @@ -1176,8 +1178,8 @@ Remark: Get an operation from NdbIndexOperation object idlelist and get getOperation will set the theTableId in the NdbIndexOperation object, synchronous. *****************************************************************************/ NdbIndexOperation* -NdbConnection::getNdbIndexOperation(NdbIndexImpl * anIndex, - NdbTableImpl * aTable, +NdbConnection::getNdbIndexOperation(const NdbIndexImpl * anIndex, + const NdbTableImpl * aTable, NdbOperation* aNextOp) { NdbIndexOperation* tOp; @@ -1220,8 +1222,8 @@ NdbConnection::getNdbIndexOperation(NdbIndexImpl * anIndex, }//NdbConnection::getNdbIndexOperation() NdbIndexOperation* -NdbConnection::getNdbIndexOperation(NdbDictionary::Index * index, - NdbDictionary::Table * table) +NdbConnection::getNdbIndexOperation(const NdbDictionary::Index * index, + const NdbDictionary::Table * table) { if (index && table) return getNdbIndexOperation(& NdbIndexImpl::getImpl(*index), diff --git a/ndb/src/ndbapi/NdbDictionary.cpp b/ndb/src/ndbapi/NdbDictionary.cpp index d0fb062f78a..6396cb6bb1d 100644 --- a/ndb/src/ndbapi/NdbDictionary.cpp +++ b/ndb/src/ndbapi/NdbDictionary.cpp @@ -65,7 +65,7 @@ NdbDictionary::Column::getName() const { void NdbDictionary::Column::setType(Type t){ - m_impl.m_type = t; + m_impl.init(t); } NdbDictionary::Column::Type @@ -103,6 +103,54 @@ NdbDictionary::Column::getLength() const{ return m_impl.m_length; } +void +NdbDictionary::Column::setInlineSize(int size) +{ + m_impl.m_precision = size; +} + +void +NdbDictionary::Column::setCharset(CHARSET_INFO* cs) +{ + m_impl.m_cs = cs; +} + +CHARSET_INFO* +NdbDictionary::Column::getCharset() const +{ + return m_impl.m_cs; +} + +int +NdbDictionary::Column::getInlineSize() const +{ + return m_impl.m_precision; +} + +void +NdbDictionary::Column::setPartSize(int size) +{ + m_impl.m_scale = size; +} + +int +NdbDictionary::Column::getPartSize() const +{ + return m_impl.m_scale; +} + +void +NdbDictionary::Column::setStripeSize(int size) +{ + m_impl.m_length = size; +} + +int +NdbDictionary::Column::getStripeSize() const +{ + return m_impl.m_length; +} + int NdbDictionary::Column::getSize() const{ return m_impl.m_attrSize; @@ -681,13 +729,23 @@ NdbDictionary::Dictionary::alterTable(const Table & t){ } const NdbDictionary::Table * -NdbDictionary::Dictionary::getTable(const char * name){ - NdbTableImpl * t = m_impl.getTable(name); +NdbDictionary::Dictionary::getTable(const char * name, void **data){ + NdbTableImpl * t = m_impl.getTable(name, data); if(t) return t->m_facade; return 0; } +void NdbDictionary::Dictionary::set_local_table_data_size(unsigned sz) +{ + m_impl.m_local_table_data_size= sz; +} + +const NdbDictionary::Table * +NdbDictionary::Dictionary::getTable(const char * name){ + return getTable(name, 0); +} + void NdbDictionary::Dictionary::invalidateTable(const char * name){ NdbTableImpl * t = m_impl.getTable(name); @@ -810,6 +868,8 @@ NdbDictionary::Dictionary::getNdbError() const { NdbOut& operator<<(NdbOut& out, const NdbDictionary::Column& col) { + const CHARSET_INFO *cs = col.getCharset(); + const char *csname = cs ? cs->name : "?"; out << col.getName() << " "; switch (col.getType()) { case NdbDictionary::Column::Tinyint: @@ -852,10 +912,10 @@ operator<<(NdbOut& out, const NdbDictionary::Column& col) out << "Decimal(" << col.getScale() << "," << col.getPrecision() << ")"; break; case NdbDictionary::Column::Char: - out << "Char(" << col.getLength() << ")"; + out << "Char(" << col.getLength() << ";" << csname << ")"; break; case NdbDictionary::Column::Varchar: - out << "Varchar(" << col.getLength() << ")"; + out << "Varchar(" << col.getLength() << ";" << csname << ")"; break; case NdbDictionary::Column::Binary: out << "Binary(" << col.getLength() << ")"; @@ -875,7 +935,7 @@ operator<<(NdbOut& out, const NdbDictionary::Column& col) break; case NdbDictionary::Column::Text: out << "Text(" << col.getInlineSize() << "," << col.getPartSize() - << ";" << col.getStripeSize() << ")"; + << ";" << col.getStripeSize() << ";" << csname << ")"; break; case NdbDictionary::Column::Undefined: out << "Undefined"; diff --git a/ndb/src/ndbapi/NdbDictionaryImpl.cpp b/ndb/src/ndbapi/NdbDictionaryImpl.cpp index b221966896e..c2c987f3bdb 100644 --- a/ndb/src/ndbapi/NdbDictionaryImpl.cpp +++ b/ndb/src/ndbapi/NdbDictionaryImpl.cpp @@ -36,6 +36,7 @@ #include "NdbEventOperationImpl.hpp" #include "NdbBlob.hpp" #include <AttributeHeader.hpp> +#include <my_sys.h> #define DEBUG_PRINT 0 #define INCOMPATIBLE_VERSION -2 @@ -64,6 +65,7 @@ NdbColumnImpl::operator=(const NdbColumnImpl& col) m_name = col.m_name; m_type = col.m_type; m_precision = col.m_precision; + m_cs = col.m_cs; m_scale = col.m_scale; m_length = col.m_length; m_pk = col.m_pk; @@ -87,10 +89,66 @@ NdbColumnImpl::operator=(const NdbColumnImpl& col) } void -NdbColumnImpl::init() +NdbColumnImpl::init(Type t) { + // do not use default_charset_info as it may not be initialized yet + // use binary collation until NDB tests can handle charsets + CHARSET_INFO* default_cs = &my_charset_latin1_bin; m_attrId = -1; - m_type = NdbDictionary::Column::Unsigned; + m_type = t; + switch (m_type) { + case Tinyint: + case Tinyunsigned: + case Smallint: + case Smallunsigned: + case Mediumint: + case Mediumunsigned: + case Int: + case Unsigned: + case Bigint: + case Bigunsigned: + case Float: + case Double: + m_precision = 0; + m_scale = 0; + m_length = 1; + m_cs = NULL; + break; + case Decimal: + m_precision = 10; + m_scale = 0; + m_length = 1; + m_cs = NULL; + break; + case Char: + case Varchar: + m_precision = 0; + m_scale = 0; + m_length = 1; + m_cs = default_cs; + break; + case Binary: + case Varbinary: + case Datetime: + case Timespec: + m_precision = 0; + m_scale = 0; + m_length = 1; + m_cs = NULL; + break; + case Blob: + m_precision = 256; + m_scale = 8000; + m_length = 4; + m_cs = NULL; + break; + case Text: + m_precision = 256; + m_scale = 8000; + m_length = 4; + m_cs = default_cs; + break; + } m_pk = false; m_nullable = false; m_tupleKey = false; @@ -98,12 +156,10 @@ NdbColumnImpl::init() m_distributionKey = false; m_distributionGroup = false; m_distributionGroupBits = 8; - m_length = 1; - m_scale = 5; - m_precision = 5; m_keyInfoPos = 0; - m_attrSize = 4, - m_arraySize = 1, + // next 2 are set at run time + m_attrSize = 0; + m_arraySize = 0; m_autoIncrement = false; m_autoIncrementInitialValue = 1; m_blobTable = NULL; @@ -146,52 +202,12 @@ NdbColumnImpl::equal(const NdbColumnImpl& col) const return false; } } - if(m_length != col.m_length){ + if (m_precision != col.m_precision || + m_scale != col.m_scale || + m_length != col.m_length || + m_cs != col.m_cs) { return false; } - - switch(m_type){ - case NdbDictionary::Column::Undefined: - break; - case NdbDictionary::Column::Tinyint: - case NdbDictionary::Column::Tinyunsigned: - case NdbDictionary::Column::Smallint: - case NdbDictionary::Column::Smallunsigned: - case NdbDictionary::Column::Mediumint: - case NdbDictionary::Column::Mediumunsigned: - case NdbDictionary::Column::Int: - case NdbDictionary::Column::Unsigned: - case NdbDictionary::Column::Float: - break; - case NdbDictionary::Column::Decimal: - if(m_scale != col.m_scale || - m_precision != col.m_precision){ - return false; - } - break; - case NdbDictionary::Column::Char: - case NdbDictionary::Column::Varchar: - case NdbDictionary::Column::Binary: - case NdbDictionary::Column::Varbinary: - if(m_length != col.m_length){ - return false; - } - break; - case NdbDictionary::Column::Bigint: - case NdbDictionary::Column::Bigunsigned: - case NdbDictionary::Column::Double: - case NdbDictionary::Column::Datetime: - case NdbDictionary::Column::Timespec: - break; - case NdbDictionary::Column::Blob: - case NdbDictionary::Column::Text: - if (m_precision != col.m_precision || - m_scale != col.m_scale || - m_length != col.m_length) { - return false; - } - break; - } if (m_autoIncrement != col.m_autoIncrement){ return false; } @@ -209,14 +225,18 @@ NdbColumnImpl::create_psuedo(const char * name){ if(!strcmp(name, "NDB$FRAGMENT")){ col->setType(NdbDictionary::Column::Unsigned); col->m_impl.m_attrId = AttributeHeader::FRAGMENT; + col->m_impl.m_attrSize = 4; + col->m_impl.m_arraySize = 1; } else if(!strcmp(name, "NDB$ROW_COUNT")){ col->setType(NdbDictionary::Column::Bigunsigned); col->m_impl.m_attrId = AttributeHeader::ROW_COUNT; col->m_impl.m_attrSize = 8; + col->m_impl.m_arraySize = 1; } else if(!strcmp(name, "NDB$COMMIT_COUNT")){ col->setType(NdbDictionary::Column::Bigunsigned); col->m_impl.m_attrId = AttributeHeader::COMMIT_COUNT; col->m_impl.m_attrSize = 8; + col->m_impl.m_arraySize = 1; } else { abort(); } @@ -579,6 +599,7 @@ NdbDictionaryImpl::NdbDictionaryImpl(Ndb &ndb) m_ndb(ndb) { m_globalHash = 0; + m_local_table_data_size= 0; } NdbDictionaryImpl::NdbDictionaryImpl(Ndb &ndb, @@ -589,31 +610,69 @@ NdbDictionaryImpl::NdbDictionaryImpl(Ndb &ndb, m_ndb(ndb) { m_globalHash = 0; + m_local_table_data_size= 0; } static int f_dictionary_count = 0; NdbDictionaryImpl::~NdbDictionaryImpl() { - NdbElement_t<NdbTableImpl> * curr = m_localHash.m_tableHash.getNext(0); - while(curr != 0){ + NdbElement_t<Ndb_local_table_info> * curr = m_localHash.m_tableHash.getNext(0); + if(m_globalHash){ + while(curr != 0){ + m_globalHash->lock(); + m_globalHash->release(curr->theData->m_table_impl); + Ndb_local_table_info::destroy(curr->theData); + m_globalHash->unlock(); + + curr = m_localHash.m_tableHash.getNext(curr); + } + m_globalHash->lock(); - m_globalHash->release(curr->theData); + if(--f_dictionary_count == 0){ + delete NdbDictionary::Column::FRAGMENT; + delete NdbDictionary::Column::ROW_COUNT; + delete NdbDictionary::Column::COMMIT_COUNT; + NdbDictionary::Column::FRAGMENT= 0; + NdbDictionary::Column::ROW_COUNT= 0; + NdbDictionary::Column::COMMIT_COUNT= 0; + } m_globalHash->unlock(); - - curr = m_localHash.m_tableHash.getNext(curr); + } else { + assert(curr == 0); } +} + +Ndb_local_table_info * +NdbDictionaryImpl::fetchGlobalTableImpl(const char * internalTableName) +{ + NdbTableImpl *impl; m_globalHash->lock(); - if(--f_dictionary_count == 0){ - delete NdbDictionary::Column::FRAGMENT; - delete NdbDictionary::Column::ROW_COUNT; - delete NdbDictionary::Column::COMMIT_COUNT; - NdbDictionary::Column::FRAGMENT= 0; - NdbDictionary::Column::ROW_COUNT= 0; - NdbDictionary::Column::COMMIT_COUNT= 0; - } + impl = m_globalHash->get(internalTableName); m_globalHash->unlock(); + + if (impl == 0){ + impl = m_receiver.getTable(internalTableName, m_ndb.usingFullyQualifiedNames()); + m_globalHash->lock(); + m_globalHash->put(internalTableName, impl); + m_globalHash->unlock(); + + if(impl == 0){ + return 0; + } + } + + Ndb_local_table_info *info= Ndb_local_table_info::create(impl, m_local_table_data_size); + + m_localHash.put(internalTableName, info); + + m_ndb.theFirstTupleId[impl->getTableId()] = ~0; + m_ndb.theLastTupleId[impl->getTableId()] = ~0; + + addBlobTables(*impl); + + return info; } #if 0 @@ -1088,6 +1147,7 @@ indexTypeMapping[] = { { -1, -1 } }; +// TODO: remove, api-kernel type codes must match now static const ApiKernelMapping columnTypeMapping[] = { @@ -1194,9 +1254,23 @@ NdbDictInterface::parseTableInfo(NdbTableImpl ** ret, return 703; } col->m_extType = attrDesc.AttributeExtType; - col->m_precision = attrDesc.AttributeExtPrecision; + col->m_precision = (attrDesc.AttributeExtPrecision & 0xFFFF); col->m_scale = attrDesc.AttributeExtScale; col->m_length = attrDesc.AttributeExtLength; + // charset in upper half of precision + unsigned cs_number = (attrDesc.AttributeExtPrecision >> 16); + // charset is defined exactly for char types + if (col->getCharType() != (cs_number != 0)) { + delete impl; + return 703; + } + if (col->getCharType()) { + col->m_cs = get_charset(cs_number, MYF(0)); + if (col->m_cs == NULL) { + delete impl; + return 743; + } + } // translate to old kernel types and sizes if (! attrDesc.translateExtType()) { @@ -1447,9 +1521,23 @@ NdbDictInterface::createOrAlterTable(Ndb & ndb, getKernelConstant(col->m_type, columnTypeMapping, DictTabInfo::ExtUndefined); - tmpAttr.AttributeExtPrecision = col->m_precision; + tmpAttr.AttributeExtPrecision = ((unsigned)col->m_precision & 0xFFFF); tmpAttr.AttributeExtScale = col->m_scale; tmpAttr.AttributeExtLength = col->m_length; + // charset is defined exactly for char types + if (col->getCharType() != (col->m_cs != NULL)) { + m_error.code = 703; + return -1; + } + // primary key type check + if (col->m_pk && ! NdbSqlUtil::usable_in_pk(col->m_type, col->m_cs)) { + m_error.code = 743; + return -1; + } + // charset in upper half of precision + if (col->getCharType()) { + tmpAttr.AttributeExtPrecision |= (col->m_cs->number << 16); + } // DICT will ignore and recompute this (void)tmpAttr.translateExtType(); @@ -1498,7 +1586,6 @@ NdbDictInterface::createOrAlterTable(Ndb & ndb, : createTable(&tSignal, ptr); if (!alter && haveAutoIncrement) { - // if (!ndb.setAutoIncrementValue(impl.m_internalName.c_str(), autoIncrementValue)) { if (!ndb.setAutoIncrementValue(impl.m_externalName.c_str(), autoIncrementValue)) { if (ndb.theError.code == 0) { m_error.code = 4336; @@ -1769,11 +1856,12 @@ NdbIndexImpl* NdbDictionaryImpl::getIndexImpl(const char * externalName, const char * internalName) { - NdbTableImpl* tab = getTableImpl(internalName); - if(tab == 0){ + Ndb_local_table_info * info = get_local_table_info(internalName); + if(info == 0){ m_error.code = 4243; return 0; } + NdbTableImpl * tab = info->m_table_impl; if(tab->m_indexType == NdbDictionary::Index::Undefined){ // Not an index @@ -1790,14 +1878,31 @@ NdbDictionaryImpl::getIndexImpl(const char * externalName, /** * Create index impl */ - NdbIndexImpl* idx = new NdbIndexImpl(); + NdbIndexImpl* idx; + if(NdbDictInterface::create_index_obj_from_table(&idx, tab, prim) == 0){ + idx->m_table = tab; + idx->m_externalName.assign(externalName); + idx->m_internalName.assign(internalName); + // TODO Assign idx to tab->m_index + // Don't do it right now since assign can't asign a table with index + // tab->m_index = idx; + return idx; + } + return 0; +} + +int +NdbDictInterface::create_index_obj_from_table(NdbIndexImpl** dst, + const NdbTableImpl* tab, + const NdbTableImpl* prim){ + NdbIndexImpl *idx = new NdbIndexImpl(); idx->m_version = tab->m_version; idx->m_status = tab->m_status; idx->m_indexId = tab->m_tableId; - idx->m_internalName.assign(internalName); - idx->m_externalName.assign(externalName); + idx->m_externalName.assign(tab->getName()); idx->m_tableName.assign(prim->m_externalName); idx->m_type = tab->m_indexType; + idx->m_logging = tab->m_logging; // skip last attribute (NDB$PK or NDB$TNODE) for(unsigned i = 0; i+1<tab->m_columns.size(); i++){ NdbColumnImpl* col = new NdbColumnImpl; @@ -1813,12 +1918,9 @@ NdbDictionaryImpl::getIndexImpl(const char * externalName, idx->m_key_ids[key_id] = i; col->m_keyInfoPos = key_id; } - - idx->m_table = tab; - // TODO Assign idx to tab->m_index - // Don't do it right now since assign can't asign a table with index - // tab->m_index = idx; - return idx; + + * dst = idx; + return 0; } /***************************************************************** @@ -1897,6 +1999,14 @@ NdbDictInterface::createIndex(Ndb & ndb, m_error.code = 4245; return -1; } + // index key type check + if (it == DictTabInfo::UniqueHashIndex && + ! NdbSqlUtil::usable_in_hash_index(col->m_type, col->m_cs) || + it == DictTabInfo::OrderedIndex && + ! NdbSqlUtil::usable_in_ordered_index(col->m_type, col->m_cs)) { + m_error.code = 743; + return -1; + } attributeList.id[i] = col->m_attrId; } if (it == DictTabInfo::UniqueHashIndex) { diff --git a/ndb/src/ndbapi/NdbDictionaryImpl.hpp b/ndb/src/ndbapi/NdbDictionaryImpl.hpp index d05c34520b8..cf659c71397 100644 --- a/ndb/src/ndbapi/NdbDictionaryImpl.hpp +++ b/ndb/src/ndbapi/NdbDictionaryImpl.hpp @@ -52,7 +52,7 @@ public: NdbColumnImpl(NdbDictionary::Column &); // This is not a copy constructor ~NdbColumnImpl(); NdbColumnImpl& operator=(const NdbColumnImpl&); - void init(); + void init(Type t = Unsigned); int m_attrId; BaseString m_name; @@ -60,6 +60,7 @@ public: int m_precision; int m_scale; int m_length; + CHARSET_INFO * m_cs; // not const in MySQL bool m_pk; bool m_tupleKey; @@ -82,6 +83,7 @@ public: Uint32 m_keyInfoPos; Uint32 m_extType; // used by restore (kernel type in versin v2x) bool getInterpretableType() const ; + bool getCharType() const; bool getBlobType() const; /** @@ -304,6 +306,10 @@ public: const Uint32 * data, Uint32 len, bool fullyQualifiedNames); + static int create_index_obj_from_table(NdbIndexImpl ** dst, + const NdbTableImpl*, + const NdbTableImpl*); + NdbError & m_error; private: Uint32 m_reference; @@ -386,8 +392,8 @@ public: int listObjects(List& list, NdbDictionary::Object::Type type); int listIndexes(List& list, const char * tableName); - NdbTableImpl * getTable(const char * tableName); - NdbTableImpl * getTableImpl(const char * internalName); + NdbTableImpl * getTable(const char * tableName, void **data= 0); + Ndb_local_table_info * get_local_table_info(const char * internalName); NdbIndexImpl * getIndex(const char * indexName, const char * tableName); NdbIndexImpl * getIndexImpl(const char * name, const char * internalName); @@ -396,6 +402,7 @@ public: const NdbError & getNdbError() const; NdbError m_error; + Uint32 m_local_table_data_size; LocalDictCache m_localHash; GlobalDictCache * m_globalHash; @@ -406,6 +413,8 @@ public: NdbDictInterface m_receiver; Ndb & m_ndb; +private: + Ndb_local_table_info * fetchGlobalTableImpl(const char * internalName); }; inline @@ -441,6 +450,14 @@ NdbColumnImpl::getInterpretableType() const { inline bool +NdbColumnImpl::getCharType() const { + return (m_type == NdbDictionary::Column::Char || + m_type == NdbDictionary::Column::Varchar || + m_type == NdbDictionary::Column::Text); +} + +inline +bool NdbColumnImpl::getBlobType() const { return (m_type == NdbDictionary::Column::Blob || m_type == NdbDictionary::Column::Text); @@ -594,45 +611,28 @@ NdbDictionaryImpl::getImpl(const NdbDictionary::Dictionary & t){ inline NdbTableImpl * -NdbDictionaryImpl::getTable(const char * tableName) +NdbDictionaryImpl::getTable(const char * tableName, void **data) { const char * internalTableName = m_ndb.internalizeTableName(tableName); - - return getTableImpl(internalTableName); + Ndb_local_table_info *info= get_local_table_info(internalTableName); + if (info == 0) { + return 0; + } + if (data) { + *data= info->m_local_data; + } + return info->m_table_impl; } inline -NdbTableImpl * -NdbDictionaryImpl::getTableImpl(const char * internalTableName) +Ndb_local_table_info * +NdbDictionaryImpl::get_local_table_info(const char * internalTableName) { - NdbTableImpl *ret = m_localHash.get(internalTableName); - - if (ret != 0) { - return ret; // autoincrement already initialized + Ndb_local_table_info *info= m_localHash.get(internalTableName); + if (info != 0) { + return info; // autoincrement already initialized } - - m_globalHash->lock(); - ret = m_globalHash->get(internalTableName); - m_globalHash->unlock(); - - if (ret == 0){ - ret = m_receiver.getTable(internalTableName, m_ndb.usingFullyQualifiedNames()); - m_globalHash->lock(); - m_globalHash->put(internalTableName, ret); - m_globalHash->unlock(); - - if(ret == 0){ - return 0; - } - } - m_localHash.put(internalTableName, ret); - - m_ndb.theFirstTupleId[ret->getTableId()] = ~0; - m_ndb.theLastTupleId[ret->getTableId()] = ~0; - - addBlobTables(*ret); - - return ret; + return fetchGlobalTableImpl(internalTableName); } inline @@ -650,9 +650,9 @@ NdbDictionaryImpl::getIndex(const char * indexName, internalIndexName = m_ndb.internalizeTableName(indexName); // Index is also a table } if (internalIndexName) { - NdbTableImpl * tab = getTableImpl(internalIndexName); - - if (tab) { + Ndb_local_table_info * info = get_local_table_info(internalIndexName); + if (info) { + NdbTableImpl * tab = info->m_table_impl; if (tab->m_index == 0) tab->m_index = getIndexImpl(indexName, internalIndexName); if (tab->m_index != 0) diff --git a/ndb/src/ndbapi/NdbIndexOperation.cpp b/ndb/src/ndbapi/NdbIndexOperation.cpp index 7bea3b9f3d2..0742f8d911c 100644 --- a/ndb/src/ndbapi/NdbIndexOperation.cpp +++ b/ndb/src/ndbapi/NdbIndexOperation.cpp @@ -54,8 +54,8 @@ NdbIndexOperation::~NdbIndexOperation() * Remark: Initiates operation record after allocation. *****************************************************************************/ int -NdbIndexOperation::indxInit(NdbIndexImpl * anIndex, - NdbTableImpl * aTable, +NdbIndexOperation::indxInit(const NdbIndexImpl * anIndex, + const NdbTableImpl * aTable, NdbConnection* myConnection) { NdbOperation::init(aTable, myConnection); diff --git a/ndb/src/ndbapi/NdbLinHash.hpp b/ndb/src/ndbapi/NdbLinHash.hpp index 5d0d52a31d8..f786600607f 100644 --- a/ndb/src/ndbapi/NdbLinHash.hpp +++ b/ndb/src/ndbapi/NdbLinHash.hpp @@ -59,7 +59,7 @@ public: void releaseHashTable(void); int insertKey(const char * str, Uint32 len, Uint32 lkey1, C* data); - int deleteKey(const char * str, Uint32 len); + C *deleteKey(const char * str, Uint32 len); C* getData(const char *, Uint32); Uint32* getKey(const char *, Uint32); @@ -277,7 +277,7 @@ NdbLinHash<C>::getData( const char* str, Uint32 len ){ template <class C> inline -int +C * NdbLinHash<C>::deleteKey ( const char* str, Uint32 len){ const Uint32 hash = Hash(str, len); int dir, seg; @@ -288,19 +288,21 @@ NdbLinHash<C>::deleteKey ( const char* str, Uint32 len){ for(NdbElement_t<C> * chain = *chainp; chain != 0; chain = chain->next){ if(chain->len == len && !memcmp(chain->str, str, len)){ if (oldChain == 0) { + C *data= chain->theData; delete chain; * chainp = 0; - return 1; + return data; } else { + C *data= chain->theData; oldChain->next = chain->next; delete chain; - return 1; + return data; } } else { oldChain = chain; } } - return -1; /* Element doesn't exist */ + return 0; /* Element doesn't exist */ } template <class C> diff --git a/ndb/src/ndbapi/NdbOperation.cpp b/ndb/src/ndbapi/NdbOperation.cpp index d645641c2eb..53a94d98a5a 100644 --- a/ndb/src/ndbapi/NdbOperation.cpp +++ b/ndb/src/ndbapi/NdbOperation.cpp @@ -131,7 +131,7 @@ NdbOperation::setErrorCodeAbort(int anErrorCode) *****************************************************************************/ int -NdbOperation::init(NdbTableImpl* tab, NdbConnection* myConnection){ +NdbOperation::init(const NdbTableImpl* tab, NdbConnection* myConnection){ NdbApiSignal* tSignal; theStatus = Init; theError.code = 0; diff --git a/ndb/src/ndbapi/NdbScanOperation.cpp b/ndb/src/ndbapi/NdbScanOperation.cpp index 557e643e96c..86c174c4545 100644 --- a/ndb/src/ndbapi/NdbScanOperation.cpp +++ b/ndb/src/ndbapi/NdbScanOperation.cpp @@ -95,7 +95,7 @@ NdbScanOperation::setErrorCodeAbort(int aErrorCode){ * Remark: Initiates operation record after allocation. *****************************************************************************/ int -NdbScanOperation::init(NdbTableImpl* tab, NdbConnection* myConnection) +NdbScanOperation::init(const NdbTableImpl* tab, NdbConnection* myConnection) { m_transConnection = myConnection; //NdbConnection* aScanConnection = theNdb->startTransaction(myConnection); @@ -386,8 +386,8 @@ NdbIndexScanOperation::saveBoundATTRINFO() Uint32 cnt = m_accessTable->getNoOfColumns() - 1; m_sort_columns = cnt - i; for(; i<cnt; i++){ - NdbColumnImpl* key = m_accessTable->m_index->m_columns[i]; - NdbColumnImpl* col = m_currentTable->getColumn(key->m_keyInfoPos); + const NdbColumnImpl* key = m_accessTable->m_index->m_columns[i]; + const NdbColumnImpl* col = m_currentTable->getColumn(key->m_keyInfoPos); NdbRecAttr* tmp = NdbScanOperation::getValue_impl(col, (char*)-1); UintPtr newVal = UintPtr(tmp); theTupleKeyDefined[i][0] = FAKE_PTR; @@ -674,7 +674,6 @@ void NdbScanOperation::closeScan() if(m_api_receivers_count+m_conf_receivers_count){ // Send close scan - ndbout_c("sending close %d %d", m_api_receivers_count, m_conf_receivers_count); send_next_scan(0, true); // Close scan } @@ -1169,8 +1168,8 @@ NdbIndexScanOperation::fix_get_values(){ Uint32 cnt = m_accessTable->getNoOfColumns() - 1; assert(cnt < NDB_MAX_NO_OF_ATTRIBUTES_IN_KEY); - NdbIndexImpl * idx = m_accessTable->m_index; - NdbTableImpl * tab = m_currentTable; + const NdbIndexImpl * idx = m_accessTable->m_index; + const NdbTableImpl * tab = m_currentTable; for(Uint32 i = 0; i<cnt; i++){ Uint32 val = theTupleKeyDefined[i][0]; switch(val){ diff --git a/ndb/src/ndbapi/Ndbinit.cpp b/ndb/src/ndbapi/Ndbinit.cpp index 9ec500b2a46..9495c05cef2 100644 --- a/ndb/src/ndbapi/Ndbinit.cpp +++ b/ndb/src/ndbapi/Ndbinit.cpp @@ -16,12 +16,9 @@ #include <ndb_global.h> -#include <my_sys.h> #include "NdbApiSignal.hpp" #include "NdbImpl.hpp" -//#include "NdbSchemaOp.hpp" -//#include "NdbSchemaCon.hpp" #include "NdbOperation.hpp" #include "NdbConnection.hpp" #include "NdbRecAttr.hpp" @@ -40,11 +37,11 @@ void NdbGlobalEventBuffer_drop(NdbGlobalEventBufferHandle *); /** * Static object for NDB */ -static int theNoOfNdbObjects = 0; +// only needed for backwards compatability, before ndb_cluster_connection static char *ndbConnectString = 0; +static int theNoOfNdbObjects = 0; static Ndb_cluster_connection *global_ndb_cluster_connection= 0; - #if defined NDB_WIN32 || defined SCO static NdbMutex & createNdbMutex = * NdbMutex_Create(); #else @@ -59,13 +56,15 @@ Parameters: aDataBase : Name of the database. Remark: Connect to the database. ***************************************************************************/ Ndb::Ndb( const char* aDataBase , const char* aSchema) { + NdbMutex_Lock(&createNdbMutex); + if (theNoOfNdbObjects < 0) + abort(); // old and new Ndb constructor used mixed + theNoOfNdbObjects++; if (global_ndb_cluster_connection == 0) { - if (theNoOfNdbObjects > 0) - abort(); // old and new Ndb constructor used mixed - my_init(); global_ndb_cluster_connection= new Ndb_cluster_connection(ndbConnectString); global_ndb_cluster_connection->connect(); } + NdbMutex_Unlock(&createNdbMutex); setup(global_ndb_cluster_connection, aDataBase, aSchema); } @@ -75,6 +74,7 @@ Ndb::Ndb( Ndb_cluster_connection *ndb_cluster_connection, if (global_ndb_cluster_connection != 0 && global_ndb_cluster_connection != ndb_cluster_connection) abort(); // old and new Ndb constructor used mixed + theNoOfNdbObjects= -1; setup(ndb_cluster_connection, aDataBase, aSchema); } @@ -168,9 +168,6 @@ void Ndb::setup(Ndb_cluster_connection *ndb_cluster_connection, theWaiter.m_mutex = TransporterFacade::instance()->theMutexPtr; - // For keeping track of how many Ndb objects that exists. - theNoOfNdbObjects += 1; - // Signal that the constructor has finished OK if (theInitState == NotConstructed) theInitState = NotInitialised; @@ -229,10 +226,9 @@ Ndb::~Ndb() NdbMutex_Lock(&createNdbMutex); - theNoOfNdbObjects -= 1; - if(theNoOfNdbObjects == 0){ - TransporterFacade::stop_instance(); - if (global_ndb_cluster_connection != 0) { + if (global_ndb_cluster_connection != 0) { + theNoOfNdbObjects--; + if(theNoOfNdbObjects == 0){ delete global_ndb_cluster_connection; global_ndb_cluster_connection= 0; } diff --git a/ndb/src/ndbapi/TransporterFacade.cpp b/ndb/src/ndbapi/TransporterFacade.cpp index 4a7ad8a6872..f0b0bfe2de4 100644 --- a/ndb/src/ndbapi/TransporterFacade.cpp +++ b/ndb/src/ndbapi/TransporterFacade.cpp @@ -413,20 +413,13 @@ runSendRequest_C(void * me) void TransporterFacade::threadMainSend(void) { - SocketServer socket_server; - theTransporterRegistry->startSending(); - if (!theTransporterRegistry->start_service(socket_server)){ - ndbout_c("Unable to start theTransporterRegistry->start_service"); - exit(0); - } - if (!theTransporterRegistry->start_clients()){ ndbout_c("Unable to start theTransporterRegistry->start_clients"); exit(0); } - socket_server.startServer(); + m_socket_server.startServer(); while(!theStopReceive) { NdbSleep_MilliSleep(10); @@ -439,8 +432,8 @@ void TransporterFacade::threadMainSend(void) } theTransporterRegistry->stopSending(); - socket_server.stopServer(); - socket_server.stopSessions(); + m_socket_server.stopServer(); + m_socket_server.stopSessions(); theTransporterRegistry->stop_clients(); } @@ -558,6 +551,11 @@ TransporterFacade::init(Uint32 nodeId, const ndb_mgm_configuration* props) } #endif + if (!theTransporterRegistry->start_service(m_socket_server)){ + ndbout_c("Unable to start theTransporterRegistry->start_service"); + return false; + } + theReceiveThread = NdbThread_Create(runReceiveResponse_C, (void**)this, 32768, diff --git a/ndb/src/ndbapi/TransporterFacade.hpp b/ndb/src/ndbapi/TransporterFacade.hpp index 130a24345b7..76beaa708f1 100644 --- a/ndb/src/ndbapi/TransporterFacade.hpp +++ b/ndb/src/ndbapi/TransporterFacade.hpp @@ -138,6 +138,7 @@ private: void doStop(); TransporterRegistry* theTransporterRegistry; + SocketServer m_socket_server; int sendPerformedLastInterval; int theOwnId; diff --git a/ndb/src/ndbapi/ndb_cluster_connection.cpp b/ndb/src/ndbapi/ndb_cluster_connection.cpp index bd0ea246a04..27695cec187 100644 --- a/ndb/src/ndbapi/ndb_cluster_connection.cpp +++ b/ndb/src/ndbapi/ndb_cluster_connection.cpp @@ -145,6 +145,7 @@ int Ndb_cluster_connection::connect(int reconnect) Ndb_cluster_connection::~Ndb_cluster_connection() { + TransporterFacade::stop_instance(); if (m_connect_thread) { void *status; diff --git a/ndb/src/ndbapi/ndberror.c b/ndb/src/ndbapi/ndberror.c index 7991004e3d0..2ebcf4be444 100644 --- a/ndb/src/ndbapi/ndberror.c +++ b/ndb/src/ndbapi/ndberror.c @@ -280,6 +280,9 @@ ErrorBundle ErrorCodes[] = { { 739, SE, "Unsupported primary key length" }, { 740, SE, "Nullable primary key not supported" }, { 741, SE, "Unsupported alter table" }, + { 742, SE, "Unsupported attribute type in index" }, + { 743, SE, "Unsupported character set in table or index" }, + { 744, SE, "Character conversion error" }, { 241, SE, "Invalid schema object version" }, { 283, SE, "Table is being dropped" }, { 284, SE, "Table not defined in transaction coordinator" }, diff --git a/ndb/test/include/NDBT_Table.hpp b/ndb/test/include/NDBT_Table.hpp index 59db3ed1092..d2f99b85187 100644 --- a/ndb/test/include/NDBT_Table.hpp +++ b/ndb/test/include/NDBT_Table.hpp @@ -33,10 +33,10 @@ public: { assert(_name != 0); + setType(_type); + setLength(_length); setNullable(_nullable); setPrimaryKey(_pk); - setLength(_length); - setType(_type); } }; diff --git a/ndb/test/ndbapi/Makefile.am b/ndb/test/ndbapi/Makefile.am index 95fcf621e89..787589dd9b6 100644 --- a/ndb/test/ndbapi/Makefile.am +++ b/ndb/test/ndbapi/Makefile.am @@ -30,7 +30,7 @@ testSystemRestart \ testTimeout \ testTransactions \ testDeadlock \ -test_event ndbapi_slow_select testReadPerf +test_event ndbapi_slow_select testReadPerf testLcp #flexTimedAsynch #testBlobs @@ -68,6 +68,7 @@ testDeadlock_SOURCES = testDeadlock.cpp test_event_SOURCES = test_event.cpp ndbapi_slow_select_SOURCES = slow_select.cpp testReadPerf_SOURCES = testReadPerf.cpp +testLcp_SOURCES = testLcp.cpp INCLUDES_LOC = -I$(top_srcdir)/ndb/include/kernel diff --git a/ndb/test/ndbapi/acid.cpp b/ndb/test/ndbapi/acid.cpp index 157b3c7b3ef..3eb1625be26 100644 --- a/ndb/test/ndbapi/acid.cpp +++ b/ndb/test/ndbapi/acid.cpp @@ -434,6 +434,7 @@ extern "C" void* NdbThreadFuncRead(void* pArg) NDB_COMMAND(acid, "acid", "acid", "acid", 65535) { + ndb_init(); long nSeconds = 60; int rc = NDBT_OK; diff --git a/ndb/test/ndbapi/acid2.cpp b/ndb/test/ndbapi/acid2.cpp index 434a0450daa..7bd7ec00ac5 100644 --- a/ndb/test/ndbapi/acid2.cpp +++ b/ndb/test/ndbapi/acid2.cpp @@ -610,6 +610,7 @@ extern "C" void* ThreadFunc(void*) int main(int argc, char* argv[]) { + ndb_init(); Uint32 nSeconds = 1; Uint32 nThread = 1; diff --git a/ndb/test/ndbapi/bank/Bank.cpp b/ndb/test/ndbapi/bank/Bank.cpp index 7a2c5b057a1..c6029259357 100644 --- a/ndb/test/ndbapi/bank/Bank.cpp +++ b/ndb/test/ndbapi/bank/Bank.cpp @@ -156,7 +156,14 @@ int Bank::performTransactionImpl1(int fromAccountId, int check; + // Ok, all clear to do the transaction + Uint64 transId; + if (getNextTransactionId(transId) != NDBT_OK){ + return NDBT_FAILED; + } + NdbConnection* pTrans = m_ndb.startTransaction(); + if( pTrans == NULL ) { const NdbError err = m_ndb.getNdbError(); if (err.status == NdbError::TemporaryError){ @@ -167,6 +174,13 @@ int Bank::performTransactionImpl1(int fromAccountId, return NDBT_FAILED; } + Uint64 currTime; + if (prepareGetCurrTimeOp(pTrans, currTime) != NDBT_OK){ + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + /** * Check balance on from account */ @@ -205,29 +219,6 @@ int Bank::performTransactionImpl1(int fromAccountId, return NDBT_FAILED; } - check = pTrans->execute(NoCommit); - if( check == -1 ) { - const NdbError err = pTrans->getNdbError(); - m_ndb.closeTransaction(pTrans); - if (err.status == NdbError::TemporaryError){ - ERR(err); - return NDBT_TEMPORARY; - } - ERR(err); - return NDBT_FAILED; - } - - Uint32 balanceFrom = balanceFromRec->u_32_value(); - // ndbout << "balanceFrom: " << balanceFrom << endl; - - if (((Int64)balanceFrom - amount) < 0){ - m_ndb.closeTransaction(pTrans); - //ndbout << "Not enough funds" << endl; - return NOT_ENOUGH_FUNDS; - } - - Uint32 fromAccountType = fromAccountTypeRec->u_32_value(); - /** * Read balance on to account */ @@ -278,21 +269,22 @@ int Bank::performTransactionImpl1(int fromAccountId, return NDBT_FAILED; } - Uint32 balanceTo = balanceToRec->u_32_value(); - // ndbout << "balanceTo: " << balanceTo << endl; - Uint32 toAccountType = toAccountTypeRec->u_32_value(); - // Ok, all clear to do the transaction - Uint64 transId; - if (getNextTransactionId(transId) != NDBT_OK){ - return NDBT_FAILED; - } + Uint32 balanceFrom = balanceFromRec->u_32_value(); + // ndbout << "balanceFrom: " << balanceFrom << endl; - Uint64 currTime; - if (getCurrTime(currTime) != NDBT_OK){ - return NDBT_FAILED; + if (((Int64)balanceFrom - amount) < 0){ + m_ndb.closeTransaction(pTrans); + //ndbout << "Not enough funds" << endl; + return NOT_ENOUGH_FUNDS; } + Uint32 fromAccountType = fromAccountTypeRec->u_32_value(); + + Uint32 balanceTo = balanceToRec->u_32_value(); + // ndbout << "balanceTo: " << balanceTo << endl; + Uint32 toAccountType = toAccountTypeRec->u_32_value(); + /** * Update balance on from account */ @@ -1988,47 +1980,50 @@ int Bank::readSystemValue(SystemValueId sysValId, Uint64 & value){ ERR(m_ndb.getNdbError()); return NDBT_FAILED; } - - NdbOperation* pOp = pTrans->getNdbOperation("SYSTEM_VALUES"); - if (pOp == NULL) { + + if (prepareReadSystemValueOp(pTrans, sysValId, value) != NDBT_OK) { ERR(pTrans->getNdbError()); m_ndb.closeTransaction(pTrans); return NDBT_FAILED; } - - check = pOp->readTuple(); + + check = pTrans->execute(Commit); if( check == -1 ) { ERR(pTrans->getNdbError()); m_ndb.closeTransaction(pTrans); return NDBT_FAILED; } - check = pOp->equal("SYSTEM_VALUES_ID", sysValId); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); + m_ndb.closeTransaction(pTrans); + return NDBT_OK; + +} + +int Bank::prepareReadSystemValueOp(NdbConnection* pTrans, SystemValueId sysValId, Uint64 & value){ + + int check; + + NdbOperation* pOp = pTrans->getNdbOperation("SYSTEM_VALUES"); + if (pOp == NULL) { return NDBT_FAILED; } - NdbRecAttr* valueRec = pOp->getValue("VALUE"); - if( valueRec ==NULL ) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); + check = pOp->readTuple(); + if( check == -1 ) { return NDBT_FAILED; } - check = pTrans->execute(Commit); + check = pOp->equal("SYSTEM_VALUES_ID", sysValId); if( check == -1 ) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); return NDBT_FAILED; } - value = valueRec->u_64_value(); + NdbRecAttr* valueRec = pOp->getValue("VALUE", (char *)&value); + if( valueRec == NULL ) { + return NDBT_FAILED; + } - m_ndb.closeTransaction(pTrans); return NDBT_OK; - } int Bank::writeSystemValue(SystemValueId sysValId, Uint64 value){ @@ -2097,47 +2092,50 @@ int Bank::increaseSystemValue(SystemValueId sysValId, Uint64 &value){ * */ + DBUG_ENTER("Bank::increaseSystemValue"); + int check; NdbConnection* pTrans = m_ndb.startTransaction(); if (pTrans == NULL){ ERR(m_ndb.getNdbError()); - return NDBT_FAILED; + DBUG_RETURN(NDBT_FAILED); } NdbOperation* pOp = pTrans->getNdbOperation("SYSTEM_VALUES"); if (pOp == NULL) { ERR(pTrans->getNdbError()); m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; + DBUG_RETURN(NDBT_FAILED); } check = pOp->readTupleExclusive(); + // check = pOp->readTuple(); if( check == -1 ) { ERR(pTrans->getNdbError()); m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; + DBUG_RETURN(NDBT_FAILED); } check = pOp->equal("SYSTEM_VALUES_ID", sysValId); if( check == -1 ) { ERR(pTrans->getNdbError()); m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; + DBUG_RETURN(NDBT_FAILED); } NdbRecAttr* valueRec = pOp->getValue("VALUE"); if( valueRec ==NULL ) { ERR(pTrans->getNdbError()); m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; + DBUG_RETURN(NDBT_FAILED); } check = pTrans->execute(NoCommit); if( check == -1 ) { ERR(pTrans->getNdbError()); m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; + DBUG_RETURN(NDBT_FAILED); } value = valueRec->u_64_value(); @@ -2147,49 +2145,56 @@ int Bank::increaseSystemValue(SystemValueId sysValId, Uint64 &value){ if (pOp2 == NULL) { ERR(pTrans->getNdbError()); m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; + DBUG_RETURN(NDBT_FAILED); } check = pOp2->updateTuple(); if( check == -1 ) { ERR(pTrans->getNdbError()); m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; + DBUG_RETURN(NDBT_FAILED); } check = pOp2->equal("SYSTEM_VALUES_ID", sysValId); if( check == -1 ) { ERR(pTrans->getNdbError()); m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; + DBUG_RETURN(NDBT_FAILED); } check = pOp2->setValue("VALUE", value); if( check == -1 ) { ERR(pTrans->getNdbError()); m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; + DBUG_RETURN(NDBT_FAILED); + } + + check = pTrans->execute(NoCommit); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + DBUG_RETURN(NDBT_FAILED); } NdbOperation* pOp3 = pTrans->getNdbOperation("SYSTEM_VALUES"); if (pOp3 == NULL) { ERR(pTrans->getNdbError()); m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; + DBUG_RETURN(NDBT_FAILED); } check = pOp3->readTuple(); if( check == -1 ) { ERR(pTrans->getNdbError()); m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; + DBUG_RETURN(NDBT_FAILED); } check = pOp3->equal("SYSTEM_VALUES_ID", sysValId); if( check == -1 ) { ERR(pTrans->getNdbError()); m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; + DBUG_RETURN(NDBT_FAILED); } // Read new value @@ -2197,28 +2202,31 @@ int Bank::increaseSystemValue(SystemValueId sysValId, Uint64 &value){ if( valueNewRec ==NULL ) { ERR(pTrans->getNdbError()); m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; + DBUG_RETURN(NDBT_FAILED); } check = pTrans->execute(Commit); if( check == -1 ) { ERR(pTrans->getNdbError()); m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; + DBUG_RETURN(NDBT_FAILED); } // Check that value updated equals the value we read after the update if (valueNewRec->u_64_value() != value){ + + printf("value actual=%lld\n", valueNewRec->u_64_value()); + printf("value expected=%lld actual=%lld\n", value, valueNewRec->u_64_value()); + + DBUG_PRINT("info", ("value expected=%ld actual=%ld", value, valueNewRec->u_64_value())); g_err << "getNextTransactionId: value was not updated" << endl; m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; + DBUG_RETURN(NDBT_FAILED); } m_ndb.closeTransaction(pTrans); - - - return 0; + DBUG_RETURN(0); } int Bank::increaseSystemValue2(SystemValueId sysValId, Uint64 &value){ @@ -2294,6 +2302,10 @@ int Bank::getCurrTime(Uint64 &time){ return readSystemValue(CurrentTime, time); } +int Bank::prepareGetCurrTimeOp(NdbConnection *pTrans, Uint64 &time){ + return prepareReadSystemValueOp(pTrans, CurrentTime, time); +} + int Bank::performSumAccounts(int maxSleepBetweenSums, int yield){ if (init() != NDBT_OK) diff --git a/ndb/test/ndbapi/bank/Bank.hpp b/ndb/test/ndbapi/bank/Bank.hpp index e6816fd7111..34c5ff51cc2 100644 --- a/ndb/test/ndbapi/bank/Bank.hpp +++ b/ndb/test/ndbapi/bank/Bank.hpp @@ -29,7 +29,7 @@ public: Bank(); - int createAndLoadBank(bool overWrite); + int createAndLoadBank(bool overWrite, int num_accounts=10); int dropBank(); int performTransactions(int maxSleepBetweenTrans = 20, int yield=0); @@ -118,6 +118,9 @@ private: int incCurrTime(Uint64 &value); int getCurrTime(Uint64 &time); + int prepareReadSystemValueOp(NdbConnection*, SystemValueId sysValId, Uint64 &time); + int prepareGetCurrTimeOp(NdbConnection*, Uint64 &time); + int createTables(); int createTable(const char* tabName); diff --git a/ndb/test/ndbapi/bank/BankLoad.cpp b/ndb/test/ndbapi/bank/BankLoad.cpp index bbaac27735b..39dc8097115 100644 --- a/ndb/test/ndbapi/bank/BankLoad.cpp +++ b/ndb/test/ndbapi/bank/BankLoad.cpp @@ -53,7 +53,7 @@ int Bank::getNumAccountTypes(){ return accountTypesSize; } -int Bank::createAndLoadBank(bool ovrWrt){ +int Bank::createAndLoadBank(bool ovrWrt, int num_accounts){ m_ndb.init(); if (m_ndb.waitUntilReady() != 0) @@ -78,7 +78,7 @@ int Bank::createAndLoadBank(bool ovrWrt){ if (loadAccountType() != NDBT_OK) return NDBT_FAILED; - if (loadAccount(10) != NDBT_OK) + if (loadAccount(num_accounts) != NDBT_OK) return NDBT_FAILED; if (loadSystemValues() != NDBT_OK) diff --git a/ndb/test/ndbapi/bank/bankCreator.cpp b/ndb/test/ndbapi/bank/bankCreator.cpp index 5331ec6ba69..301d8bda6d2 100644 --- a/ndb/test/ndbapi/bank/bankCreator.cpp +++ b/ndb/test/ndbapi/bank/bankCreator.cpp @@ -27,6 +27,7 @@ int main(int argc, const char** argv){ + ndb_init(); int _help = 0; struct getargs args[] = { diff --git a/ndb/test/ndbapi/bank/bankMakeGL.cpp b/ndb/test/ndbapi/bank/bankMakeGL.cpp index 54bc559fbf9..9e2762ed8ae 100644 --- a/ndb/test/ndbapi/bank/bankMakeGL.cpp +++ b/ndb/test/ndbapi/bank/bankMakeGL.cpp @@ -27,6 +27,7 @@ int main(int argc, const char** argv){ + ndb_init(); int _help = 0; struct getargs args[] = { diff --git a/ndb/test/ndbapi/bank/bankSumAccounts.cpp b/ndb/test/ndbapi/bank/bankSumAccounts.cpp index c0a903f9034..b576161b27b 100644 --- a/ndb/test/ndbapi/bank/bankSumAccounts.cpp +++ b/ndb/test/ndbapi/bank/bankSumAccounts.cpp @@ -27,6 +27,7 @@ int main(int argc, const char** argv){ + ndb_init(); int _help = 0; struct getargs args[] = { diff --git a/ndb/test/ndbapi/bank/bankTimer.cpp b/ndb/test/ndbapi/bank/bankTimer.cpp index ba3165fccb4..874afd9c21e 100644 --- a/ndb/test/ndbapi/bank/bankTimer.cpp +++ b/ndb/test/ndbapi/bank/bankTimer.cpp @@ -28,6 +28,7 @@ int main(int argc, const char** argv){ + ndb_init(); int _help = 0; int _wait = 30; diff --git a/ndb/test/ndbapi/bank/bankTransactionMaker.cpp b/ndb/test/ndbapi/bank/bankTransactionMaker.cpp index fe9b53e0c8d..e5ff9aeb918 100644 --- a/ndb/test/ndbapi/bank/bankTransactionMaker.cpp +++ b/ndb/test/ndbapi/bank/bankTransactionMaker.cpp @@ -28,6 +28,7 @@ int main(int argc, const char** argv){ + ndb_init(); int _help = 0; int _wait = 20; diff --git a/ndb/test/ndbapi/bank/bankValidateAllGLs.cpp b/ndb/test/ndbapi/bank/bankValidateAllGLs.cpp index f9d974bb5f7..cf298ecc8e3 100644 --- a/ndb/test/ndbapi/bank/bankValidateAllGLs.cpp +++ b/ndb/test/ndbapi/bank/bankValidateAllGLs.cpp @@ -28,6 +28,7 @@ int main(int argc, const char** argv){ + ndb_init(); int _help = 0; struct getargs args[] = { diff --git a/ndb/test/ndbapi/bank/testBank.cpp b/ndb/test/ndbapi/bank/testBank.cpp index 77ac1172d7c..3ef2799cd3c 100644 --- a/ndb/test/ndbapi/bank/testBank.cpp +++ b/ndb/test/ndbapi/bank/testBank.cpp @@ -141,6 +141,7 @@ TESTCASE("Bank", NDBT_TESTSUITE_END(testBank); int main(int argc, const char** argv){ + ndb_init(); // Tables should not be auto created testBank.setCreateTable(false); diff --git a/ndb/test/ndbapi/benchronja.cpp b/ndb/test/ndbapi/benchronja.cpp index ce0aee35e8f..91b2a041186 100644 --- a/ndb/test/ndbapi/benchronja.cpp +++ b/ndb/test/ndbapi/benchronja.cpp @@ -66,6 +66,7 @@ static int ThreadReady[MAXTHREADS]; static int ThreadStart[MAXTHREADS]; NDB_COMMAND(benchronja, "benchronja", "benchronja", "benchronja", 65535){ + ndb_init(); ThreadNdb tabThread[MAXTHREADS]; int i = 0 ; diff --git a/ndb/test/ndbapi/bulk_copy.cpp b/ndb/test/ndbapi/bulk_copy.cpp index 18881cae216..8821a92fb27 100644 --- a/ndb/test/ndbapi/bulk_copy.cpp +++ b/ndb/test/ndbapi/bulk_copy.cpp @@ -221,6 +221,7 @@ int insertFile(Ndb* pNdb, int main(int argc, const char** argv){ + ndb_init(); const char* _tabname = NULL; int _help = 0; diff --git a/ndb/test/ndbapi/cdrserver.cpp b/ndb/test/ndbapi/cdrserver.cpp index 8354d28f53f..8d15061e94b 100644 --- a/ndb/test/ndbapi/cdrserver.cpp +++ b/ndb/test/ndbapi/cdrserver.cpp @@ -113,6 +113,7 @@ using namespace std; int main(int argc, const char** argv) { + ndb_init(); /******** NDB ***********/ /* Ndb MyNdb( "TEST_DB" ); diff --git a/ndb/test/ndbapi/celloDb.cpp b/ndb/test/ndbapi/celloDb.cpp index ec61e783585..2d6401c355a 100644 --- a/ndb/test/ndbapi/celloDb.cpp +++ b/ndb/test/ndbapi/celloDb.cpp @@ -73,6 +73,7 @@ static int failed = 0 ; NDB_COMMAND(celloDb, "celloDb", "celloDb", "celloDb", 65535) { + ndb_init(); int tTableId; int i; diff --git a/ndb/test/ndbapi/create_all_tabs.cpp b/ndb/test/ndbapi/create_all_tabs.cpp index 55d04888144..97236b98b36 100644 --- a/ndb/test/ndbapi/create_all_tabs.cpp +++ b/ndb/test/ndbapi/create_all_tabs.cpp @@ -25,6 +25,7 @@ int main(int argc, const char** argv){ + ndb_init(); int _temp = false; int _help = 0; diff --git a/ndb/test/ndbapi/create_tab.cpp b/ndb/test/ndbapi/create_tab.cpp index c2e3b7f64ea..f3f18982ed0 100644 --- a/ndb/test/ndbapi/create_tab.cpp +++ b/ndb/test/ndbapi/create_tab.cpp @@ -25,6 +25,7 @@ int main(int argc, const char** argv){ + ndb_init(); int _temp = false; int _help = 0; diff --git a/ndb/test/ndbapi/drop_all_tabs.cpp b/ndb/test/ndbapi/drop_all_tabs.cpp index 59c57396acd..c024a81a5e6 100644 --- a/ndb/test/ndbapi/drop_all_tabs.cpp +++ b/ndb/test/ndbapi/drop_all_tabs.cpp @@ -23,6 +23,7 @@ #include <getarg.h> int main(int argc, const char** argv){ + ndb_init(); int _help = 0; struct getargs args[] = { diff --git a/ndb/test/ndbapi/flexAsynch.cpp b/ndb/test/ndbapi/flexAsynch.cpp index 9192ec21b93..8c0ba46130c 100644 --- a/ndb/test/ndbapi/flexAsynch.cpp +++ b/ndb/test/ndbapi/flexAsynch.cpp @@ -145,6 +145,7 @@ tellThreads(StartType what) NDB_COMMAND(flexAsynch, "flexAsynch", "flexAsynch", "flexAsynch", 65535) { + ndb_init(); ThreadNdb* pThreadData; int tLoops=0, i; int returnValue = NDBT_OK; diff --git a/ndb/test/ndbapi/flexBench.cpp b/ndb/test/ndbapi/flexBench.cpp index 38c8f6e280f..b19944498f4 100644 --- a/ndb/test/ndbapi/flexBench.cpp +++ b/ndb/test/ndbapi/flexBench.cpp @@ -281,6 +281,7 @@ tellThreads(ThreadData* pt, StartType what) NDB_COMMAND(flexBench, "flexBench", "flexBench", "flexbench", 65535) { + ndb_init(); ThreadData* pThreadsData; int tLoops = 0, i; int returnValue = NDBT_OK; diff --git a/ndb/test/ndbapi/flexHammer.cpp b/ndb/test/ndbapi/flexHammer.cpp index c1c47923de9..80cc7c5a53f 100644 --- a/ndb/test/ndbapi/flexHammer.cpp +++ b/ndb/test/ndbapi/flexHammer.cpp @@ -178,6 +178,7 @@ tellThreads(ThreadNdb* threadArrayP, const StartType what) NDB_COMMAND(flexHammer, "flexHammer", "flexHammer", "flexHammer", 65535) //main(int argc, const char** argv) { + ndb_init(); ThreadNdb* pThreads = NULL; // Pointer to thread data array Ndb* pMyNdb = NULL; // Pointer to Ndb object int tLoops = 0; diff --git a/ndb/test/ndbapi/flexScan.cpp b/ndb/test/ndbapi/flexScan.cpp index 5b5b4dde730..b09d71fb010 100644 --- a/ndb/test/ndbapi/flexScan.cpp +++ b/ndb/test/ndbapi/flexScan.cpp @@ -297,6 +297,7 @@ static int checkThreadResults(ThreadNdb *threadArrayP, char *action) NDB_COMMAND(flexScan, "flexScan", "flexScan", "flexScan", 65535) { + ndb_init(); ThreadNdb* pThreads = NULL; Ndb* pMyNdb = NULL; int tLoops = 0; diff --git a/ndb/test/ndbapi/flexTT.cpp b/ndb/test/ndbapi/flexTT.cpp index c0ff31d1677..162fc080218 100644 --- a/ndb/test/ndbapi/flexTT.cpp +++ b/ndb/test/ndbapi/flexTT.cpp @@ -171,6 +171,7 @@ tellThreads(StartType what) NDB_COMMAND(flexTT, "flexTT", "flexTT", "flexTT", 65535) { + ndb_init(); ThreadNdb* pThreadData; int returnValue = NDBT_OK; int i; diff --git a/ndb/test/ndbapi/flexTimedAsynch.cpp b/ndb/test/ndbapi/flexTimedAsynch.cpp index 761be53fdd3..27380cc79fd 100644 --- a/ndb/test/ndbapi/flexTimedAsynch.cpp +++ b/ndb/test/ndbapi/flexTimedAsynch.cpp @@ -174,6 +174,7 @@ void deleteAttributeSpace(){ NDB_COMMAND(flexTimedAsynch, "flexTimedAsynch", "flexTimedAsynch [-tpoilcas]", "flexTimedAsynch", 65535) { + ndb_init(); ThreadNdb tabThread[MAXTHREADS]; int tLoops=0; int returnValue; diff --git a/ndb/test/ndbapi/flex_bench_mysql.cpp b/ndb/test/ndbapi/flex_bench_mysql.cpp index 7cc883ab3e6..8e1fbcd9058 100644 --- a/ndb/test/ndbapi/flex_bench_mysql.cpp +++ b/ndb/test/ndbapi/flex_bench_mysql.cpp @@ -308,6 +308,7 @@ tellThreads(ThreadData* pt, StartType what) NDB_COMMAND(flexBench, "flexBench", "flexBench", "flexbench", 65535) { + ndb_init(); ThreadData* pThreadsData; int tLoops = 0; int returnValue = NDBT_OK; diff --git a/ndb/test/ndbapi/index.cpp b/ndb/test/ndbapi/index.cpp index 508186de529..c22da594164 100644 --- a/ndb/test/ndbapi/index.cpp +++ b/ndb/test/ndbapi/index.cpp @@ -81,63 +81,63 @@ static void createTable(Ndb &myNdb, bool storeInACC, bool twoKey, bool longKey) int res; column.setName("NAME"); - column.setPrimaryKey(true); column.setType(NdbDictionary::Column::Char); column.setLength((longKey)? 1024 // 1KB => long key :12); + column.setPrimaryKey(true); column.setNullable(false); table.addColumn(column); if (twoKey) { column.setName("KEY2"); - column.setPrimaryKey(true); column.setType(NdbDictionary::Column::Unsigned); column.setLength(1); + column.setPrimaryKey(true); column.setNullable(false); table.addColumn(column); } column.setName("PNUM1"); - column.setPrimaryKey(false); column.setType(NdbDictionary::Column::Unsigned); column.setLength(1); + column.setPrimaryKey(false); column.setNullable(false); table.addColumn(column); column.setName("PNUM2"); - column.setPrimaryKey(false); column.setType(NdbDictionary::Column::Unsigned); column.setLength(1); + column.setPrimaryKey(false); column.setNullable(false); table.addColumn(column); column.setName("PNUM3"); - column.setPrimaryKey(false); column.setType(NdbDictionary::Column::Unsigned); column.setLength(1); + column.setPrimaryKey(false); column.setNullable(false); table.addColumn(column); column.setName("PNUM4"); - column.setPrimaryKey(false); column.setType(NdbDictionary::Column::Unsigned); column.setLength(1); + column.setPrimaryKey(false); column.setNullable(false); table.addColumn(column); column.setName("AGE"); - column.setPrimaryKey(false); column.setType(NdbDictionary::Column::Unsigned); column.setLength(1); + column.setPrimaryKey(false); column.setNullable(false); table.addColumn(column); column.setName("STRING_AGE"); - column.setPrimaryKey(false); column.setType(NdbDictionary::Column::Char); column.setLength(1); column.setLength(256); + column.setPrimaryKey(false); column.setNullable(false); table.addColumn(column); @@ -771,6 +771,7 @@ static void dropIndex(Ndb &myNdb, unsigned int noOfIndexes) NDB_COMMAND(indexTest, "indexTest", "indexTest", "indexTest", 65535) { + ndb_init(); bool createTableOp, createIndexOp, dropIndexOp, insertOp, updateOp, deleteOp, readOp, readIndexOp, updateIndexOp, deleteIndexOp, twoKey, longKey; unsigned int noOfTuples = 1; unsigned int noOfOperations = 1; diff --git a/ndb/test/ndbapi/index2.cpp b/ndb/test/ndbapi/index2.cpp index e49113d2f1b..f739468d7df 100644 --- a/ndb/test/ndbapi/index2.cpp +++ b/ndb/test/ndbapi/index2.cpp @@ -81,16 +81,16 @@ static void createTable(Ndb &myNdb, bool storeInACC, bool twoKey, bool longKey) int res; column.setName("X"); - column.setPrimaryKey(true); column.setType(NdbDictionary::Column::Unsigned); column.setLength(1); + column.setPrimaryKey(true); column.setNullable(false); table.addColumn(column); column.setName("Y"); - column.setPrimaryKey(false); column.setType(NdbDictionary::Column::Unsigned); column.setLength(1); + column.setPrimaryKey(false); column.setNullable(false); table.addColumn(column); @@ -608,6 +608,7 @@ static void dropIndex(Ndb &myNdb, unsigned int noOfIndexes) NDB_COMMAND(indexTest, "indexTest", "indexTest", "indexTest", 65535) { + ndb_init(); bool createTableOp, createIndexOp, dropIndexOp, insertOp, updateOp, deleteOp, readOp, readIndexOp, updateIndexOp, deleteIndexOp, twoKey, longKey; unsigned int noOfTuples = 1; unsigned int noOfOperations = 1; diff --git a/ndb/test/ndbapi/initronja.cpp b/ndb/test/ndbapi/initronja.cpp index b3215104822..3ce274e4319 100644 --- a/ndb/test/ndbapi/initronja.cpp +++ b/ndb/test/ndbapi/initronja.cpp @@ -46,6 +46,7 @@ static char attrName[MAXATTR][MAXSTRLEN]; inline int InsertRecords(Ndb*, int) ; NDB_COMMAND(initronja, "initronja", "initronja", "initronja", 65535){ + ndb_init(); Ndb* pNdb = NULL ; NdbSchemaCon *MySchemaTransaction = NULL ; diff --git a/ndb/test/ndbapi/interpreterInTup.cpp b/ndb/test/ndbapi/interpreterInTup.cpp index 47960cd5d12..20d84e6e96d 100644 --- a/ndb/test/ndbapi/interpreterInTup.cpp +++ b/ndb/test/ndbapi/interpreterInTup.cpp @@ -105,6 +105,7 @@ int bTestPassed = 0; int main(int argc, const char** argv) { + ndb_init(); int operationType = 0; int tupTest = 0; diff --git a/ndb/test/ndbapi/mainAsyncGenerator.cpp b/ndb/test/ndbapi/mainAsyncGenerator.cpp index f613c66d07b..16cb50e160f 100644 --- a/ndb/test/ndbapi/mainAsyncGenerator.cpp +++ b/ndb/test/ndbapi/mainAsyncGenerator.cpp @@ -282,6 +282,7 @@ threadRoutine(void *arg) NDB_COMMAND(DbAsyncGenerator, "DbAsyncGenerator", "DbAsyncGenerator", "DbAsyncGenerator", 65535) { + ndb_init(); int i; int j; int k; diff --git a/ndb/test/ndbapi/msa.cpp b/ndb/test/ndbapi/msa.cpp index 7a734f9cb79..e39f7a8c64a 100644 --- a/ndb/test/ndbapi/msa.cpp +++ b/ndb/test/ndbapi/msa.cpp @@ -971,6 +971,7 @@ void ShowHelp(const char* szCmd) int main(int argc, char* argv[]) { + ndb_init(); int iRes = -1; g_nNumThreads = 0; g_nMaxCallsPerSecond = 0; diff --git a/ndb/test/ndbapi/restarter.cpp b/ndb/test/ndbapi/restarter.cpp index 9a522f5dcac..d6831494b48 100644 --- a/ndb/test/ndbapi/restarter.cpp +++ b/ndb/test/ndbapi/restarter.cpp @@ -28,6 +28,7 @@ #include <NDBT.hpp> int main(int argc, const char** argv){ + ndb_init(); const char* _hostName = NULL; int _loops = 10; diff --git a/ndb/test/ndbapi/restarter2.cpp b/ndb/test/ndbapi/restarter2.cpp index f2bcf6f8e7b..846748a7bba 100644 --- a/ndb/test/ndbapi/restarter2.cpp +++ b/ndb/test/ndbapi/restarter2.cpp @@ -26,6 +26,7 @@ #include <NDBT.hpp> int main(int argc, const char** argv){ + ndb_init(); const char* _hostName = NULL; int _loops = 10; diff --git a/ndb/test/ndbapi/restarts.cpp b/ndb/test/ndbapi/restarts.cpp index 0ec2883d53c..184e754de4a 100644 --- a/ndb/test/ndbapi/restarts.cpp +++ b/ndb/test/ndbapi/restarts.cpp @@ -27,6 +27,7 @@ #include <NDBT.hpp> int main(int argc, const char** argv){ + ndb_init(); const char* _restartName = NULL; int _loops = 1; diff --git a/ndb/test/ndbapi/size.cpp b/ndb/test/ndbapi/size.cpp index c506771ebde..ff178b11d68 100644 --- a/ndb/test/ndbapi/size.cpp +++ b/ndb/test/ndbapi/size.cpp @@ -19,6 +19,7 @@ int main(void) { + ndb_init(); printf("cdrstruct=%d\n",sizeof(struct cdr_record)); printf("long int=%d\n",sizeof(long int)); printf("int=%d\n",sizeof(int)); diff --git a/ndb/test/ndbapi/slow_select.cpp b/ndb/test/ndbapi/slow_select.cpp index a953e1539d0..625dbc34457 100644 --- a/ndb/test/ndbapi/slow_select.cpp +++ b/ndb/test/ndbapi/slow_select.cpp @@ -36,6 +36,7 @@ static void lookup(); int main(void){ + ndb_init(); Ndb g_ndb("test"); g_ndb.init(1024); diff --git a/ndb/test/ndbapi/testBackup.cpp b/ndb/test/ndbapi/testBackup.cpp index d328a7db292..509cd4780bf 100644 --- a/ndb/test/ndbapi/testBackup.cpp +++ b/ndb/test/ndbapi/testBackup.cpp @@ -215,7 +215,7 @@ int runDropTable(NDBT_Context* ctx, NDBT_Step* step){ int runCreateBank(NDBT_Context* ctx, NDBT_Step* step){ Bank bank; int overWriteExisting = true; - if (bank.createAndLoadBank(overWriteExisting) != NDBT_OK) + if (bank.createAndLoadBank(overWriteExisting, 10) != NDBT_OK) return NDBT_FAILED; return NDBT_OK; } @@ -428,6 +428,15 @@ TESTCASE("BackupBank", INITIALIZER(runCreateBank); STEP(runBankTimer); STEP(runBankTransactions); + STEP(runBankTransactions); + STEP(runBankTransactions); + STEP(runBankTransactions); + STEP(runBankTransactions); + STEP(runBankTransactions); + STEP(runBankTransactions); + STEP(runBankTransactions); + STEP(runBankTransactions); + STEP(runBankTransactions); STEP(runBankGL); // TODO STEP(runBankSum); STEP(runBackupBank); @@ -473,6 +482,7 @@ TESTCASE("FailSlave", NDBT_TESTSUITE_END(testBackup); int main(int argc, const char** argv){ + ndb_init(); return testBackup.execute(argc, argv); } diff --git a/ndb/test/ndbapi/testBasic.cpp b/ndb/test/ndbapi/testBasic.cpp index 26622f9b066..7d03016b87a 100644 --- a/ndb/test/ndbapi/testBasic.cpp +++ b/ndb/test/ndbapi/testBasic.cpp @@ -1278,6 +1278,7 @@ TESTCASE("MassiveTransaction", NDBT_TESTSUITE_END(testBasic); int main(int argc, const char** argv){ + ndb_init(); return testBasic.execute(argc, argv); } diff --git a/ndb/test/ndbapi/testBasicAsynch.cpp b/ndb/test/ndbapi/testBasicAsynch.cpp index a97920e53da..6daa22fdc6a 100644 --- a/ndb/test/ndbapi/testBasicAsynch.cpp +++ b/ndb/test/ndbapi/testBasicAsynch.cpp @@ -181,6 +181,7 @@ TESTCASE("PkDeleteAsynch", NDBT_TESTSUITE_END(testBasicAsynch); int main(int argc, const char** argv){ + ndb_init(); return testBasicAsynch.execute(argc, argv); } diff --git a/ndb/test/ndbapi/testBlobs.cpp b/ndb/test/ndbapi/testBlobs.cpp index 64881ca39ab..e18f4a8bd1a 100644 --- a/ndb/test/ndbapi/testBlobs.cpp +++ b/ndb/test/ndbapi/testBlobs.cpp @@ -1338,6 +1338,7 @@ static struct { NDB_COMMAND(testOdbcDriver, "testBlobs", "testBlobs", "testBlobs", 65535) { + ndb_init(); while (++argv, --argc > 0) { const char* arg = argv[0]; if (strcmp(arg, "-batch") == 0) { diff --git a/ndb/test/ndbapi/testDataBuffers.cpp b/ndb/test/ndbapi/testDataBuffers.cpp index 2e29dbb0d7b..94658d5c6b9 100644 --- a/ndb/test/ndbapi/testDataBuffers.cpp +++ b/ndb/test/ndbapi/testDataBuffers.cpp @@ -545,6 +545,7 @@ testcase(int flag) NDB_COMMAND(testDataBuffers, "testDataBuffers", "testDataBuffers", "testDataBuffers", 65535) { + ndb_init(); while (++argv, --argc > 0) { char const* p = argv[0]; if (*p++ != '-' || strlen(p) != 1) diff --git a/ndb/test/ndbapi/testDeadlock.cpp b/ndb/test/ndbapi/testDeadlock.cpp index f51b3cea1e5..a445823b8a8 100644 --- a/ndb/test/ndbapi/testDeadlock.cpp +++ b/ndb/test/ndbapi/testDeadlock.cpp @@ -491,6 +491,7 @@ wl1822_main(char scantx) NDB_COMMAND(testOdbcDriver, "testDeadlock", "testDeadlock", "testDeadlock", 65535) { + ndb_init(); while (++argv, --argc > 0) { const char* arg = argv[0]; if (strcmp(arg, "-scan") == 0) { diff --git a/ndb/test/ndbapi/testDict.cpp b/ndb/test/ndbapi/testDict.cpp index a0c7bb1414b..7cba5ce4cc8 100644 --- a/ndb/test/ndbapi/testDict.cpp +++ b/ndb/test/ndbapi/testDict.cpp @@ -1128,9 +1128,9 @@ runCreateAutoincrementTable(NDBT_Context* ctx, NDBT_Step* step){ myTable.setName(tabname); myColumn.setName("ATTR1"); - myColumn.setPrimaryKey(true); myColumn.setType(NdbDictionary::Column::Unsigned); myColumn.setLength(1); + myColumn.setPrimaryKey(true); myColumn.setNullable(false); myColumn.setAutoIncrement(true); if (startvalue != ~0) // check that default value starts with 1 @@ -1576,6 +1576,7 @@ TESTCASE("DictionaryPerf", NDBT_TESTSUITE_END(testDict); int main(int argc, const char** argv){ + ndb_init(); // Tables should not be auto created testDict.setCreateTable(false); myRandom48Init(NdbTick_CurrentMillisecond()); diff --git a/ndb/test/ndbapi/testGrep.cpp b/ndb/test/ndbapi/testGrep.cpp index 0bf84cb4ec8..713aefbeafa 100644 --- a/ndb/test/ndbapi/testGrep.cpp +++ b/ndb/test/ndbapi/testGrep.cpp @@ -533,6 +533,7 @@ TESTCASE("FailSlave", NDBT_TESTSUITE_END(testGrep); int main(int argc, const char** argv){ + ndb_init(); return testGrep.execute(argc, argv); } diff --git a/ndb/test/ndbapi/testGrepVerify.cpp b/ndb/test/ndbapi/testGrepVerify.cpp index 05445c1ba1b..52dcda9a162 100644 --- a/ndb/test/ndbapi/testGrepVerify.cpp +++ b/ndb/test/ndbapi/testGrepVerify.cpp @@ -40,6 +40,7 @@ continue; } int main(int argc, const char** argv){ + ndb_init(); const char * connectString = NULL; diff --git a/ndb/test/ndbapi/testIndex.cpp b/ndb/test/ndbapi/testIndex.cpp index 6ebbfd8b680..bef3b310c96 100644 --- a/ndb/test/ndbapi/testIndex.cpp +++ b/ndb/test/ndbapi/testIndex.cpp @@ -1528,6 +1528,7 @@ TESTCASE("UniqueNull", NDBT_TESTSUITE_END(testIndex); int main(int argc, const char** argv){ + ndb_init(); return testIndex.execute(argc, argv); } diff --git a/ndb/test/ndbapi/testInterpreter.cpp b/ndb/test/ndbapi/testInterpreter.cpp index 9c584d6f581..0baba33d2b2 100644 --- a/ndb/test/ndbapi/testInterpreter.cpp +++ b/ndb/test/ndbapi/testInterpreter.cpp @@ -224,6 +224,7 @@ TESTCASE("NdbErrorOperation", NDBT_TESTSUITE_END(testInterpreter); int main(int argc, const char** argv){ + ndb_init(); // TABLE("T1"); return testInterpreter.execute(argc, argv); } diff --git a/ndb/test/ndbapi/testLcp.cpp b/ndb/test/ndbapi/testLcp.cpp new file mode 100644 index 00000000000..c92be091a97 --- /dev/null +++ b/ndb/test/ndbapi/testLcp.cpp @@ -0,0 +1,320 @@ + +#include <NDBT.hpp> +#include <NdbApi.hpp> +#include <NdbRestarter.hpp> +#include <HugoOperations.hpp> +#include <UtilTransactions.hpp> +#include <signaldata/DumpStateOrd.hpp> + +struct CASE +{ + bool start_row; + bool end_row; + bool curr_row; + const char * op1; + const char * op2; + int val; +}; + +static CASE g_ops[] = +{ + { false, true, false, "INSERT", 0, 0 }, + { false, true, false, "INSERT", "UPDATE", 0 }, + { false, false, false, "INSERT", "DELETE", 0 }, + { true, true, false, "UPDATE", 0, 0 }, + { true, true, false, "UPDATE", "UPDATE", 0 }, + { true, false, false, "UPDATE", "DELETE", 0 }, + { true, false, false, "DELETE", 0, 0 }, + { true, true, false, "DELETE", "INSERT", 0 } +}; +const size_t OP_COUNT = (sizeof(g_ops)/sizeof(g_ops[0])); + +static Ndb* g_ndb = 0; +static CASE* g_cases; +static HugoOperations* g_hugo_ops; + +static int g_rows = 1000; +static int g_setup_tables = 1; +static const char * g_tablename = "T1"; +static const NdbDictionary::Table* g_table = 0; +static NdbRestarter g_restarter; + +static int init_ndb(int argc, char** argv); +static int parse_args(int argc, char** argv); +static int connect_ndb(); +static int drop_all_tables(); +static int load_table(); +static int pause_lcp(); +static int do_op(int row); +static int continue_lcp(int error); +static int commit(); +static int restart(); +static int validate(); + +#define require(x) { bool b = x; if(!b){g_err << __LINE__ << endl; abort();}} + +int +main(int argc, char ** argv){ + + require(!init_ndb(argc, argv)); + require(!parse_args(argc, argv)); + require(!connect_ndb()); + + if(g_setup_tables){ + require(!drop_all_tables()); + + if(NDBT_Tables::createTable(g_ndb, g_tablename) != 0){ + exit(-1); + } + } + + g_table = g_ndb->getDictionary()->getTable(g_tablename); + if(g_table == 0){ + g_err << "Failed to retreive table: " << g_tablename << endl; + exit(-1); + } + require(g_hugo_ops = new HugoOperations(* g_table)); + require(!g_hugo_ops->startTransaction(g_ndb)); + + g_cases= new CASE[g_rows]; + require(!load_table()); + + g_info << "Performing all ops wo/ inteference of LCP" << endl; + + g_info << "Testing pre LCP operations, ZLCP_OP_WRITE_RT_BREAK" << endl; + g_info << " where ZLCP_OP_WRITE_RT_BREAK is finished before SAVE_PAGES" + << endl; + require(!pause_lcp()); + for(size_t j = 0; j<g_rows; j++){ + require(!do_op(j)); + } + require(!continue_lcp(5900)); + require(!commit()); + require(!restart()); + require(!validate()); + + g_info << "Testing pre LCP operations, ZLCP_OP_WRITE_RT_BREAK" << endl; + g_info << " where ZLCP_OP_WRITE_RT_BREAK is finished after SAVE_PAGES" + << endl; + require(!load_table()); + require(!pause_lcp()); + for(size_t j = 0; j<g_rows; j++){ + require(!do_op(j)); + } + require(!continue_lcp(5901)); + require(!commit()); + require(!restart()); + require(!validate()); + + g_info << "Testing pre LCP operations, undo-ed at commit" << endl; + require(!load_table()); + require(!pause_lcp()); + for(size_t j = 0; j<g_rows; j++){ + require(!do_op(j)); + } + require(!continue_lcp(5902)); + require(!commit()); + require(!continue_lcp(5903)); + require(!restart()); + require(!validate()); +} + +static int init_ndb(int argc, char** argv) +{ + return 0; +} + +static int parse_args(int argc, char** argv) +{ + return 0; +} + +static int connect_ndb() +{ + g_ndb = new Ndb("TEST_DB"); + g_ndb->init(); + if(g_ndb->waitUntilReady(30) == 0){ + int args[] = { DumpStateOrd::DihMaxTimeBetweenLCP }; + return g_restarter.dumpStateAllNodes(args, 1); + } + return -1; +} + +static int disconnect_ndb() +{ + delete g_ndb; + g_ndb = 0; + g_table = 0; + return 0; +} + +static int drop_all_tables() +{ + NdbDictionary::Dictionary * dict = g_ndb->getDictionary(); + require(dict); + + BaseString db = g_ndb->getDatabaseName(); + BaseString schema = g_ndb->getSchemaName(); + + NdbDictionary::Dictionary::List list; + if (dict->listObjects(list, NdbDictionary::Object::TypeUndefined) == -1){ + g_err << "Failed to list tables: " << endl + << dict->getNdbError() << endl; + return -1; + } + for (unsigned i = 0; i < list.count; i++) { + NdbDictionary::Dictionary::List::Element& elt = list.elements[i]; + switch (elt.type) { + case NdbDictionary::Object::SystemTable: + case NdbDictionary::Object::UserTable: + g_ndb->setDatabaseName(elt.database); + g_ndb->setSchemaName(elt.schema); + if(dict->dropTable(elt.name) != 0){ + g_err << "Failed to drop table: " + << elt.database << "/" << elt.schema << "/" << elt.name <<endl; + g_err << dict->getNdbError() << endl; + return -1; + } + break; + case NdbDictionary::Object::UniqueHashIndex: + case NdbDictionary::Object::OrderedIndex: + case NdbDictionary::Object::HashIndexTrigger: + case NdbDictionary::Object::IndexTrigger: + case NdbDictionary::Object::SubscriptionTrigger: + case NdbDictionary::Object::ReadOnlyConstraint: + default: + break; + } + } + + g_ndb->setDatabaseName(db.c_str()); + g_ndb->setSchemaName(schema.c_str()); + + return 0; +} + +static int load_table() +{ + UtilTransactions clear(* g_table); + require(!clear.clearTable(g_ndb)); + + HugoOperations ops(* g_table); + require(!ops.startTransaction(g_ndb)); + for(size_t i = 0; i<g_rows; i++){ + g_cases[i] = g_ops[ i % OP_COUNT]; + if(g_cases[i].start_row){ + g_cases[i].curr_row = true; + g_cases[i].val = rand(); + require(!ops.pkInsertRecord(g_ndb, i, 1, g_cases[i].val)); + } + if((i+1) % 100 == 0){ + require(!ops.execute_Commit(g_ndb)); + require(!ops.getTransaction()->restart()); + } + } + if((g_rows+1) % 100 != 0) + require(!ops.execute_Commit(g_ndb)); + return 0; +} + +static int pause_lcp() +{ + return 0; +} + +static int do_op(int row) +{ + HugoOperations & ops = * g_hugo_ops; + if(strcmp(g_cases[row].op1, "INSERT") == 0){ + require(!g_cases[row].curr_row); + g_cases[row].curr_row = true; + g_cases[row].val = rand(); + require(!ops.pkInsertRecord(g_ndb, row, 1, g_cases[row].val)); + } else if(strcmp(g_cases[row].op1, "UPDATE") == 0){ + require(g_cases[row].curr_row); + g_cases[row].val = rand(); + require(!ops.pkUpdateRecord(g_ndb, row, 1, g_cases[row].val)); + } else if(strcmp(g_cases[row].op1, "DELETE") == 0){ + require(g_cases[row].curr_row); + g_cases[row].curr_row = false; + require(!ops.pkDeleteRecord(g_ndb, row, 1)); + } + + require(!ops.execute_NoCommit(g_ndb)); + + if(g_cases[row].op2 == 0){ + } else if(strcmp(g_cases[row].op2, "INSERT") == 0){ + require(!g_cases[row].curr_row); + g_cases[row].curr_row = true; + g_cases[row].val = rand(); + require(!ops.pkInsertRecord(g_ndb, row, 1, g_cases[row].val)); + } else if(strcmp(g_cases[row].op2, "UPDATE") == 0){ + require(g_cases[row].curr_row); + g_cases[row].val = rand(); + require(!ops.pkUpdateRecord(g_ndb, row, 1, g_cases[row].val)); + } else if(strcmp(g_cases[row].op2, "DELETE") == 0){ + require(g_cases[row].curr_row); + g_cases[row].curr_row = false; + require(!ops.pkDeleteRecord(g_ndb, row, 1)); + } + + if(g_cases[row].op2 != 0) + require(!ops.execute_NoCommit(g_ndb)); + return 0; +} + +static int continue_lcp(int error) +{ + error = 0; + if(g_restarter.insertErrorInAllNodes(error) == 0){ + int args[] = { DumpStateOrd::DihStartLcpImmediately }; + return g_restarter.dumpStateAllNodes(args, 1); + } + return -1; +} + +static int commit() +{ + HugoOperations & ops = * g_hugo_ops; + int res = ops.execute_Commit(g_ndb); + if(res == 0){ + return ops.getTransaction()->restart(); + } + return res; +} + +static int restart() +{ + g_info << "Restarting cluster" << endl; + disconnect_ndb(); + delete g_hugo_ops; + + require(!g_restarter.restartAll()); + require(!g_restarter.waitClusterStarted(30)); + require(!connect_ndb()); + + g_table = g_ndb->getDictionary()->getTable(g_tablename); + require(g_table); + require(g_hugo_ops = new HugoOperations(* g_table)); + require(!g_hugo_ops->startTransaction(g_ndb)); + return 0; +} + +static int validate() +{ + HugoOperations ops(* g_table); + for(size_t i = 0; i<g_rows; i++){ + require(g_cases[i].curr_row == g_cases[i].end_row); + require(!ops.startTransaction(g_ndb)); + ops.pkReadRecord(g_ndb, i, 1); + int res = ops.execute_Commit(g_ndb); + if(g_cases[i].curr_row){ + require(res == 0 && ops.verifyUpdatesValue(g_cases[i].val) == 0); + } else { + require(res == 626); + } + ops.closeTransaction(g_ndb); + } + return 0; +} + diff --git a/ndb/test/ndbapi/testMgm.cpp b/ndb/test/ndbapi/testMgm.cpp index d5b9372cc9b..ef653d3f972 100644 --- a/ndb/test/ndbapi/testMgm.cpp +++ b/ndb/test/ndbapi/testMgm.cpp @@ -178,6 +178,7 @@ TESTCASE("SingleUserMode", NDBT_TESTSUITE_END(testMgm); int main(int argc, const char** argv){ + ndb_init(); myRandom48Init(NdbTick_CurrentMillisecond()); return testMgm.execute(argc, argv); } diff --git a/ndb/test/ndbapi/testNdbApi.cpp b/ndb/test/ndbapi/testNdbApi.cpp index 5b171d42578..47987629fe3 100644 --- a/ndb/test/ndbapi/testNdbApi.cpp +++ b/ndb/test/ndbapi/testNdbApi.cpp @@ -1006,6 +1006,7 @@ TESTCASE("NdbErrorOperation", NDBT_TESTSUITE_END(testNdbApi); int main(int argc, const char** argv){ + ndb_init(); // TABLE("T1"); return testNdbApi.execute(argc, argv); } diff --git a/ndb/test/ndbapi/testNodeRestart.cpp b/ndb/test/ndbapi/testNodeRestart.cpp index 89b38c78e71..6bfe59f8d3f 100644 --- a/ndb/test/ndbapi/testNodeRestart.cpp +++ b/ndb/test/ndbapi/testNodeRestart.cpp @@ -434,6 +434,7 @@ TESTCASE("StopOnError", NDBT_TESTSUITE_END(testNodeRestart); int main(int argc, const char** argv){ + ndb_init(); #if 0 // It might be interesting to have longer defaults for num // loops in this test diff --git a/ndb/test/ndbapi/testOIBasic.cpp b/ndb/test/ndbapi/testOIBasic.cpp index 29d03f0c33e..ac28b96af80 100644 --- a/ndb/test/ndbapi/testOIBasic.cpp +++ b/ndb/test/ndbapi/testOIBasic.cpp @@ -979,9 +979,9 @@ createtable(Par par) for (unsigned k = 0; k < tab.m_cols; k++) { const Col& col = tab.m_col[k]; NdbDictionary::Column c(col.m_name); - c.setPrimaryKey(col.m_pk); c.setType(col.m_type); c.setLength(col.m_length); + c.setPrimaryKey(col.m_pk); c.setNullable(col.m_nullable); t.addColumn(c); } @@ -2236,9 +2236,8 @@ pkreadfast(Par par, unsigned count) keyrow.calc(par, i); CHK(keyrow.selrow(par) == 0); NdbRecAttr* rec; - CHK(con.getValue((Uint32)0, rec) == 0); - CHK(con.executeScan() == 0); // get 1st column + CHK(con.getValue((Uint32)0, rec) == 0); CHK(con.execute(Commit) == 0); con.closeTransaction(); } @@ -3201,6 +3200,7 @@ runtest(Par par) NDB_COMMAND(testOIBasic, "testOIBasic", "testOIBasic", "testOIBasic", 65535) { + ndb_init(); while (++argv, --argc > 0) { const char* arg = argv[0]; if (*arg != '-') { diff --git a/ndb/test/ndbapi/testOperations.cpp b/ndb/test/ndbapi/testOperations.cpp index bb58e69e898..ba41e1d1c40 100644 --- a/ndb/test/ndbapi/testOperations.cpp +++ b/ndb/test/ndbapi/testOperations.cpp @@ -230,6 +230,7 @@ runClearTable(NDBT_Context* ctx, NDBT_Step* step){ int main(int argc, const char** argv){ + ndb_init(); NDBT_TestSuite ts("testOperations"); for(Uint32 i = 0; i<sizeof(matrix)/sizeof(matrix[0]); i++){ diff --git a/ndb/test/ndbapi/testOrderedIndex.cpp b/ndb/test/ndbapi/testOrderedIndex.cpp index 51cc53c9975..b3a75410646 100644 --- a/ndb/test/ndbapi/testOrderedIndex.cpp +++ b/ndb/test/ndbapi/testOrderedIndex.cpp @@ -218,6 +218,7 @@ NDBT_TESTSUITE_END(testOrderedIndex); int main(int argc, const char** argv) { + ndb_init(); return testOrderedIndex.execute(argc, argv); } diff --git a/ndb/test/ndbapi/testReadPerf.cpp b/ndb/test/ndbapi/testReadPerf.cpp index 412661c4ff8..7cf3755d66f 100644 --- a/ndb/test/ndbapi/testReadPerf.cpp +++ b/ndb/test/ndbapi/testReadPerf.cpp @@ -91,6 +91,7 @@ void print_result(); int main(int argc, const char** argv){ + ndb_init(); int verbose = 1; int optind = 0; diff --git a/ndb/test/ndbapi/testRestartGci.cpp b/ndb/test/ndbapi/testRestartGci.cpp index 54d38654ff2..4cdfca29e6f 100644 --- a/ndb/test/ndbapi/testRestartGci.cpp +++ b/ndb/test/ndbapi/testRestartGci.cpp @@ -214,6 +214,7 @@ TESTCASE("InsertRestartGci", NDBT_TESTSUITE_END(testRestartGci); int main(int argc, const char** argv){ + ndb_init(); return testRestartGci.execute(argc, argv); } diff --git a/ndb/test/ndbapi/testScan.cpp b/ndb/test/ndbapi/testScan.cpp index 3d8b37df0ca..0cd30dfefde 100644 --- a/ndb/test/ndbapi/testScan.cpp +++ b/ndb/test/ndbapi/testScan.cpp @@ -1400,6 +1400,7 @@ TESTCASE("ScanRestart", NDBT_TESTSUITE_END(testScan); int main(int argc, const char** argv){ + ndb_init(); myRandom48Init(NdbTick_CurrentMillisecond()); return testScan.execute(argc, argv); } diff --git a/ndb/test/ndbapi/testScanInterpreter.cpp b/ndb/test/ndbapi/testScanInterpreter.cpp index 3b5baf954e0..3a5ef22b613 100644 --- a/ndb/test/ndbapi/testScanInterpreter.cpp +++ b/ndb/test/ndbapi/testScanInterpreter.cpp @@ -273,6 +273,7 @@ TESTCASE("ScanLessThanLoop", NDBT_TESTSUITE_END(testScanInterpreter); int main(int argc, const char** argv){ + ndb_init(); return testScanInterpreter.execute(argc, argv); } diff --git a/ndb/test/ndbapi/testScanPerf.cpp b/ndb/test/ndbapi/testScanPerf.cpp index 829ba5a0f15..8c1a41047ca 100644 --- a/ndb/test/ndbapi/testScanPerf.cpp +++ b/ndb/test/ndbapi/testScanPerf.cpp @@ -72,6 +72,7 @@ int drop_table(); int main(int argc, const char** argv){ + ndb_init(); int verbose = 1; int optind = 0; diff --git a/ndb/test/ndbapi/testSystemRestart.cpp b/ndb/test/ndbapi/testSystemRestart.cpp index 61e086ff941..68e5eacc631 100644 --- a/ndb/test/ndbapi/testSystemRestart.cpp +++ b/ndb/test/ndbapi/testSystemRestart.cpp @@ -1179,6 +1179,7 @@ TESTCASE("SR8", NDBT_TESTSUITE_END(testSystemRestart); int main(int argc, const char** argv){ + ndb_init(); return testSystemRestart.execute(argc, argv); } diff --git a/ndb/test/ndbapi/testTimeout.cpp b/ndb/test/ndbapi/testTimeout.cpp index 62e69125073..5cabb86541d 100644 --- a/ndb/test/ndbapi/testTimeout.cpp +++ b/ndb/test/ndbapi/testTimeout.cpp @@ -406,6 +406,7 @@ TESTCASE("BuddyTransNoTimeout5", NDBT_TESTSUITE_END(testTimeout); int main(int argc, const char** argv){ + ndb_init(); myRandom48Init(NdbTick_CurrentMillisecond()); return testTimeout.execute(argc, argv); } diff --git a/ndb/test/ndbapi/testTransactions.cpp b/ndb/test/ndbapi/testTransactions.cpp index 67a2df24390..2dca9e24fb4 100644 --- a/ndb/test/ndbapi/testTransactions.cpp +++ b/ndb/test/ndbapi/testTransactions.cpp @@ -364,6 +364,7 @@ runClearTable(NDBT_Context* ctx, NDBT_Step* step){ int main(int argc, const char** argv){ + ndb_init(); NDBT_TestSuite ts("testOperations"); for(Uint32 i = 0; i<sizeof(matrix)/sizeof(matrix[0]); i++){ diff --git a/ndb/test/ndbapi/test_event.cpp b/ndb/test/ndbapi/test_event.cpp index 40fc1c6defa..cb2793e42b9 100644 --- a/ndb/test/ndbapi/test_event.cpp +++ b/ndb/test/ndbapi/test_event.cpp @@ -137,6 +137,7 @@ NDBT_TESTSUITE_END(test_event); #endif int main(int argc, const char** argv){ + ndb_init(); return test_event.execute(argc, argv); } diff --git a/ndb/test/run-test/Makefile.am b/ndb/test/run-test/Makefile.am index 611362ad735..03b53509f05 100644 --- a/ndb/test/run-test/Makefile.am +++ b/ndb/test/run-test/Makefile.am @@ -18,5 +18,8 @@ LDADD_LOC = $(top_builddir)/ndb/src/mgmclient/CpcClient.o \ $(top_builddir)/mysys/libmysys.a \ $(top_builddir)/strings/libmystrings.a +wrappersdir=$(prefix)/bin +wrappers_SCRIPTS=atrt-testBackup atrt-mysql-test-run + # Don't update the files from bitkeeper %::SCCS/s.% diff --git a/ndb/test/run-test/atrt-mysql-test-run b/ndb/test/run-test/atrt-mysql-test-run new file mode 100755 index 00000000000..3a044e43288 --- /dev/null +++ b/ndb/test/run-test/atrt-mysql-test-run @@ -0,0 +1,5 @@ +#!/bin/sh + +set -e -x +cd $MYSQL_BASE_DIR/mysql-test +./mysql-test-run --with-ndbcluster --ndbconnectstring=$NDB_CONNECTSTRING $* diff --git a/ndb/test/run-test/atrt-testBackup b/ndb/test/run-test/atrt-testBackup new file mode 100755 index 00000000000..3ed7641a42e --- /dev/null +++ b/ndb/test/run-test/atrt-testBackup @@ -0,0 +1,6 @@ +#!/bin/sh + +PATH=$PATH:$MYSQL_BASE_DIR/bin +export PATH + +testBackup $* diff --git a/ndb/test/run-test/daily-basic-tests.txt b/ndb/test/run-test/daily-basic-tests.txt index 631378cb636..8d7e8a06c72 100644 --- a/ndb/test/run-test/daily-basic-tests.txt +++ b/ndb/test/run-test/daily-basic-tests.txt @@ -1006,3 +1006,18 @@ max-time: 1500 cmd: testSystemRestart args: -n SR2 T7 +max-time: 1500 +cmd: testSystemRestart +args: -n SR_UNDO T1 + +max-time: 1500 +cmd: testSystemRestart +args: -n SR_UNDO T6 + +max-time: 1500 +cmd: testSystemRestart +args: -n SR_UNDO T7 + +max-time: 1500 +cmd: testSystemRestart +args: -n SR_UNDO T8 diff --git a/ndb/test/run-test/daily-devel-tests.txt b/ndb/test/run-test/daily-devel-tests.txt index 15fa4db4abc..723d241aa46 100644 --- a/ndb/test/run-test/daily-devel-tests.txt +++ b/ndb/test/run-test/daily-devel-tests.txt @@ -1,3 +1,7 @@ +max-time: 2500 +cmd: atrt-mysql-test-run +args: --do-test=ndb --force + # # INDEX # @@ -19,13 +23,13 @@ args: -n CreateLoadDrop T1 T10 # BACKUP # max-time: 600 -cmd: testBackup +cmd: atrt-testBackup args: -n BackupOne T1 T6 T3 I3 -#max-time: 600 -#cmd: testBackup -#args: -n BackupBank T6 -# +max-time: 1000 +cmd: testBackup +args: -n BackupBank T6 + # # MGMAPI AND MGSRV # @@ -37,21 +41,6 @@ args: -n SingleUserMode T1 # # SYSTEM RESTARTS # -max-time: 1500 -cmd: testSystemRestart -args: -n SR_UNDO T1 - -max-time: 1500 -cmd: testSystemRestart -args: -n SR_UNDO T6 - -max-time: 1500 -cmd: testSystemRestart -args: -n SR_UNDO T7 - -max-time: 1500 -cmd: testSystemRestart -args: -n SR_UNDO T8 max-time: 1500 cmd: testSystemRestart diff --git a/ndb/test/run-test/main.cpp b/ndb/test/run-test/main.cpp index bdc40fb02b2..22799a9a1b2 100644 --- a/ndb/test/run-test/main.cpp +++ b/ndb/test/run-test/main.cpp @@ -79,6 +79,7 @@ const int arg_count = 10; int main(int argc, const char ** argv){ + ndb_init(); bool restart = true; int lineno = 1; @@ -451,13 +452,14 @@ setup_config(atrt_config& config){ proc.m_proc.m_stderr = "2>&1"; proc.m_proc.m_runas = proc.m_host->m_user; proc.m_proc.m_ulimit = "c:unlimited"; + proc.m_proc.m_env.assfmt("MYSQL_BASE_DIR=%s", dir.c_str()); proc.m_hostname = proc.m_host->m_hostname; proc.m_ndb_mgm_port = g_default_base_port; if(split1[0] == "mgm"){ proc.m_type = atrt_process::NDB_MGM; proc.m_proc.m_name.assfmt("%d-%s", index, "ndb_mgmd"); proc.m_proc.m_path.assign(dir).append("/libexec/ndb_mgmd"); - proc.m_proc.m_args = "-n -c initconfig.txt"; + proc.m_proc.m_args = "--nodaemon -c initconfig.txt"; proc.m_proc.m_cwd.appfmt("%d.ndb_mgmd", index); connect_string.appfmt("host=%s:%d;", proc.m_hostname.c_str(), proc.m_ndb_mgm_port); @@ -501,8 +503,8 @@ setup_config(atrt_config& config){ // Setup connect string for(size_t i = 0; i<config.m_processes.size(); i++){ - config.m_processes[i].m_proc.m_env.assfmt("NDB_CONNECTSTRING=%s", - connect_string.c_str()); + config.m_processes[i].m_proc.m_env.appfmt(" NDB_CONNECTSTRING=%s", + connect_string.c_str()); } end: diff --git a/ndb/test/src/HugoTransactions.cpp b/ndb/test/src/HugoTransactions.cpp index 05039562c76..53809ecc851 100644 --- a/ndb/test/src/HugoTransactions.cpp +++ b/ndb/test/src/HugoTransactions.cpp @@ -728,7 +728,8 @@ HugoTransactions::loadTable(Ndb* pNdb, if (doSleep > 0) NdbSleep_MilliSleep(doSleep); - if (first_batch || !oneTrans) { + // if (first_batch || !oneTrans) { + if (first_batch) { first_batch = false; pTrans = pNdb->startTransaction(); @@ -774,8 +775,10 @@ HugoTransactions::loadTable(Ndb* pNdb, // Execute the transaction and insert the record if (!oneTrans || (c + batch) >= records) { - closeTrans = true; + // closeTrans = true; + closeTrans = false; check = pTrans->execute( Commit ); + pTrans->restart(); } else { closeTrans = false; check = pTrans->execute( NoCommit ); diff --git a/ndb/test/src/NDBT_Test.cpp b/ndb/test/src/NDBT_Test.cpp index 7ccc9e5588f..4ff94bcf296 100644 --- a/ndb/test/src/NDBT_Test.cpp +++ b/ndb/test/src/NDBT_Test.cpp @@ -15,7 +15,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include <ndb_global.h> -#include <my_sys.h> #include "NDBT.hpp" #include "NDBT_Test.hpp" @@ -859,6 +858,11 @@ void NDBT_TestSuite::execute(Ndb* ndb, const NdbDictionary::Table* pTab, else numTestsOk++; numTestsExecuted++; + + if (result == NDBT_OK && createTable == true){ + pDict->dropTable(pTab->getName()); + } + delete ctx; } } @@ -985,7 +989,6 @@ int NDBT_TestSuite::execute(int argc, const char** argv){ } #ifndef DBUG_OFF - my_init(); if (debug_option) DBUG_PUSH(debug_option); #endif diff --git a/ndb/test/src/NdbBackup.cpp b/ndb/test/src/NdbBackup.cpp index f33c5d8c313..71b4b49b3a6 100644 --- a/ndb/test/src/NdbBackup.cpp +++ b/ndb/test/src/NdbBackup.cpp @@ -140,14 +140,16 @@ NdbBackup::execRestore(bool _restore_data, */ snprintf(buf, buf_len, - "scp %s:%s/BACKUP/BACKUP-%d/* .", + "scp %s:%s/BACKUP/BACKUP-%d/BACKUP-%d*.%d.* .", host, path, - _backup_id); + _backup_id, + _backup_id, + _node_id); ndbout << "buf: "<< buf <<endl; int res = system(buf); - ndbout << "res: " << res << endl; + ndbout << "scp res: " << res << endl; snprintf(buf, 255, "%sndb_restore -c \"host=%s\" -n %d -b %d %s %s .", #if 1 @@ -162,9 +164,9 @@ NdbBackup::execRestore(bool _restore_data, _restore_meta?"-m":""); ndbout << "buf: "<< buf <<endl; - res = system(buf); + res = system(buf); - ndbout << "res: " << res << endl; + ndbout << "ndb_restore res: " << res << endl; return res; @@ -180,20 +182,13 @@ NdbBackup::restore(unsigned _backup_id){ return -1; int res; - if ( ndbNodes.size() == 1) { - // restore metadata and data in one call - res = execRestore(true, true, ndbNodes[0].node_id, _backup_id); - } else { - assert(ndbNodes.size() > 1); - - // restore metadata first - res = execRestore(false, true, ndbNodes[0].node_id, _backup_id); - - // Restore data once for each node - for(size_t i = 0; i < ndbNodes.size(); i++){ - res = execRestore(true, false, ndbNodes[i].node_id, _backup_id); - } + // restore metadata first and data for first node + res = execRestore(true, true, ndbNodes[0].node_id, _backup_id); + + // Restore data once for each node + for(size_t i = 1; i < ndbNodes.size(); i++){ + res = execRestore(true, false, ndbNodes[i].node_id, _backup_id); } return 0; diff --git a/ndb/test/src/UtilTransactions.cpp b/ndb/test/src/UtilTransactions.cpp index 9f3f1d33587..506356dd140 100644 --- a/ndb/test/src/UtilTransactions.cpp +++ b/ndb/test/src/UtilTransactions.cpp @@ -1138,90 +1138,93 @@ UtilTransactions::readRowFromTableAndIndex(Ndb* pNdb, */ NdbIndexOperation* pIndexOp= NULL; NdbIndexScanOperation *pScanOp= NULL; - { - void* pOpCheck= NULL; - if (indexType == NdbDictionary::Index::UniqueHashIndex) { - pOpCheck= pIndexOp= pTrans1->getNdbIndexOperation(indexName, tab.getName()); - } else { - pOpCheck= pScanOp= pTrans1->getNdbIndexScanOperation(indexName, tab.getName()); - } + NdbOperation *pIOp= 0; - if (pOpCheck == NULL) { - ERR(pTrans1->getNdbError()); - goto close_all; + bool null_found= false; + for(a = 0; a<(int)pIndex->getNoOfColumns(); a++){ + const NdbDictionary::Column * col = pIndex->getColumn(a); + + if (row.attributeStore(col->getName())->isNULL()) + { + null_found= true; + break; } } - + + const char * tabName= tab.getName(); + if(!null_found) { - bool not_ok; - if (pIndexOp) { - not_ok = pIndexOp->readTuple() == -1; + if (indexType == NdbDictionary::Index::UniqueHashIndex) { + pIOp= pIndexOp= pTrans1->getNdbIndexOperation(indexName, tabName); } else { - not_ok = (cursor= pScanOp->readTuples()) == 0; + pIOp= pScanOp= pTrans1->getNdbIndexScanOperation(indexName, tabName); } - - if( not_ok ) { + + if (pIOp == NULL) { ERR(pTrans1->getNdbError()); goto close_all; } - } + + { + bool not_ok; + if (pIndexOp) { + not_ok = pIndexOp->readTuple() == -1; + } else { + not_ok = (cursor= pScanOp->readTuples()) == 0; + } + + if( not_ok ) { + ERR(pTrans1->getNdbError()); + goto close_all; + } + } // Define primary keys for index #if VERBOSE - printf("SI: "); + printf("SI: "); #endif - for(a = 0; a<(int)pIndex->getNoOfColumns(); a++){ - const NdbDictionary::Column * col = pIndex->getColumn(a); - - int r; - if (pIndexOp) - r = pIndexOp->equal(col->getName(), row.attributeStore(col->getName())->aRef()); - else { - // setBound not possible for null attributes + for(a = 0; a<(int)pIndex->getNoOfColumns(); a++){ + const NdbDictionary::Column * col = pIndex->getColumn(a); + + int r; if ( !row.attributeStore(col->getName())->isNULL() ) { - r = pScanOp->setBound(col->getName(), - NdbIndexScanOperation::BoundEQ, - row.attributeStore(col->getName())->aRef()); + if(pIOp->equal(col->getName(), + row.attributeStore(col->getName())->aRef()) != 0){ + ERR(pTrans1->getNdbError()); + goto close_all; + } } - } - if (r != 0){ - ERR(pTrans1->getNdbError()); - goto close_all; - } #if VERBOSE - printf("%s = %d: ", col->getName(), row.attributeStore(a)->aRef()); + printf("%s = %d: ", col->getName(), row.attributeStore(a)->aRef()); #endif - } + } #if VERBOSE - printf("\n"); + printf("\n"); #endif - - // Read all attributes + + // Read all attributes #if VERBOSE - printf("Reading %u attributes: ", tab.getNoOfColumns()); + printf("Reading %u attributes: ", tab.getNoOfColumns()); #endif - for(a = 0; a<tab.getNoOfColumns(); a++){ - void* pCheck; - - if (pIndexOp) - pCheck= indexRow.attributeStore(a)= - pIndexOp->getValue(tab.getColumn(a)->getName()); - else - pCheck= indexRow.attributeStore(a)= - pScanOp->getValue(tab.getColumn(a)->getName()); - - if(pCheck == NULL) { - ERR(pTrans1->getNdbError()); - goto close_all; - } + for(a = 0; a<tab.getNoOfColumns(); a++){ + void* pCheck; + + pCheck= indexRow.attributeStore(a)= + pIOp->getValue(tab.getColumn(a)->getName()); + + if(pCheck == NULL) { + ERR(pTrans1->getNdbError()); + goto close_all; + } #if VERBOSE - printf("%s ", tab.getColumn(a)->getName()); + printf("%s ", tab.getColumn(a)->getName()); #endif + } } #if VERBOSE printf("\n"); #endif - + check = pTrans1->execute(Commit); if( check == -1 ) { const NdbError err = pTrans1->getNdbError(); @@ -1238,41 +1241,43 @@ UtilTransactions::readRowFromTableAndIndex(Ndb* pNdb, ndbout << "row: " << row.c_str().c_str() << endl; goto close_all; } - + /** * Compare the two rows */ - if (pScanOp) { - if (cursor->nextResult() != 0){ - const NdbError err = pTrans1->getNdbError(); - ERR(err); - ndbout << "Error when comparing records - index op next_result missing" << endl; - ndbout << "row: " << row.c_str().c_str() << endl; - goto close_all; + if(!null_found){ + if (pScanOp) { + if (cursor->nextResult() != 0){ + const NdbError err = pTrans1->getNdbError(); + ERR(err); + ndbout << "Error when comparing records - index op next_result missing" << endl; + ndbout << "row: " << row.c_str().c_str() << endl; + goto close_all; + } } - } - if (!(tabRow.c_str() == indexRow.c_str())){ - ndbout << "Error when comapring records" << endl; - ndbout << " tabRow: \n" << tabRow.c_str().c_str() << endl; - ndbout << " indexRow: \n" << indexRow.c_str().c_str() << endl; - goto close_all; - } - if (pScanOp) { - if (cursor->nextResult() == 0){ - ndbout << "Error when comparing records - index op next_result to many" << endl; - ndbout << "row: " << row.c_str().c_str() << endl; + if (!(tabRow.c_str() == indexRow.c_str())){ + ndbout << "Error when comapring records" << endl; + ndbout << " tabRow: \n" << tabRow.c_str().c_str() << endl; + ndbout << " indexRow: \n" << indexRow.c_str().c_str() << endl; goto close_all; } + if (pScanOp) { + if (cursor->nextResult() == 0){ + ndbout << "Error when comparing records - index op next_result to many" << endl; + ndbout << "row: " << row.c_str().c_str() << endl; + goto close_all; + } + } } return_code= NDBT_OK; goto close_all; } - close_all: +close_all: if (cursor) cursor->close(); if (pTrans1) pNdb->closeTransaction(pTrans1); - + return return_code; } diff --git a/ndb/test/tools/copy_tab.cpp b/ndb/test/tools/copy_tab.cpp index 33ce8e01d9a..30141acaa78 100644 --- a/ndb/test/tools/copy_tab.cpp +++ b/ndb/test/tools/copy_tab.cpp @@ -24,6 +24,7 @@ #include <getarg.h> int main(int argc, const char** argv){ + ndb_init(); const char* _tabname = NULL; const char* _to_tabname = NULL; diff --git a/ndb/test/tools/cpcc.cpp b/ndb/test/tools/cpcc.cpp index e30d458ffee..dd59e577f2c 100644 --- a/ndb/test/tools/cpcc.cpp +++ b/ndb/test/tools/cpcc.cpp @@ -173,6 +173,7 @@ add_hosts(Vector<SimpleCpcClient*> & hosts, BaseString list){ int main(int argc, const char** argv){ + ndb_init(); int help = 0; const char *cmd=0, *name=0, *group=0, *owner=0; int list = 0, start = 0, stop = 0, rm = 0; diff --git a/ndb/test/tools/create_index.cpp b/ndb/test/tools/create_index.cpp index f883755ea24..75a657522f6 100644 --- a/ndb/test/tools/create_index.cpp +++ b/ndb/test/tools/create_index.cpp @@ -26,6 +26,7 @@ int main(int argc, const char** argv){ + ndb_init(); const char* _dbname = "TEST_DB"; int _help = 0; diff --git a/ndb/test/tools/hugoCalculator.cpp b/ndb/test/tools/hugoCalculator.cpp index 7f2751be2ba..82c4bbff1a4 100644 --- a/ndb/test/tools/hugoCalculator.cpp +++ b/ndb/test/tools/hugoCalculator.cpp @@ -28,6 +28,7 @@ int main(int argc, const char** argv) { + ndb_init(); int _row = 0; int _column = 0; int _updates = 0; diff --git a/ndb/test/tools/hugoFill.cpp b/ndb/test/tools/hugoFill.cpp index dee6ce2e6c8..6253bd1bb12 100644 --- a/ndb/test/tools/hugoFill.cpp +++ b/ndb/test/tools/hugoFill.cpp @@ -25,6 +25,7 @@ int main(int argc, const char** argv){ + ndb_init(); int _records = 0; const char* _tabname = NULL; diff --git a/ndb/test/tools/hugoLoad.cpp b/ndb/test/tools/hugoLoad.cpp index be7f878d106..c697ad22aad 100644 --- a/ndb/test/tools/hugoLoad.cpp +++ b/ndb/test/tools/hugoLoad.cpp @@ -24,6 +24,7 @@ int main(int argc, const char** argv){ + ndb_init(); int _records = 0; const char* _tabname = NULL; diff --git a/ndb/test/tools/hugoLockRecords.cpp b/ndb/test/tools/hugoLockRecords.cpp index e2c2cd13f00..629408d401d 100644 --- a/ndb/test/tools/hugoLockRecords.cpp +++ b/ndb/test/tools/hugoLockRecords.cpp @@ -27,6 +27,7 @@ #include <HugoTransactions.hpp> int main(int argc, const char** argv){ + ndb_init(); int _records = 0; int _loops = 1; diff --git a/ndb/test/tools/hugoPkDelete.cpp b/ndb/test/tools/hugoPkDelete.cpp index 1855f19796f..78a90ebcb46 100644 --- a/ndb/test/tools/hugoPkDelete.cpp +++ b/ndb/test/tools/hugoPkDelete.cpp @@ -27,6 +27,7 @@ #include <HugoTransactions.hpp> int main(int argc, const char** argv){ + ndb_init(); int _records = 0; int _loops = 1; diff --git a/ndb/test/tools/hugoPkRead.cpp b/ndb/test/tools/hugoPkRead.cpp index 50351f08195..cf08b137e8e 100644 --- a/ndb/test/tools/hugoPkRead.cpp +++ b/ndb/test/tools/hugoPkRead.cpp @@ -28,6 +28,7 @@ int main(int argc, const char** argv){ + ndb_init(); int _records = 0; int _loops = 1; diff --git a/ndb/test/tools/hugoPkReadRecord.cpp b/ndb/test/tools/hugoPkReadRecord.cpp index 85f20bd2060..38b7cae2bf4 100644 --- a/ndb/test/tools/hugoPkReadRecord.cpp +++ b/ndb/test/tools/hugoPkReadRecord.cpp @@ -28,6 +28,7 @@ int main(int argc, const char** argv) { + ndb_init(); int _row = 0; int _hex = 0; int _primaryKey = 0; diff --git a/ndb/test/tools/hugoPkUpdate.cpp b/ndb/test/tools/hugoPkUpdate.cpp index e7edc3a991d..286be14a01c 100644 --- a/ndb/test/tools/hugoPkUpdate.cpp +++ b/ndb/test/tools/hugoPkUpdate.cpp @@ -27,6 +27,7 @@ #include <HugoTransactions.hpp> int main(int argc, const char** argv){ + ndb_init(); int _records = 0; int _loops = 1; diff --git a/ndb/test/tools/hugoScanRead.cpp b/ndb/test/tools/hugoScanRead.cpp index 47ea8f4a8a7..cdfdcea4654 100644 --- a/ndb/test/tools/hugoScanRead.cpp +++ b/ndb/test/tools/hugoScanRead.cpp @@ -27,6 +27,7 @@ #include <HugoTransactions.hpp> int main(int argc, const char** argv){ + ndb_init(); int _records = 0; int _loops = 1; diff --git a/ndb/test/tools/hugoScanUpdate.cpp b/ndb/test/tools/hugoScanUpdate.cpp index 3e2255ca0f3..96a487a02bf 100644 --- a/ndb/test/tools/hugoScanUpdate.cpp +++ b/ndb/test/tools/hugoScanUpdate.cpp @@ -27,6 +27,7 @@ #include <HugoTransactions.hpp> int main(int argc, const char** argv){ + ndb_init(); int _records = 0; int _loops = 1; diff --git a/ndb/test/tools/restart.cpp b/ndb/test/tools/restart.cpp index 88cfb231a72..9ad20801fd7 100644 --- a/ndb/test/tools/restart.cpp +++ b/ndb/test/tools/restart.cpp @@ -27,6 +27,7 @@ #include <NDBT.hpp> int main(int argc, const char** argv){ + ndb_init(); const char* _hostName = NULL; int _initial = 0; diff --git a/ndb/test/tools/transproxy.cpp b/ndb/test/tools/transproxy.cpp index 384a8a34f03..90e216ec785 100644 --- a/ndb/test/tools/transproxy.cpp +++ b/ndb/test/tools/transproxy.cpp @@ -346,6 +346,7 @@ start() int main(int av, char** ac) { + ndb_init(); debug("start"); hostname = "ndb-srv7"; if (Ndb_getInAddr(&hostaddr.sin_addr, hostname) != 0) { diff --git a/ndb/test/tools/verify_index.cpp b/ndb/test/tools/verify_index.cpp index 1295b657e9b..6c8e304e1a1 100644 --- a/ndb/test/tools/verify_index.cpp +++ b/ndb/test/tools/verify_index.cpp @@ -27,6 +27,7 @@ int main(int argc, const char** argv){ + ndb_init(); int _parallelism = 240; const char* _tabname = NULL; const char* _indexname = NULL; diff --git a/ndb/tools/delete_all.cpp b/ndb/tools/delete_all.cpp index 5110947c6a2..aa5798376ae 100644 --- a/ndb/tools/delete_all.cpp +++ b/ndb/tools/delete_all.cpp @@ -26,6 +26,7 @@ static int clear_table(Ndb* pNdb, const NdbDictionary::Table* pTab, int parallelism=240); int main(int argc, const char** argv){ + ndb_init(); const char* _tabname = NULL; const char* _dbname = "TEST_DB"; diff --git a/ndb/tools/desc.cpp b/ndb/tools/desc.cpp index e5b98c4c8e9..0ab11a0fdd2 100644 --- a/ndb/tools/desc.cpp +++ b/ndb/tools/desc.cpp @@ -22,6 +22,7 @@ int main(int argc, const char** argv){ + ndb_init(); const char* _tabname = NULL; const char* _dbname = "TEST_DB"; int _unqualified = 0; @@ -50,7 +51,6 @@ int main(int argc, const char** argv){ Ndb* pMyNdb; pMyNdb = new Ndb(_dbname); - pMyNdb->useFullyQualifiedNames(!_unqualified); pMyNdb->init(); ndbout << "Waiting..."; diff --git a/ndb/tools/drop_index.cpp b/ndb/tools/drop_index.cpp index 327f15741c9..70c29461c23 100644 --- a/ndb/tools/drop_index.cpp +++ b/ndb/tools/drop_index.cpp @@ -23,6 +23,7 @@ #include <getarg.h> int main(int argc, const char** argv){ + ndb_init(); const char* _tabname = NULL; const char* _dbname = "TEST_DB"; diff --git a/ndb/tools/drop_tab.cpp b/ndb/tools/drop_tab.cpp index 70e5d85aabe..15c229cb0fb 100644 --- a/ndb/tools/drop_tab.cpp +++ b/ndb/tools/drop_tab.cpp @@ -23,6 +23,7 @@ #include <getarg.h> int main(int argc, const char** argv){ + ndb_init(); const char* _tabname = NULL; const char* _dbname = "TEST_DB"; diff --git a/ndb/tools/listTables.cpp b/ndb/tools/listTables.cpp index b9e050ab6a4..4b24929ee4b 100644 --- a/ndb/tools/listTables.cpp +++ b/ndb/tools/listTables.cpp @@ -22,7 +22,6 @@ */ #include <ndb_global.h> -#include <my_sys.h> #include <getarg.h> #include <NdbApi.hpp> @@ -167,6 +166,7 @@ const char *debug_option= 0; #endif int main(int argc, const char** argv){ + ndb_init(); int _loops = 1; const char* _tabname = NULL; const char* _dbname = "TEST_DB"; @@ -209,14 +209,12 @@ int main(int argc, const char** argv){ _tabname = argv[optind]; #ifndef DBUG_OFF - my_init(); if (debug_option) DBUG_PUSH(debug_option); #endif ndb_cluster_connection = new Ndb_cluster_connection(_connect_str); ndb = new Ndb(ndb_cluster_connection, _dbname); - ndb->useFullyQualifiedNames(!_unqualified); if (ndb->init() != 0) fatal("init"); ndb_cluster_connection->connect(); diff --git a/ndb/tools/ndbsql.cpp b/ndb/tools/ndbsql.cpp index 6af5f47f6f4..1997e4abebd 100644 --- a/ndb/tools/ndbsql.cpp +++ b/ndb/tools/ndbsql.cpp @@ -671,6 +671,7 @@ void print_help_virtual() { int main(int argc, const char** argv) { + ndb_init(); const char* usage = "Usage: ndbsql [-h] [-d dsn] [-f file] [stmt]\n-h help\n-d <database name or connect string>\n-f <file name> batch mode\nstmt single SQL statement\n"; const char* dsn = "TEST_DB"; bool helpFlg = false, batchMode = false; diff --git a/ndb/tools/select_all.cpp b/ndb/tools/select_all.cpp index eb95947fc0f..8fb8437ba5f 100644 --- a/ndb/tools/select_all.cpp +++ b/ndb/tools/select_all.cpp @@ -16,7 +16,6 @@ #include <ndb_global.h> -#include <my_sys.h> #include <NdbOut.hpp> @@ -42,6 +41,7 @@ int scanReadRecords(Ndb*, bool orderby); int main(int argc, const char** argv){ + ndb_init(); int _parallelism = 240; const char* _delimiter = "\t"; int _header = true; @@ -89,7 +89,6 @@ int main(int argc, const char** argv){ _tabname = argv[optind]; #ifndef DBUG_OFF - my_init(); if (debug_option) DBUG_PUSH(debug_option); #endif diff --git a/ndb/tools/select_count.cpp b/ndb/tools/select_count.cpp index bb7c9dea49b..6650421e637 100644 --- a/ndb/tools/select_count.cpp +++ b/ndb/tools/select_count.cpp @@ -33,6 +33,7 @@ select_count(Ndb* pNdb, const NdbDictionary::Table* pTab, UtilTransactions::ScanLock lock); int main(int argc, const char** argv){ + ndb_init(); const char* _dbname = "TEST_DB"; int _parallelism = 240; int _help = 0; diff --git a/ndb/tools/waiter.cpp b/ndb/tools/waiter.cpp index 63469c6d746..c27b46c9356 100644 --- a/ndb/tools/waiter.cpp +++ b/ndb/tools/waiter.cpp @@ -30,6 +30,7 @@ int waitClusterStatus(const char* _addr, ndb_mgm_node_status _status, unsigned int _timeout); int main(int argc, const char** argv){ + ndb_init(); const char* _hostName = NULL; int _no_contact = 0; |