diff options
Diffstat (limited to 'ndb')
197 files changed, 3895 insertions, 2455 deletions
diff --git a/ndb/examples/select_all/select_all.cpp b/ndb/examples/select_all/select_all.cpp index bd25fb60128..24bb1214bd2 100644 --- a/ndb/examples/select_all/select_all.cpp +++ b/ndb/examples/select_all/select_all.cpp @@ -98,7 +98,7 @@ void ResultSetContainer::init(NdbDictionary::Dictionary * dict, // Store all attribute names for the table for (int i = 0; i < m_cols; i++) { m_names[i] = new char[255]; - snprintf(m_names[i], 255, "%s", tab->getColumn(i)->getName()); + BaseString::snprintf(m_names[i], 255, "%s", tab->getColumn(i)->getName()); } } diff --git a/ndb/include/kernel/BlockNumbers.h b/ndb/include/kernel/BlockNumbers.h index e89a82ee0cb..cb3cc697eee 100644 --- a/ndb/include/kernel/BlockNumbers.h +++ b/ndb/include/kernel/BlockNumbers.h @@ -20,13 +20,13 @@ #include <kernel_types.h> #include <RefConvert.hpp> -// 240 +/* 240 */ #define MIN_API_BLOCK_NO 0x8000 -// 2047 +/* 2047 */ #define API_PACKED 0x07ff -// 4002 +/* 4002 */ #define API_CLUSTERMGR 0x0FA2 #define BACKUP 0xF4 diff --git a/ndb/include/kernel/GlobalSignalNumbers.h b/ndb/include/kernel/GlobalSignalNumbers.h index 88acef8c772..9413f4ef56a 100644 --- a/ndb/include/kernel/GlobalSignalNumbers.h +++ b/ndb/include/kernel/GlobalSignalNumbers.h @@ -78,7 +78,7 @@ extern const GlobalSignalNumber NO_OF_SIGNAL_NAMES; #define GSN_SCAN_NEXTREQ 28 #define GSN_SCAN_TABCONF 29 -// 30 unused +/* 30 unused */ #define GSN_SCAN_TABREF 31 #define GSN_SCAN_TABREQ 32 #define GSN_KEYINFO20 33 @@ -91,42 +91,42 @@ extern const GlobalSignalNumber NO_OF_SIGNAL_NAMES; #define GSN_TCSEIZEREF 38 #define GSN_TCSEIZEREQ 39 -// 40 unused -// 41 unused -// 42 unused -// 43 unused -// 44 unused -// 45 unused -// 46 unused -// 47 unused -// 48 unused -// 49 unused -// 50 unused -// 51 unused -// 52 unused -// 53 unused -// 54 unused -// 55 unused -// 56 unused -// 57 unused -// 58 unused -// 59 unused -// 60 unused -// 61 unused -// 62 unused -// 63 unused -// 64 unused -// 65 unused -// 66 unused +/* 40 unused */ +/* 41 unused */ +/* 42 unused */ +/* 43 unused */ +/* 44 unused */ +/* 45 unused */ +/* 46 unused */ +/* 47 unused */ +/* 48 unused */ +/* 49 unused */ +/* 50 unused */ +/* 51 unused */ +/* 52 unused */ +/* 53 unused */ +/* 54 unused */ +/* 55 unused */ +/* 56 unused */ +/* 57 unused */ +/* 58 unused */ +/* 59 unused */ +/* 60 unused */ +/* 61 unused */ +/* 62 unused */ +/* 63 unused */ +/* 64 unused */ +/* 65 unused */ +/* 66 unused */ /** * These are used only by kernel */ #define GSN_ACC_ABORTCONF 67 -// 68 unused -// 69 unused -// 70 unused +/* 68 unused */ +/* 69 unused */ +/* 70 unused */ #define GSN_ACC_ABORTREQ 71 #define GSN_ACC_CHECK_SCAN 72 #define GSN_ACC_COMMITCONF 73 @@ -172,42 +172,42 @@ extern const GlobalSignalNumber NO_OF_SIGNAL_NAMES; #define GSN_API_FAILCONF 113 #define GSN_API_FAILREQ 114 #define GSN_CNTR_START_REQ 115 -// 116 not unused +/* 116 not unused */ #define GSN_CNTR_START_REF 117 #define GSN_CNTR_START_CONF 118 #define GSN_CNTR_START_REP 119 -// 120 unused -// 121 unused -// 122 unused -// 123 unused -// 124 unused +/* 120 unused */ +/* 121 unused */ +/* 122 unused */ +/* 123 unused */ +/* 124 unused */ #define GSN_CHECK_LCP_STOP 125 -#define GSN_CLOSE_COMCONF 126 // local -#define GSN_CLOSE_COMREQ 127 // local -#define GSN_CM_ACKADD 128 // distr. -// 129 unused -#define GSN_CM_ADD 130 // distr. -// 131 unused -// 132 not unused -// 133 not unused -#define GSN_CM_HEARTBEAT 134 // distr. -// 135 unused -// 136 unused -// 137 unused -#define GSN_CM_NODEINFOCONF 138 // distr. -#define GSN_CM_NODEINFOREF 139 // distr. -#define GSN_CM_NODEINFOREQ 140 // distr. -#define GSN_CM_REGCONF 141 // distr. -#define GSN_CM_REGREF 142 // distr. -#define GSN_CM_REGREQ 143 // distr. -// 144 unused -// 145 unused -// 146 unused -#define GSN_CM_ADD_REP 147 // local -// 148 unused -// 149 unused -// 150 unused -#define GSN_CNTR_WAITREP 151 // distr. +#define GSN_CLOSE_COMCONF 126 /* local */ +#define GSN_CLOSE_COMREQ 127 /* local */ +#define GSN_CM_ACKADD 128 /* distr. */ +/* 129 unused */ +#define GSN_CM_ADD 130 /* distr. */ +/* 131 unused */ +/* 132 not unused */ +/* 133 not unused */ +#define GSN_CM_HEARTBEAT 134 /* distr. */ +/* 135 unused */ +/* 136 unused */ +/* 137 unused */ +#define GSN_CM_NODEINFOCONF 138 /* distr. */ +#define GSN_CM_NODEINFOREF 139 /* distr. */ +#define GSN_CM_NODEINFOREQ 140 /* distr. */ +#define GSN_CM_REGCONF 141 /* distr. */ +#define GSN_CM_REGREF 142 /* distr. */ +#define GSN_CM_REGREQ 143 /* distr. */ +/* 144 unused */ +/* 145 unused */ +/* 146 unused */ +#define GSN_CM_ADD_REP 147 /* local */ +/* 148 unused */ +/* 149 unused */ +/* 150 unused */ +#define GSN_CNTR_WAITREP 151 /* distr. */ #define GSN_COMMIT 152 #define GSN_COMMIT_FAILCONF 153 #define GSN_COMMIT_FAILREQ 154 @@ -220,7 +220,7 @@ extern const GlobalSignalNumber NO_OF_SIGNAL_NAMES; #define GSN_COMPLETEREQ 162 #define GSN_CONNECT_REP 163 #define GSN_CONTINUEB 164 -// 165 not unused +/* 165 not unused */ #define GSN_COPY_ACTIVECONF 166 #define GSN_COPY_ACTIVEREF 167 #define GSN_COPY_ACTIVEREQ 168 @@ -243,9 +243,9 @@ extern const GlobalSignalNumber NO_OF_SIGNAL_NAMES; #define GSN_DIADDTABCONF 185 #define GSN_DIADDTABREF 186 #define GSN_DIADDTABREQ 187 -// 188 not unused -// 189 not unused -// 190 not unused +/* 188 not unused */ +/* 189 not unused */ +/* 190 not unused */ #define GSN_DICTSTARTCONF 191 #define GSN_DICTSTARTREQ 192 @@ -301,9 +301,9 @@ extern const GlobalSignalNumber NO_OF_SIGNAL_NAMES; #define GSN_DIH_RESTARTREF 218 #define GSN_DIH_RESTARTREQ 219 -// 220 not unused -// 221 not unused -// 222 not unused +/* 220 not unused */ +/* 221 not unused */ +/* 222 not unused */ #define GSN_EMPTY_LCP_REQ 223 #define GSN_EMPTY_LCP_CONF 224 @@ -315,8 +315,8 @@ extern const GlobalSignalNumber NO_OF_SIGNAL_NAMES; #define GSN_MASTER_GCPREF 228 #define GSN_MASTER_GCPREQ 229 -// 230 not unused -// 231 not unused +/* 230 not unused */ +/* 231 not unused */ #define GSN_DIRELEASECONF 232 #define GSN_DIRELEASEREF 233 @@ -388,8 +388,8 @@ extern const GlobalSignalNumber NO_OF_SIGNAL_NAMES; #define GSN_LCP_HOLDOPREQ 299 #define GSN_SHRINKCHECK2 301 #define GSN_GET_SCHEMA_INFOREQ 302 -// 303 not unused -// 304 not unused +/* 303 not unused */ +/* 304 not unused */ #define GSN_LQH_RESTART_OP 305 #define GSN_LQH_TRANSCONF 306 #define GSN_LQH_TRANSREQ 307 @@ -421,12 +421,12 @@ extern const GlobalSignalNumber NO_OF_SIGNAL_NAMES; #define GSN_NEXT_SCANREQ 332 #define GSN_NEXTOPERATION 333 -#define GSN_READ_CONFIG_REQ 334 // new name for sizealt, local -#define GSN_READ_CONFIG_CONF 335 // new name for sizealt, local +#define GSN_READ_CONFIG_REQ 334 /* new name for sizealt, local */ +#define GSN_READ_CONFIG_CONF 335 /* new name for sizealt, local */ -// 336 unused -// 337 unused -// 338 unused +/* 336 unused */ +/* 337 unused */ +/* 338 unused */ #define GSN_OPEN_COMCONF 339 #define GSN_OPEN_COMREF 340 #define GSN_OPEN_COMREQ 341 @@ -452,7 +452,7 @@ extern const GlobalSignalNumber NO_OF_SIGNAL_NAMES; #define GSN_TUP_ALLOCREQ 360 #define GSN_TUP_DEALLOCREQ 361 -// 362 not unused +/* 362 not unused */ #define GSN_TUP_WRITELOG_REQ 363 #define GSN_LQH_WRITELOG_REQ 364 @@ -507,16 +507,16 @@ extern const GlobalSignalNumber NO_OF_SIGNAL_NAMES; #define GSN_TEST_ORD 407 #define GSN_TESTSIG 408 #define GSN_TIME_SIGNAL 409 -// 410 unused -// 411 unused -// 412 unused +/* 410 unused */ +/* 411 unused */ +/* 412 unused */ #define GSN_TUP_ABORTREQ 414 #define GSN_TUP_ADD_ATTCONF 415 #define GSN_TUP_ADD_ATTRREF 416 #define GSN_TUP_ADD_ATTRREQ 417 #define GSN_TUP_ATTRINFO 418 #define GSN_TUP_COMMITREQ 419 -// 420 unused +/* 420 unused */ #define GSN_TUP_LCPCONF 421 #define GSN_TUP_LCPREF 422 #define GSN_TUP_LCPREQ 423 @@ -553,8 +553,8 @@ extern const GlobalSignalNumber NO_OF_SIGNAL_NAMES; #define GSN_STATISTICS_CONF 454 #define GSN_START_ORD 455 -// 456 unused -// 457 unused +/* 456 unused */ +/* 457 unused */ #define GSN_EVENT_SUBSCRIBE_REQ 458 #define GSN_EVENT_SUBSCRIBE_CONF 459 @@ -576,7 +576,7 @@ extern const GlobalSignalNumber NO_OF_SIGNAL_NAMES; #define GSN_CHECKNODEGROUPSREQ 471 #define GSN_CHECKNODEGROUPSCONF 472 -// 473 unused +/* 473 unused */ #define GSN_ARBIT_PREPREQ 474 #define GSN_ARBIT_PREPCONF 475 #define GSN_ARBIT_PREPREF 476 @@ -612,7 +612,7 @@ extern const GlobalSignalNumber NO_OF_SIGNAL_NAMES; #define GSN_WAIT_GCP_REF 500 #define GSN_WAIT_GCP_CONF 501 -// 502 not used +/* 502 not used */ /** * Trigger and index signals @@ -732,7 +732,7 @@ extern const GlobalSignalNumber NO_OF_SIGNAL_NAMES; #define GSN_SUB_STOP_REQ 572 #define GSN_SUB_STOP_REF 573 #define GSN_SUB_STOP_CONF 574 -// 575 unused +/* 575 unused */ #define GSN_SUB_CREATE_REQ 576 #define GSN_SUB_CREATE_REF 577 #define GSN_SUB_CREATE_CONF 578 @@ -832,7 +832,7 @@ extern const GlobalSignalNumber NO_OF_SIGNAL_NAMES; #define GSN_GREP_REMOVE_REF 654 #define GSN_GREP_REMOVE_CONF 655 -// Start Global Replication +/* Start Global Replication */ #define GSN_GREP_REQ 656 /** @@ -891,8 +891,8 @@ extern const GlobalSignalNumber NO_OF_SIGNAL_NAMES; #define GSN_TUX_MAINT_CONF 678 #define GSN_TUX_MAINT_REF 679 -// not used 680 -// not used 681 +/* not used 680 */ +/* not used 681 */ /** * from mgmtsrvr to NDBCNTR @@ -903,10 +903,10 @@ extern const GlobalSignalNumber NO_OF_SIGNAL_NAMES; #define GSN_API_VERSION_REQ 697 #define GSN_API_VERSION_CONF 698 -// not used 686 -// not used 687 -// not used 689 -// not used 690 +/* not used 686 */ +/* not used 687 */ +/* not used 689 */ +/* not used 690 */ /** * SUMA restart protocol @@ -915,9 +915,9 @@ extern const GlobalSignalNumber NO_OF_SIGNAL_NAMES; #define GSN_SUMA_HANDOVER_REQ 692 #define GSN_SUMA_HANDOVER_CONF 693 -// not used 694 -// not used 695 -// not used 696 +/* not used 694 */ +/* not used 695 */ +/* not used 696 */ /** * GREP restart protocol diff --git a/ndb/include/kernel/LogLevel.hpp b/ndb/include/kernel/LogLevel.hpp index be0627c98a8..6cfbe44af86 100644 --- a/ndb/include/kernel/LogLevel.hpp +++ b/ndb/include/kernel/LogLevel.hpp @@ -47,6 +47,7 @@ public: LogLevel & operator= (const LogLevel &); enum EventCategory { + llInvalid = -1, llStartUp = CFG_LOGLEVEL_STARTUP - CFG_MIN_LOGLEVEL, llShutdown = CFG_LOGLEVEL_SHUTDOWN - CFG_MIN_LOGLEVEL, llStatistic = CFG_LOGLEVEL_STATISTICS - CFG_MIN_LOGLEVEL, diff --git a/ndb/include/kernel/ndb_limits.h b/ndb/include/kernel/ndb_limits.h index 9411a98f091..88fcff22da7 100644 --- a/ndb/include/kernel/ndb_limits.h +++ b/ndb/include/kernel/ndb_limits.h @@ -50,7 +50,7 @@ **/ #define MAX_TUPLES_PER_PAGE 8191 #define MAX_TUPLES_BITS 13 /* 13 bits = 8191 tuples per page */ -//#define MAX_NO_OF_TUPLEKEY 16 Not currently used +/*#define MAX_NO_OF_TUPLEKEY 16 Not currently used */ #define MAX_TABLES 1600 #define MAX_TAB_NAME_SIZE 128 #define MAX_ATTR_NAME_SIZE 32 @@ -108,13 +108,13 @@ /* * Ordered index constants. Make configurable per index later. */ -#define MAX_TTREE_NODE_SIZE 64 // total words in node -#define MAX_TTREE_PREF_SIZE 4 // words in min prefix -#define MAX_TTREE_NODE_SLACK 3 // diff between max and min occupancy +#define MAX_TTREE_NODE_SIZE 64 /* total words in node */ +#define MAX_TTREE_PREF_SIZE 4 /* words in min prefix */ +#define MAX_TTREE_NODE_SLACK 2 /* diff between max and min occupancy */ /* * Blobs. */ -#define NDB_BLOB_HEAD_SIZE 2 // sizeof(NdbBlob::Head) >> 2 +#define NDB_BLOB_HEAD_SIZE 2 /* sizeof(NdbBlob::Head) >> 2 */ #endif diff --git a/ndb/include/kernel/signaldata/ArbitSignalData.hpp b/ndb/include/kernel/signaldata/ArbitSignalData.hpp index 271b9920cd0..f255b8dcbbe 100644 --- a/ndb/include/kernel/signaldata/ArbitSignalData.hpp +++ b/ndb/include/kernel/signaldata/ArbitSignalData.hpp @@ -54,7 +54,7 @@ public: } inline void getText(char *buf, size_t buf_len) const { - snprintf(buf, buf_len, "%08x%08x", data[0], data[1]); + BaseString::snprintf(buf, buf_len, "%08x%08x", data[0], data[1]); } /* inline char* getText() const { @@ -113,19 +113,19 @@ public: static inline void getErrText(Uint32 code, char* buf, size_t buf_len) { switch (code) { case ErrTicket: - snprintf(buf, buf_len, "invalid arbitrator-ticket"); + BaseString::snprintf(buf, buf_len, "invalid arbitrator-ticket"); break; case ErrToomany: - snprintf(buf, buf_len, "too many requests"); + BaseString::snprintf(buf, buf_len, "too many requests"); break; case ErrState: - snprintf(buf, buf_len, "invalid state"); + BaseString::snprintf(buf, buf_len, "invalid state"); break; case ErrTimeout: - snprintf(buf, buf_len, "timeout"); + BaseString::snprintf(buf, buf_len, "timeout"); break; default: - snprintf(buf, buf_len, "unknown error [code=%u]", code); + BaseString::snprintf(buf, buf_len, "unknown error [code=%u]", code); break; } } diff --git a/ndb/include/kernel/signaldata/AttrInfo.hpp b/ndb/include/kernel/signaldata/AttrInfo.hpp index 18bd9b22c40..c87470db8b0 100644 --- a/ndb/include/kernel/signaldata/AttrInfo.hpp +++ b/ndb/include/kernel/signaldata/AttrInfo.hpp @@ -35,7 +35,8 @@ class AttrInfo { */ friend class Dbtc; friend class Dblqh; - + friend class NdbScanOperation; + friend bool printATTRINFO(FILE *, const Uint32 *, Uint32, Uint16); public: diff --git a/ndb/include/kernel/signaldata/DictTabInfo.hpp b/ndb/include/kernel/signaldata/DictTabInfo.hpp index a9a50f19fbc..df0ac988e6e 100644 --- a/ndb/include/kernel/signaldata/DictTabInfo.hpp +++ b/ndb/include/kernel/signaldata/DictTabInfo.hpp @@ -38,7 +38,7 @@ offsetof(x, l) } #define DTIBREAK(x) \ - { DictTabInfo::x, 0, SimpleProperties::InvalidValue, 0, 0 } + { DictTabInfo::x, 0, SimpleProperties::InvalidValue, 0, 0, 0 } class DictTabInfo { /** diff --git a/ndb/include/kernel/signaldata/DihContinueB.hpp b/ndb/include/kernel/signaldata/DihContinueB.hpp index e683b55351c..77ecf360601 100644 --- a/ndb/include/kernel/signaldata/DihContinueB.hpp +++ b/ndb/include/kernel/signaldata/DihContinueB.hpp @@ -24,7 +24,8 @@ class DihContinueB { * Sender(s)/Reciver(s) */ friend class Dbdih; - friend bool printCONTINUEB_DBDIH(FILE * output, const Uint32 * theData, Uint32 len); + friend bool printCONTINUEB_DBDIH(FILE * output, const Uint32 * theData, + Uint32 len, Uint16); private: enum Type { ZPACK_TABLE_INTO_PAGES = 1, diff --git a/ndb/include/kernel/signaldata/KeyInfo.hpp b/ndb/include/kernel/signaldata/KeyInfo.hpp index a4c698f89b2..686f3ae053d 100644 --- a/ndb/include/kernel/signaldata/KeyInfo.hpp +++ b/ndb/include/kernel/signaldata/KeyInfo.hpp @@ -26,6 +26,7 @@ class KeyInfo { friend class DbUtil; friend class NdbOperation; friend class NdbScanOperation; + friend class NdbIndexScanOperation; /** * Reciver(s) diff --git a/ndb/include/kernel/signaldata/NdbfsContinueB.hpp b/ndb/include/kernel/signaldata/NdbfsContinueB.hpp index 2d569be721f..6154e5c19b1 100644 --- a/ndb/include/kernel/signaldata/NdbfsContinueB.hpp +++ b/ndb/include/kernel/signaldata/NdbfsContinueB.hpp @@ -24,7 +24,8 @@ class NdbfsContinueB { * Sender(s)/Reciver(s) */ friend class Ndbfs; - friend bool printCONTINUEB_NDBFS(FILE * output, const Uint32 * theData, Uint32 len); + friend bool printCONTINUEB_NDBFS(FILE * output, const Uint32 * theData, + Uint32 len, Uint16); private: enum { ZSCAN_MEMORYCHANNEL_10MS_DELAY = 0, diff --git a/ndb/include/kernel/signaldata/ScanFrag.hpp b/ndb/include/kernel/signaldata/ScanFrag.hpp index d3a89b8dc25..41ea569c45d 100644 --- a/ndb/include/kernel/signaldata/ScanFrag.hpp +++ b/ndb/include/kernel/signaldata/ScanFrag.hpp @@ -34,14 +34,16 @@ class ScanFragReq { friend class Dblqh; public: STATIC_CONST( SignalLength = 12 ); - + + friend bool printSCAN_FRAGREQ(FILE *, const Uint32*, Uint32, Uint16); + public: Uint32 senderData; Uint32 resultRef; // Where to send the result Uint32 savePointId; Uint32 requestInfo; Uint32 tableId; - Uint32 fragmentNo; + Uint32 fragmentNoKeyLen; Uint32 schemaVersion; Uint32 transId1; Uint32 transId2; diff --git a/ndb/include/kernel/signaldata/ScanTab.hpp b/ndb/include/kernel/signaldata/ScanTab.hpp index 1acd7ae4736..fb5f18eae9e 100644 --- a/ndb/include/kernel/signaldata/ScanTab.hpp +++ b/ndb/include/kernel/signaldata/ScanTab.hpp @@ -55,7 +55,7 @@ private: * DATA VARIABLES */ UintR apiConnectPtr; // DATA 0 - UintR attrLen; // DATA 1 + UintR attrLenKeyLen; // DATA 1 UintR requestInfo; // DATA 2 UintR tableId; // DATA 3 UintR tableSchemaVersion; // DATA 4 @@ -74,6 +74,7 @@ private: static Uint8 getHoldLockFlag(const UintR & requestInfo); static Uint8 getReadCommittedFlag(const UintR & requestInfo); static Uint8 getRangeScanFlag(const UintR & requestInfo); + static Uint8 getKeyinfoFlag(const UintR & requestInfo); static Uint16 getScanBatch(const UintR & requestInfo); /** @@ -85,6 +86,7 @@ private: static void setHoldLockFlag(UintR & requestInfo, Uint32 flag); static void setReadCommittedFlag(UintR & requestInfo, Uint32 flag); static void setRangeScanFlag(UintR & requestInfo, Uint32 flag); + static void setKeyinfoFlag(UintR & requestInfo, Uint32 flag); static void setScanBatch(Uint32& requestInfo, Uint32 sz); }; @@ -95,12 +97,13 @@ private: l = Lock mode - 1 Bit 8 h = Hold lock mode - 1 Bit 10 c = Read Committed - 1 Bit 11 + k = Keyinfo - 1 Bit 12 x = Range Scan (TUX) - 1 Bit 15 b = Scan batch - 10 Bit 16-25 (max 1023) 1111111111222222222233 01234567890123456789012345678901 - ppppppppl hc xbbbbbbbbbb + ppppppppl hck xbbbbbbbbbb */ #define PARALLELL_SHIFT (0) @@ -112,6 +115,9 @@ private: #define HOLD_LOCK_SHIFT (10) #define HOLD_LOCK_MASK (1) +#define KEYINFO_SHIFT (12) +#define KEYINFO_MASK (1) + #define READ_COMMITTED_SHIFT (11) #define READ_COMMITTED_MASK (1) @@ -206,6 +212,20 @@ ScanTabReq::setScanBatch(Uint32 & requestInfo, Uint32 flag){ requestInfo |= (flag << SCAN_BATCH_SHIFT); } +inline +Uint8 +ScanTabReq::getKeyinfoFlag(const UintR & requestInfo){ + return (Uint8)((requestInfo >> KEYINFO_SHIFT) & KEYINFO_MASK); +} + +inline +void +ScanTabReq::setKeyinfoFlag(UintR & requestInfo, Uint32 flag){ + ASSERT_BOOL(flag, "ScanTabReq::setKeyinfoFlag"); + requestInfo |= (flag << KEYINFO_SHIFT); +} + + /** * * SENDER: Dbtc diff --git a/ndb/include/kernel/signaldata/SignalData.hpp b/ndb/include/kernel/signaldata/SignalData.hpp index 6e5748217b2..f9d3a6faa64 100644 --- a/ndb/include/kernel/signaldata/SignalData.hpp +++ b/ndb/include/kernel/signaldata/SignalData.hpp @@ -20,6 +20,7 @@ #include <ndb_global.h> #include <ndb_limits.h> #include <kernel_types.h> +#include <BaseString.hpp> #define ASSERT_BOOL(flag, message) assert(flag<=1) #define ASSERT_RANGE(value, min, max, message) \ @@ -50,4 +51,169 @@ Uint32 getTCErrorCode() { return TCErrorCode; }; \ void setTCErrorCode(Uint32 _s) { TCErrorCode = _s; }; +#define GSN_PRINT_SIGNATURE(f) bool f(FILE *, const Uint32 *, Uint32, Uint16) + +GSN_PRINT_SIGNATURE(printTCKEYREQ); +GSN_PRINT_SIGNATURE(printTCKEYCONF); +GSN_PRINT_SIGNATURE(printTCKEYREF); +GSN_PRINT_SIGNATURE(printLQHKEYREQ); +GSN_PRINT_SIGNATURE(printLQHKEYCONF); +GSN_PRINT_SIGNATURE(printLQHKEYREF); +GSN_PRINT_SIGNATURE(printTUPKEYREQ); +GSN_PRINT_SIGNATURE(printTUPKEYCONF); +GSN_PRINT_SIGNATURE(printTUPKEYREF); +GSN_PRINT_SIGNATURE(printTUPCOMMITREQ); +GSN_PRINT_SIGNATURE(printCONTINUEB); +GSN_PRINT_SIGNATURE(printFSOPENREQ); +GSN_PRINT_SIGNATURE(printFSCLOSEREQ); +GSN_PRINT_SIGNATURE(printFSREADWRITEREQ); +GSN_PRINT_SIGNATURE(printFSREADWRITEREQ); +GSN_PRINT_SIGNATURE(printFSREF); +GSN_PRINT_SIGNATURE(printFSREF); +GSN_PRINT_SIGNATURE(printFSREF); +GSN_PRINT_SIGNATURE(printFSREF); +GSN_PRINT_SIGNATURE(printFSREF); +GSN_PRINT_SIGNATURE(printFSCONF); +GSN_PRINT_SIGNATURE(printFSCONF); +GSN_PRINT_SIGNATURE(printFSCONF); +GSN_PRINT_SIGNATURE(printFSCONF); +GSN_PRINT_SIGNATURE(printFSCONF); +GSN_PRINT_SIGNATURE(printCLOSECOMREQCONF); +GSN_PRINT_SIGNATURE(printCLOSECOMREQCONF); +GSN_PRINT_SIGNATURE(printPACKED_SIGNAL); +GSN_PRINT_SIGNATURE(printPREPFAILREQREF); +GSN_PRINT_SIGNATURE(printPREPFAILREQREF); +GSN_PRINT_SIGNATURE(printALTER_TABLE_REQ); +GSN_PRINT_SIGNATURE(printALTER_TABLE_CONF); +GSN_PRINT_SIGNATURE(printALTER_TABLE_REF); +GSN_PRINT_SIGNATURE(printALTER_TAB_REQ); +GSN_PRINT_SIGNATURE(printALTER_TAB_CONF); +GSN_PRINT_SIGNATURE(printALTER_TAB_REF); +GSN_PRINT_SIGNATURE(printCREATE_TRIG_REQ); +GSN_PRINT_SIGNATURE(printCREATE_TRIG_CONF); +GSN_PRINT_SIGNATURE(printCREATE_TRIG_REF); +GSN_PRINT_SIGNATURE(printALTER_TRIG_REQ); +GSN_PRINT_SIGNATURE(printALTER_TRIG_CONF); +GSN_PRINT_SIGNATURE(printALTER_TRIG_REF); +GSN_PRINT_SIGNATURE(printDROP_TRIG_REQ); +GSN_PRINT_SIGNATURE(printDROP_TRIG_CONF); +GSN_PRINT_SIGNATURE(printDROP_TRIG_REF); +GSN_PRINT_SIGNATURE(printFIRE_TRIG_ORD); +GSN_PRINT_SIGNATURE(printTRIG_ATTRINFO); +GSN_PRINT_SIGNATURE(printCREATE_INDX_REQ); +GSN_PRINT_SIGNATURE(printCREATE_INDX_CONF); +GSN_PRINT_SIGNATURE(printCREATE_INDX_REF); +GSN_PRINT_SIGNATURE(printDROP_INDX_REQ); +GSN_PRINT_SIGNATURE(printDROP_INDX_CONF); +GSN_PRINT_SIGNATURE(printDROP_INDX_REF); +GSN_PRINT_SIGNATURE(printALTER_INDX_REQ); +GSN_PRINT_SIGNATURE(printALTER_INDX_CONF); +GSN_PRINT_SIGNATURE(printALTER_INDX_REF); +GSN_PRINT_SIGNATURE(printTCINDXREQ); +GSN_PRINT_SIGNATURE(printTCINDXCONF); +GSN_PRINT_SIGNATURE(printTCINDXREF); +GSN_PRINT_SIGNATURE(printINDXKEYINFO); +GSN_PRINT_SIGNATURE(printINDXATTRINFO); +GSN_PRINT_SIGNATURE(printFSAPPENDREQ); +GSN_PRINT_SIGNATURE(printBACKUP_REQ); +GSN_PRINT_SIGNATURE(printBACKUP_DATA); +GSN_PRINT_SIGNATURE(printBACKUP_REF); +GSN_PRINT_SIGNATURE(printBACKUP_CONF); +GSN_PRINT_SIGNATURE(printABORT_BACKUP_ORD); +GSN_PRINT_SIGNATURE(printBACKUP_ABORT_REP); +GSN_PRINT_SIGNATURE(printBACKUP_COMPLETE_REP); +GSN_PRINT_SIGNATURE(printBACKUP_NF_COMPLETE_REP); +GSN_PRINT_SIGNATURE(printDEFINE_BACKUP_REQ); +GSN_PRINT_SIGNATURE(printDEFINE_BACKUP_REF); +GSN_PRINT_SIGNATURE(printDEFINE_BACKUP_CONF); +GSN_PRINT_SIGNATURE(printSTART_BACKUP_REQ); +GSN_PRINT_SIGNATURE(printSTART_BACKUP_REF); +GSN_PRINT_SIGNATURE(printSTART_BACKUP_CONF); +GSN_PRINT_SIGNATURE(printBACKUP_FRAGMENT_REQ); +GSN_PRINT_SIGNATURE(printBACKUP_FRAGMENT_REF); +GSN_PRINT_SIGNATURE(printBACKUP_FRAGMENT_CONF); +GSN_PRINT_SIGNATURE(printSTOP_BACKUP_REQ); +GSN_PRINT_SIGNATURE(printSTOP_BACKUP_REF); +GSN_PRINT_SIGNATURE(printSTOP_BACKUP_CONF); +GSN_PRINT_SIGNATURE(printBACKUP_STATUS_REQ); +GSN_PRINT_SIGNATURE(printBACKUP_STATUS_CONF); +GSN_PRINT_SIGNATURE(printUTIL_SEQUENCE_REQ); +GSN_PRINT_SIGNATURE(printUTIL_SEQUENCE_REF); +GSN_PRINT_SIGNATURE(printUTIL_SEQUENCE_CONF); +GSN_PRINT_SIGNATURE(printUTIL_PREPARE_REQ); +GSN_PRINT_SIGNATURE(printUTIL_PREPARE_REF); +GSN_PRINT_SIGNATURE(printUTIL_PREPARE_CONF); +GSN_PRINT_SIGNATURE(printUTIL_EXECUTE_REQ); +GSN_PRINT_SIGNATURE(printUTIL_EXECUTE_REF); +GSN_PRINT_SIGNATURE(printUTIL_EXECUTE_CONF); +GSN_PRINT_SIGNATURE(printSCANTABREQ); +GSN_PRINT_SIGNATURE(printSCANTABCONF); +GSN_PRINT_SIGNATURE(printSCANTABREF); +GSN_PRINT_SIGNATURE(printSCANNEXTREQ); +GSN_PRINT_SIGNATURE(printLQH_FRAG_REQ); +GSN_PRINT_SIGNATURE(printLQH_FRAG_REF); +GSN_PRINT_SIGNATURE(printLQH_FRAG_CONF); +GSN_PRINT_SIGNATURE(printPREP_DROP_TAB_REQ); +GSN_PRINT_SIGNATURE(printPREP_DROP_TAB_REF); +GSN_PRINT_SIGNATURE(printPREP_DROP_TAB_CONF); +GSN_PRINT_SIGNATURE(printDROP_TAB_REQ); +GSN_PRINT_SIGNATURE(printDROP_TAB_REF); +GSN_PRINT_SIGNATURE(printDROP_TAB_CONF); +GSN_PRINT_SIGNATURE(printLCP_FRAG_ORD); +GSN_PRINT_SIGNATURE(printLCP_FRAG_REP); +GSN_PRINT_SIGNATURE(printLCP_COMPLETE_REP); +GSN_PRINT_SIGNATURE(printSTART_LCP_REQ); +GSN_PRINT_SIGNATURE(printSTART_LCP_CONF); +GSN_PRINT_SIGNATURE(printMASTER_LCP_REQ); +GSN_PRINT_SIGNATURE(printMASTER_LCP_REF); +GSN_PRINT_SIGNATURE(printMASTER_LCP_CONF); +GSN_PRINT_SIGNATURE(printCOPY_GCI_REQ); +GSN_PRINT_SIGNATURE(printSYSTEM_ERROR); +GSN_PRINT_SIGNATURE(printSTART_REC_REQ); +GSN_PRINT_SIGNATURE(printSTART_REC_CONF); +GSN_PRINT_SIGNATURE(printNF_COMPLETE_REP); +GSN_PRINT_SIGNATURE(printSIGNAL_DROPPED_REP); +GSN_PRINT_SIGNATURE(printFAIL_REP); +GSN_PRINT_SIGNATURE(printDISCONNECT_REP); +GSN_PRINT_SIGNATURE(printSUB_CREATE_REQ); +GSN_PRINT_SIGNATURE(printSUB_CREATE_CONF); +GSN_PRINT_SIGNATURE(printSUB_START_REQ); +GSN_PRINT_SIGNATURE(printSUB_START_REF); +GSN_PRINT_SIGNATURE(printSUB_START_CONF); +GSN_PRINT_SIGNATURE(printSUB_SYNC_REQ); +GSN_PRINT_SIGNATURE(printSUB_SYNC_REF); +GSN_PRINT_SIGNATURE(printSUB_SYNC_CONF); +GSN_PRINT_SIGNATURE(printSUB_META_DATA); +GSN_PRINT_SIGNATURE(printSUB_TABLE_DATA); +GSN_PRINT_SIGNATURE(printSUB_SYNC_CONTINUE_REQ); +GSN_PRINT_SIGNATURE(printSUB_SYNC_CONTINUE_REF); +GSN_PRINT_SIGNATURE(printSUB_SYNC_CONTINUE_CONF); +GSN_PRINT_SIGNATURE(printSUB_GCP_COMPLETE_REP); +GSN_PRINT_SIGNATURE(printCREATE_FRAGMENTATION_REQ); +GSN_PRINT_SIGNATURE(printCREATE_FRAGMENTATION_REF); +GSN_PRINT_SIGNATURE(printCREATE_FRAGMENTATION_CONF); +GSN_PRINT_SIGNATURE(printUTIL_CREATE_LOCK_REQ); +GSN_PRINT_SIGNATURE(printUTIL_CREATE_LOCK_REF); +GSN_PRINT_SIGNATURE(printUTIL_CREATE_LOCK_CONF); +GSN_PRINT_SIGNATURE(printUTIL_DESTROY_LOCK_REQ); +GSN_PRINT_SIGNATURE(printUTIL_DESTROY_LOCK_REF); +GSN_PRINT_SIGNATURE(printUTIL_DESTROY_LOCK_CONF); +GSN_PRINT_SIGNATURE(printUTIL_LOCK_REQ); +GSN_PRINT_SIGNATURE(printUTIL_LOCK_REF); +GSN_PRINT_SIGNATURE(printUTIL_LOCK_CONF); +GSN_PRINT_SIGNATURE(printUTIL_UNLOCK_REQ); +GSN_PRINT_SIGNATURE(printUTIL_UNLOCK_REF); +GSN_PRINT_SIGNATURE(printUTIL_UNLOCK_CONF); +GSN_PRINT_SIGNATURE(printCNTR_START_REQ); +GSN_PRINT_SIGNATURE(printCNTR_START_REF); +GSN_PRINT_SIGNATURE(printCNTR_START_CONF); +GSN_PRINT_SIGNATURE(printREAD_NODES_CONF); +GSN_PRINT_SIGNATURE(printTUX_MAINT_REQ); +GSN_PRINT_SIGNATURE(printACC_LOCKREQ); +GSN_PRINT_SIGNATURE(printLQH_TRANSCONF); +GSN_PRINT_SIGNATURE(printSCAN_FRAGREQ); + +GSN_PRINT_SIGNATURE(printCONTINUEB_NDBFS); +GSN_PRINT_SIGNATURE(printCONTINUEB_DBDIH); + #endif diff --git a/ndb/include/kernel/signaldata/TcContinueB.hpp b/ndb/include/kernel/signaldata/TcContinueB.hpp index 7a093b457e8..85213791b2a 100644 --- a/ndb/include/kernel/signaldata/TcContinueB.hpp +++ b/ndb/include/kernel/signaldata/TcContinueB.hpp @@ -42,7 +42,9 @@ private: ZWAIT_ABORT_ALL = 14, ZCHECK_SCAN_ACTIVE_FAILED_LQH = 15, CHECK_WAIT_DROP_TAB_FAILED_LQH = 16, - TRIGGER_PENDING = 17 + TRIGGER_PENDING = 17, + + DelayTCKEYCONF = 18 }; }; diff --git a/ndb/include/kernel/signaldata/TcKeyConf.hpp b/ndb/include/kernel/signaldata/TcKeyConf.hpp index 27ff344f793..277872b990b 100644 --- a/ndb/include/kernel/signaldata/TcKeyConf.hpp +++ b/ndb/include/kernel/signaldata/TcKeyConf.hpp @@ -47,7 +47,8 @@ public: */ STATIC_CONST( StaticLength = 5 ); STATIC_CONST( OperationLength = 2 ); - + STATIC_CONST( SimpleReadBit = (((Uint32)1) << 31) ); + private: /** diff --git a/ndb/include/kernel/signaldata/TuxBound.hpp b/ndb/include/kernel/signaldata/TuxBound.hpp index 1f256150573..87ce3c3c098 100644 --- a/ndb/include/kernel/signaldata/TuxBound.hpp +++ b/ndb/include/kernel/signaldata/TuxBound.hpp @@ -48,7 +48,6 @@ private: Uint32 tuxScanPtrI; /* * Number of words of bound info included after fixed signal data. - * Starts with 5 unused words (word 0 is length used by LQH). */ Uint32 boundAiLength; }; diff --git a/ndb/include/kernel/signaldata/UpgradeStartup.hpp b/ndb/include/kernel/signaldata/UpgradeStartup.hpp index badc7ca0e4d..a4450221c59 100644 --- a/ndb/include/kernel/signaldata/UpgradeStartup.hpp +++ b/ndb/include/kernel/signaldata/UpgradeStartup.hpp @@ -1,6 +1,8 @@ #ifndef NDB_UPGRADE_STARTUP #define NDB_UPGRADE_STARTUP +class Ndbcntr; + struct UpgradeStartup { static void installEXEC(SimulatedBlock*); diff --git a/ndb/include/kernel/trigger_definitions.h b/ndb/include/kernel/trigger_definitions.h index 439d65c6c30..7ce74877de4 100644 --- a/ndb/include/kernel/trigger_definitions.h +++ b/ndb/include/kernel/trigger_definitions.h @@ -47,11 +47,11 @@ struct TriggerType { struct TriggerActionTime { enum Value { - TA_BEFORE = 0, // Immediate, before operation - TA_AFTER = 1, // Immediate, after operation - TA_DEFERRED = 2, // Before commit - TA_DETACHED = 3, // After commit in a separate transaction, NYI - TA_CUSTOM = 4 // Hardcoded per TriggerType + TA_BEFORE = 0, /* Immediate, before operation */ + TA_AFTER = 1, /* Immediate, after operation */ + TA_DEFERRED = 2, /* Before commit */ + TA_DETACHED = 3, /* After commit in a separate transaction, NYI */ + TA_CUSTOM = 4 /* Hardcoded per TriggerType */ }; }; @@ -60,7 +60,7 @@ struct TriggerEvent { TE_INSERT = 0, TE_DELETE = 1, TE_UPDATE = 2, - TE_CUSTOM = 3 // Hardcoded per TriggerType + TE_CUSTOM = 3 /* Hardcoded per TriggerType */ }; }; diff --git a/ndb/include/mgmapi/mgmapi.h b/ndb/include/mgmapi/mgmapi.h index 44307c3e73c..6dcf58b44e2 100644 --- a/ndb/include/mgmapi/mgmapi.h +++ b/ndb/include/mgmapi/mgmapi.h @@ -64,32 +64,32 @@ extern "C" { * NDB Cluster node types */ enum ndb_mgm_node_type { - NDB_MGM_NODE_TYPE_UNKNOWN = -1, /*/< Node type not known*/ - NDB_MGM_NODE_TYPE_API = NODE_TYPE_API, /*/< An application node (API)*/ - NDB_MGM_NODE_TYPE_NDB = NODE_TYPE_DB, /*/< A database node (DB)*/ - NDB_MGM_NODE_TYPE_MGM = NODE_TYPE_MGM, /*/< A management server node (MGM)*/ - NDB_MGM_NODE_TYPE_REP = NODE_TYPE_REP, ///< A replication node - - NDB_MGM_NODE_TYPE_MIN = 0, /*/< Min valid value*/ - NDB_MGM_NODE_TYPE_MAX = 3 /*/< Max valid value*/ + NDB_MGM_NODE_TYPE_UNKNOWN = -1, /*< Node type not known*/ + NDB_MGM_NODE_TYPE_API = NODE_TYPE_API,/*< An application node (API)*/ + NDB_MGM_NODE_TYPE_NDB = NODE_TYPE_DB, /*< A database node (DB)*/ + NDB_MGM_NODE_TYPE_MGM = NODE_TYPE_MGM,/*< A mgmt server node (MGM)*/ + NDB_MGM_NODE_TYPE_REP = NODE_TYPE_REP,/*< A replication node */ + + NDB_MGM_NODE_TYPE_MIN = 0, /*< Min valid value*/ + NDB_MGM_NODE_TYPE_MAX = 3 /*< Max valid value*/ }; /** * Database node status */ enum ndb_mgm_node_status { - NDB_MGM_NODE_STATUS_UNKNOWN = 0, ///< Node status not known - NDB_MGM_NODE_STATUS_NO_CONTACT = 1, ///< No contact with node - NDB_MGM_NODE_STATUS_NOT_STARTED = 2, ///< Has not run starting protocol - NDB_MGM_NODE_STATUS_STARTING = 3, ///< Is running starting protocol - NDB_MGM_NODE_STATUS_STARTED = 4, ///< Running - NDB_MGM_NODE_STATUS_SHUTTING_DOWN = 5, ///< Is shutting down - NDB_MGM_NODE_STATUS_RESTARTING = 6, ///< Is restarting - NDB_MGM_NODE_STATUS_SINGLEUSER = 7, ///< Maintenance mode - NDB_MGM_NODE_STATUS_RESUME = 8, ///< Resume mode - - NDB_MGM_NODE_STATUS_MIN = 0, ///< Min valid value - NDB_MGM_NODE_STATUS_MAX = 6 ///< Max valid value + NDB_MGM_NODE_STATUS_UNKNOWN = 0, /*< Node status not known*/ + NDB_MGM_NODE_STATUS_NO_CONTACT = 1, /*< No contact with node*/ + NDB_MGM_NODE_STATUS_NOT_STARTED = 2, /*< Has not run starting protocol*/ + NDB_MGM_NODE_STATUS_STARTING = 3, /*< Is running starting protocol*/ + NDB_MGM_NODE_STATUS_STARTED = 4, /*< Running*/ + NDB_MGM_NODE_STATUS_SHUTTING_DOWN = 5, /*< Is shutting down*/ + NDB_MGM_NODE_STATUS_RESTARTING = 6, /*< Is restarting*/ + NDB_MGM_NODE_STATUS_SINGLEUSER = 7, /*< Maintenance mode*/ + NDB_MGM_NODE_STATUS_RESUME = 8, /*< Resume mode*/ + + NDB_MGM_NODE_STATUS_MIN = 0, /*< Min valid value*/ + NDB_MGM_NODE_STATUS_MAX = 6 /*< Max valid value*/ }; /** @@ -122,7 +122,10 @@ extern "C" { /* Service errors - Single User Mode */ NDB_MGM_COULD_NOT_ENTER_SINGLE_USER_MODE = 4001, - NDB_MGM_COULD_NOT_EXIT_SINGLE_USER_MODE = 4002 + NDB_MGM_COULD_NOT_EXIT_SINGLE_USER_MODE = 4002, + + /* Usage errors */ + NDB_MGM_USAGE_ERROR = 5001 }; struct Ndb_Mgm_Error_Msg { @@ -158,7 +161,11 @@ extern "C" { { NDB_MGM_COULD_NOT_ENTER_SINGLE_USER_MODE, "Could not enter single user mode" }, { NDB_MGM_COULD_NOT_EXIT_SINGLE_USER_MODE, - "Could not exit single user mode" } + "Could not exit single user mode" }, + + /* Usage errors */ + { NDB_MGM_USAGE_ERROR, + "Usage error" } }; const int ndb_mgm_noOfErrorMsgs = @@ -168,24 +175,27 @@ extern "C" { * Structure returned by ndb_mgm_get_status */ struct ndb_mgm_node_state { - int node_id; ///< NDB Cluster node id - enum ndb_mgm_node_type node_type; ///< Type of NDB Cluster node - enum ndb_mgm_node_status node_status; ///< State of node - int start_phase; ///< Start phase. - ///< @note Start phase is only - ///< valid if - ///< node_type is - ///< NDB_MGM_NODE_TYPE_NDB and - ///< node_status is - ///< NDB_MGM_NODE_STATUS_STARTING - int dynamic_id; ///< Id for heartbeats and - ///< master take-over - ///< (only valid for DB nodes) - int node_group; ///< Node group of node - ///< (only valid for DB nodes) - int version; ///< Internal version number - int connect_count; ///< No of times node has connected - ///< or disconnected to the mgm srv + int node_id; /*< NDB Cluster node id*/ + enum ndb_mgm_node_type node_type; /*< Type of NDB Cluster node*/ + enum ndb_mgm_node_status node_status; /*< State of node*/ + int start_phase; /*< Start phase. + *< @note Start phase is only + *< valid if + *< node_type is + *< NDB_MGM_NODE_TYPE_NDB and + *< node_status is + *< NDB_MGM_NODE_STATUS_STARTING + */ + int dynamic_id; /*< Id for heartbeats and + *< master take-over + *< (only valid for DB nodes) + */ + int node_group; /*< Node group of node + *< (only valid for DB nodes)*/ + 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]; }; @@ -193,9 +203,10 @@ extern "C" { * Cluster status */ struct ndb_mgm_cluster_state { - int no_of_nodes; ///< No of entries in the - ///< node_states array - struct ndb_mgm_node_state ///< An array with node_states + int no_of_nodes; /*< No of entries in the + *< node_states array + */ + struct ndb_mgm_node_state /*< An array with node_states*/ node_states[1]; const char *hostname; }; @@ -204,17 +215,18 @@ extern "C" { * Default reply from the server */ struct ndb_mgm_reply { - int return_code; ///< 0 if successful, - ///< otherwise error code. - char message[256]; ///< Error or reply message. + int return_code; /*< 0 if successful, + *< otherwise error code. + */ + char message[256]; /*< Error or reply message.*/ }; /** * Default information types */ enum ndb_mgm_info { - NDB_MGM_INFO_CLUSTER, ///< ? - NDB_MGM_INFO_CLUSTERLOG ///< Cluster log + NDB_MGM_INFO_CLUSTER, /*< ?*/ + NDB_MGM_INFO_CLUSTERLOG /*< Cluster log*/ }; /** @@ -222,39 +234,47 @@ extern "C" { * (Used only in the development of NDB Cluster.) */ enum ndb_mgm_signal_log_mode { - NDB_MGM_SIGNAL_LOG_MODE_IN, ///< Log receiving signals - NDB_MGM_SIGNAL_LOG_MODE_OUT, ///< Log sending signals - NDB_MGM_SIGNAL_LOG_MODE_INOUT, ///< Log both sending/receiving - NDB_MGM_SIGNAL_LOG_MODE_OFF ///< Log off + NDB_MGM_SIGNAL_LOG_MODE_IN, /*< Log receiving signals */ + NDB_MGM_SIGNAL_LOG_MODE_OUT, /*< Log sending signals*/ + NDB_MGM_SIGNAL_LOG_MODE_INOUT, /*< Log both sending/receiving*/ + NDB_MGM_SIGNAL_LOG_MODE_OFF /*< Log off*/ }; /** * Log severities (used to filter the cluster log) */ enum ndb_mgm_clusterlog_level { - NDB_MGM_CLUSTERLOG_OFF = 0, ///< Cluster log off - NDB_MGM_CLUSTERLOG_DEBUG = 1, ///< Used in NDB Cluster - ///< developement - NDB_MGM_CLUSTERLOG_INFO = 2, ///< Informational messages - NDB_MGM_CLUSTERLOG_WARNING = 3, ///< Conditions that are not - ///< error condition, but - ///< might require handling - NDB_MGM_CLUSTERLOG_ERROR = 4, ///< Conditions that should be - ///< corrected - NDB_MGM_CLUSTERLOG_CRITICAL = 5, ///< Critical conditions, like - ///< device errors or out of - ///< resources - NDB_MGM_CLUSTERLOG_ALERT = 6, ///< A condition that should be - ///< corrected immediately, - ///< such as a corrupted system - NDB_MGM_CLUSTERLOG_ALL = 7 ///< All severities on + NDB_MGM_CLUSTERLOG_OFF = 0, /*< Cluster log off*/ + NDB_MGM_CLUSTERLOG_DEBUG = 1, /*< Used in NDB Cluster + *< developement + */ + NDB_MGM_CLUSTERLOG_INFO = 2, /*< Informational messages*/ + NDB_MGM_CLUSTERLOG_WARNING = 3, /*< Conditions that are not + *< error condition, but + *< might require handling + */ + NDB_MGM_CLUSTERLOG_ERROR = 4, /*< Conditions that should be + *< corrected + */ + NDB_MGM_CLUSTERLOG_CRITICAL = 5, /*< Critical conditions, like + *< device errors or out of + *< resources + */ + NDB_MGM_CLUSTERLOG_ALERT = 6, /*< A condition that should be + *< corrected immediately, + *< such as a corrupted system + */ + NDB_MGM_CLUSTERLOG_ALL = 7 /*< All severities on*/ }; /** * Log categories */ enum ndb_mgm_event_category { - NDB_MGM_ILLEGAL_EVENT_CATEGORY = -1, ///< Invalid + /** + * Invalid + */ + NDB_MGM_ILLEGAL_EVENT_CATEGORY = -1, /** * Events during all kinds of startups */ diff --git a/ndb/include/mgmcommon/LocalConfig.hpp b/ndb/include/mgmcommon/LocalConfig.hpp index c741b35f482..9ceeffdba36 100644 --- a/ndb/include/mgmcommon/LocalConfig.hpp +++ b/ndb/include/mgmcommon/LocalConfig.hpp @@ -53,14 +53,14 @@ struct LocalConfig { void printUsage() const; void setError(int lineNumber, const char * _msg); - bool readConnectString(const char *); + bool readConnectString(const char *, const char *info); bool readFile(const char * file, bool &fopenError); bool parseLine(char * line, int lineNumber); bool parseNodeId(const char *buf); bool parseHostName(const char *buf); bool parseFileName(const char *buf); - bool parseString(const char *buf, char *line); + bool parseString(const char *buf, BaseString &err); }; #endif // LocalConfig_H diff --git a/ndb/include/ndb_global.h b/ndb/include/ndb_global.h index 3ce37a2edee..c128323241a 100644 --- a/ndb/include/ndb_global.h +++ b/ndb/include/ndb_global.h @@ -13,6 +13,9 @@ #undef NDB_WIN32 #endif +#ifdef _AIX +#undef _H_STRINGS +#endif #include <m_string.h> #include <m_ctype.h> #include <ndb_types.h> diff --git a/ndb/include/ndb_types.h b/ndb/include/ndb_types.h index 87ebd3d6c6b..a2988dbae78 100644 --- a/ndb/include/ndb_types.h +++ b/ndb/include/ndb_types.h @@ -33,7 +33,7 @@ typedef unsigned int UintR; #ifdef __SIZE_TYPE__ typedef __SIZE_TYPE__ UintPtr; #else -#include <my_global.h> +#include <ndb_global.h> #ifdef HAVE_STDINT_H #include <stdint.h> #endif diff --git a/ndb/include/ndbapi/Ndb.hpp b/ndb/include/ndbapi/Ndb.hpp index 550d0c0931a..5ec09269695 100644 --- a/ndb/include/ndbapi/Ndb.hpp +++ b/ndb/include/ndbapi/Ndb.hpp @@ -881,6 +881,7 @@ class Table; class BaseString; class NdbEventOperation; class NdbBlob; +class NdbReceiver; typedef void (* NdbEventCallback)(NdbEventOperation*, Ndb*, void*); @@ -1612,7 +1613,6 @@ private: char prefixName[NDB_MAX_INTERNAL_TABLE_LENGTH]; char * prefixEnd; - //Table* theTable; // The table object class NdbImpl * theImpl; class NdbDictionaryImpl* theDictionary; class NdbGlobalEventBufferHandle* theGlobalEventBufferHandle; @@ -1698,10 +1698,13 @@ private: NdbApiSignal* theCommitAckSignal; + +#ifdef POORMANSPURIFY int cfreeSignals; int cnewSignals; int cgetSignals; int creleaseSignals; +#endif static void executeMessage(void*, NdbApiSignal *, struct LinearSectionPtr ptr[3]); diff --git a/ndb/include/ndbapi/NdbConnection.hpp b/ndb/include/ndbapi/NdbConnection.hpp index ef4972f205b..92b940e96f7 100644 --- a/ndb/include/ndbapi/NdbConnection.hpp +++ b/ndb/include/ndbapi/NdbConnection.hpp @@ -526,9 +526,8 @@ private: int sendCOMMIT(); // Send a TC_COMMITREQ signal; void setGCI(int GCI); // Set the global checkpoint identity - int OpCompleteFailure(); // Operation Completed with success - int OpCompleteSuccess(); // Operation Completed with success - + int OpCompleteFailure(Uint8 abortoption); + int OpCompleteSuccess(); void CompletedOperations(); // Move active ops to list of completed void OpSent(); // Operation Sent with success @@ -649,6 +648,18 @@ private: Uint32 theNodeSequence; // The sequence no of the db node bool theReleaseOnClose; + /** + * handle transaction spanning + * multiple TC/db nodes + * + * 1) Bitmask with used nodes + * 2) Bitmask with nodes failed during op + */ + Uint32 m_db_nodes[2]; + Uint32 m_failed_db_nodes[2]; + + int report_node_failure(Uint32 id); + // Scan operations bool m_waitForReply; NdbIndexScanOperation* m_theFirstScanOperation; @@ -673,6 +684,9 @@ private: void printState(); #endif bool checkState_TransId(const Uint32 * transId) const; + + void remove_list(NdbOperation*& head, NdbOperation*); + void define_scan_op(NdbIndexScanOperation*); }; inline diff --git a/ndb/include/ndbapi/NdbIndexScanOperation.hpp b/ndb/include/ndbapi/NdbIndexScanOperation.hpp index 82aed04a9fc..66b3fc9d43b 100644 --- a/ndb/include/ndbapi/NdbIndexScanOperation.hpp +++ b/ndb/include/ndbapi/NdbIndexScanOperation.hpp @@ -56,27 +56,11 @@ public: } /** - * @name Define Range Scan - * - * A range scan is a scan on an ordered index. The operation is on - * the index table but tuples are returned from the primary table. - * The index contains all tuples where at least one index key has not - * null value. - * - * A range scan is currently opened via a normal open scan method. - * Bounds can be defined for each index key. After setting bounds, - * usual scan methods can be used (get value, interpreter, take over). - * These operate on the primary table. - * - * @{ - */ - - /** * Type of ordered index key bound. The values (0-4) will not change * and can be used explicitly (e.g. they could be computed). */ enum BoundType { - BoundLE = 0, ///< lower bound, + BoundLE = 0, ///< lower bound BoundLT = 1, ///< lower bound, strict BoundGE = 2, ///< upper bound BoundGT = 3, ///< upper bound, strict @@ -86,20 +70,28 @@ public: /** * Define bound on index key in range scan. * - * Each index key can have lower and/or upper bound, or can be set - * equal to a value. The bounds can be defined in any order but - * a duplicate definition is an error. + * Each index key can have lower and/or upper bound. Setting the key + * equal to a value defines both upper and lower bounds. The bounds + * can be defined in any order. Conflicting definitions is an error. + * + * For equality, it is better to use BoundEQ instead of the equivalent + * pair of BoundLE and BoundGE. This is especially true when table + * distribution key is an initial part of the index key. + * + * The sets of lower and upper bounds must be on initial sequences of + * index keys. All but possibly the last bound must be non-strict. + * So "a >= 2 and b > 3" is ok but "a > 2 and b >= 3" is not. * - * The bounds must specify a single range i.e. they are on an initial - * sequence of index keys and the condition is equality for all but - * (at most) the last key which has a lower and/or upper bound. + * The scan may currently return tuples for which the bounds are not + * satisfied. For example, "a <= 2 and b <= 3" scans the index up to + * (a=2, b=3) but also returns any (a=1, b=4). * * NULL is treated like a normal value which is less than any not-NULL - * value and equal to another NULL value. To search for NULL use + * value and equal to another NULL value. To compare against NULL use * setBound with null pointer (0). * - * An index stores also all-NULL keys (this may become optional). - * Doing index scan with empty bound set returns all table tuples. + * An index stores also all-NULL keys. Doing index scan with empty + * bound set returns all table tuples. * * @param attrName Attribute name, alternatively: * @param anAttrId Index column id (starting from 0) @@ -117,14 +109,19 @@ public: */ int setBound(Uint32 anAttrId, int type, const void* aValue, Uint32 len = 0); - /** @} *********************************************************************/ + /** + * Reset bounds and put operation in list that will be + * sent on next execute + */ + int reset_bounds(); + bool getSorted() const { return m_ordered; } private: NdbIndexScanOperation(Ndb* aNdb); virtual ~NdbIndexScanOperation(); int setBound(const NdbColumnImpl*, int type, const void* aValue, Uint32 len); - int saveBoundATTRINFO(); + int insertBOUNDS(Uint32 * data, Uint32 sz); virtual int equal_impl(const NdbColumnImpl*, const char*, Uint32); virtual NdbRecAttr* getValue_impl(const NdbColumnImpl*, char*); diff --git a/ndb/include/ndbapi/NdbOperation.hpp b/ndb/include/ndbapi/NdbOperation.hpp index a8bd8b9bfea..8e0294e41e6 100644 --- a/ndb/include/ndbapi/NdbOperation.hpp +++ b/ndb/include/ndbapi/NdbOperation.hpp @@ -717,6 +717,8 @@ public: NotDefined ///< Internal for debugging }; + LockMode getLockMode() const { return theLockMode; } + protected: /****************************************************************************** * These are the methods used to create and delete the NdbOperation objects. @@ -749,7 +751,6 @@ protected: FinalGetValue, SubroutineExec, SubroutineEnd, - SetBound, WaitResponse, WaitCommitResponse, Finished, @@ -786,11 +787,6 @@ protected: int receiveTCKEYREF(NdbApiSignal*); - - int receiveTRANSID_AI(const Uint32* aDataPtr, Uint32 aDataLength); - int receiveREAD_CONF(const Uint32* aDataPtr, Uint32 aDataLength); - - int checkMagicNumber(bool b = true); // Verify correct object int checkState_TransId(NdbApiSignal* aSignal); @@ -814,8 +810,6 @@ protected: int branch_col_null(Uint32 type, Uint32 col, Uint32 Label); // Handle ATTRINFO signals - int receiveREAD_AI(Uint32* aDataPtr, Uint32 aLength); - int insertATTRINFO(Uint32 aData); int insertATTRINFOloop(const Uint32* aDataPtr, Uint32 aLength); @@ -894,7 +888,7 @@ protected: // currently defined OperationType theOperationType; // Read Request, Update Req...... - Uint8 theLockMode; // Can be set to WRITE if read operation + LockMode theLockMode; // Can be set to WRITE if read operation OperationStatus theStatus; // The status of the operation. Uint32 theMagicNumber; // Magic number to verify that object // is correct @@ -921,9 +915,6 @@ protected: Uint16 m_keyInfoGSN; Uint16 m_attrInfoGSN; - // saveBoundATTRINFO() moves ATTRINFO here when setBound() is ready - NdbApiSignal* theBoundATTRINFO; - Uint32 theTotalBoundAI_Len; // Blobs in this operation NdbBlob* theBlobList; diff --git a/ndb/include/ndbapi/NdbReceiver.hpp b/ndb/include/ndbapi/NdbReceiver.hpp index b7f73bb618d..b95313db274 100644 --- a/ndb/include/ndbapi/NdbReceiver.hpp +++ b/ndb/include/ndbapi/NdbReceiver.hpp @@ -19,8 +19,11 @@ #ifndef DOXYGEN_SHOULD_SKIP_INTERNAL // Not part of public interface #include <ndb_types.h> +#include <ndb_global.h> class Ndb; +class NdbConnection; + class NdbReceiver { friend class Ndb; @@ -59,6 +62,7 @@ public: inline void next(NdbReceiver* next) { m_next = next;} inline NdbReceiver* next() { return m_next; } + void setErrorCode(int); private: Uint32 theMagicNumber; Ndb* m_ndb; @@ -127,7 +131,8 @@ int NdbReceiver::execTCOPCONF(Uint32 len){ Uint32 tmp = m_received_result_length; m_expected_result_length = len; - return (tmp == len ? 1 : 0); + assert(!(tmp && !len)); + return ((bool)len ^ (bool)tmp ? 0 : 1); } inline diff --git a/ndb/include/ndbapi/NdbResultSet.hpp b/ndb/include/ndbapi/NdbResultSet.hpp index 483e08179c0..478daf8aad2 100644 --- a/ndb/include/ndbapi/NdbResultSet.hpp +++ b/ndb/include/ndbapi/NdbResultSet.hpp @@ -138,7 +138,11 @@ public: */ int deleteTuple(); int deleteTuple(NdbConnection* takeOverTransaction); - + + /** + * Get underlying operation + */ + NdbOperation* getOperation(); private: NdbResultSet(NdbScanOperation*); @@ -149,4 +153,10 @@ private: NdbScanOperation* m_operation; }; +inline +NdbOperation* +NdbResultSet::getOperation(){ + return m_operation; +} + #endif diff --git a/ndb/include/ndbapi/NdbScanOperation.hpp b/ndb/include/ndbapi/NdbScanOperation.hpp index e8a4408469c..2e4d173ac75 100644 --- a/ndb/include/ndbapi/NdbScanOperation.hpp +++ b/ndb/include/ndbapi/NdbScanOperation.hpp @@ -32,6 +32,7 @@ #include <NdbOperation.hpp> class NdbBlob; +class NdbResultSet; /** * @class NdbScanOperation @@ -87,12 +88,13 @@ protected: CursorType m_cursor_type; NdbScanOperation(Ndb* aNdb); - ~NdbScanOperation(); + virtual ~NdbScanOperation(); int nextResult(bool fetchAllowed = true); virtual void release(); void closeScan(); + int close_impl(class TransporterFacade*); // Overloaded methods from NdbCursorOperation int executeCursor(int ProcessorId); @@ -119,6 +121,7 @@ protected: int prepareSendScan(Uint32 TC_ConnectPtr, Uint64 TransactionId); int fix_receivers(Uint32 parallel); + void reset_receivers(Uint32 parallel, Uint32 ordered); Uint32* m_array; // containing all arrays below Uint32 m_allocated_receivers; NdbReceiver** m_receivers; // All receivers diff --git a/ndb/include/portlib/NdbCondition.h b/ndb/include/portlib/NdbCondition.h index fb1f2fcd69e..3d959a0db41 100644 --- a/ndb/include/portlib/NdbCondition.h +++ b/ndb/include/portlib/NdbCondition.h @@ -26,21 +26,21 @@ extern "C" { struct NdbCondition; -/* -// Create a condition -// -// * returnvalue: pointer to the condition structure -*/ +/** + * Create a condition + * + * returnvalue: pointer to the condition structure + */ struct NdbCondition* NdbCondition_Create(void); -/* -// Wait for a condition, allows a thread to wait for -// a condition and atomically releases the associated mutex. -// -// * p_cond: pointer to the condition structure -// * p_mutex: pointer to the mutex structure -// * returnvalue: 0 = succeeded, 1 = failed -*/ +/** + * Wait for a condition, allows a thread to wait for + * a condition and atomically releases the associated mutex. + * + * p_cond: pointer to the condition structure + * p_mutex: pointer to the mutex structure + * returnvalue: 0 = succeeded, 1 = failed + */ int NdbCondition_Wait(struct NdbCondition* p_cond, NdbMutex* p_mutex); @@ -60,29 +60,29 @@ NdbCondition_WaitTimeout(struct NdbCondition* p_cond, int msec); -/* -// Signal a condition -// -// * p_cond: pointer to the condition structure -// * returnvalue: 0 = succeeded, 1 = failed -*/ +/** + * Signal a condition + * + * p_cond: pointer to the condition structure + * returnvalue: 0 = succeeded, 1 = failed + */ int NdbCondition_Signal(struct NdbCondition* p_cond); -/* -// Broadcast a condition -// -// * p_cond: pointer to the condition structure -// * returnvalue: 0 = succeeded, 1 = failed -*/ +/** + * Broadcast a condition + * + * p_cond: pointer to the condition structure + * returnvalue: 0 = succeeded, 1 = failed + */ int NdbCondition_Broadcast(struct NdbCondition* p_cond); -/* -// Destroy a condition -// -// * p_cond: pointer to the condition structure -// * returnvalue: 0 = succeeded, 1 = failed -*/ +/** + * Destroy a condition + * + * p_cond: pointer to the condition structure + * returnvalue: 0 = succeeded, 1 = failed + */ int NdbCondition_Destroy(struct NdbCondition* p_cond); #ifdef __cplusplus diff --git a/ndb/include/portlib/PortDefs.h b/ndb/include/portlib/PortDefs.h index 5e24e08ec61..b61bb627e65 100644 --- a/ndb/include/portlib/PortDefs.h +++ b/ndb/include/portlib/PortDefs.h @@ -28,35 +28,35 @@ struct tms { - time_t tms_utime; // user time - time_t tms_stime; // system time - time_t tms_cutime; // user time of children - time_t tms_cstime; // system time of children + time_t tms_utime; /* user time */ + time_t tms_stime; /* system time */ + time_t tms_cutime; /* user time of children */ + time_t tms_cstime; /* system time of children */ }; struct timespec { - long tv_sec; // Seconds - long tv_nsec; // Nanoseconds + long tv_sec; /* Seconds */ + long tv_nsec; /* Nanoseconds */ }; #define strcasecmp(a,b) _strcmpi(a,b) - // Exports a WIN32 getopt function +/* Exports a WIN32 getopt function */ extern int optind; extern char *optarg; int getopt(int, char **, char *opts); -#endif // NDB_WIN32 +#endif /* NDB_WIN32 */ #ifdef NDB_ALPHA -#ifdef NDB_GCC // only for NDB_ALPHA +#ifdef NDB_GCC /* only for NDB_ALPHA */ extern int gnuShouldNotUseRPCC(); #define RPCC() gnuShouldNotUseRPCC(); #else #ifdef NDB_WIN32 #ifdef __cplusplus extern "C" { -#endif //__cplusplus +#endif /* __cplusplus */ u_int64 __asm(char *, ...); double __dasm(char *, ...); float __fasm(char *, ...); @@ -65,32 +65,32 @@ extern "C" { int __ADD_ATOMIC_LONG2(void *, int); #ifdef __cplusplus }; -#endif //__cplusplus +#endif /* __cplusplus */ #pragma intrinsic (__asm, __dasm, __fasm) #pragma intrinsic(_ReleaseSpinLock, _AcquireSpinLock) #pragma intrinsic(__ADD_ATOMIC_LONG2) -#endif // NDB_WIN32 +#endif /* NDB_WIN32 */ #define RPCC() ((int)__asm(" rpcc v0;")) #define MB() __asm(" mb;"); #define WMB() __asm(" wmb;"); #ifdef USE_INITIALSP #define IS_IP() (__asm(" mov sp,v0;") < IPinitialSP) -#else // USE_INITIALSP +#else /* USE_INITIALSP */ #define IS_IP() (((__asm(" rpcc v0;") >> 32) & 0x7) == IP_CPU) #endif -#endif //NDB_GCC -#else // NDB_ALPHA +#endif /* NDB_GCC */ +#else /* NDB_ALPHA */ #if defined NDB_SPARC -#define MB() asm ("membar 0x0;"); // LoadLoad -#define WMB() asm ("membar 0x3;"); // StoreStore -#else // NDB_SPARC +#define MB() asm ("membar 0x0;"); /* LoadLoad */ +#define WMB() asm ("membar 0x3;"); /* StoreStore */ +#else /* NDB_SPARC */ #define MB() #define WMB() -#endif // NDB_SPARC +#endif /* NDB_SPARC */ #define IS_IP() (1==1) extern int shouldNotUseRPCC(); #define RPCC() shouldNotUseRPCC(); -#endif // NDB_ALPHA +#endif /* NDB_ALPHA */ #endif diff --git a/ndb/include/portlib/prefetch.h b/ndb/include/portlib/prefetch.h index d663dd4c40d..729c80bd93e 100644 --- a/ndb/include/portlib/prefetch.h +++ b/ndb/include/portlib/prefetch.h @@ -42,7 +42,7 @@ inline void prefetch(void* p) { #ifdef NDB_ALPHA __asm(" ldl r31,0(a0);", p); -#endif // NDB_ALPHA +#endif /* NDB_ALPHA */ #ifdef NDB_FORTE6 sparc_prefetch_read_once(p); #else @@ -54,7 +54,7 @@ inline void writehint(void* p) { #ifdef NDB_ALPHA __asm(" wh64 (a0);", p); -#endif // NDB_ALPHA +#endif /* NDB_ALPHA */ #ifdef NDB_FORTE6 sparc_prefetch_write_once(p); #else diff --git a/ndb/include/util/BaseString.hpp b/ndb/include/util/BaseString.hpp index a1bb91ea9c5..066a24f294e 100644 --- a/ndb/include/util/BaseString.hpp +++ b/ndb/include/util/BaseString.hpp @@ -177,6 +177,12 @@ public: * Trim string from <i>delim</i> */ static char* trim(char * src, const char * delim); + + /** + * snprintf on some platforms need special treatment + */ + static int snprintf(char *str, size_t size, const char *format, ...); + static int vsnprintf(char *str, size_t size, const char *format, va_list ap); private: char* m_chr; unsigned m_len; diff --git a/ndb/include/util/basestring_vsnprintf.h b/ndb/include/util/basestring_vsnprintf.h new file mode 100644 index 00000000000..7c804f22841 --- /dev/null +++ b/ndb/include/util/basestring_vsnprintf.h @@ -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 */ + +#ifndef BASESTRING_VSNPRINTF_H +#define BASESTRING_VSNPRINTF_H +#include <stdarg.h> +#if defined(__cplusplus) +extern "C" +{ +#endif +int basestring_snprintf(char*, size_t, const char*, ...); +int basestring_vsnprintf(char*,size_t, const char*,va_list); +#if defined(__cplusplus) +} +#endif +#endif diff --git a/ndb/src/common/debugger/DebuggerNames.cpp b/ndb/src/common/debugger/DebuggerNames.cpp index b2a79e2385b..8571b8ece86 100644 --- a/ndb/src/common/debugger/DebuggerNames.cpp +++ b/ndb/src/common/debugger/DebuggerNames.cpp @@ -15,6 +15,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include <ndb_global.h> +#include <BaseString.hpp> #include "DebuggerNames.hpp" @@ -53,14 +54,13 @@ initSignalNames(const char * dst[], const GsnName src[], unsigned short len){ static int initSignalPrinters(SignalDataPrintFunction dst[], - const NameFunctionPair src[], - unsigned short len){ + const NameFunctionPair src[]){ unsigned i; for(i = 0; i<=MAX_GSN; i++) dst[i] = 0; - for(i = 0; i<len; i++){ - unsigned short gsn = src[i].gsn; + unsigned short gsn; + for(i = 0; (gsn = src[i].gsn) > 0; i++){ SignalDataPrintFunction fun = src[i].function; if(dst[gsn] != 0 && fun != 0){ @@ -107,8 +107,7 @@ xxx_DUMMY_SIGNAL_NAMES_xxx = initSignalNames(localSignalNames, NO_OF_SIGNAL_NAMES); static const int xxx_DUMMY_PRINT_FUNCTIONS_xxx = initSignalPrinters(localPrintFunctions, - SignalDataPrintFunctions, - NO_OF_PRINT_FUNCTIONS); + SignalDataPrintFunctions); static const int xxx_DUMMY_BLOCK_NAMES_xxx = initBlockNames(localBlockNames, @@ -133,7 +132,7 @@ getBlockName(unsigned short blockNo, const char * ret){ return localBlockNames[blockNo-MIN_BLOCK_NO]; if (ret == 0) { static char buf[20]; - snprintf(buf, sizeof(buf), "BLOCK#%d", (int)blockNo); + BaseString::snprintf(buf, sizeof(buf), "BLOCK#%d", (int)blockNo); return buf; } return ret; diff --git a/ndb/src/common/debugger/EventLogger.cpp b/ndb/src/common/debugger/EventLogger.cpp index 03445622e6a..8a09be9a0a7 100644 --- a/ndb/src/common/debugger/EventLogger.cpp +++ b/ndb/src/common/debugger/EventLogger.cpp @@ -127,7 +127,7 @@ EventLogger::getText(char * m_text, size_t m_text_len, // TODO: Change the switch implementation... char theNodeId[32]; if (nodeId != 0){ - ::snprintf(theNodeId, 32, "Node %u: ", nodeId); + BaseString::snprintf(theNodeId, 32, "Node %u: ", nodeId); } else { theNodeId[0] = 0; } @@ -135,13 +135,13 @@ EventLogger::getText(char * m_text, size_t m_text_len, EventReport::EventType eventType = (EventReport::EventType)type; switch (eventType){ case EventReport::Connected: - ::snprintf(m_text, m_text_len, + BaseString::snprintf(m_text, m_text_len, "%sNode %u Connected", theNodeId, theData[1]); break; case EventReport::ConnectedApiVersion: - ::snprintf(m_text, m_text_len, + BaseString::snprintf(m_text, m_text_len, "%sNode %u: API version %d.%d.%d", theNodeId, theData[1], @@ -150,7 +150,7 @@ EventLogger::getText(char * m_text, size_t m_text_len, getBuild(theData[2])); break; case EventReport::Disconnected: - ::snprintf(m_text, m_text_len, + BaseString::snprintf(m_text, m_text_len, "%sNode %u Disconnected", theNodeId, theData[1]); @@ -159,7 +159,7 @@ EventLogger::getText(char * m_text, size_t m_text_len, //----------------------------------------------------------------------- // REPORT communication to node closed. //----------------------------------------------------------------------- - ::snprintf(m_text, m_text_len, + BaseString::snprintf(m_text, m_text_len, "%sCommunication to Node %u closed", theNodeId, theData[1]); @@ -168,7 +168,7 @@ EventLogger::getText(char * m_text, size_t m_text_len, //----------------------------------------------------------------------- // REPORT communication to node opened. //----------------------------------------------------------------------- - ::snprintf(m_text, m_text_len, + BaseString::snprintf(m_text, m_text_len, "%sCommunication to Node %u opened", theNodeId, theData[1]); @@ -177,7 +177,7 @@ EventLogger::getText(char * m_text, size_t m_text_len, //----------------------------------------------------------------------- // Start of NDB has been initiated. //----------------------------------------------------------------------- - ::snprintf(m_text, m_text_len, + BaseString::snprintf(m_text, m_text_len, "%sStart initiated (version %d.%d.%d)", theNodeId , getMajor(theData[1]), @@ -185,13 +185,13 @@ EventLogger::getText(char * m_text, size_t m_text_len, getBuild(theData[1])); break; case EventReport::NDBStopStarted: - ::snprintf(m_text, m_text_len, + BaseString::snprintf(m_text, m_text_len, "%s%s shutdown initiated", theNodeId, (theData[1] == 1 ? "Cluster" : "Node")); break; case EventReport::NDBStopAborted: - ::snprintf(m_text, m_text_len, + BaseString::snprintf(m_text, m_text_len, "%sNode shutdown aborted", theNodeId); break; @@ -199,7 +199,7 @@ EventLogger::getText(char * m_text, size_t m_text_len, //----------------------------------------------------------------------- // Start of NDB has been completed. //----------------------------------------------------------------------- - ::snprintf(m_text, m_text_len, + BaseString::snprintf(m_text, m_text_len, "%sStarted (version %d.%d.%d)", theNodeId , getMajor(theData[1]), @@ -211,7 +211,7 @@ EventLogger::getText(char * m_text, size_t m_text_len, //----------------------------------------------------------------------- // STTORRY recevied after restart finished. //----------------------------------------------------------------------- - ::snprintf(m_text, m_text_len, + BaseString::snprintf(m_text, m_text_len, "%sSTTORRY received after restart finished", theNodeId); break; @@ -237,7 +237,7 @@ EventLogger::getText(char * m_text, size_t m_text_len, type = ""; break; default:{ - ::snprintf(m_text, m_text_len, + BaseString::snprintf(m_text, m_text_len, "%sStart phase %u completed (unknown = %d)", theNodeId, theData[1], @@ -245,7 +245,7 @@ EventLogger::getText(char * m_text, size_t m_text_len, return m_text; } } - ::snprintf(m_text, m_text_len, + BaseString::snprintf(m_text, m_text_len, "%sStart phase %u completed %s", theNodeId, theData[1], @@ -254,7 +254,7 @@ EventLogger::getText(char * m_text, size_t m_text_len, break; } case EventReport::CM_REGCONF: - ::snprintf(m_text, m_text_len, + BaseString::snprintf(m_text, m_text_len, "%sCM_REGCONF president = %u, own Node = %u, our dynamic id = %u" , theNodeId, @@ -286,7 +286,7 @@ EventLogger::getText(char * m_text, size_t m_text_len, break; }//switch - ::snprintf(m_text, m_text_len, + BaseString::snprintf(m_text, m_text_len, "%sCM_REGREF from Node %u to our Node %u. Cause = %s", theNodeId, theData[2], @@ -298,7 +298,7 @@ EventLogger::getText(char * m_text, size_t m_text_len, //----------------------------------------------------------------------- // REPORT Node Restart copied a fragment. //----------------------------------------------------------------------- - ::snprintf(m_text, + BaseString::snprintf(m_text, m_text_len, "%sWe are Node %u with dynamic ID %u, our left neighbour " "is Node %u, our right is Node %u", @@ -315,13 +315,13 @@ EventLogger::getText(char * m_text, size_t m_text_len, if (theData[1] == 0) { if (theData[3] != 0) { - ::snprintf(m_text, m_text_len, + BaseString::snprintf(m_text, m_text_len, "%sNode %u completed failure of Node %u", theNodeId, theData[3], theData[2]); } else { - ::snprintf(m_text, m_text_len, + BaseString::snprintf(m_text, m_text_len, "%sAll nodes completed failure of Node %u", theNodeId, theData[2]); @@ -338,7 +338,7 @@ EventLogger::getText(char * m_text, size_t m_text_len, line = "DBLQH"; } - ::snprintf(m_text, m_text_len, + BaseString::snprintf(m_text, m_text_len, "%sNode failure of %u %s completed", theNodeId, theData[2], @@ -346,7 +346,7 @@ EventLogger::getText(char * m_text, size_t m_text_len, } break; case EventReport::NODE_FAILREP: - ::snprintf(m_text, + BaseString::snprintf(m_text, m_text_len, "%sNode %u has failed. The Node state at failure " "was %u", @@ -366,41 +366,41 @@ EventLogger::getText(char * m_text, size_t m_text_len, const unsigned state = sd->code >> 16; switch (code) { case ArbitCode::ThreadStart: - ::snprintf(m_text, m_text_len, + BaseString::snprintf(m_text, m_text_len, "%sPresident restarts arbitration thread [state=%u]", theNodeId, state); break; case ArbitCode::PrepPart2: sd->ticket.getText(ticketText, sizeof(ticketText)); - ::snprintf(m_text, m_text_len, + BaseString::snprintf(m_text, m_text_len, "%sPrepare arbitrator node %u [ticket=%s]", theNodeId, sd->node, ticketText); break; case ArbitCode::PrepAtrun: sd->ticket.getText(ticketText, sizeof(ticketText)); - ::snprintf(m_text, m_text_len, + BaseString::snprintf(m_text, m_text_len, "%sReceive arbitrator node %u [ticket=%s]", theNodeId, sd->node, ticketText); break; case ArbitCode::ApiStart: sd->ticket.getText(ticketText, sizeof(ticketText)); - ::snprintf(m_text, m_text_len, + BaseString::snprintf(m_text, m_text_len, "%sStarted arbitrator node %u [ticket=%s]", theNodeId, sd->node, ticketText); break; case ArbitCode::ApiFail: - ::snprintf(m_text, m_text_len, + BaseString::snprintf(m_text, m_text_len, "%sLost arbitrator node %u - process failure [state=%u]", theNodeId, sd->node, state); break; case ArbitCode::ApiExit: - ::snprintf(m_text, m_text_len, + BaseString::snprintf(m_text, m_text_len, "%sLost arbitrator node %u - process exit [state=%u]", theNodeId, sd->node, state); break; default: ArbitCode::getErrText(code, errText, sizeof(errText)); - ::snprintf(m_text, m_text_len, + BaseString::snprintf(m_text, m_text_len, "%sLost arbitrator node %u - %s [state=%u]", theNodeId, sd->node, errText, state); break; @@ -417,48 +417,48 @@ EventLogger::getText(char * m_text, size_t m_text_len, const unsigned state = sd->code >> 16; switch (code) { case ArbitCode::LoseNodes: - ::snprintf(m_text, m_text_len, + BaseString::snprintf(m_text, m_text_len, "%sArbitration check lost - less than 1/2 nodes left", theNodeId); break; case ArbitCode::WinGroups: - ::snprintf(m_text, m_text_len, + BaseString::snprintf(m_text, m_text_len, "%sArbitration check won - node group majority", theNodeId); break; case ArbitCode::LoseGroups: - ::snprintf(m_text, m_text_len, + BaseString::snprintf(m_text, m_text_len, "%sArbitration check lost - missing node group", theNodeId); break; case ArbitCode::Partitioning: - ::snprintf(m_text, m_text_len, + BaseString::snprintf(m_text, m_text_len, "%sNetwork partitioning - arbitration required", theNodeId); break; case ArbitCode::WinChoose: - ::snprintf(m_text, m_text_len, + BaseString::snprintf(m_text, m_text_len, "%sArbitration won - positive reply from node %u", theNodeId, sd->node); break; case ArbitCode::LoseChoose: - ::snprintf(m_text, m_text_len, + BaseString::snprintf(m_text, m_text_len, "%sArbitration lost - negative reply from node %u", theNodeId, sd->node); break; case ArbitCode::LoseNorun: - ::snprintf(m_text, m_text_len, + BaseString::snprintf(m_text, m_text_len, "%sNetwork partitioning - no arbitrator available", theNodeId); break; case ArbitCode::LoseNocfg: - ::snprintf(m_text, m_text_len, + BaseString::snprintf(m_text, m_text_len, "%sNetwork partitioning - no arbitrator configured", theNodeId); break; default: ArbitCode::getErrText(code, errText, sizeof(errText)); - ::snprintf(m_text, m_text_len, + BaseString::snprintf(m_text, m_text_len, "%sArbitration failure - %s [state=%u]", theNodeId, errText, state); break; @@ -470,7 +470,7 @@ EventLogger::getText(char * m_text, size_t m_text_len, // This event reports that a global checkpoint has been started and this // node is the master of this global checkpoint. //----------------------------------------------------------------------- - ::snprintf(m_text, + BaseString::snprintf(m_text, m_text_len, "%sGlobal checkpoint %u started", theNodeId, @@ -481,7 +481,7 @@ EventLogger::getText(char * m_text, size_t m_text_len, // This event reports that a global checkpoint has been completed on this // node and the node is the master of this global checkpoint. //----------------------------------------------------------------------- - ::snprintf(m_text, m_text_len, + BaseString::snprintf(m_text, m_text_len, "%sGlobal checkpoint %u completed", theNodeId, theData[1]); @@ -491,7 +491,7 @@ EventLogger::getText(char * m_text, size_t m_text_len, // This event reports that a local checkpoint has been started and this // node is the master of this local checkpoint. //----------------------------------------------------------------------- - ::snprintf(m_text, + BaseString::snprintf(m_text, m_text_len, "%sLocal checkpoint %u started. " "Keep GCI = %u oldest restorable GCI = %u", @@ -505,7 +505,7 @@ EventLogger::getText(char * m_text, size_t m_text_len, // This event reports that a local checkpoint has been completed on this // node and the node is the master of this local checkpoint. //----------------------------------------------------------------------- - ::snprintf(m_text, + BaseString::snprintf(m_text, m_text_len, "%sLocal checkpoint %u completed", theNodeId, @@ -515,14 +515,14 @@ EventLogger::getText(char * m_text, size_t m_text_len, //----------------------------------------------------------------------- // This event reports that a table has been created. //----------------------------------------------------------------------- - ::snprintf(m_text, m_text_len, + BaseString::snprintf(m_text, m_text_len, "%sTable with ID = %u created", theNodeId, theData[1]); break; case EventReport::LCPStoppedInCalcKeepGci: if (theData[1] == 0) - ::snprintf(m_text, m_text_len, + BaseString::snprintf(m_text, m_text_len, "%sLocal Checkpoint stopped in CALCULATED_KEEP_GCI", theNodeId); break; @@ -530,7 +530,7 @@ EventLogger::getText(char * m_text, size_t m_text_len, //----------------------------------------------------------------------- // REPORT Node Restart completed copy of dictionary information. //----------------------------------------------------------------------- - ::snprintf(m_text, + BaseString::snprintf(m_text, m_text_len, "%sNode restart completed copy of dictionary information", theNodeId); @@ -539,7 +539,7 @@ EventLogger::getText(char * m_text, size_t m_text_len, //----------------------------------------------------------------------- // REPORT Node Restart completed copy of distribution information. //----------------------------------------------------------------------- - ::snprintf(m_text, + BaseString::snprintf(m_text, m_text_len, "%sNode restart completed copy of distribution information", theNodeId); @@ -548,7 +548,7 @@ EventLogger::getText(char * m_text, size_t m_text_len, //----------------------------------------------------------------------- // REPORT Node Restart is starting to copy the fragments. //----------------------------------------------------------------------- - ::snprintf(m_text, + BaseString::snprintf(m_text, m_text_len, "%sNode restart starting to copy the fragments " "to Node %u", @@ -559,7 +559,7 @@ EventLogger::getText(char * m_text, size_t m_text_len, //----------------------------------------------------------------------- // REPORT Node Restart copied a fragment. //----------------------------------------------------------------------- - ::snprintf(m_text, + BaseString::snprintf(m_text, m_text_len, "%sTable ID = %u, fragment ID = %u have been copied " "to Node %u", @@ -569,7 +569,7 @@ EventLogger::getText(char * m_text, size_t m_text_len, theData[1]); break; case EventReport::NR_CopyFragsCompleted: - ::snprintf(m_text, + BaseString::snprintf(m_text, m_text_len, "%sNode restart completed copying the fragments " "to Node %u", @@ -577,7 +577,7 @@ EventLogger::getText(char * m_text, size_t m_text_len, theData[1]); break; case EventReport::LCPFragmentCompleted: - ::snprintf(m_text, + BaseString::snprintf(m_text, m_text_len, "%sTable ID = %u, fragment ID = %u has completed LCP " "on Node %u", @@ -590,7 +590,7 @@ EventLogger::getText(char * m_text, size_t m_text_len, // ------------------------------------------------------------------- // Report information about transaction activity once per 10 seconds. // ------------------------------------------------------------------- - ::snprintf(m_text, + BaseString::snprintf(m_text, m_text_len, "%sTrans. Count = %u, Commit Count = %u, " "Read Count = %u, Simple Read Count = %u,\n" @@ -610,7 +610,7 @@ EventLogger::getText(char * m_text, size_t m_text_len, theData[10]); break; case EventReport::OperationReportCounters: - ::snprintf(m_text, m_text_len, + BaseString::snprintf(m_text, m_text_len, "%sOperations=%u", theNodeId, theData[1]); @@ -619,7 +619,7 @@ EventLogger::getText(char * m_text, size_t m_text_len, //----------------------------------------------------------------------- // REPORT Undo Logging blocked due to buffer near to overflow. //----------------------------------------------------------------------- - ::snprintf(m_text, + BaseString::snprintf(m_text, m_text_len, "%sACC Blocked %u and TUP Blocked %u times last second", theNodeId, @@ -628,7 +628,7 @@ EventLogger::getText(char * m_text, size_t m_text_len, break; case EventReport::TransporterError: case EventReport::TransporterWarning: - ::snprintf(m_text, + BaseString::snprintf(m_text, m_text_len, "%sTransporter to node %d reported error 0x%x", theNodeId, @@ -639,7 +639,7 @@ EventLogger::getText(char * m_text, size_t m_text_len, //----------------------------------------------------------------------- // REPORT Undo Logging blocked due to buffer near to overflow. //----------------------------------------------------------------------- - ::snprintf(m_text, + BaseString::snprintf(m_text, m_text_len, "%sNode %d missed heartbeat %d", theNodeId, @@ -650,21 +650,21 @@ EventLogger::getText(char * m_text, size_t m_text_len, //----------------------------------------------------------------------- // REPORT Undo Logging blocked due to buffer near to overflow. //----------------------------------------------------------------------- - ::snprintf(m_text, + BaseString::snprintf(m_text, m_text_len, "%sNode %d declared dead due to missed heartbeat", theNodeId, theData[1]); break; case EventReport::JobStatistic: - ::snprintf(m_text, + BaseString::snprintf(m_text, m_text_len, "%sMean loop Counter in doJob last 8192 times = %u", theNodeId, theData[1]); break; case EventReport::SendBytesStatistic: - ::snprintf(m_text, + BaseString::snprintf(m_text, m_text_len, "%sMean send size to Node = %d last 4096 sends = %u bytes", theNodeId, @@ -672,7 +672,7 @@ EventLogger::getText(char * m_text, size_t m_text_len, theData[2]); break; case EventReport::ReceiveBytesStatistic: - ::snprintf(m_text, + BaseString::snprintf(m_text, m_text_len, "%sMean receive size to Node = %d last 4096 sends = %u bytes", theNodeId, @@ -680,14 +680,14 @@ EventLogger::getText(char * m_text, size_t m_text_len, theData[2]); break; case EventReport::SentHeartbeat: - ::snprintf(m_text, + BaseString::snprintf(m_text, m_text_len, "%sNode Sent Heartbeat to node = %d", theNodeId, theData[1]); break; case EventReport::CreateLogBytes: - ::snprintf(m_text, + BaseString::snprintf(m_text, m_text_len, "%sLog part %u, log file %u, MB %u", theNodeId, @@ -696,7 +696,7 @@ EventLogger::getText(char * m_text, size_t m_text_len, theData[3]); break; case EventReport::StartLog: - ::snprintf(m_text, + BaseString::snprintf(m_text, m_text_len, "%sLog part %u, start MB %u, stop MB %u, last GCI, log exec %u", theNodeId, @@ -706,7 +706,7 @@ EventLogger::getText(char * m_text, size_t m_text_len, theData[4]); break; case EventReport::StartREDOLog: - ::snprintf(m_text, + BaseString::snprintf(m_text, m_text_len, "%sNode: %d StartLog: [GCI Keep: %d LastCompleted: %d NewestRestorable: %d]", theNodeId, @@ -723,7 +723,7 @@ EventLogger::getText(char * m_text, size_t m_text_len, line = "DBACC"; } - ::snprintf(m_text, + BaseString::snprintf(m_text, m_text_len, "%s UNDO %s %d [%d %d %d %d %d %d %d %d %d]", theNodeId, @@ -741,36 +741,36 @@ EventLogger::getText(char * m_text, size_t m_text_len, } break; case EventReport::InfoEvent: - ::snprintf(m_text, + BaseString::snprintf(m_text, m_text_len, "%s%s", theNodeId, (char *)&theData[1]); break; case EventReport::WarningEvent: - ::snprintf(m_text, + BaseString::snprintf(m_text, m_text_len, "%s%s", theNodeId, (char *)&theData[1]); break; case EventReport::GCP_TakeoverStarted: - ::snprintf(m_text, + BaseString::snprintf(m_text, m_text_len, "%sGCP Take over started", theNodeId); break; case EventReport::GCP_TakeoverCompleted: - ::snprintf(m_text, + BaseString::snprintf(m_text, m_text_len, "%sGCP Take over completed", theNodeId); break; case EventReport::LCP_TakeoverStarted: - ::snprintf(m_text, + BaseString::snprintf(m_text, m_text_len, "%sLCP Take over started", theNodeId); break; case EventReport::LCP_TakeoverCompleted: - ::snprintf(m_text, + BaseString::snprintf(m_text, m_text_len, "%sLCP Take over completed (state = %d)", theNodeId, theData[1]); @@ -783,7 +783,7 @@ EventLogger::getText(char * m_text, size_t m_text_len, const int block = theData[5]; const int percent = (used*100)/total; - ::snprintf(m_text, m_text_len, + BaseString::snprintf(m_text, m_text_len, "%s%s usage %s %d%s(%d %dK pages of total %d)", theNodeId, (block==DBACC ? "Index" : (block == DBTUP ?"Data":"<unknown>")), @@ -802,7 +802,7 @@ EventLogger::getText(char * m_text, size_t m_text_len, const int subId = theData[2]; const int subKey = theData[3]; const int err = theData[4]; - ::snprintf(m_text, m_text_len, + BaseString::snprintf(m_text, m_text_len, "Grep::SSCoord: Created subscription id" " (subId=%d,SubKey=%d)" " Return code: %d.", @@ -816,7 +816,7 @@ EventLogger::getText(char * m_text, size_t m_text_len, const int subId = theData[2]; const int subKey = theData[3]; const int err = theData[4]; - ::snprintf(m_text, m_text_len, + BaseString::snprintf(m_text, m_text_len, "Grep::PSCoord: Created subscription id" " (subId=%d,SubKey=%d)" " Return code: %d.", @@ -831,7 +831,7 @@ EventLogger::getText(char * m_text, size_t m_text_len, const int subKey = theData[3]; const int err = theData[4]; const int nodegrp = theData[5]; - ::snprintf(m_text, m_text_len, + BaseString::snprintf(m_text, m_text_len, "Grep::SSCoord: Created subscription using" " (subId=%d,SubKey=%d)" " in primary system. Primary system has %d nodegroup(s)." @@ -847,7 +847,7 @@ EventLogger::getText(char * m_text, size_t m_text_len, const int subId = theData[2]; const int subKey = theData[3]; const int err = theData[4]; - ::snprintf(m_text, m_text_len, + BaseString::snprintf(m_text, m_text_len, "Grep::PSCoord: All participants have created " "subscriptions" " using (subId=%d,SubKey=%d)." @@ -862,7 +862,7 @@ EventLogger::getText(char * m_text, size_t m_text_len, const int subId = theData[2]; const int subKey = theData[3]; const int err = theData[4]; - ::snprintf(m_text, m_text_len, + BaseString::snprintf(m_text, m_text_len, "Grep::SSCoord: Logging started on meta data changes." " using (subId=%d,SubKey=%d)" " Return code: %d", @@ -876,7 +876,7 @@ EventLogger::getText(char * m_text, size_t m_text_len, const int subId = theData[2]; const int subKey = theData[3]; const int err = theData[4]; - ::snprintf(m_text, m_text_len, + BaseString::snprintf(m_text, m_text_len, "Grep::PSCoord: All participants have started " "logging meta data" " changes on the subscription subId=%d,SubKey=%d) " @@ -891,7 +891,7 @@ EventLogger::getText(char * m_text, size_t m_text_len, const int subId = theData[2]; const int subKey = theData[3]; const int err = theData[4]; - ::snprintf(m_text, m_text_len, + BaseString::snprintf(m_text, m_text_len, "Grep::SSCoord: Logging started on table data changes " " using (subId=%d,SubKey=%d)" " Return code: %d", @@ -905,7 +905,7 @@ EventLogger::getText(char * m_text, size_t m_text_len, const int subId = theData[2]; const int subKey = theData[3]; const int err = theData[4]; - ::snprintf(m_text, m_text_len, + BaseString::snprintf(m_text, m_text_len, "Grep::PSCoord: All participants have started logging " "table data changes on the subscription " "subId=%d,SubKey=%d)." @@ -920,7 +920,7 @@ EventLogger::getText(char * m_text, size_t m_text_len, const int subId = theData[2]; const int subKey = theData[3]; const int err = theData[4]; - ::snprintf(m_text, m_text_len, + BaseString::snprintf(m_text, m_text_len, "Grep::PSCoord: All participants have started " " synchronization on meta data (META SCAN) using " "(subId=%d,SubKey=%d)." @@ -935,7 +935,7 @@ EventLogger::getText(char * m_text, size_t m_text_len, const int subId = theData[2]; const int subKey = theData[3]; const int err = theData[4]; - ::snprintf(m_text, m_text_len, + BaseString::snprintf(m_text, m_text_len, "Grep::SSCoord: Synchronization started (META SCAN) on " " meta data using (subId=%d,SubKey=%d)" " Return code: %d", @@ -949,7 +949,7 @@ EventLogger::getText(char * m_text, size_t m_text_len, const int subId = theData[2]; const int subKey = theData[3]; const int err = theData[4]; - ::snprintf(m_text, m_text_len, + BaseString::snprintf(m_text, m_text_len, "Grep::PSCoord: All participants have started " "synchronization " " on table data (DATA SCAN) using (subId=%d,SubKey=%d)." @@ -965,7 +965,7 @@ EventLogger::getText(char * m_text, size_t m_text_len, const int subKey = theData[3]; const int err = theData[4]; const int gci = theData[5]; - ::snprintf(m_text, m_text_len, + BaseString::snprintf(m_text, m_text_len, "Grep::SSCoord: Synchronization started (DATA SCAN) on " "table data using (subId=%d,SubKey=%d). GCI = %d" " Return code: %d", @@ -980,7 +980,7 @@ EventLogger::getText(char * m_text, size_t m_text_len, const int subId = theData[2]; const int subKey = theData[3]; const int err = theData[4]; - ::snprintf(m_text, m_text_len, + BaseString::snprintf(m_text, m_text_len, "Grep::PSCoord: All participants have removed " "subscription (subId=%d,SubKey=%d). I have cleaned " "up resources I've used." @@ -995,7 +995,7 @@ EventLogger::getText(char * m_text, size_t m_text_len, const int subId = theData[2]; const int subKey = theData[3]; const int err = theData[4]; - ::snprintf(m_text, m_text_len, + BaseString::snprintf(m_text, m_text_len, "Grep::SSCoord: Removed subscription " "(subId=%d,SubKey=%d)" " Return code: %d", @@ -1005,7 +1005,7 @@ EventLogger::getText(char * m_text, size_t m_text_len, break; } default: - ::snprintf(m_text, + BaseString::snprintf(m_text, m_text_len, "%sUnknown GrepSubscriptonInfo event: %d", theNodeId, @@ -1024,7 +1024,7 @@ EventLogger::getText(char * m_text, size_t m_text_len, const int subId = theData[2]; const int subKey = theData[3]; const int err = theData[4]; - ::snprintf(m_text, m_text_len, + BaseString::snprintf(m_text, m_text_len, "Grep::SSCoord:Error code: %d Error message: %s" " (subId=%d,SubKey=%d)", err, @@ -1038,7 +1038,7 @@ EventLogger::getText(char * m_text, size_t m_text_len, const int subId = theData[2]; const int subKey = theData[3]; const int err = theData[4]; - ::snprintf(m_text, m_text_len, + BaseString::snprintf(m_text, m_text_len, "Grep::SSCoord: FAILED to Created subscription using" " (subId=%d,SubKey=%d)in primary system." " Error code: %d Error Message: %s", @@ -1053,7 +1053,7 @@ EventLogger::getText(char * m_text, size_t m_text_len, const int subId = theData[2]; const int subKey = theData[3]; const int err = theData[4]; - ::snprintf(m_text, m_text_len, + BaseString::snprintf(m_text, m_text_len, "Grep::SSCoord: Logging failed to start on meta " "data changes." " using (subId=%d,SubKey=%d)" @@ -1069,7 +1069,7 @@ EventLogger::getText(char * m_text, size_t m_text_len, const int subId = theData[2]; const int subKey = theData[3]; const int err = theData[4]; - ::snprintf(m_text, m_text_len, + BaseString::snprintf(m_text, m_text_len, "Grep::SSCoord: Logging FAILED to start on table data " " changes using (subId=%d,SubKey=%d)" " Error code: %d Error Message: %s", @@ -1084,7 +1084,7 @@ EventLogger::getText(char * m_text, size_t m_text_len, const int subId = theData[2]; const int subKey = theData[3]; const int err = theData[4]; - ::snprintf(m_text, m_text_len, + BaseString::snprintf(m_text, m_text_len, "Grep::SSCoord: Synchronization FAILED (META SCAN) on " " meta data using (subId=%d,SubKey=%d)" " Error code: %d Error Message: %s", @@ -1100,7 +1100,7 @@ EventLogger::getText(char * m_text, size_t m_text_len, const int subKey = theData[3]; const int err = theData[4]; const int gci = theData[5]; - ::snprintf(m_text, m_text_len, + BaseString::snprintf(m_text, m_text_len, "Grep::SSCoord: Synchronization FAILED (DATA SCAN) on " "table data using (subId=%d,SubKey=%d). GCI = %d" " Error code: %d Error Message: %s", @@ -1116,7 +1116,7 @@ EventLogger::getText(char * m_text, size_t m_text_len, const int subId = theData[2]; const int subKey = theData[3]; const int err = theData[4]; - ::snprintf(m_text, m_text_len, + BaseString::snprintf(m_text, m_text_len, "Grep::SSCoord: Failed to remove subscription " "(subId=%d,SubKey=%d). " " Error code: %d Error Message: %s", @@ -1133,7 +1133,7 @@ EventLogger::getText(char * m_text, size_t m_text_len, const int subId = theData[2]; const int subKey = theData[3]; const int err = theData[4]; - ::snprintf(m_text, m_text_len, + BaseString::snprintf(m_text, m_text_len, "Grep::PSCoord: Error code: %d Error Message: %s" " (subId=%d,SubKey=%d)", err, @@ -1147,7 +1147,7 @@ EventLogger::getText(char * m_text, size_t m_text_len, const int subId = theData[2]; const int subKey = theData[3]; const int err = theData[4]; - ::snprintf(m_text, m_text_len, + BaseString::snprintf(m_text, m_text_len, "Grep::PSCoord: FAILED to Created subscription using" " (subId=%d,SubKey=%d)in primary system." " Error code: %d Error Message: %s", @@ -1162,7 +1162,7 @@ EventLogger::getText(char * m_text, size_t m_text_len, const int subId = theData[2]; const int subKey = theData[3]; const int err = theData[4]; - ::snprintf(m_text, m_text_len, + BaseString::snprintf(m_text, m_text_len, "Grep::PSCoord: Logging failed to start on meta " "data changes." " using (subId=%d,SubKey=%d)" @@ -1178,7 +1178,7 @@ EventLogger::getText(char * m_text, size_t m_text_len, const int subId = theData[2]; const int subKey = theData[3]; const int err = theData[4]; - ::snprintf(m_text, m_text_len, + BaseString::snprintf(m_text, m_text_len, "Grep::PSCoord: Logging FAILED to start on table data " " changes using (subId=%d,SubKey=%d)" " Error code: %d Error Message: %s", @@ -1193,7 +1193,7 @@ EventLogger::getText(char * m_text, size_t m_text_len, const int subId = theData[2]; const int subKey = theData[3]; const int err = theData[4]; - ::snprintf(m_text, m_text_len, + BaseString::snprintf(m_text, m_text_len, "Grep::PSCoord: Synchronization FAILED (META SCAN) on " " meta data using (subId=%d,SubKey=%d)" " Error code: %d Error Message: %s", @@ -1209,7 +1209,7 @@ EventLogger::getText(char * m_text, size_t m_text_len, const int subKey = theData[3]; const int err = theData[4]; const int gci = theData[5]; - ::snprintf(m_text, m_text_len, + BaseString::snprintf(m_text, m_text_len, "Grep::PSCoord: Synchronization FAILED (DATA SCAN) on " "table data using (subId=%d,SubKey=%d). GCI = %d. " " Error code: %d Error Message: %s", @@ -1225,7 +1225,7 @@ EventLogger::getText(char * m_text, size_t m_text_len, const int subId = theData[2]; const int subKey = theData[3]; const int err = theData[4]; - ::snprintf(m_text, m_text_len, + BaseString::snprintf(m_text, m_text_len, "Grep::PSCoord: Failed to remove subscription " "(subId=%d,SubKey=%d)." " Error code: %d Error Message: %s", @@ -1239,7 +1239,7 @@ EventLogger::getText(char * m_text, size_t m_text_len, { const int err = theData[4]; const int nodeId = theData[5]; - ::snprintf(m_text, m_text_len, + BaseString::snprintf(m_text, m_text_len, "Rep: Node %d." " Error code: %d Error Message: %s", nodeId, @@ -1250,7 +1250,7 @@ EventLogger::getText(char * m_text, size_t m_text_len, default: - ::snprintf(m_text, + BaseString::snprintf(m_text, m_text_len, "%sUnknown GrepSubscriptionAlert event: %d", theNodeId, @@ -1261,19 +1261,19 @@ EventLogger::getText(char * m_text, size_t m_text_len, } case EventReport::BackupStarted: - ::snprintf(m_text, + BaseString::snprintf(m_text, m_text_len, "%sBackup %d started from node %d", theNodeId, theData[2], refToNode(theData[1])); break; case EventReport::BackupFailedToStart: - ::snprintf(m_text, + BaseString::snprintf(m_text, m_text_len, "%sBackup request from %d failed to start. Error: %d", theNodeId, refToNode(theData[1]), theData[2]); break; case EventReport::BackupCompleted: - ::snprintf(m_text, + BaseString::snprintf(m_text, m_text_len, "%sBackup %d started from node %d completed\n" " StartGCP: %d StopGCP: %d\n" @@ -1284,7 +1284,7 @@ EventLogger::getText(char * m_text, size_t m_text_len, theData[5], theData[7]); break; case EventReport::BackupAborted: - ::snprintf(m_text, + BaseString::snprintf(m_text, m_text_len, "%sBackup %d started from %d has been aborted. Error: %d", theNodeId, @@ -1293,7 +1293,7 @@ EventLogger::getText(char * m_text, size_t m_text_len, theData[3]); break; default: - ::snprintf(m_text, + BaseString::snprintf(m_text, m_text_len, "%sUnknown event: %d", theNodeId, @@ -1306,7 +1306,7 @@ EventLogger::getText(char * m_text, size_t m_text_len, EventLogger::EventLogger() : m_filterLevel(15) { setCategory("EventLogger"); - enable(Logger::Logger::LL_INFO, Logger::Logger::LL_ALERT); + enable(Logger::LL_INFO, Logger::LL_ALERT); } EventLogger::~EventLogger() @@ -1343,7 +1343,7 @@ EventLogger::log(int eventType, const Uint32* theData, NodeId nodeId, { Uint32 threshold = 0; Logger::LoggerLevel severity = Logger::LL_WARNING; - LogLevel::EventCategory cat; + LogLevel::EventCategory cat= LogLevel::llInvalid; for(unsigned i = 0; i<EventLoggerBase::matrixSize; i++){ if(EventLoggerBase::matrix[i].eventType == eventType){ @@ -1353,6 +1353,9 @@ EventLogger::log(int eventType, const Uint32* theData, NodeId nodeId, break; } } + + if (cat == LogLevel::llInvalid) + return; Uint32 set = ll?ll->getLogLevel(cat) : m_logLevel.getLogLevel(cat); if (threshold <= set){ diff --git a/ndb/src/common/debugger/signaldata/ContinueB.cpp b/ndb/src/common/debugger/signaldata/ContinueB.cpp index 1be6da86cb1..c295041bc01 100644 --- a/ndb/src/common/debugger/signaldata/ContinueB.cpp +++ b/ndb/src/common/debugger/signaldata/ContinueB.cpp @@ -24,9 +24,9 @@ bool printCONTINUEB(FILE * output, const Uint32 * theData, Uint32 len, Uint16 receiverBlockNo){ if(receiverBlockNo == DBDIH){ - return printCONTINUEB_DBDIH(output, theData, len); + return printCONTINUEB_DBDIH(output, theData, len, 0); } else if(receiverBlockNo == NDBFS) { - return printCONTINUEB_NDBFS(output, theData, len); + return printCONTINUEB_NDBFS(output, theData, len, 0); } return false; diff --git a/ndb/src/common/debugger/signaldata/CopyGCI.cpp b/ndb/src/common/debugger/signaldata/CopyGCI.cpp index 96186e82525..173b3f6708f 100644 --- a/ndb/src/common/debugger/signaldata/CopyGCI.cpp +++ b/ndb/src/common/debugger/signaldata/CopyGCI.cpp @@ -21,22 +21,22 @@ void print(char * buf, size_t buf_len, CopyGCIReq::CopyReason r){ switch(r){ case CopyGCIReq::IDLE: - snprintf(buf, buf_len, "IDLE"); + BaseString::snprintf(buf, buf_len, "IDLE"); break; case CopyGCIReq::LOCAL_CHECKPOINT: - snprintf(buf, buf_len, "LOCAL_CHECKPOINT"); + BaseString::snprintf(buf, buf_len, "LOCAL_CHECKPOINT"); break; case CopyGCIReq::RESTART: - snprintf(buf, buf_len, "RESTART"); + BaseString::snprintf(buf, buf_len, "RESTART"); break; case CopyGCIReq::GLOBAL_CHECKPOINT: - snprintf(buf, buf_len, "GLOBAL_CHECKPOINT"); + BaseString::snprintf(buf, buf_len, "GLOBAL_CHECKPOINT"); break; case CopyGCIReq::INITIAL_START_COMPLETED: - snprintf(buf, buf_len, "INITIAL_START_COMPLETED"); + BaseString::snprintf(buf, buf_len, "INITIAL_START_COMPLETED"); break; default: - snprintf(buf, buf_len, "<Unknown>"); + BaseString::snprintf(buf, buf_len, "<Unknown>"); } } diff --git a/ndb/src/common/debugger/signaldata/CreateTrig.cpp b/ndb/src/common/debugger/signaldata/CreateTrig.cpp index ddd45080cba..db5344cfbe7 100644 --- a/ndb/src/common/debugger/signaldata/CreateTrig.cpp +++ b/ndb/src/common/debugger/signaldata/CreateTrig.cpp @@ -28,51 +28,51 @@ bool printCREATE_TRIG_REQ(FILE * output, const Uint32 * theData, Uint32 len, Uin //sig->getTriggerName((char *) &triggerName); switch (sig->getTriggerType()) { case(TriggerType::SECONDARY_INDEX): - snprintf(triggerType, sizeof(triggerType), "SECONDARY_INDEX"); + BaseString::snprintf(triggerType, sizeof(triggerType), "SECONDARY_INDEX"); break; case(TriggerType::SUBSCRIPTION): - snprintf(triggerType, sizeof(triggerType), "SUBSCRIPTION"); + BaseString::snprintf(triggerType, sizeof(triggerType), "SUBSCRIPTION"); break; case(TriggerType::ORDERED_INDEX): - snprintf(triggerType, sizeof(triggerType), "ORDERED_INDEX"); + BaseString::snprintf(triggerType, sizeof(triggerType), "ORDERED_INDEX"); break; default: - snprintf(triggerType, sizeof(triggerType), "UNKNOWN [%d]", (int)sig->getTriggerType()); + BaseString::snprintf(triggerType, sizeof(triggerType), "UNKNOWN [%d]", (int)sig->getTriggerType()); break; } switch (sig->getTriggerActionTime()) { case (TriggerActionTime::TA_BEFORE): - snprintf(triggerActionTime, sizeof(triggerActionTime), "BEFORE"); + BaseString::snprintf(triggerActionTime, sizeof(triggerActionTime), "BEFORE"); break; case(TriggerActionTime::TA_AFTER): - snprintf(triggerActionTime, sizeof(triggerActionTime), "AFTER"); + BaseString::snprintf(triggerActionTime, sizeof(triggerActionTime), "AFTER"); break; case (TriggerActionTime::TA_DEFERRED): - snprintf(triggerActionTime, sizeof(triggerActionTime), "DEFERRED"); + BaseString::snprintf(triggerActionTime, sizeof(triggerActionTime), "DEFERRED"); break; case (TriggerActionTime::TA_DETACHED): - snprintf(triggerActionTime, sizeof(triggerActionTime), "DETACHED"); + BaseString::snprintf(triggerActionTime, sizeof(triggerActionTime), "DETACHED"); break; default: - snprintf(triggerActionTime, sizeof(triggerActionTime), + BaseString::snprintf(triggerActionTime, sizeof(triggerActionTime), "UNKNOWN [%d]", (int)sig->getTriggerActionTime()); break; } switch (sig->getTriggerEvent()) { case (TriggerEvent::TE_INSERT): - snprintf(triggerEvent, sizeof(triggerEvent), "INSERT"); + BaseString::snprintf(triggerEvent, sizeof(triggerEvent), "INSERT"); break; case(TriggerEvent::TE_DELETE): - snprintf(triggerEvent, sizeof(triggerEvent), "DELETE"); + BaseString::snprintf(triggerEvent, sizeof(triggerEvent), "DELETE"); break; case(TriggerEvent::TE_UPDATE): - snprintf(triggerEvent, sizeof(triggerEvent), "UPDATE"); + BaseString::snprintf(triggerEvent, sizeof(triggerEvent), "UPDATE"); break; case(TriggerEvent::TE_CUSTOM): - snprintf(triggerEvent, sizeof(triggerEvent), "CUSTOM"); + BaseString::snprintf(triggerEvent, sizeof(triggerEvent), "CUSTOM"); break; default: - snprintf(triggerEvent, sizeof(triggerEvent), "UNKNOWN [%d]", (int)sig->getTriggerEvent()); + BaseString::snprintf(triggerEvent, sizeof(triggerEvent), "UNKNOWN [%d]", (int)sig->getTriggerEvent()); break; } diff --git a/ndb/src/common/debugger/signaldata/DihContinueB.cpp b/ndb/src/common/debugger/signaldata/DihContinueB.cpp index 94453e76d72..9fece17315c 100644 --- a/ndb/src/common/debugger/signaldata/DihContinueB.cpp +++ b/ndb/src/common/debugger/signaldata/DihContinueB.cpp @@ -18,7 +18,10 @@ #include <signaldata/DihContinueB.hpp> bool -printCONTINUEB_DBDIH(FILE * output, const Uint32 * theData, Uint32 len){ +printCONTINUEB_DBDIH(FILE * output, const Uint32 * theData, + Uint32 len, Uint16 not_used){ + + (void)not_used; switch (theData[0]) { case DihContinueB::ZPACK_TABLE_INTO_PAGES: diff --git a/ndb/src/common/debugger/signaldata/Makefile.am b/ndb/src/common/debugger/signaldata/Makefile.am index 0a5806e1e00..c855c5f8a18 100644 --- a/ndb/src/common/debugger/signaldata/Makefile.am +++ b/ndb/src/common/debugger/signaldata/Makefile.am @@ -23,7 +23,8 @@ libsignaldataprint_la_SOURCES = \ FailRep.cpp DisconnectRep.cpp SignalDroppedRep.cpp \ SumaImpl.cpp NdbSttor.cpp CreateFragmentation.cpp \ UtilLock.cpp TuxMaint.cpp AccLock.cpp \ - LqhTrans.cpp ReadNodesConf.cpp CntrStart.cpp + LqhTrans.cpp ReadNodesConf.cpp CntrStart.cpp \ + ScanFrag.cpp include $(top_srcdir)/ndb/config/common.mk.am include $(top_srcdir)/ndb/config/type_ndbapi.mk.am diff --git a/ndb/src/common/debugger/signaldata/MasterLCP.cpp b/ndb/src/common/debugger/signaldata/MasterLCP.cpp index aa30404524f..078b92f6f2e 100644 --- a/ndb/src/common/debugger/signaldata/MasterLCP.cpp +++ b/ndb/src/common/debugger/signaldata/MasterLCP.cpp @@ -23,16 +23,16 @@ void print(char *buf, size_t buf_len, MasterLCPConf::State s){ switch(s){ case MasterLCPConf::LCP_STATUS_IDLE: - snprintf(buf, buf_len, "LCP_STATUS_IDLE"); + BaseString::snprintf(buf, buf_len, "LCP_STATUS_IDLE"); break; case MasterLCPConf::LCP_STATUS_ACTIVE: - snprintf(buf, buf_len, "LCP_STATUS_ACTIVE"); + BaseString::snprintf(buf, buf_len, "LCP_STATUS_ACTIVE"); break; case MasterLCPConf::LCP_TAB_COMPLETED: - snprintf(buf, buf_len, "LCP_TAB_COMPLETED"); + BaseString::snprintf(buf, buf_len, "LCP_TAB_COMPLETED"); break; case MasterLCPConf::LCP_TAB_SAVED: - snprintf(buf, buf_len, "LCP_TAB_SAVED"); + BaseString::snprintf(buf, buf_len, "LCP_TAB_SAVED"); break; } } diff --git a/ndb/src/common/debugger/signaldata/NdbfsContinueB.cpp b/ndb/src/common/debugger/signaldata/NdbfsContinueB.cpp index b3c7a61136e..9f55efae017 100644 --- a/ndb/src/common/debugger/signaldata/NdbfsContinueB.cpp +++ b/ndb/src/common/debugger/signaldata/NdbfsContinueB.cpp @@ -18,7 +18,10 @@ #include <signaldata/NdbfsContinueB.hpp> bool -printCONTINUEB_NDBFS(FILE * output, const Uint32 * theData, Uint32 len){ +printCONTINUEB_NDBFS(FILE * output, const Uint32 * theData, + Uint32 len, Uint16 not_used){ + + (void)not_used; switch (theData[0]) { case NdbfsContinueB::ZSCAN_MEMORYCHANNEL_10MS_DELAY: diff --git a/ndb/src/common/debugger/signaldata/ScanFrag.cpp b/ndb/src/common/debugger/signaldata/ScanFrag.cpp new file mode 100644 index 00000000000..4d19a325637 --- /dev/null +++ b/ndb/src/common/debugger/signaldata/ScanFrag.cpp @@ -0,0 +1,42 @@ +/* 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 <BlockNumbers.h> +#include <signaldata/ScanTab.hpp> +#include <signaldata/ScanFrag.hpp> + +bool +printSCAN_FRAGREQ(FILE * output, const Uint32 * theData, + Uint32 len, Uint16 receiverBlockNo) { + const ScanFragReq * const sig = (ScanFragReq *)theData; + fprintf(output, " senderData: %x\n", sig->senderData); + fprintf(output, " resultRef: %x\n", sig->resultRef); + fprintf(output, " savePointId: %x\n", sig->savePointId); + fprintf(output, " requestInfo: %x\n", sig->requestInfo); + fprintf(output, " tableId: %x\n", sig->tableId); + fprintf(output, " fragmentNo: %x\n", sig->fragmentNoKeyLen & 0xFFFF); + fprintf(output, " keyLen: %x\n", sig->fragmentNoKeyLen >> 16); + fprintf(output, " schemaVersion: %x\n", sig->schemaVersion); + fprintf(output, " transId1: %x\n", sig->transId1); + fprintf(output, " transId2: %x\n", sig->transId2); + fprintf(output, " clientOpPtr: %x\n", sig->clientOpPtr); + fprintf(output, " batch_size_rows: %x\n", sig->batch_size_rows); + fprintf(output, " batch_size_bytes: %x\n", sig->batch_size_bytes); + return true; +} + diff --git a/ndb/src/common/debugger/signaldata/ScanTab.cpp b/ndb/src/common/debugger/signaldata/ScanTab.cpp index 3f2109d9477..72a4d9f94b9 100644 --- a/ndb/src/common/debugger/signaldata/ScanTab.cpp +++ b/ndb/src/common/debugger/signaldata/ScanTab.cpp @@ -30,15 +30,18 @@ printSCANTABREQ(FILE * output, const Uint32 * theData, Uint32 len, Uint16 receiv fprintf(output, " apiConnectPtr: H\'%.8x", sig->apiConnectPtr); fprintf(output, " requestInfo: H\'%.8x:\n", requestInfo); - fprintf(output, " Parallellism: %u, Batch: %u LockMode: %u, Holdlock: %u, RangeScan: %u\n", + fprintf(output, " Parallellism: %u, Batch: %u LockMode: %u, Keyinfo: %u Holdlock: %u, RangeScan: %u\n", sig->getParallelism(requestInfo), sig->getScanBatch(requestInfo), sig->getLockMode(requestInfo), sig->getHoldLockFlag(requestInfo), - sig->getRangeScanFlag(requestInfo)); + sig->getRangeScanFlag(requestInfo), + sig->getKeyinfoFlag(requestInfo)); - fprintf(output, " attrLen: %d, tableId: %d, tableSchemaVer: %d\n", - sig->attrLen, sig->tableId, sig->tableSchemaVersion); + Uint32 keyLen = (sig->attrLenKeyLen >> 16); + Uint32 attrLen = (sig->attrLenKeyLen & 0xFFFF); + fprintf(output, " attrLen: %d, keyLen: %d tableId: %d, tableSchemaVer: %d\n", + attrLen, keyLen, sig->tableId, sig->tableSchemaVersion); fprintf(output, " transId(1, 2): (H\'%.8x, H\'%.8x) storedProcId: H\'%.8x\n", sig->transId1, sig->transId2, sig->storedProcId); diff --git a/ndb/src/common/debugger/signaldata/SignalDataPrint.cpp b/ndb/src/common/debugger/signaldata/SignalDataPrint.cpp index 65351663789..3314f0bd097 100644 --- a/ndb/src/common/debugger/signaldata/SignalDataPrint.cpp +++ b/ndb/src/common/debugger/signaldata/SignalDataPrint.cpp @@ -53,6 +53,7 @@ #include <signaldata/UtilPrepare.hpp> #include <signaldata/UtilExecute.hpp> #include <signaldata/ScanTab.hpp> +#include <signaldata/ScanFrag.hpp> #include <signaldata/LqhFrag.hpp> #include <signaldata/LqhTransConf.hpp> #include <signaldata/DropTab.hpp> @@ -75,12 +76,11 @@ #include <signaldata/TuxMaint.hpp> #include <signaldata/AccLock.hpp> -bool printCONTINUEB(FILE *, const Uint32 *, Uint32, Uint16); - /** * This is the register */ -const NameFunctionPair + +const NameFunctionPair SignalDataPrintFunctions[] = { { GSN_TCKEYREQ, printTCKEYREQ }, { GSN_TCKEYCONF, printTCKEYCONF }, @@ -250,10 +250,10 @@ SignalDataPrintFunctions[] = { ,{ GSN_TUX_MAINT_REQ, printTUX_MAINT_REQ } ,{ GSN_ACC_LOCKREQ, printACC_LOCKREQ } ,{ GSN_LQH_TRANSCONF, printLQH_TRANSCONF } + ,{ GSN_SCAN_FRAGREQ, printSCAN_FRAGREQ } + ,{ 0, 0 } }; -const unsigned short NO_OF_PRINT_FUNCTIONS = sizeof(SignalDataPrintFunctions)/sizeof(NameFunctionPair); - template class Bitmask<1>; template class Bitmask<2>; template class Bitmask<4>; diff --git a/ndb/src/common/debugger/signaldata/SignalNames.cpp b/ndb/src/common/debugger/signaldata/SignalNames.cpp index 9d4d5bdf6f5..9228e305677 100644 --- a/ndb/src/common/debugger/signaldata/SignalNames.cpp +++ b/ndb/src/common/debugger/signaldata/SignalNames.cpp @@ -446,6 +446,8 @@ const GsnName SignalNames [] = { ,{ GSN_STOP_REQ, "STOP_REQ" } ,{ GSN_STOP_REF, "STOP_REF" } + ,{ GSN_API_VERSION_REQ, "API_VERSION_REQ" } + ,{ GSN_API_VERSION_CONF, "API_VERSION_CONF" } ,{ GSN_ABORT_ALL_REQ, "ABORT_ALL_REQ" } ,{ GSN_ABORT_ALL_REF, "ABORT_ALL_REF" } diff --git a/ndb/src/common/debugger/signaldata/TcKeyConf.cpp b/ndb/src/common/debugger/signaldata/TcKeyConf.cpp index 727e097a464..652c2b8a557 100644 --- a/ndb/src/common/debugger/signaldata/TcKeyConf.cpp +++ b/ndb/src/common/debugger/signaldata/TcKeyConf.cpp @@ -22,38 +22,48 @@ printTCKEYCONF(FILE * output, const Uint32 * theData, Uint32 len, Uint16 receive if (receiverBlockNo == API_PACKED) { - fprintf(output, "Signal data: "); - Uint32 i = 0; - while (i < len) - fprintf(output, "H\'%.8x ", theData[i++]); - fprintf(output,"\n"); + return false; + Uint32 Theader = * theData++; + Uint32 TpacketLen = (Theader & 0x1F) + 3; + Uint32 TrecBlockNo = Theader >> 16; + + do { + fprintf(output, "Block: %d %d %d\n", TrecBlockNo, len, TpacketLen); + printTCKEYCONF(output, theData, TpacketLen, TrecBlockNo); + assert(len >= (1 + TpacketLen)); + len -= (1 + TpacketLen); + theData += TpacketLen; + } while(len); + return true; } else { const TcKeyConf * const sig = (TcKeyConf *) theData; - fprintf(output, "Signal data: "); Uint32 i = 0; Uint32 confInfo = sig->confInfo; Uint32 noOfOp = TcKeyConf::getNoOfOperations(confInfo); if (noOfOp > 10) noOfOp = 10; - while (i < len) - fprintf(output, "H\'%.8x ", theData[i++]); - fprintf(output,"\n"); - fprintf(output, "apiConnectPtr: H'%.8x, gci: %u, transId:(H'%.8x, H'%.8x)\n", + fprintf(output, " apiConnectPtr: H'%.8x, gci: %u, transId:(H'%.8x, H'%.8x)\n", sig->apiConnectPtr, sig->gci, sig->transId1, sig->transId2); - fprintf(output, "noOfOperations: %u, commitFlag: %s, markerFlag: %s\n", + fprintf(output, " noOfOperations: %u, commitFlag: %s, markerFlag: %s\n", noOfOp, (TcKeyConf::getCommitFlag(confInfo) == 0)?"false":"true", (TcKeyConf::getMarkerFlag(confInfo) == 0)?"false":"true"); fprintf(output, "Operations:\n"); for(i = 0; i < noOfOp; i++) { - fprintf(output, - "apiOperationPtr: H'%.8x, attrInfoLen: %u\n", - sig->operations[i].apiOperationPtr, - sig->operations[i].attrInfoLen); + if(sig->operations[i].attrInfoLen > TcKeyConf::SimpleReadBit) + fprintf(output, + " apiOperationPtr: H'%.8x, simplereadnode: %u\n", + sig->operations[i].apiOperationPtr, + sig->operations[i].attrInfoLen & (~TcKeyConf::SimpleReadBit)); + else + fprintf(output, + " apiOperationPtr: H'%.8x, attrInfoLen: %u\n", + sig->operations[i].apiOperationPtr, + sig->operations[i].attrInfoLen); } } - + return true; } diff --git a/ndb/src/common/logger/FileLogHandler.cpp b/ndb/src/common/logger/FileLogHandler.cpp index 632db71db15..29172ff93ad 100644 --- a/ndb/src/common/logger/FileLogHandler.cpp +++ b/ndb/src/common/logger/FileLogHandler.cpp @@ -153,11 +153,11 @@ FileLogHandler::createNewFile() if (fileNo >= m_maxNoFiles) { fileNo = 1; - ::snprintf(newName, sizeof(newName), + BaseString::snprintf(newName, sizeof(newName), "%s.%d", m_pLogFile->getName(), fileNo); break; } - ::snprintf(newName, sizeof(newName), + BaseString::snprintf(newName, sizeof(newName), "%s.%d", m_pLogFile->getName(), fileNo++); } while (File_class::exists(newName)); diff --git a/ndb/src/common/logger/LogHandler.cpp b/ndb/src/common/logger/LogHandler.cpp index 83d479c82fd..4fab957fc50 100644 --- a/ndb/src/common/logger/LogHandler.cpp +++ b/ndb/src/common/logger/LogHandler.cpp @@ -45,7 +45,7 @@ LogHandler::getDefaultHeader(char* pStr, const char* pCategory, Logger::LoggerLevel level) const { char time[MAX_DATE_TIME_HEADER_LENGTH]; - ::snprintf(pStr, MAX_HEADER_LENGTH, "%s [%s] %s -- ", + BaseString::snprintf(pStr, MAX_HEADER_LENGTH, "%s [%s] %s -- ", getTimeAsString((char*)time), pCategory, Logger::LoggerLevelNames[level]); @@ -84,7 +84,7 @@ LogHandler::getTimeAsString(char* pStr) const tm_now = ::localtime(&now); //uses the "current" timezone #endif - ::snprintf(pStr, MAX_DATE_TIME_HEADER_LENGTH, + BaseString::snprintf(pStr, MAX_DATE_TIME_HEADER_LENGTH, m_pDateTimeFormat, tm_now->tm_year + 1900, tm_now->tm_mon + 1, //month is [0,11]. +1 -> [1,12] diff --git a/ndb/src/common/logger/Logger.cpp b/ndb/src/common/logger/Logger.cpp index c2fdecb642b..fed5c211149 100644 --- a/ndb/src/common/logger/Logger.cpp +++ b/ndb/src/common/logger/Logger.cpp @@ -340,7 +340,7 @@ Logger::log(LoggerLevel logLevel, const char* pMsg, va_list ap) const while ( (pHandler = m_pHandlerList->next()) != NULL) { char buf[1024]; - vsnprintf(buf, sizeof(buf), pMsg, ap); + BaseString::vsnprintf(buf, sizeof(buf), pMsg, ap); pHandler->append(m_pCategory, logLevel, buf); } } diff --git a/ndb/src/common/logger/listtest/LogHandlerListUnitTest.cpp b/ndb/src/common/logger/listtest/LogHandlerListUnitTest.cpp index 44ee11717b4..7de9ee46479 100644 --- a/ndb/src/common/logger/listtest/LogHandlerListUnitTest.cpp +++ b/ndb/src/common/logger/listtest/LogHandlerListUnitTest.cpp @@ -48,7 +48,7 @@ int main(int argc, char* argv[]) { ndbout << "-- " << " Test " << i + 1 << " [" << testCases[i].name << "] --" << endl; - snprintf(str, 256, "%s %s %s %d", "Logging ", + BaseString::snprintf(str, 256, "%s %s %s %d", "Logging ", testCases[i].name, " message ", i); if (testCases[i].test(str)) { @@ -128,7 +128,7 @@ LogHandlerListUnitTest::testTraverseNext(const char* msg) { char* str = new char[3]; pHandlers[i] = new ConsoleLogHandler(); - ::snprintf(str, 3, "%d", i); + BaseString::snprintf(str, 3, "%d", i); pHandlers[i]->setDateTimeFormat(str); list.add(pHandlers[i]); } diff --git a/ndb/src/common/logger/loggertest/LoggerUnitTest.cpp b/ndb/src/common/logger/loggertest/LoggerUnitTest.cpp index 017dcb79c1f..990d2e0eada 100644 --- a/ndb/src/common/logger/loggertest/LoggerUnitTest.cpp +++ b/ndb/src/common/logger/loggertest/LoggerUnitTest.cpp @@ -86,7 +86,7 @@ NDB_COMMAND(loggertest, "loggertest", "loggertest -console | -file", { ndbout << "-- " << " Test " << i + 1 << " [" << testCases[i].name << "] --" << endl; - ::snprintf(str, 256, "%s %s %s %d", "Logging ", + BaseString::snprintf(str, 256, "%s %s %s %d", "Logging ", testCases[i].name, " message ", i); if (testCases[i].test(str)) { diff --git a/ndb/src/common/mgmcommon/ConfigRetriever.cpp b/ndb/src/common/mgmcommon/ConfigRetriever.cpp index b4f2d0b9897..d8417ac146a 100644 --- a/ndb/src/common/mgmcommon/ConfigRetriever.cpp +++ b/ndb/src/common/mgmcommon/ConfigRetriever.cpp @@ -186,7 +186,7 @@ ConfigRetriever::getConfig(const char * filename){ const int res = stat(filename, &sbuf); if(res != 0){ char buf[255]; - snprintf(buf, sizeof(buf), "Could not find file: \"%s\"", filename); + BaseString::snprintf(buf, sizeof(buf), "Could not find file: \"%s\"", filename); setError(CR_ERROR, buf); return 0; } @@ -211,7 +211,7 @@ ConfigRetriever::getConfig(const char * filename){ ConfigValuesFactory cvf; if(!cvf.unpack(buf2, bytes)){ char buf[255]; - snprintf(buf, sizeof(buf), "Error while unpacking"); + BaseString::snprintf(buf, sizeof(buf), "Error while unpacking"); setError(CR_ERROR, buf); delete []buf2; return 0; @@ -241,7 +241,7 @@ ConfigRetriever::verifyConfig(const struct ndb_mgm_configuration * conf, Uint32 it = ndb_mgm_create_configuration_iterator((struct ndb_mgm_configuration *)conf, CFG_SECTION_NODE); if(it == 0){ - snprintf(buf, 255, "Unable to create config iterator"); + BaseString::snprintf(buf, 255, "Unable to create config iterator"); setError(CR_ERROR, buf); return false; @@ -249,14 +249,14 @@ ConfigRetriever::verifyConfig(const struct ndb_mgm_configuration * conf, Uint32 NdbAutoPtr<ndb_mgm_configuration_iterator> ptr(it); if(ndb_mgm_find(it, CFG_NODE_ID, nodeid) != 0){ - snprintf(buf, 255, "Unable to find node with id: %d", nodeid); + BaseString::snprintf(buf, 255, "Unable to find node with id: %d", nodeid); setError(CR_ERROR, buf); return false; } const char * hostname; if(ndb_mgm_get_string_parameter(it, CFG_NODE_HOST, &hostname)){ - snprintf(buf, 255, "Unable to get hostname(%d) from config",CFG_NODE_HOST); + BaseString::snprintf(buf, 255, "Unable to get hostname(%d) from config",CFG_NODE_HOST); setError(CR_ERROR, buf); return false; } @@ -268,7 +268,7 @@ ConfigRetriever::verifyConfig(const struct ndb_mgm_configuration * conf, Uint32 if (hostname && hostname[0] != 0 && !SocketServer::tryBind(0,hostname)) { - snprintf(buf, 255, "Config hostname(%s) don't match a local interface," + BaseString::snprintf(buf, 255, "Config hostname(%s) don't match a local interface," " tried to bind, error = %d - %s", hostname, errno, strerror(errno)); setError(CR_ERROR, buf); @@ -277,14 +277,14 @@ ConfigRetriever::verifyConfig(const struct ndb_mgm_configuration * conf, Uint32 unsigned int _type; if(ndb_mgm_get_int_parameter(it, CFG_TYPE_OF_SECTION, &_type)){ - snprintf(buf, 255, "Unable to get type of node(%d) from config", + BaseString::snprintf(buf, 255, "Unable to get type of node(%d) from config", CFG_TYPE_OF_SECTION); setError(CR_ERROR, buf); return false; } if(_type != m_node_type){ - snprintf(buf, 255, "Supplied node type(%d) and config node type(%d) " + BaseString::snprintf(buf, 255, "Supplied node type(%d) and config node type(%d) " " don't match", m_node_type, _type); setError(CR_ERROR, buf); return false; diff --git a/ndb/src/common/mgmcommon/LocalConfig.cpp b/ndb/src/common/mgmcommon/LocalConfig.cpp index cc66f357236..3cd4341c6b7 100644 --- a/ndb/src/common/mgmcommon/LocalConfig.cpp +++ b/ndb/src/common/mgmcommon/LocalConfig.cpp @@ -40,7 +40,7 @@ LocalConfig::init(const char *connectString, //1. Check connectString if(connectString != 0 && connectString[0] != 0){ - if(readConnectString(connectString)){ + if(readConnectString(connectString, "connect string")){ return true; } return false; @@ -59,7 +59,7 @@ LocalConfig::init(const char *connectString, char buf[255]; if(NdbEnv_GetEnv("NDB_CONNECTSTRING", buf, sizeof(buf)) && strlen(buf) != 0){ - if(readConnectString(buf)){ + if(readConnectString(buf, "NDB_CONNECTSTRING")){ return true; } return false; @@ -90,8 +90,8 @@ LocalConfig::init(const char *connectString, //7. Check { char buf[256]; - snprintf(buf, sizeof(buf), "host=localhost:%s", NDB_BASE_PORT); - if(readConnectString(buf)) + BaseString::snprintf(buf, sizeof(buf), "host=localhost:%s", NDB_BASE_PORT); + if(readConnectString(buf, "default connect string")) return true; } @@ -109,8 +109,10 @@ void LocalConfig::setError(int lineNumber, const char * _msg) { } void LocalConfig::printError() const { - ndbout << "Local configuration error"<< endl - << "Line: "<< error_line << ", " << error_msg << endl << endl; + ndbout << "Configuration error" << endl; + if (error_line) + ndbout << "Line: "<< error_line << ", "; + ndbout << error_msg << endl << endl; } void LocalConfig::printUsage() const { @@ -140,7 +142,7 @@ const char *nodeIdTokens[] = { const char *hostNameTokens[] = { "host://%[^:]:%i", "host=%[^:]:%i", - "%[^:]:%i", + "%[^:^=^ ]:%i", "%s %i", 0 }; @@ -192,7 +194,7 @@ LocalConfig::parseFileName(const char * buf){ } bool -LocalConfig::parseString(const char * connectString, char *line){ +LocalConfig::parseString(const char * connectString, BaseString &err){ char * for_strtok; char * copy = strdup(connectString); NdbAutoPtr<char> tmp_aptr(copy); @@ -212,15 +214,12 @@ LocalConfig::parseString(const char * connectString, char *line){ if (found_other = parseFileName(tok)) continue; - if (line) - snprintf(line, 150, "Unexpected entry: \"%s\"", tok); + err.assfmt("Unexpected entry: \"%s\"", tok); return false; } if (!found_other) { - if (line) - snprintf(line, 150, "Missing host/file name extry in \"%s\"", - connectString); + err.appfmt("Missing host/file name extry in \"%s\"", connectString); return false; } @@ -235,7 +234,8 @@ bool LocalConfig::readFile(const char * filename, bool &fopenError) FILE * file = fopen(filename, "r"); if(file == 0){ - snprintf(line, 150, "Unable to open local config file: %s", filename); + BaseString::snprintf(line, sizeof(line), + "Unable to open local config file: %s", filename); setError(0, line); fopenError = true; return false; @@ -243,7 +243,7 @@ bool LocalConfig::readFile(const char * filename, bool &fopenError) BaseString theString; - while(fgets(line, 1024, file)){ + while(fgets(line, sizeof(line), file)){ BaseString tmp(line); tmp.trim(" \t\n\r"); if(tmp.length() > 0 && tmp.c_str()[0] != '#'){ @@ -251,7 +251,7 @@ bool LocalConfig::readFile(const char * filename, bool &fopenError) break; } } - while (fgets(line, 1024, file)) { + while (fgets(line, sizeof(line), file)) { BaseString tmp(line); tmp.trim(" \t\n\r"); if(tmp.length() > 0 && tmp.c_str()[0] != '#'){ @@ -260,11 +260,12 @@ bool LocalConfig::readFile(const char * filename, bool &fopenError) } } - bool return_value = parseString(theString.c_str(), line); + BaseString err; + bool return_value = parseString(theString.c_str(), err); if (!return_value) { BaseString tmp; - tmp.assfmt("Reading %s: %s", filename, line); + tmp.assfmt("Reading %s: %s", filename, err.c_str()); setError(0, tmp.c_str()); } @@ -273,12 +274,14 @@ bool LocalConfig::readFile(const char * filename, bool &fopenError) } bool -LocalConfig::readConnectString(const char * connectString){ - char line[150], line2[150]; - bool return_value = parseString(connectString, line); +LocalConfig::readConnectString(const char * connectString, + const char * info){ + BaseString err; + bool return_value = parseString(connectString, err); if (!return_value) { - snprintf(line2, 150, "Reading NDB_CONNECTSTRING \"%s\": %s", connectString, line); - setError(0,line2); + BaseString err2; + err2.assfmt("Reading %d \"%s\": %s", info, connectString, err.c_str()); + setError(0,err2.c_str()); } return return_value; } diff --git a/ndb/src/common/portlib/NdbDaemon.c b/ndb/src/common/portlib/NdbDaemon.c index d8d33595156..c73b5927ff4 100644 --- a/ndb/src/common/portlib/NdbDaemon.c +++ b/ndb/src/common/portlib/NdbDaemon.c @@ -28,6 +28,8 @@ NdbDaemon_Make(const char* lockfile, const char* logfile, unsigned flags) int lockfd = -1, logfd = -1, n; char buf[64]; + (void)flags; /* remove warning for unused parameter */ + /* Check that we have write access to lock file */ assert(lockfile != NULL); lockfd = open(lockfile, O_CREAT|O_RDWR, 0644); diff --git a/ndb/src/common/portlib/NdbMem.c b/ndb/src/common/portlib/NdbMem.c index c077d6650ce..f964f4d9937 100644 --- a/ndb/src/common/portlib/NdbMem.c +++ b/ndb/src/common/portlib/NdbMem.c @@ -42,6 +42,7 @@ void* NdbMem_Allocate(size_t size) void* NdbMem_AllocateAlign(size_t size, size_t alignment) { + (void)alignment; /* remove warning for unused parameter */ /* return (void*)memalign(alignment, size); TEMP fix diff --git a/ndb/src/common/portlib/NdbSleep.c b/ndb/src/common/portlib/NdbSleep.c index 8702a25d1b1..19ab526fda8 100644 --- a/ndb/src/common/portlib/NdbSleep.c +++ b/ndb/src/common/portlib/NdbSleep.c @@ -16,7 +16,7 @@ #include <ndb_global.h> -#include "NdbSleep.h" +#include <NdbSleep.h> int NdbSleep_MilliSleep(int milliseconds){ diff --git a/ndb/src/common/portlib/NdbThread.c b/ndb/src/common/portlib/NdbThread.c index 60687a9053e..69e39994a9c 100644 --- a/ndb/src/common/portlib/NdbThread.c +++ b/ndb/src/common/portlib/NdbThread.c @@ -42,6 +42,8 @@ struct NdbThread* NdbThread_Create(NDB_THREAD_FUNC *p_thread_func, int result; pthread_attr_t thread_attr; + (void)thread_prio; /* remove warning for unused parameter */ + if (p_thread_func == NULL) return 0; @@ -49,8 +51,7 @@ struct NdbThread* NdbThread_Create(NDB_THREAD_FUNC *p_thread_func, if (tmpThread == NULL) return NULL; - snprintf(tmpThread->thread_name, sizeof(tmpThread->thread_name), - "%s", p_thread_name); + strnmov(tmpThread->thread_name,p_thread_name,sizeof(tmpThread->thread_name)); pthread_attr_init(&thread_attr); pthread_attr_setstacksize(&thread_attr, thread_stack_size); @@ -109,6 +110,7 @@ int NdbThread_SetConcurrencyLevel(int level) #ifdef USE_PTHREAD_EXTRAS return pthread_setconcurrency(level); #else + (void)level; /* remove warning for unused parameter */ return 0; #endif } diff --git a/ndb/src/common/portlib/memtest.c b/ndb/src/common/portlib/memtest.c index 059a4ec025e..673f23fa803 100644 --- a/ndb/src/common/portlib/memtest.c +++ b/ndb/src/common/portlib/memtest.c @@ -90,7 +90,7 @@ void malloctest(int loopcount, int memsize, int touch) { long long start=0; int total=0; int i=0, j=0; - int size=memsize*1024*1024; //bytes; + int size=memsize*1024*1024; /*bytes*/; float mean; char * ptr =0; @@ -126,7 +126,7 @@ void mmaptest(int loopcount, int memsize, int touch) { int total=0; int i=0, j=0; char * ptr; - int size=memsize*1024*1024; //bytes; + int size=memsize*1024*1024; /*bytes*/; float mean; printf("Staring mmaptest "); @@ -165,7 +165,7 @@ void unmaptest(loopcount, memsize) int total=0; int i=0, j=0; char * ptr; - int size=memsize*1024*1024; //bytes; + int size=memsize*1024*1024; /*bytes*/; float mean; printf("Staring munmap test (loopcount = 1 no matter what you prev. set)\n"); @@ -215,7 +215,7 @@ void freetest(int loopcount, int memsize) { long long start=0; int total=0; int i=0, j=0; - int size=memsize*1024*1024; //bytes; + int size=memsize*1024*1024; /*bytes*/; float mean; char * ptr =0; diff --git a/ndb/src/common/transporter/OSE_Receiver.cpp b/ndb/src/common/transporter/OSE_Receiver.cpp index b7d47b2f88c..63a33fc8f24 100644 --- a/ndb/src/common/transporter/OSE_Receiver.cpp +++ b/ndb/src/common/transporter/OSE_Receiver.cpp @@ -41,7 +41,7 @@ OSE_Receiver::OSE_Receiver(TransporterRegistry * tr, phantomCreated = false; localNodeId = _localNodeId; - snprintf(localHostName, sizeof(localHostName), + BaseString::snprintf(localHostName, sizeof(localHostName), "ndb_node%d", localNodeId); DEBUG("localNodeId = " << localNodeId << " -> localHostName = " diff --git a/ndb/src/common/transporter/OSE_Transporter.cpp b/ndb/src/common/transporter/OSE_Transporter.cpp index c9b0f777319..a52862a80e5 100644 --- a/ndb/src/common/transporter/OSE_Transporter.cpp +++ b/ndb/src/common/transporter/OSE_Transporter.cpp @@ -51,10 +51,10 @@ OSE_Transporter::OSE_Transporter(int _prioASignalSize, prioBSignalSize = _prioBSignalSize; if (strcmp(lHostName, rHostName) == 0){ - snprintf(remoteNodeName, sizeof(remoteNodeName), + BaseString::snprintf(remoteNodeName, sizeof(remoteNodeName), "ndb_node%d", remoteNodeId); } else { - snprintf(remoteNodeName, sizeof(remoteNodeName), + BaseString::snprintf(remoteNodeName, sizeof(remoteNodeName), "%s/ndb_node%d", rHostName, remoteNodeId); } diff --git a/ndb/src/common/transporter/TCP_Transporter.cpp b/ndb/src/common/transporter/TCP_Transporter.cpp index 7cfdc224b34..524ecd653e0 100644 --- a/ndb/src/common/transporter/TCP_Transporter.cpp +++ b/ndb/src/common/transporter/TCP_Transporter.cpp @@ -362,7 +362,7 @@ TCP_Transporter::doReceive() { // Select-function must return the socket for read // before this method is called // It reads the external TCP/IP interface once - int size = receiveBuffer.sizeOfBuffer - receiveBuffer.sizeOfData; + Uint32 size = receiveBuffer.sizeOfBuffer - receiveBuffer.sizeOfData; if(size > 0){ const int nBytesRead = recv(theSocket, receiveBuffer.insertPtr, diff --git a/ndb/src/common/transporter/Transporter.cpp b/ndb/src/common/transporter/Transporter.cpp index 7a469252c00..e68bc86718e 100644 --- a/ndb/src/common/transporter/Transporter.cpp +++ b/ndb/src/common/transporter/Transporter.cpp @@ -32,7 +32,7 @@ Transporter::Transporter(TransporterRegistry &t_reg, NodeId rNodeId, int _byteorder, bool _compression, bool _checksum, bool _signalId) - : m_r_port(r_port), localNodeId(lNodeId), remoteNodeId(rNodeId), + : m_r_port(r_port), remoteNodeId(rNodeId), localNodeId(lNodeId), isServer(lNodeId < rNodeId), m_packer(_signalId, _checksum), m_transporter_registry(t_reg) diff --git a/ndb/src/common/transporter/perftest/perfTransporterTest.cpp b/ndb/src/common/transporter/perftest/perfTransporterTest.cpp index d33221c2835..71df9f12a4c 100644 --- a/ndb/src/common/transporter/perftest/perfTransporterTest.cpp +++ b/ndb/src/common/transporter/perftest/perfTransporterTest.cpp @@ -276,7 +276,7 @@ printReport(TestPhase & p){ char buf[255]; if(p.signalSize != 0){ - snprintf(buf, 255, + BaseString::snprintf(buf, 255, "%d\t%d\t%s\t%s\t%s\t%s\t%d\t%d", p.noOfSignals, 4*p.signalSize, @@ -287,7 +287,7 @@ printReport(TestPhase & p){ (int)(p.sendLenBytes / (p.sendCount == 0 ? 1 : p.sendCount)), (int)(p.recvLenBytes / (p.recvCount == 0 ? 1 : p.recvCount))); } else { - snprintf(buf, 255, + BaseString::snprintf(buf, 255, "%d\trand\t%s\t%s\t%s\t%s\t%d\t%d", p.noOfSignals, st, diff --git a/ndb/src/common/transporter/priotest/prioTransporterTest.cpp b/ndb/src/common/transporter/priotest/prioTransporterTest.cpp index 0fce6aaad39..6c5623a49a6 100644 --- a/ndb/src/common/transporter/priotest/prioTransporterTest.cpp +++ b/ndb/src/common/transporter/priotest/prioTransporterTest.cpp @@ -375,7 +375,7 @@ printReport(TestPhase & p){ char buf[255]; if(p.signalSize != 0){ - snprintf(buf, 255, + BaseString::snprintf(buf, 255, "%d\t%d\t%d\t%s\t%s\t%s\t%d\t%d\t%d\t%d", p.noOfSignals, p.signalSize, @@ -388,7 +388,7 @@ printReport(TestPhase & p){ (int)(p.totTimePrioA / p.loopCount), (int)(p.bytesSentBeforePrioA)); } else { - snprintf(buf, 255, + BaseString::snprintf(buf, 255, "%d\trand\t4*rand\t%s\t%s\t%s\t%d\t%d\t%d\t%d", p.noOfSignals, st, diff --git a/ndb/src/common/util/BaseString.cpp b/ndb/src/common/util/BaseString.cpp index 8b7df485f77..dbff44c377d 100644 --- a/ndb/src/common/util/BaseString.cpp +++ b/ndb/src/common/util/BaseString.cpp @@ -17,6 +17,7 @@ /* -*- c-basic-offset: 4; -*- */ #include <ndb_global.h> #include <BaseString.hpp> +#include <basestring_vsnprintf.h> BaseString::BaseString() { @@ -127,14 +128,14 @@ BaseString::assfmt(const char *fmt, ...) * when called as vsnprintf(NULL, 0, ...). */ va_start(ap, fmt); - l = vsnprintf(buf, sizeof(buf), fmt, ap) + 1; + l = basestring_vsnprintf(buf, sizeof(buf), fmt, ap) + 1; va_end(ap); if(l > (int)m_len) { delete[] m_chr; m_chr = new char[l]; } va_start(ap, fmt); - vsnprintf(m_chr, l, fmt, ap); + basestring_vsnprintf(m_chr, l, fmt, ap); va_end(ap); m_len = strlen(m_chr); return *this; @@ -152,11 +153,11 @@ BaseString::appfmt(const char *fmt, ...) * when called as vsnprintf(NULL, 0, ...). */ va_start(ap, fmt); - l = vsnprintf(buf, sizeof(buf), fmt, ap) + 1; + l = basestring_vsnprintf(buf, sizeof(buf), fmt, ap) + 1; va_end(ap); char *tmp = new char[l]; va_start(ap, fmt); - vsnprintf(tmp, l, fmt, ap); + basestring_vsnprintf(tmp, l, fmt, ap); va_end(ap); append(tmp); delete[] tmp; @@ -335,6 +336,22 @@ BaseString::trim(char * str, const char * delim){ return str; } +int +BaseString::vsnprintf(char *str, size_t size, const char *format, va_list ap) +{ + return(basestring_vsnprintf(str, size, format, ap)); +} + +int +BaseString::snprintf(char *str, size_t size, const char *format, ...) +{ + va_list ap; + va_start(ap, format); + int ret= basestring_vsnprintf(str, size, format, ap); + va_end(ap); + return(ret); +} + #ifdef TEST_BASE_STRING diff --git a/ndb/src/common/util/ConfigValues.cpp b/ndb/src/common/util/ConfigValues.cpp index 8a14882550c..5c4b17c73ca 100644 --- a/ndb/src/common/util/ConfigValues.cpp +++ b/ndb/src/common/util/ConfigValues.cpp @@ -1,9 +1,6 @@ + +#include <ndb_global.h> #include <ConfigValues.hpp> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <assert.h> -#include <new> #include <NdbOut.hpp> #include <NdbTCP.h> diff --git a/ndb/src/common/util/File.cpp b/ndb/src/common/util/File.cpp index 22d262a0d27..f3faa8c4f7f 100644 --- a/ndb/src/common/util/File.cpp +++ b/ndb/src/common/util/File.cpp @@ -83,7 +83,7 @@ File_class::File_class(const char* aFileName, const char* mode) : m_file(NULL), m_fileMode(mode) { - ::snprintf(m_fileName, MAX_FILE_NAME_SIZE, aFileName); + BaseString::snprintf(m_fileName, MAX_FILE_NAME_SIZE, aFileName); } bool @@ -99,7 +99,7 @@ File_class::open(const char* aFileName, const char* mode) /** * Only copy if it's not the same string */ - ::snprintf(m_fileName, MAX_FILE_NAME_SIZE, aFileName); + BaseString::snprintf(m_fileName, MAX_FILE_NAME_SIZE, aFileName); } m_fileMode = mode; bool rc = true; diff --git a/ndb/src/common/util/Makefile.am b/ndb/src/common/util/Makefile.am index efb249dd330..0235adae7c9 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 ndb_init.c + ConfigValues.cpp ndb_init.c basestring_vsnprintf.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/NdbErrHnd.cpp b/ndb/src/common/util/NdbErrHnd.cpp index f1c28a7bbdd..38a67f29853 100644 --- a/ndb/src/common/util/NdbErrHnd.cpp +++ b/ndb/src/common/util/NdbErrHnd.cpp @@ -346,53 +346,53 @@ extern "C" OSBOOLEAN ndb_err_hnd(bool user_called, file_name = "ose_err.h"; } - snprintf (error_message.header1, + BaseString::snprintf(error_message.header1, BUFSIZE, "This is the OSE Example System Error handler\r\n"); - snprintf (error_message.err_hnd_file, + BaseString::snprintf(error_message.err_hnd_file, BUFSIZE, "located in: " __FILE__ "\r\n"); - snprintf (error_message.header2, + BaseString::snprintf(error_message.header2, BUFSIZE, "An Error has been reported:\r\n"); if (user_called == (OSBOOLEAN) 0 ) { - snprintf(error_message.user_called_line, + BaseString::snprintf(error_message.user_called_line, BUFSIZE, "user_called: 0x%x (Error detected by the kernel)\r\n", user_called); } else { - snprintf(error_message.user_called_line, + BaseString::snprintf(error_message.user_called_line, BUFSIZE, "user_called: 0x%x (Error detected by an application)\r\n", user_called); } - snprintf (error_message.error_code_line, + BaseString::snprintf(error_message.error_code_line, BUFSIZE, "error code: 0x%08x\r\n", error_code); - snprintf (error_message.subcode_line, + BaseString::snprintf(error_message.subcode_line, BUFSIZE, " subcode: %s (0x%08x)\r\n", subcode_mnemonic, ( subcode << 16)); - snprintf (error_message.product_line, + BaseString::snprintf(error_message.product_line, BUFSIZE, " product: %s\r\n", product_name); - snprintf (error_message.header_file_line, + BaseString::snprintf(error_message.header_file_line, BUFSIZE, " header file: %s\r\n", file_name); - snprintf (error_message.extra_line, + BaseString::snprintf(error_message.extra_line, BUFSIZE, "extra: 0x%08x\r\n", extra); @@ -401,22 +401,22 @@ extern "C" OSBOOLEAN ndb_err_hnd(bool user_called, struct OS_pcb *pcb = get_pcb(current_process()); const char *process_name = &pcb->strings[pcb->name]; - snprintf(error_message.current_process_id_line, + BaseString::snprintf(error_message.current_process_id_line, BUFSIZE, "Current Process: 0x%08x\r\n", current_process()); - snprintf(error_message.current_process_name_line, + BaseString::snprintf(error_message.current_process_name_line, BUFSIZE, "Process Name: %s\r\n", process_name); - snprintf(error_message.file_line, + BaseString::snprintf(error_message.file_line, BUFSIZE, "File: %s\r\n", &pcb->strings[pcb->file]); - snprintf(error_message.line_line, + BaseString::snprintf(error_message.line_line, BUFSIZE, "Line: %d\r\n", pcb->line); @@ -452,7 +452,7 @@ extern "C" OSBOOLEAN ndb_err_hnd(bool user_called, char *expr = ((char **)extra)[0]; char *file = ((char **)extra)[1]; unsigned line = ((unsigned *)extra)[2]; - snprintf(assert_line, BUFSIZE, "Assertion Failed: %s:%u: %s\r\n", file, line, expr); + BaseString::snprintf(assert_line, BUFSIZE, "Assertion Failed: %s:%u: %s\r\n", file, line, expr); ndbout << assert_line; } } @@ -467,13 +467,13 @@ extern "C" OSBOOLEAN ndb_err_hnd(bool user_called, const char *rcv_name = &rcv->strings[rcv->name]; struct OS_pcb *snd = get_pcb(snd_); const char *snd_name = &snd->strings[snd->name]; - snprintf(unknown_signal_line, BUFSIZE, + BaseString::snprintf(unknown_signal_line, BUFSIZE, "Unknown Signal Received\r\n"); - snprintf(unknown_signal_line, BUFSIZE, + BaseString::snprintf(unknown_signal_line, BUFSIZE, "Signal Number: 0x%08lx\r\n", signo); - snprintf(unknown_signal_line, BUFSIZE, + BaseString::snprintf(unknown_signal_line, BUFSIZE, "Sending Process: 0x%08lx (%s))\r\n", snd_, snd_name); - snprintf(unknown_signal_line, BUFSIZE, + BaseString::snprintf(unknown_signal_line, BUFSIZE, "Receiving Process: 0x%08lx (%s))\r\n", rcv_, rcv_name); free_buf((union SIGNAL **)&rcv); free_buf((union SIGNAL **)&snd); } diff --git a/ndb/src/common/util/NdbOut.cpp b/ndb/src/common/util/NdbOut.cpp index 6d76cf22402..fa74cb364f3 100644 --- a/ndb/src/common/util/NdbOut.cpp +++ b/ndb/src/common/util/NdbOut.cpp @@ -102,7 +102,7 @@ NdbOut::print(const char * fmt, ...){ va_start(ap, fmt); if (fmt != 0) - vsnprintf(buf, sizeof(buf)-1, fmt, ap); + BaseString::vsnprintf(buf, sizeof(buf)-1, fmt, ap); ndbout << buf; va_end(ap); } @@ -114,7 +114,7 @@ NdbOut::println(const char * fmt, ...){ va_start(ap, fmt); if (fmt != 0) - vsnprintf(buf, sizeof(buf)-1, fmt, ap); + BaseString::vsnprintf(buf, sizeof(buf)-1, fmt, ap); ndbout << buf << endl; va_end(ap); } @@ -127,7 +127,7 @@ ndbout_c(const char * fmt, ...){ va_start(ap, fmt); if (fmt != 0) - vsnprintf(buf, sizeof(buf)-1, fmt, ap); + BaseString::vsnprintf(buf, sizeof(buf)-1, fmt, ap); ndbout << buf << endl; va_end(ap); } diff --git a/ndb/src/common/util/OutputStream.cpp b/ndb/src/common/util/OutputStream.cpp index bf3599dbac9..a41eef649dd 100644 --- a/ndb/src/common/util/OutputStream.cpp +++ b/ndb/src/common/util/OutputStream.cpp @@ -74,7 +74,7 @@ SoftOseOutputStream::print(const char * fmt, ...){ va_start(ap, fmt); if (fmt != 0) - vsnprintf(buf, sizeof(buf)-1, fmt, ap); + BaseString::vsnprintf(buf, sizeof(buf)-1, fmt, ap); else buf[0] = 0; va_end(ap); @@ -88,7 +88,7 @@ SoftOseOutputStream::println(const char * fmt, ...){ va_start(ap, fmt); if (fmt != 0) - vsnprintf(buf, sizeof(buf)-1, fmt, ap); + BaseString::vsnprintf(buf, sizeof(buf)-1, fmt, ap); else buf[0] = 0; va_end(ap); diff --git a/ndb/src/common/util/Properties.cpp b/ndb/src/common/util/Properties.cpp index 80fb0027830..a13e31780eb 100644 --- a/ndb/src/common/util/Properties.cpp +++ b/ndb/src/common/util/Properties.cpp @@ -371,7 +371,7 @@ Properties::print(FILE * out, const char * prefix) const{ break; case PropertiesType_Properties: char buf2 [1024]; - snprintf(buf2, sizeof(buf2), "%s%s%c",buf, impl->content[i]->name, + BaseString::snprintf(buf2, sizeof(buf2), "%s%s%c",buf, impl->content[i]->name, Properties::delimiter); ((Properties *)impl->content[i]->value)->print(out, buf2); break; @@ -994,7 +994,7 @@ bool Properties::put(const char * name, Uint32 no, Uint32 val, bool replace){ size_t tmp_len = strlen(name)+20; char * tmp = (char*)malloc(tmp_len); - snprintf(tmp, tmp_len, "%s_%d", name, no); + BaseString::snprintf(tmp, tmp_len, "%s_%d", name, no); bool res = put(tmp, val, replace); free(tmp); return res; @@ -1004,7 +1004,7 @@ bool Properties::put64(const char * name, Uint32 no, Uint64 val, bool replace){ size_t tmp_len = strlen(name)+20; char * tmp = (char*)malloc(tmp_len); - snprintf(tmp, tmp_len, "%s_%d", name, no); + BaseString::snprintf(tmp, tmp_len, "%s_%d", name, no); bool res = put(tmp, val, replace); free(tmp); return res; @@ -1015,7 +1015,7 @@ bool Properties::put(const char * name, Uint32 no, const char * val, bool replace){ size_t tmp_len = strlen(name)+20; char * tmp = (char*)malloc(tmp_len); - snprintf(tmp, tmp_len, "%s_%d", name, no); + BaseString::snprintf(tmp, tmp_len, "%s_%d", name, no); bool res = put(tmp, val, replace); free(tmp); return res; @@ -1027,7 +1027,7 @@ Properties::put(const char * name, Uint32 no, const Properties * val, bool replace){ size_t tmp_len = strlen(name)+20; char * tmp = (char*)malloc(tmp_len); - snprintf(tmp, tmp_len, "%s_%d", name, no); + BaseString::snprintf(tmp, tmp_len, "%s_%d", name, no); bool res = put(tmp, val, replace); free(tmp); return res; @@ -1039,7 +1039,7 @@ Properties::getTypeOf(const char * name, Uint32 no, PropertiesType * type) const { size_t tmp_len = strlen(name)+20; char * tmp = (char*)malloc(tmp_len); - snprintf(tmp, tmp_len, "%s_%d", name, no); + BaseString::snprintf(tmp, tmp_len, "%s_%d", name, no); bool res = getTypeOf(tmp, type); free(tmp); return res; @@ -1049,7 +1049,7 @@ bool Properties::contains(const char * name, Uint32 no) const { size_t tmp_len = strlen(name)+20; char * tmp = (char*)malloc(tmp_len); - snprintf(tmp, tmp_len, "%s_%d", name, no); + BaseString::snprintf(tmp, tmp_len, "%s_%d", name, no); bool res = contains(tmp); free(tmp); return res; @@ -1059,7 +1059,7 @@ bool Properties::get(const char * name, Uint32 no, Uint32 * value) const{ size_t tmp_len = strlen(name)+20; char * tmp = (char*)malloc(tmp_len); - snprintf(tmp, tmp_len, "%s_%d", name, no); + BaseString::snprintf(tmp, tmp_len, "%s_%d", name, no); bool res = get(tmp, value); free(tmp); return res; @@ -1069,7 +1069,7 @@ bool Properties::get(const char * name, Uint32 no, Uint64 * value) const{ size_t tmp_len = strlen(name)+20; char * tmp = (char*)malloc(tmp_len); - snprintf(tmp, tmp_len, "%s_%d", name, no); + BaseString::snprintf(tmp, tmp_len, "%s_%d", name, no); bool res = get(tmp, value); free(tmp); return res; @@ -1080,7 +1080,7 @@ bool Properties::get(const char * name, Uint32 no, const char ** value) const { size_t tmp_len = strlen(name)+20; char * tmp = (char*)malloc(tmp_len); - snprintf(tmp, tmp_len, "%s_%d", name, no); + BaseString::snprintf(tmp, tmp_len, "%s_%d", name, no); bool res = get(tmp, value); free(tmp); return res; @@ -1091,7 +1091,7 @@ bool Properties::get(const char * name, Uint32 no, const Properties ** value) const{ size_t tmp_len = strlen(name)+20; char * tmp = (char*)malloc(tmp_len); - snprintf(tmp, tmp_len, "%s_%d", name, no); + BaseString::snprintf(tmp, tmp_len, "%s_%d", name, no); bool res = get(tmp, value); free(tmp); return res; @@ -1102,7 +1102,7 @@ bool Properties::getCopy(const char * name, Uint32 no, char ** value) const { size_t tmp_len = strlen(name)+20; char * tmp = (char*)malloc(tmp_len); - snprintf(tmp, tmp_len, "%s_%d", name, no); + BaseString::snprintf(tmp, tmp_len, "%s_%d", name, no); bool res = getCopy(tmp, value); free(tmp); return res; @@ -1113,7 +1113,7 @@ bool Properties::getCopy(const char * name, Uint32 no, Properties ** value) const { size_t tmp_len = strlen(name)+20; char * tmp = (char*)malloc(tmp_len); - snprintf(tmp, tmp_len, "%s_%d", name, no); + BaseString::snprintf(tmp, tmp_len, "%s_%d", name, no); bool res = getCopy(tmp, value); free(tmp); return res; diff --git a/ndb/src/common/util/SimpleProperties.cpp b/ndb/src/common/util/SimpleProperties.cpp index c3980f03c4d..00c440fcb4e 100644 --- a/ndb/src/common/util/SimpleProperties.cpp +++ b/ndb/src/common/util/SimpleProperties.cpp @@ -293,7 +293,7 @@ SimpleProperties::Reader::printAll(NdbOut& ndbout){ break; default: ndbout << "Unknown type for key: " << getKey() - << " type: " << getValueType() << endl; + << " type: " << (Uint32)getValueType() << endl; } } } diff --git a/ndb/src/common/util/basestring_vsnprintf.c b/ndb/src/common/util/basestring_vsnprintf.c new file mode 100644 index 00000000000..10932226d18 --- /dev/null +++ b/ndb/src/common/util/basestring_vsnprintf.c @@ -0,0 +1,37 @@ +/* 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 */ + +/* define on IRIX to get posix compliant vsnprintf */ +#define _XOPEN_SOURCE 500 +#include <stdio.h> +#include <basestring_vsnprintf.h> + +int +basestring_snprintf(char *str, size_t size, const char *format, ...) +{ + int ret; + va_list ap; + va_start(ap, format); + ret= basestring_vsnprintf(str, size, format, ap); + va_end(ap); + return(ret); +} + +int +basestring_vsnprintf(char *str, size_t size, const char *format, va_list ap) +{ + return(vsnprintf(str, size, format, ap)); +} diff --git a/ndb/src/common/util/socket_io.cpp b/ndb/src/common/util/socket_io.cpp index b2f4ef91031..6f4c7e63684 100644 --- a/ndb/src/common/util/socket_io.cpp +++ b/ndb/src/common/util/socket_io.cpp @@ -175,13 +175,13 @@ vprint_socket(NDB_SOCKET_TYPE socket, int timeout_millis, size_t size = sizeof(buf); if (fmt != 0) { - size = vsnprintf(buf, sizeof(buf), fmt, ap); + size = BaseString::vsnprintf(buf, sizeof(buf), fmt, ap); /* Check if the output was truncated */ if(size >= sizeof(buf)) { buf2 = (char *)malloc(size+1); if(buf2 == NULL) return -1; - vsnprintf(buf2, size, fmt, ap); + BaseString::vsnprintf(buf2, size, fmt, ap); } else size = sizeof(buf); } else @@ -202,13 +202,13 @@ vprintln_socket(NDB_SOCKET_TYPE socket, int timeout_millis, size_t size = sizeof(buf); if (fmt != 0) { - size = vsnprintf(buf, sizeof(buf), fmt, ap); + size = BaseString::vsnprintf(buf, sizeof(buf), fmt, ap); /* Check if the output was truncated */ if(size >= sizeof(buf)-1) { buf2 = (char *)malloc(size+2); if(buf2 == NULL) return -1; - vsnprintf(buf2, size+1, fmt, ap); + BaseString::vsnprintf(buf2, size+1, fmt, ap); } else size = sizeof(buf); } else diff --git a/ndb/src/cw/cpcd/APIService.cpp b/ndb/src/cw/cpcd/APIService.cpp index de0e40cebfc..63d0aaafe86 100644 --- a/ndb/src/cw/cpcd/APIService.cpp +++ b/ndb/src/cw/cpcd/APIService.cpp @@ -309,7 +309,7 @@ propToString(Properties *prop, const char *key) { case PropertiesType_Uint32: Uint32 val; prop->get(key, &val); - snprintf(buf, sizeof buf, "%d", val); + BaseString::snprintf(buf, sizeof buf, "%d", val); retval = buf; break; case PropertiesType_char: @@ -318,7 +318,7 @@ propToString(Properties *prop, const char *key) { retval = str; break; default: - snprintf(buf, sizeof buf, "(unknown)"); + BaseString::snprintf(buf, sizeof buf, "(unknown)"); retval = buf; } return retval; diff --git a/ndb/src/cw/cpcd/CPCD.cpp b/ndb/src/cw/cpcd/CPCD.cpp index bc9f350755f..69a7b840528 100644 --- a/ndb/src/cw/cpcd/CPCD.cpp +++ b/ndb/src/cw/cpcd/CPCD.cpp @@ -237,9 +237,9 @@ CPCD::saveProcessList(){ FILE *f; /* Create the filenames that we will use later */ - snprintf(newfile, sizeof(newfile), "%s.new", m_procfile.c_str()); - snprintf(oldfile, sizeof(oldfile), "%s.old", m_procfile.c_str()); - snprintf(curfile, sizeof(curfile), "%s", m_procfile.c_str()); + BaseString::snprintf(newfile, sizeof(newfile), "%s.new", m_procfile.c_str()); + BaseString::snprintf(oldfile, sizeof(oldfile), "%s.old", m_procfile.c_str()); + BaseString::snprintf(curfile, sizeof(curfile), "%s", m_procfile.c_str()); f = fopen(newfile, "w"); @@ -380,7 +380,7 @@ CPCD::getProcessList() { void CPCD::RequestStatus::err(enum RequestStatusCode status, const char *msg) { m_status = status; - snprintf(m_errorstring, sizeof(m_errorstring), "%s", msg); + BaseString::snprintf(m_errorstring, sizeof(m_errorstring), "%s", msg); } #if 0 diff --git a/ndb/src/cw/cpcd/Process.cpp b/ndb/src/cw/cpcd/Process.cpp index c38b2a45145..2d3973d1aba 100644 --- a/ndb/src/cw/cpcd/Process.cpp +++ b/ndb/src/cw/cpcd/Process.cpp @@ -140,7 +140,7 @@ CPCD::Process::readPid() { memset(buf, 0, sizeof(buf)); - snprintf(filename, sizeof(filename), "%d", m_id); + BaseString::snprintf(filename, sizeof(filename), "%d", m_id); f = fopen(filename, "r"); @@ -167,8 +167,8 @@ CPCD::Process::writePid(int pid) { char filename[PATH_MAX*2+1]; FILE *f; - snprintf(tmpfilename, sizeof(tmpfilename), "tmp.XXXXXX"); - snprintf(filename, sizeof(filename), "%d", m_id); + BaseString::snprintf(tmpfilename, sizeof(tmpfilename), "tmp.XXXXXX"); + BaseString::snprintf(filename, sizeof(filename), "%d", m_id); int fd = mkstemp(tmpfilename); if(fd < 0) { @@ -439,7 +439,7 @@ void CPCD::Process::stop() { char filename[PATH_MAX*2+1]; - snprintf(filename, sizeof(filename), "%d", m_id); + BaseString::snprintf(filename, sizeof(filename), "%d", m_id); unlink(filename); if(m_pid <= 1){ diff --git a/ndb/src/kernel/blocks/ERROR_codes.txt b/ndb/src/kernel/blocks/ERROR_codes.txt index 43532a973f9..70f11c33cd7 100644 --- a/ndb/src/kernel/blocks/ERROR_codes.txt +++ b/ndb/src/kernel/blocks/ERROR_codes.txt @@ -3,7 +3,7 @@ Next NDBCNTR 1000 Next NDBFS 2000 Next DBACC 3001 Next DBTUP 4007 -Next DBLQH 5040 +Next DBLQH 5042 Next DBDICT 6006 Next DBDIH 7174 Next DBTC 8035 @@ -193,6 +193,8 @@ Delay execution of ABORTREQ signal 2 seconds to generate time-out. 5038: Drop LQHKEYREQ + set 5039 5039: Drop ABORT + set 5003 +8048: Make TC not choose own node for simple/dirty read +5041: Crash is receiving simple read from other TC on different node ERROR CODES FOR TESTING TIME-OUT HANDLING IN DBTC ------------------------------------------------- diff --git a/ndb/src/kernel/blocks/backup/Backup.cpp b/ndb/src/kernel/blocks/backup/Backup.cpp index 08a8bf83e20..e6fe63d9014 100644 --- a/ndb/src/kernel/blocks/backup/Backup.cpp +++ b/ndb/src/kernel/blocks/backup/Backup.cpp @@ -1307,7 +1307,7 @@ Backup::sendCreateTrig(Signal* signal, for (int i=0; i < 3; i++) { req->setTriggerEvent(triggerEventValues[i]); - snprintf(triggerName, sizeof(triggerName), triggerNameFormat[i], + BaseString::snprintf(triggerName, sizeof(triggerName), triggerNameFormat[i], ptr.p->backupId, tabPtr.p->tableId); w.reset(); w.add(CreateTrigReq::TriggerNameKey, triggerName); @@ -1945,7 +1945,7 @@ Backup::sendDropTrig(Signal* signal, BackupRecordPtr ptr, TablePtr tabPtr) sendSignal(DBDICT_REF, GSN_DROP_TRIG_REQ, signal, DropTrigReq::SignalLength, JBB); } else { - snprintf(triggerName, sizeof(triggerName), triggerNameFormat[i], + BaseString::snprintf(triggerName, sizeof(triggerName), triggerNameFormat[i], ptr.p->backupId, tabPtr.p->tableId); w.reset(); w.add(CreateTrigReq::TriggerNameKey, triggerName); @@ -3360,7 +3360,7 @@ Backup::execBACKUP_FRAGMENT_REQ(Signal* signal) req->senderData = filePtr.i; req->resultRef = reference(); req->schemaVersion = table.schemaVersion; - req->fragmentNo = fragNo; + req->fragmentNoKeyLen = fragNo; req->requestInfo = 0; req->savePointId = 0; req->tableId = table.tableId; diff --git a/ndb/src/kernel/blocks/backup/restore/Restore.cpp b/ndb/src/kernel/blocks/backup/restore/Restore.cpp index 9e1ad228ee5..fb3bde6bdef 100644 --- a/ndb/src/kernel/blocks/backup/restore/Restore.cpp +++ b/ndb/src/kernel/blocks/backup/restore/Restore.cpp @@ -515,7 +515,7 @@ BackupFile::setCtlFile(Uint32 nodeId, Uint32 backupId, const char * path){ m_expectedFileHeader.FileType = BackupFormat::CTL_FILE; char name[PATH_MAX]; const Uint32 sz = sizeof(name); - snprintf(name, sz, "BACKUP-%d.%d.ctl", backupId, nodeId); + BaseString::snprintf(name, sz, "BACKUP-%d.%d.ctl", backupId, nodeId); setName(path, name); } @@ -526,7 +526,7 @@ BackupFile::setDataFile(const BackupFile & bf, Uint32 no){ m_expectedFileHeader.FileType = BackupFormat::DATA_FILE; char name[PATH_MAX]; const Uint32 sz = sizeof(name); - snprintf(name, sz, "BACKUP-%d-%d.%d.Data", + BaseString::snprintf(name, sz, "BACKUP-%d-%d.%d.Data", m_expectedFileHeader.BackupId, no, m_nodeId); setName(bf.m_path, name); } @@ -538,7 +538,7 @@ BackupFile::setLogFile(const BackupFile & bf, Uint32 no){ m_expectedFileHeader.FileType = BackupFormat::LOG_FILE; char name[PATH_MAX]; const Uint32 sz = sizeof(name); - snprintf(name, sz, "BACKUP-%d.%d.log", + BaseString::snprintf(name, sz, "BACKUP-%d.%d.log", m_expectedFileHeader.BackupId, m_nodeId); setName(bf.m_path, name); } @@ -548,15 +548,15 @@ BackupFile::setName(const char * p, const char * n){ const Uint32 sz = sizeof(m_path); if(p != 0 && strlen(p) > 0){ if(p[strlen(p)-1] == '/'){ - snprintf(m_path, sz, "%s", p); + BaseString::snprintf(m_path, sz, "%s", p); } else { - snprintf(m_path, sz, "%s%s", p, "/"); + BaseString::snprintf(m_path, sz, "%s%s", p, "/"); } } else { m_path[0] = 0; } - snprintf(m_fileName, sizeof(m_fileName), "%s%s", m_path, n); + BaseString::snprintf(m_fileName, sizeof(m_fileName), "%s%s", m_path, n); debug << "Filename = " << m_fileName << endl; } @@ -936,8 +936,9 @@ operator<<(NdbOut& ndbout, const TableS & table){ for (int j = 0; j < table.getNoOfAttributes(); j++) { const AttributeDesc * desc = table[j]; - ndbout << desc->m_column->getName() << ": " << desc->m_column->getType(); - ndbout << " key: " << desc->m_column->getPrimaryKey(); + ndbout << desc->m_column->getName() << ": " + << (Uint32) desc->m_column->getType(); + ndbout << " key: " << (Uint32) desc->m_column->getPrimaryKey(); ndbout << " array: " << desc->arraySize; ndbout << " size: " << desc->size << endl; } // for diff --git a/ndb/src/kernel/blocks/backup/restore/Restore.hpp b/ndb/src/kernel/blocks/backup/restore/Restore.hpp index 8ca68fd9b23..0ec1ab852e9 100644 --- a/ndb/src/kernel/blocks/backup/restore/Restore.hpp +++ b/ndb/src/kernel/blocks/backup/restore/Restore.hpp @@ -91,7 +91,7 @@ class TupleS { private: friend class RestoreDataIterator; - TableS *m_currentTable; + class TableS *m_currentTable; AttributeData *allAttrData; bool prepareRecord(TableS &); diff --git a/ndb/src/kernel/blocks/backup/restore/consumer_restore.cpp b/ndb/src/kernel/blocks/backup/restore/consumer_restore.cpp index fb82570b0b9..a35d9d22c65 100644 --- a/ndb/src/kernel/blocks/backup/restore/consumer_restore.cpp +++ b/ndb/src/kernel/blocks/backup/restore/consumer_restore.cpp @@ -121,7 +121,7 @@ BackupRestore::get_table(const NdbDictionary::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); + BaseString::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()]; diff --git a/ndb/src/kernel/blocks/dbacc/Dbacc.hpp b/ndb/src/kernel/blocks/dbacc/Dbacc.hpp index 3bf50026c4b..169b77c0d85 100644 --- a/ndb/src/kernel/blocks/dbacc/Dbacc.hpp +++ b/ndb/src/kernel/blocks/dbacc/Dbacc.hpp @@ -1087,10 +1087,10 @@ private: void deleteLongKey(Signal* signal); void removeFromPageArrayList(Signal* signal); void insertPageArrayList(Signal* signal); - void checkPageArrayList(Signal* signal, char *); - void checkPageB4Insert(Uint32, char *); - void checkPageB4Remove(Uint32, char *); - void checkIndexInLongKeyPage(Uint32, char *); + void checkPageArrayList(Signal* signal, const char *); + void checkPageB4Insert(Uint32, const char *); + void checkPageB4Remove(Uint32, const char *); + void checkIndexInLongKeyPage(Uint32, const char *); void printoutInfoAndShutdown(LongKeyPage *); void releaseLongPage(Signal* signal); void abortOperation(Signal* signal); diff --git a/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp b/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp index 79034c9eb36..9a1bbd86562 100644 --- a/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp +++ b/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp @@ -2369,7 +2369,7 @@ void Dbacc::execACC_COMMITREQ(Signal* signal) ptrCheckGuard(rootfragrecptr, crootfragmentsize, rootfragmentrec); rootfragrecptr.p->noOfElements++; fragrecptr.p->slack -= operationRecPtr.p->insertDeleteLen; - if (fragrecptr.p->slack >= (Uint32)(1 << 31)) { + if (fragrecptr.p->slack >= (1u << 31)) { /* IT MEANS THAT IF SLACK < ZERO */ if (fragrecptr.p->expandFlag == 0) { jam(); @@ -2479,7 +2479,7 @@ void Dbacc::execACC_LOCKREQ(Signal* signal) Uint32 opCode = ZSCAN_OP; signal->theData[0] = operationRecPtr.i; signal->theData[1] = fragrecptr.i; - signal->theData[2] = opCode | (lockMode << 4) | (1 << 31); + signal->theData[2] = opCode | (lockMode << 4) | (1u << 31); signal->theData[3] = req->hashValue; signal->theData[4] = 1; // fake primKeyLen signal->theData[5] = req->transId1; @@ -4051,7 +4051,7 @@ void Dbacc::deleteLongKey(Signal* signal) }//Dbacc::deleteLongKey() -void Dbacc::checkIndexInLongKeyPage(Uint32 pageId, char *calledFrom) { +void Dbacc::checkIndexInLongKeyPage(Uint32 pageId, const char *calledFrom) { Page8Ptr pagePtr; LongKeyPage *page; Uint32 indexNo; @@ -4206,7 +4206,7 @@ void Dbacc::insertPageArrayList(Signal* signal) // --------------------------------------------------------------------------------- */ // Check the page array list. // --------------------------------------------------------------------------------- */ -void Dbacc::checkPageArrayList(Signal* signal, char *calledFrom) +void Dbacc::checkPageArrayList(Signal* signal, const char *calledFrom) { Page8Ptr pagePtr; Uint32 pageArrayIndex; @@ -4251,7 +4251,7 @@ void Dbacc::checkPageArrayList(Signal* signal, char *calledFrom) // --------------------------------------------------------------------------------- */ // Check the page to put into the pageArrayList. // --------------------------------------------------------------------------------- */ -void Dbacc::checkPageB4Insert(Uint32 pageId, char *calledFrom) { +void Dbacc::checkPageB4Insert(Uint32 pageId, const char *calledFrom) { Page8Ptr pagePtr; Uint32 pageArrayIndex; LongKeyPage *page; @@ -4318,7 +4318,7 @@ void Dbacc::checkPageB4Insert(Uint32 pageId, char *calledFrom) { // --------------------------------------------------------------------------------- */ // Check the page to remove from the pageArrayList. // --------------------------------------------------------------------------------- */ -void Dbacc::checkPageB4Remove(Uint32 pageId, char *calledFrom) { +void Dbacc::checkPageB4Remove(Uint32 pageId, const char *calledFrom) { Page8Ptr pagePtr; Uint32 pageArrayIndex; Uint32 noOfOccurrence = 0; @@ -6510,7 +6510,7 @@ void Dbacc::endofexpLab(Signal* signal) Uint32 noOfBuckets = (fragrecptr.p->maxp + 1) + fragrecptr.p->p; Uint32 Thysteres = fragrecptr.p->maxloadfactor - fragrecptr.p->minloadfactor; fragrecptr.p->slackCheck = noOfBuckets * Thysteres; - if (fragrecptr.p->slack > (Uint32)(1 << 31)) { + if (fragrecptr.p->slack > (1u << 31)) { jam(); /* IT MEANS THAT IF SLACK < ZERO */ /* --------------------------------------------------------------------------------- */ @@ -6974,7 +6974,7 @@ void Dbacc::execSHRINKCHECK2(Signal* signal) /*--------------------------------------------------------------*/ return; }//if - if (fragrecptr.p->slack > (Uint32)(1 << 31)) { + if (fragrecptr.p->slack > (1u << 31)) { jam(); /*--------------------------------------------------------------*/ /* THE SLACK IS NEGATIVE, IN THIS CASE WE WILL NOT NEED ANY */ @@ -7213,7 +7213,7 @@ void Dbacc::endofshrinkbucketLab(Signal* signal) expDirRangePtr.p->dirArray[fragrecptr.p->expSenderDirIndex >> 8] = RNIL; }//if }//if - if (fragrecptr.p->slack < (Uint32)(1 << 31)) { + if (fragrecptr.p->slack < (1u << 31)) { jam(); /*--------------------------------------------------------------*/ /* THE SLACK IS POSITIVE, IN THIS CASE WE WILL CHECK WHETHER */ @@ -13411,8 +13411,12 @@ Dbacc::execREAD_PSUEDO_REQ(Signal* signal){ default: tmp = 0; } - Uint32 * src = (Uint32*)&tmp; - signal->theData[0] = src[0]; - signal->theData[1] = src[1]; + memcpy(signal->theData, &tmp, 8); /* must be memcpy, gives strange results on + * ithanium gcc (GCC) 3.4.1 smp linux 2.4 + * otherwise + */ + // Uint32 * src = (Uint32*)&tmp; + // signal->theData[0] = src[0]; + // signal->theData[1] = src[1]; } diff --git a/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp b/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp index 572e9f39ba5..76aa745c3e0 100644 --- a/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp +++ b/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp @@ -1438,7 +1438,7 @@ void Dbdih::execREAD_NODESCONF(Signal* signal) continue; } char buf[255]; - snprintf(buf, sizeof(buf), + BaseString::snprintf(buf, sizeof(buf), "Illegal configuration change." " Initial start needs to be performed " " when changing no of storage nodes (node %d)", i); @@ -1638,7 +1638,7 @@ void Dbdih::execSTART_PERMREQ(Signal* signal) }//if if (getNodeStatus(nodeId) != NodeRecord::DEAD){ ndbout << "nodeStatus in START_PERMREQ = " - << getNodeStatus(nodeId) << endl; + << (Uint32) getNodeStatus(nodeId) << endl; ndbrequire(false); }//if @@ -3500,7 +3500,7 @@ void Dbdih::selectMasterCandidateAndSend(Signal* signal) Uint32 count = node_groups[nodePtr.i]; if(count != 0 && count != cnoReplicas){ char buf[255]; - snprintf(buf, sizeof(buf), + BaseString::snprintf(buf, sizeof(buf), "Illegal configuration change." " Initial start needs to be performed " " when changing no of replicas (%d != %d)", @@ -4268,7 +4268,7 @@ void Dbdih::failedNodeLcpHandling(Signal* signal, NodeRecordPtr failedNodePtr) failedNodePtr.p->activeStatus = Sysfile::NS_NotActive_NotTakenOver; break; default: - ndbout << "activeStatus = " << failedNodePtr.p->activeStatus; + ndbout << "activeStatus = " << (Uint32) failedNodePtr.p->activeStatus; ndbout << " at failure after NODE_FAILREP of node = "; ndbout << failedNodePtr.i << endl; ndbrequire(false); @@ -4618,6 +4618,7 @@ void Dbdih::execMASTER_GCPREQ(Signal* signal) /* BUT NOT YET COMPLETED. */ /*--------------------------------------------------*/ ndbrequire(false); + gcpState= MasterGCPConf::GCP_READY; // remove warning break; default: /*------------------------------------------------*/ @@ -4627,6 +4628,7 @@ void Dbdih::execMASTER_GCPREQ(Signal* signal) /* NODE WHICH WAS NOT A MASTER NODE. */ /*------------------------------------------------*/ ndbrequire(false); + gcpState= MasterGCPConf::GCP_READY; // remove warning break; }//switch MasterGCPConf * const masterGCPConf = (MasterGCPConf *)&signal->theData[0]; @@ -5535,6 +5537,7 @@ Dbdih::sendMASTER_LCPCONF(Signal * signal){ * it not allowed */ ndbrequire(false); + lcpState= MasterLCPConf::LCP_STATUS_IDLE; // remove warning break; case LCP_COPY_GCI: case LCP_INIT_TABLES: @@ -5543,6 +5546,7 @@ Dbdih::sendMASTER_LCPCONF(Signal * signal){ * These two states are handled by if statements above */ ndbrequire(false); + lcpState= MasterLCPConf::LCP_STATUS_IDLE; // remove warning break; }//switch ndbrequire(ok); @@ -6198,7 +6202,8 @@ void Dbdih::execCREATE_FRAGMENTATION_REQ(Signal * signal){ if (primaryTableId == RNIL) { if(fragmentNode == 0){ jam(); - NGPtr.i = c_nextNodeGroup; + // needs to be fixed for single fragment tables + NGPtr.i = 0; //c_nextNodeGroup; c_nextNodeGroup = (NGPtr.i + 1 == cnoOfNodeGroups ? 0 : NGPtr.i + 1); } else if(! (fragmentNode < MAX_NDB_NODES)) { jam(); @@ -6255,20 +6260,22 @@ void Dbdih::execCREATE_FRAGMENTATION_REQ(Signal * signal){ //@todo use section writer Uint32 count = 2; Uint32 fragments[2 + 8*MAX_REPLICAS*MAX_NDB_NODES]; + Uint32 next_replica_node[MAX_NDB_NODES]; + memset(next_replica_node,0,sizeof(next_replica_node)); if (primaryTableId == RNIL) { jam(); for(Uint32 fragNo = 0; fragNo<noOfFragments; fragNo++){ jam(); ptrCheckGuard(NGPtr, MAX_NDB_NODES, nodeGroupRecord); - Uint32 ind = NGPtr.p->nextReplicaNode; + Uint32 ind = next_replica_node[NGPtr.i]; const Uint32 max = NGPtr.p->nodeCount; //------------------------------------------------------------------- // We make an extra step to ensure that the primary replicas are // spread among the nodes. //------------------------------------------------------------------- - NGPtr.p->nextReplicaNode = (ind + 1 >= max ? 0 : ind + 1); + next_replica_node[NGPtr.i] = (ind + 1 >= max ? 0 : ind + 1); for(Uint32 replicaNo = 0; replicaNo<noOfReplicas; replicaNo++){ jam(); @@ -7127,7 +7134,7 @@ void Dbdih::checkGcpStopLab(Signal* signal) jam(); #ifdef VM_TRACE ndbout << "System crash due to GCP Stop in state = "; - ndbout << cgcpStatus << endl; + ndbout << (Uint32) cgcpStatus << endl; #endif crashSystemAtGcpStop(signal); return; @@ -7141,7 +7148,7 @@ void Dbdih::checkGcpStopLab(Signal* signal) jam(); #ifdef VM_TRACE ndbout << "System crash due to GCP Stop in state = "; - ndbout << cgcpStatus << endl; + ndbout << (Uint32) cgcpStatus << endl; #endif crashSystemAtGcpStop(signal); return; @@ -8631,7 +8638,7 @@ void Dbdih::startFragment(Signal* signal, Uint32 tableId, Uint32 fragId) /* POSSIBLE TO RESTORE THE SYSTEM. */ /* --------------------------------------------------------------------- */ char buf[100]; - snprintf(buf, sizeof(buf), + BaseString::snprintf(buf, sizeof(buf), "Unable to find restorable replica for " "table: %d fragment: %d gci: %d", tableId, fragId, SYSFILE->newestRestorableGCI); @@ -9074,7 +9081,7 @@ void Dbdih::checkTcCounterLab(Signal* signal) { CRASH_INSERTION(7009); if (c_lcpState.lcpStatus != LCP_STATUS_IDLE) { - ndbout << "lcpStatus = " << c_lcpState.lcpStatus; + ndbout << "lcpStatus = " << (Uint32) c_lcpState.lcpStatus; ndbout << "lcpStatusUpdatedPlace = " << c_lcpState.lcpStatusUpdatedPlace << endl; ndbrequire(false); @@ -12735,6 +12742,7 @@ void Dbdih::setNodeRestartInfoBits() break; default: ndbrequire(false); + tsnrNodeActiveStatus = Sysfile::NS_NotDefined; // remove warning break; }//switch Sysfile::setNodeStatus(nodePtr.i, SYSFILE->nodeStatus, @@ -12939,7 +12947,7 @@ Dbdih::execDUMP_STATE_ORD(Signal* signal) snprintf(buf, sizeof(buf), " Table %d Fragment %d - ", tabPtr.i, j); for(Uint32 k = 0; k < noOfReplicas; k++){ char tmp[100]; - snprintf(tmp, sizeof(tmp), "%d ", nodeOrder[k]); + BaseString::snprintf(tmp, sizeof(tmp), "%d ", nodeOrder[k]); strcat(buf, tmp); } infoEvent(buf); @@ -13155,12 +13163,12 @@ Dbdih::execDUMP_STATE_ORD(Signal* signal) replicaPtr.i = fragPtr.p->storedReplicas; do { ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord); - snprintf(buf2, sizeof(buf2), "%s %d(on %d)=%d(%s)", + BaseString::snprintf(buf2, sizeof(buf2), "%s %d(on %d)=%d(%s)", buf, num, replicaPtr.p->procNode, replicaPtr.p->lcpIdStarted, replicaPtr.p->lcpOngoingFlag ? "Ongoing" : "Idle"); - snprintf(buf, sizeof(buf), "%s", buf2); + BaseString::snprintf(buf, sizeof(buf), "%s", buf2); num++; replicaPtr.i = replicaPtr.p->nextReplica; diff --git a/ndb/src/kernel/blocks/dblqh/Dblqh.hpp b/ndb/src/kernel/blocks/dblqh/Dblqh.hpp index a94af7b59c8..d6987f3e478 100644 --- a/ndb/src/kernel/blocks/dblqh/Dblqh.hpp +++ b/ndb/src/kernel/blocks/dblqh/Dblqh.hpp @@ -234,10 +234,6 @@ #define ZNODE_UP 0 #define ZNODE_DOWN 1 /* ------------------------------------------------------------------------- */ -/* OPERATION TYPES */ -/* ------------------------------------------------------------------------- */ -#define ZSIMPLE_READ 1 -/* ------------------------------------------------------------------------- */ /* START PHASES */ /* ------------------------------------------------------------------------- */ #define ZLAST_START_PHASE 255 @@ -2248,7 +2244,7 @@ private: void sendAttrinfoLoop(Signal* signal); void sendAttrinfoSignal(Signal* signal); void sendLqhAttrinfoSignal(Signal* signal); - void sendKeyinfoAcc(Signal* signal); + void sendKeyinfoAcc(Signal* signal, Uint32 pos); Uint32 initScanrec(const class ScanFragReq *); void initScanTc(Signal* signal, Uint32 transid1, @@ -2437,6 +2433,7 @@ private: void abortStateHandlerLab(Signal* signal); void writeAttrinfoLab(Signal* signal); void scanAttrinfoLab(Signal* signal, Uint32* dataPtr, Uint32 length); + void abort_scan(Signal* signal, Uint32 scan_ptr_i, Uint32 errcode); void localAbortStateHandlerLab(Signal* signal); void logLqhkeyreqLab(Signal* signal); void lqhAttrinfoLab(Signal* signal, Uint32* dataPtr, Uint32 length); diff --git a/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp b/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp index 8342870d69c..cd15ad0c3b2 100644 --- a/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp +++ b/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp @@ -2803,8 +2803,10 @@ void Dblqh::execKEYINFO(Signal* signal) return; }//if TcConnectionrec * const regTcPtr = tcConnectptr.p; - if (regTcPtr->transactionState != - TcConnectionrec::WAIT_TUPKEYINFO) { + TcConnectionrec::TransactionState state = regTcPtr->transactionState; + if (state != TcConnectionrec::WAIT_TUPKEYINFO && + state != TcConnectionrec::WAIT_SCAN_AI) + { jam(); /*****************************************************************************/ /* TRANSACTION WAS ABORTED, THIS IS MOST LIKELY A SIGNAL BELONGING TO THE */ @@ -2823,14 +2825,20 @@ void Dblqh::execKEYINFO(Signal* signal) }//if jam(); terrorCode = errorCode; - abortErrorLab(signal); + if(state == TcConnectionrec::WAIT_TUPKEYINFO) + abortErrorLab(signal); + else + abort_scan(signal, regTcPtr->tcScanRec, errorCode); return; }//if - FragrecordPtr regFragptr; - regFragptr.i = regTcPtr->fragmentptr; - ptrCheckGuard(regFragptr, cfragrecFileSize, fragrecord); - fragptr = regFragptr; - endgettupkeyLab(signal); + if(state == TcConnectionrec::WAIT_TUPKEYINFO) + { + FragrecordPtr regFragptr; + regFragptr.i = regTcPtr->fragmentptr; + ptrCheckGuard(regFragptr, cfragrecFileSize, fragrecord); + fragptr = regFragptr; + endgettupkeyLab(signal); + } return; }//Dblqh::execKEYINFO() @@ -2838,9 +2846,9 @@ void Dblqh::execKEYINFO(Signal* signal) /* FILL IN KEY DATA INTO DATA BUFFERS. */ /* ------------------------------------------------------------------------- */ Uint32 Dblqh::handleLongTupKey(Signal* signal, - Uint32 keyLength, - Uint32 primKeyLength, - Uint32* dataPtr) + Uint32 keyLength, + Uint32 primKeyLength, + Uint32* dataPtr) { TcConnectionrec * const regTcPtr = tcConnectptr.p; Uint32 dataPos = 0; @@ -3293,12 +3301,15 @@ void Dblqh::execLQHKEYREQ(Signal* signal) regTcPtr->dirtyOp = LqhKeyReq::getDirtyFlag(Treqinfo); regTcPtr->opExec = LqhKeyReq::getInterpretedFlag(Treqinfo); regTcPtr->opSimple = LqhKeyReq::getSimpleFlag(Treqinfo); - regTcPtr->simpleRead = ((Treqinfo >> 18) & 15); regTcPtr->operation = LqhKeyReq::getOperation(Treqinfo); + regTcPtr->simpleRead = regTcPtr->operation == ZREAD && regTcPtr->opSimple; regTcPtr->seqNoReplica = LqhKeyReq::getSeqNoReplica(Treqinfo); UintR TreclenAiLqhkey = LqhKeyReq::getAIInLqhKeyReq(Treqinfo); regTcPtr->apiVersionNo = 0; + CRASH_INSERTION2(5041, regTcPtr->simpleRead && + refToNode(signal->senderBlockRef()) != cownNodeid); + regTcPtr->reclenAiLqhkey = TreclenAiLqhkey; regTcPtr->currReclenAi = TreclenAiLqhkey; UintR TitcKeyLen = LqhKeyReq::getKeyLen(Treqinfo); @@ -3425,7 +3436,7 @@ void Dblqh::execLQHKEYREQ(Signal* signal) if ((tfragDistKey != TdistKey) && (regTcPtr->seqNoReplica == 0) && (regTcPtr->dirtyOp == ZFALSE) && - (regTcPtr->simpleRead != ZSIMPLE_READ)) { + (regTcPtr->simpleRead == ZFALSE)) { /* ---------------------------------------------------------------------- * WE HAVE DIFFERENT OPINION THAN THE DIH THAT STARTED THE TRANSACTION. * THE REASON COULD BE THAT THIS IS AN OLD DISTRIBUTION WHICH IS NO LONGER @@ -3433,7 +3444,7 @@ void Dblqh::execLQHKEYREQ(Signal* signal) * ONE IS ADDED TO THE DISTRIBUTION KEY EVERY TIME WE ADD A NEW REPLICA. * FAILED REPLICAS DO NOT AFFECT THE DISTRIBUTION KEY. THIS MEANS THAT THE * MAXIMUM DEVIATION CAN BE ONE BETWEEN THOSE TWO VALUES. - * ---------------------------------------------------------------------- */ + * --------------------------------------------------------------------- */ Int32 tmp = TdistKey - tfragDistKey; tmp = (tmp < 0 ? - tmp : tmp); if ((tmp <= 1) || (tfragDistKey == 0)) { @@ -3686,7 +3697,7 @@ void Dblqh::prepareContinueAfterBlockedLab(Signal* signal) signal->theData[9] = sig3; signal->theData[10] = sig4; if (regTcPtr->primKeyLen > 4) { - sendKeyinfoAcc(signal); + sendKeyinfoAcc(signal, 11); }//if EXECUTE_DIRECT(refToBlock(regTcPtr->tcAccBlockref), GSN_ACCKEYREQ, signal, 7 + regTcPtr->primKeyLen); @@ -3708,9 +3719,8 @@ void Dblqh::prepareContinueAfterBlockedLab(Signal* signal) /* ======= SEND KEYINFO TO ACC ======= */ /* */ /* ========================================================================== */ -void Dblqh::sendKeyinfoAcc(Signal* signal) +void Dblqh::sendKeyinfoAcc(Signal* signal, Uint32 Ti) { - UintR Ti = 11; DatabufPtr regDatabufptr; regDatabufptr.i = tcConnectptr.p->firstTupkeybuf; @@ -3874,7 +3884,7 @@ void Dblqh::tupkeyConfLab(Signal* signal) /* ---- GET OPERATION TYPE AND CHECK WHAT KIND OF OPERATION IS REQUESTED ---- */ const TupKeyConf * const tupKeyConf = (TupKeyConf *)&signal->theData[0]; TcConnectionrec * const regTcPtr = tcConnectptr.p; - if (regTcPtr->simpleRead == ZSIMPLE_READ) { + if (regTcPtr->simpleRead) { jam(); /* ---------------------------------------------------------------------- * THE OPERATION IS A SIMPLE READ. WE WILL IMMEDIATELY COMMIT THE OPERATION. @@ -5462,6 +5472,8 @@ void Dblqh::commitContinueAfterBlockedLab(Signal* signal) TcConnectionrec * const regTcPtr = tcConnectptr.p; Fragrecord * const regFragptr = fragptr.p; Uint32 operation = regTcPtr->operation; + Uint32 simpleRead = regTcPtr->simpleRead; + Uint32 dirtyOp = regTcPtr->dirtyOp; if (regTcPtr->activeCreat == ZFALSE) { if ((cCommitBlocked == true) && (regFragptr->fragActiveStatus == ZTRUE)) { @@ -5499,13 +5511,18 @@ void Dblqh::commitContinueAfterBlockedLab(Signal* signal) tupCommitReq->hashValue = regTcPtr->hashValue; EXECUTE_DIRECT(tup, GSN_TUP_COMMITREQ, signal, TupCommitReq::SignalLength); - }//if - Uint32 acc = refToBlock(regTcPtr->tcAccBlockref); - signal->theData[0] = regTcPtr->accConnectrec; - EXECUTE_DIRECT(acc, GSN_ACC_COMMITREQ, signal, 1); - Uint32 simpleRead = regTcPtr->simpleRead; + Uint32 acc = refToBlock(regTcPtr->tcAccBlockref); + signal->theData[0] = regTcPtr->accConnectrec; + EXECUTE_DIRECT(acc, GSN_ACC_COMMITREQ, signal, 1); + } else { + if(!dirtyOp){ + Uint32 acc = refToBlock(regTcPtr->tcAccBlockref); + signal->theData[0] = regTcPtr->accConnectrec; + EXECUTE_DIRECT(acc, GSN_ACC_COMMITREQ, signal, 1); + } + } jamEntry(); - if (simpleRead == ZSIMPLE_READ) { + if (simpleRead) { jam(); /* ------------------------------------------------------------------------- */ /*THE OPERATION WAS A SIMPLE READ THUS THE COMMIT PHASE IS ONLY NEEDED TO */ @@ -5518,7 +5535,6 @@ void Dblqh::commitContinueAfterBlockedLab(Signal* signal) return; }//if }//if - Uint32 dirtyOp = regTcPtr->dirtyOp; Uint32 seqNoReplica = regTcPtr->seqNoReplica; if (regTcPtr->gci > regFragptr->newestGci) { jam(); @@ -6087,7 +6103,7 @@ void Dblqh::abortStateHandlerLab(Signal* signal) /* ------------------------------------------------------------------------- */ return; }//if - if (regTcPtr->simpleRead == ZSIMPLE_READ) { + if (regTcPtr->simpleRead) { jam(); /* ------------------------------------------------------------------------- */ /*A SIMPLE READ IS CURRENTLY RELEASING THE LOCKS OR WAITING FOR ACCESS TO */ @@ -6373,7 +6389,7 @@ void Dblqh::continueAbortLab(Signal* signal) void Dblqh::continueAfterLogAbortWriteLab(Signal* signal) { TcConnectionrec * const regTcPtr = tcConnectptr.p; - if (regTcPtr->simpleRead == ZSIMPLE_READ) { + if (regTcPtr->simpleRead) { jam(); TcKeyRef * const tcKeyRef = (TcKeyRef *) signal->getDataPtrSend(); @@ -7409,7 +7425,8 @@ void Dblqh::execSCAN_FRAGREQ(Signal* signal) jamEntry(); const Uint32 reqinfo = scanFragReq->requestInfo; - const Uint32 fragId = scanFragReq->fragmentNo; + const Uint32 fragId = (scanFragReq->fragmentNoKeyLen & 0xFFFF); + const Uint32 keyLen = (scanFragReq->fragmentNoKeyLen >> 16); tabptr.i = scanFragReq->tableId; const Uint32 max_rows = scanFragReq->batch_size_rows; const Uint32 scanLockMode = ScanFragReq::getLockMode(reqinfo); @@ -7473,6 +7490,8 @@ void Dblqh::execSCAN_FRAGREQ(Signal* signal) transid2, fragId, ZNIL); + tcConnectptr.p->save1 = 4; + tcConnectptr.p->primKeyLen = keyLen + 4; // hard coded in execKEYINFO errorCode = initScanrec(scanFragReq); if (errorCode != ZOK) { jam(); @@ -7585,23 +7604,29 @@ void Dblqh::scanAttrinfoLab(Signal* signal, Uint32* dataPtr, Uint32 length) }//if return; }//if - terrorCode = ZGET_ATTRINBUF_ERROR; + abort_scan(signal, scanptr.i, ZGET_ATTRINBUF_ERROR); +} + +void Dblqh::abort_scan(Signal* signal, Uint32 scan_ptr_i, Uint32 errcode){ + jam(); + scanptr.i = scan_ptr_i; + c_scanRecordPool.getPtr(scanptr); finishScanrec(signal); releaseScanrec(signal); tcConnectptr.p->transactionState = TcConnectionrec::IDLE; tcConnectptr.p->abortState = TcConnectionrec::ABORT_ACTIVE; - + ScanFragRef * ref = (ScanFragRef*)&signal->theData[0]; ref->senderData = tcConnectptr.p->clientConnectrec; ref->transId1 = tcConnectptr.p->transid[0]; ref->transId2 = tcConnectptr.p->transid[1]; - ref->errorCode = terrorCode; + ref->errorCode = errcode; sendSignal(tcConnectptr.p->clientBlockref, GSN_SCAN_FRAGREF, signal, ScanFragRef::SignalLength, JBB); deleteTransidHash(signal); releaseOprec(signal); releaseTcrec(signal, tcConnectptr); -}//Dblqh::scanAttrinfoLab() +} /*---------------------------------------------------------------------*/ /* Send this 'I am alive' signal to TC when it is received from ACC */ @@ -7672,34 +7697,17 @@ void Dblqh::accScanConfScanLab(Signal* signal) return; }//if scanptr.p->scanAccPtr = accScanConf->accPtr; - AttrbufPtr regAttrinbufptr; - regAttrinbufptr.i = tcConnectptr.p->firstAttrinbuf; - Uint32 boundAiLength = 0; + Uint32 boundAiLength = tcConnectptr.p->primKeyLen - 4; if (scanptr.p->rangeScan) { jam(); - // bound info length is in first of the 5 header words - ptrCheckGuard(regAttrinbufptr, cattrinbufFileSize, attrbuf); - boundAiLength = regAttrinbufptr.p->attrbuf[0]; TuxBoundInfo* const req = (TuxBoundInfo*)signal->getDataPtrSend(); req->errorCode = RNIL; req->tuxScanPtrI = scanptr.p->scanAccPtr; req->boundAiLength = boundAiLength; - Uint32* out = (Uint32*)req + TuxBoundInfo::SignalLength; - Uint32 sz = 0; - while (sz < boundAiLength) { - jam(); - ptrCheckGuard(regAttrinbufptr, cattrinbufFileSize, attrbuf); - Uint32 dataLen = regAttrinbufptr.p->attrbuf[ZINBUF_DATA_LEN]; - MEMCOPY_NO_WORDS(&out[sz], - ®Attrinbufptr.p->attrbuf[0], - dataLen); - sz += dataLen; - regAttrinbufptr.i = regAttrinbufptr.p->attrbuf[ZINBUF_NEXT]; - ptrCheckGuard(regAttrinbufptr, cattrinbufFileSize, attrbuf); - } - ndbrequire(sz == boundAiLength); + if(boundAiLength > 0) + sendKeyinfoAcc(signal, TuxBoundInfo::SignalLength); EXECUTE_DIRECT(DBTUX, GSN_TUX_BOUND_INFO, - signal, TuxBoundInfo::SignalLength + boundAiLength); + signal, TuxBoundInfo::SignalLength + boundAiLength); jamEntry(); if (req->errorCode != 0) { jam(); @@ -7716,12 +7724,14 @@ void Dblqh::accScanConfScanLab(Signal* signal) signal->theData[1] = tcConnectptr.p->tableref; signal->theData[2] = scanptr.p->scanSchemaVersion; signal->theData[3] = ZSTORED_PROC_SCAN; - ndbrequire(boundAiLength <= scanptr.p->scanAiLength); - signal->theData[4] = scanptr.p->scanAiLength - boundAiLength; + + signal->theData[4] = scanptr.p->scanAiLength; sendSignal(tcConnectptr.p->tcTupBlockref, GSN_STORED_PROCREQ, signal, 5, JBB); signal->theData[0] = tcConnectptr.p->tupConnectrec; + AttrbufPtr regAttrinbufptr; + regAttrinbufptr.i = tcConnectptr.p->firstAttrinbuf; while (regAttrinbufptr.i != RNIL) { ptrCheckGuard(regAttrinbufptr, cattrinbufFileSize, attrbuf); jam(); @@ -14797,7 +14807,7 @@ void Dblqh::execDEBUG_SIG(Signal* signal) tdebug = logPagePtr.p->logPageWord[0]; char buf[100]; - snprintf(buf, 100, + BaseString::snprintf(buf, 100, "Error while reading REDO log.\n" "D=%d, F=%d Mb=%d FP=%d W1=%d W2=%d", signal->theData[2], signal->theData[3], signal->theData[4], diff --git a/ndb/src/kernel/blocks/dbtc/Dbtc.hpp b/ndb/src/kernel/blocks/dbtc/Dbtc.hpp index a5f07f8e9e1..a209df24c44 100644 --- a/ndb/src/kernel/blocks/dbtc/Dbtc.hpp +++ b/ndb/src/kernel/blocks/dbtc/Dbtc.hpp @@ -192,7 +192,8 @@ public: OS_WAIT_ATTR = 14, OS_WAIT_COMMIT_CONF = 15, OS_WAIT_ABORT_CONF = 16, - OS_WAIT_COMPLETE_CONF = 17 + OS_WAIT_COMPLETE_CONF = 17, + OS_WAIT_SCAN = 18 }; enum AbortState { @@ -1169,6 +1170,8 @@ public: // Length of expected attribute information Uint32 scanAiLength; + Uint32 scanKeyLen; + // Reference to ApiConnectRecord Uint32 scanApiRec; @@ -1194,18 +1197,7 @@ public: Uint16 first_batch_size; Uint32 batch_byte_size; - // Shall the locks be held until the application have read the - // records - Uint8 scanLockHold; - - // Shall the locks be read or write locks - Uint8 scanLockMode; - - // Skip locks by other transactions and read latest committed - Uint8 readCommitted; - - // Scan is on ordered index - Uint8 rangeScan; + Uint32 scanRequestInfo; // ScanFrag format // Close is ordered bool m_close_scan_req; @@ -1467,7 +1459,7 @@ private: void releaseAttrinfo(); void releaseGcp(Signal* signal); void releaseKeys(); - void releaseSimpleRead(Signal* signal); + void releaseSimpleRead(Signal*, ApiConnectRecordPtr, TcConnectRecord*); void releaseDirtyWrite(Signal* signal); void releaseTcCon(); void releaseTcConnectFail(Signal* signal); @@ -1571,7 +1563,7 @@ private: void diFcountReqLab(Signal* signal, ScanRecordPtr); void signalErrorRefuseLab(Signal* signal); void abort080Lab(Signal* signal); - void packKeyData000Lab(Signal* signal, BlockReference TBRef); + void packKeyData000Lab(Signal* signal, BlockReference TBRef, Uint32 len); void abortScanLab(Signal* signal, ScanRecordPtr, Uint32 errCode); void sendAbortedAfterTimeout(Signal* signal, int Tcheck); void abort010Lab(Signal* signal); diff --git a/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp b/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp index d270c6acc61..d8b3ee10532 100644 --- a/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp +++ b/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp @@ -274,6 +274,12 @@ void Dbtc::execCONTINUEB(Signal* signal) transPtr.p->triggerPending = false; executeTriggers(signal, &transPtr); return; + case TcContinueB::DelayTCKEYCONF: + jam(); + apiConnectptr.i = Tdata0; + ptrCheckGuard(apiConnectptr, capiConnectFilesize, apiConnectRecord); + sendtckeyconf(signal, Tdata1); + return; default: ndbrequire(false); }//switch @@ -1759,6 +1765,7 @@ void Dbtc::execKEYINFO(Signal* signal) switch (apiConnectptr.p->apiConnectstate) { case CS_RECEIVING: case CS_REC_COMMITTING: + case CS_START_SCAN: jam(); /*empty*/; break; @@ -1812,12 +1819,54 @@ void Dbtc::execKEYINFO(Signal* signal) jam(); tckeyreq020Lab(signal); return; + case OS_WAIT_SCAN: + break; default: jam(); terrorCode = ZSTATE_ERROR; abortErrorLab(signal); return; }//switch + + UintR TdataPos = 0; + UintR TkeyLen = regCachePtr->keylen; + UintR Tlen = regCachePtr->save1; + + do { + if (cfirstfreeDatabuf == RNIL) { + jam(); + abort(); + seizeDatabuferrorLab(signal); + return; + }//if + linkKeybuf(signal); + arrGuard(TdataPos, 19); + databufptr.p->data[0] = signal->theData[TdataPos + 3]; + databufptr.p->data[1] = signal->theData[TdataPos + 4]; + databufptr.p->data[2] = signal->theData[TdataPos + 5]; + databufptr.p->data[3] = signal->theData[TdataPos + 6]; + Tlen = Tlen + 4; + TdataPos = TdataPos + 4; + if (Tlen < TkeyLen) { + jam(); + if (TdataPos >= tmaxData) { + jam(); + /*----------------------------------------------------*/ + /** EXIT AND WAIT FOR SIGNAL KEYINFO OR KEYINFO9 **/ + /** WHEN EITHER OF THE SIGNALS IS RECEIVED A JUMP **/ + /** TO LABEL "KEYINFO_LABEL" IS DONE. THEN THE **/ + /** PROGRAM RETURNS TO LABEL TCKEYREQ020 **/ + /*----------------------------------------------------*/ + setApiConTimer(apiConnectptr.i, ctcTimer, __LINE__); + regCachePtr->save1 = Tlen; + return; + }//if + } else { + jam(); + return; + }//if + } while (1); + return; }//Dbtc::execKEYINFO() /*---------------------------------------------------------------------------*/ @@ -1826,45 +1875,45 @@ void Dbtc::execKEYINFO(Signal* signal) /* WE WILL ALWAYS PACK 4 WORDS AT A TIME. */ /*---------------------------------------------------------------------------*/ void Dbtc::packKeyData000Lab(Signal* signal, - BlockReference TBRef) + BlockReference TBRef, + Uint32 totalLen) { CacheRecord * const regCachePtr = cachePtr.p; UintR Tmp; - Uint16 tdataPos; jam(); - tdataPos = 0; - Tmp = regCachePtr->keylen; + Uint32 len = 0; databufptr.i = regCachePtr->firstKeybuf; + signal->theData[0] = tcConnectptr.i; + signal->theData[1] = apiConnectptr.p->transid[0]; + signal->theData[2] = apiConnectptr.p->transid[1]; + Uint32 * dst = signal->theData+3; + ptrCheckGuard(databufptr, cdatabufFilesize, databufRecord); + do { jam(); - if (tdataPos == 20) { - jam(); - /*---------------------------------------------------------------------*/ - /* 4 MORE WORDS WILL NOT FIT IN THE 24 DATA WORDS IN A SIGNAL */ - /*---------------------------------------------------------------------*/ - sendKeyinfo(signal, TBRef, 20); - tdataPos = 0; - }//if - Tmp = Tmp - 4; - ptrCheckGuard(databufptr, cdatabufFilesize, databufRecord); - cdata[tdataPos ] = databufptr.p->data[0]; - cdata[tdataPos + 1] = databufptr.p->data[1]; - cdata[tdataPos + 2] = databufptr.p->data[2]; - cdata[tdataPos + 3] = databufptr.p->data[3]; - tdataPos = tdataPos + 4; - if (Tmp <= 4) { + databufptr.i = databufptr.p->nextDatabuf; + dst[len + 0] = databufptr.p->data[0]; + dst[len + 1] = databufptr.p->data[1]; + dst[len + 2] = databufptr.p->data[2]; + dst[len + 3] = databufptr.p->data[3]; + len += 4; + if (totalLen <= 4) { jam(); /*---------------------------------------------------------------------*/ /* LAST PACK OF KEY DATA HAVE BEEN SENT */ /*---------------------------------------------------------------------*/ /* THERE WERE UNSENT INFORMATION, SEND IT. */ /*---------------------------------------------------------------------*/ - sendKeyinfo(signal, TBRef, tdataPos); - releaseKeys(); + sendSignal(TBRef, GSN_KEYINFO, signal, 3 + len, JBB); return; - }//if - databufptr.i = databufptr.p->nextDatabuf; + } else if(len == KeyInfo::DataLength){ + jam(); + len = 0; + sendSignal(TBRef, GSN_KEYINFO, signal, 3 + KeyInfo::DataLength, JBB); + } + totalLen -= 4; + ptrCheckGuard(databufptr, cdatabufFilesize, databufRecord); } while (1); }//Dbtc::packKeyData000Lab() @@ -2247,6 +2296,7 @@ void Dbtc::initApiConnectRec(Signal* signal, regApiPtr->m_exec_flag = 0; regApiPtr->returncode = 0; regApiPtr->returnsignal = RS_TCKEYCONF; + ndbassert(regApiPtr->firstTcConnect == RNIL); regApiPtr->firstTcConnect = RNIL; regApiPtr->lastTcConnect = RNIL; regApiPtr->globalcheckpointid = 0; @@ -2441,18 +2491,30 @@ void Dbtc::execTCKEYREQ(Signal* signal) } break; case CS_STARTED: - //------------------------------------------------------------------------ - // Transaction is started already. Check that the operation is on the same - // transaction. - //------------------------------------------------------------------------ - compare_transid1 = regApiPtr->transid[0] ^ tcKeyReq->transId1; - compare_transid2 = regApiPtr->transid[1] ^ tcKeyReq->transId2; - jam(); - compare_transid1 = compare_transid1 | compare_transid2; - if (compare_transid1 != 0) { - TCKEY_abort(signal, 1); - return; - }//if + if(TstartFlag == 1 && regApiPtr->firstTcConnect == RNIL) + { + /** + * If last operation in last transaction was a simple/dirty read + * it does not have to be committed or rollbacked hence, + * the state will be CS_STARTED + */ + jam(); + initApiConnectRec(signal, regApiPtr); + regApiPtr->m_exec_flag = TexecFlag; + } else { + //---------------------------------------------------------------------- + // Transaction is started already. + // Check that the operation is on the same transaction. + //----------------------------------------------------------------------- + compare_transid1 = regApiPtr->transid[0] ^ tcKeyReq->transId1; + compare_transid2 = regApiPtr->transid[1] ^ tcKeyReq->transId2; + jam(); + compare_transid1 = compare_transid1 | compare_transid2; + if (compare_transid1 != 0) { + TCKEY_abort(signal, 1); + return; + }//if + } break; case CS_ABORTING: if (regApiPtr->abortState == AS_IDLE) { @@ -2601,7 +2663,7 @@ void Dbtc::execTCKEYREQ(Signal* signal) regCachePtr->schemaVersion = TtableSchemaVersion; regTcPtr->operation = TOperationType; - // Uint8 TSimpleFlag = tcKeyReq->getSimpleFlag(Treqinfo); + Uint8 TSimpleFlag = tcKeyReq->getSimpleFlag(Treqinfo); Uint8 TDirtyFlag = tcKeyReq->getDirtyFlag(Treqinfo); Uint8 TInterpretedFlag = tcKeyReq->getInterpretedFlag(Treqinfo); Uint8 TDistrGroupFlag = tcKeyReq->getDistributionGroupFlag(Treqinfo); @@ -2609,11 +2671,9 @@ void Dbtc::execTCKEYREQ(Signal* signal) Uint8 TDistrKeyFlag = tcKeyReq->getDistributionKeyFlag(Treqinfo); Uint8 TexecuteFlag = TexecFlag; - //RONM_TEST Disable simple reads temporarily - regCachePtr->opSimple = 0; - // regCachePtr->opSimple = TSimpleFlag; - regTcPtr->dirtyOp = TDirtyFlag; + regCachePtr->opSimple = TSimpleFlag; regCachePtr->opExec = TInterpretedFlag; + regTcPtr->dirtyOp = TDirtyFlag; regCachePtr->distributionGroupIndicator = TDistrGroupFlag; regCachePtr->distributionGroupType = TDistrGroupTypeFlag; @@ -2714,7 +2774,6 @@ void Dbtc::execTCKEYREQ(Signal* signal) } } - UintR Tattrlength = regCachePtr->attrlength; UintR TwriteCount = c_counters.cwriteCount; UintR Toperationsize = coperationsize; /* -------------------------------------------------------------------- @@ -2723,13 +2782,13 @@ void Dbtc::execTCKEYREQ(Signal* signal) * TEMP TABLES DON'T PARTICIPATE. * -------------------------------------------------------------------- */ if (localTabptr.p->storedTable) { - coperationsize = ((Toperationsize + Tattrlength) + TkeyLength) + 17; + coperationsize = ((Toperationsize + TattrLen) + TkeyLength) + 17; } c_counters.cwriteCount = TwriteCount + 1; switch (TOperationType) { case ZUPDATE: jam(); - if (Tattrlength == 0) { + if (TattrLen == 0) { //TCKEY_abort(signal, 5); //return; }//if @@ -2775,7 +2834,6 @@ void Dbtc::execTCKEYREQ(Signal* signal) if (regApiPtr->apiConnectstate == CS_START_COMMITTING) { jam(); // Trigger execution at commit - regApiPtr->apiConnectstate = CS_REC_COMMITTING; } else { jam(); @@ -2895,12 +2953,13 @@ void Dbtc::tckeyreq050Lab(Signal* signal) regTcPtr->tcNodedata[3] = Tdata6; Uint8 Toperation = regTcPtr->operation; + Uint8 Tdirty = regTcPtr->dirtyOp; tnoOfBackup = tnodeinfo & 3; tnoOfStandby = (tnodeinfo >> 8) & 3; regCachePtr->distributionKey = (tnodeinfo >> 16) & 255; if (Toperation == ZREAD) { - if (regCachePtr->opSimple == 1) { + if (Tdirty == 1) { jam(); /*-------------------------------------------------------------*/ /* A SIMPLE READ CAN SELECT ANY OF THE PRIMARY AND */ @@ -2910,23 +2969,28 @@ void Dbtc::tckeyreq050Lab(Signal* signal) /*-------------------------------------------------------------*/ arrGuard(tnoOfBackup, 4); UintR Tindex; + UintR TownNode = cownNodeid; for (Tindex = 1; Tindex <= tnoOfBackup; Tindex++) { UintR Tnode = regTcPtr->tcNodedata[Tindex]; - UintR TownNode = cownNodeid; jam(); if (Tnode == TownNode) { jam(); regTcPtr->tcNodedata[0] = Tnode; }//if }//for - if (regCachePtr->attrlength == 0) { - /*-------------------------------------------------------------*/ - // A simple read which does not read anything is a strange - // creature and we abort rather than continue. - /*-------------------------------------------------------------*/ - TCKEY_abort(signal, 12); - return; - }//if + if(ERROR_INSERTED(8048) || ERROR_INSERTED(8049)) + { + for (Tindex = 0; Tindex <= tnoOfBackup; Tindex++) + { + UintR Tnode = regTcPtr->tcNodedata[Tindex]; + jam(); + if (Tnode != TownNode) { + jam(); + regTcPtr->tcNodedata[0] = Tnode; + ndbout_c("Choosing %d", Tnode); + }//if + }//for + } }//if jam(); regTcPtr->lastReplicaNo = 0; @@ -3014,7 +3078,8 @@ void Dbtc::packLqhkeyreq(Signal* signal, UintR TfirstAttrbuf = regCachePtr->firstAttrbuf; sendlqhkeyreq(signal, TBRef); if (Tkeylen > 4) { - packKeyData000Lab(signal, TBRef); + packKeyData000Lab(signal, TBRef, Tkeylen - 4); + releaseKeys(); }//if packLqhkeyreq040Lab(signal, TfirstAttrbuf, @@ -3235,7 +3300,7 @@ void Dbtc::packLqhkeyreq040Lab(Signal* signal, releaseAttrinfo(); if (Tboth) { jam(); - releaseSimpleRead(signal); + releaseSimpleRead(signal, apiConnectptr, tcConnectptr.p); return; }//if regTcPtr->tcConnectstate = OS_OPERATING; @@ -3297,8 +3362,21 @@ void Dbtc::releaseAttrinfo() /* ========================================================================= */ /* ------- RELEASE ALL RECORDS CONNECTED TO A SIMPLE OPERATION ------- */ /* ========================================================================= */ -void Dbtc::releaseSimpleRead(Signal* signal) -{ +void Dbtc::releaseSimpleRead(Signal* signal, + ApiConnectRecordPtr regApiPtr, + TcConnectRecord* regTcPtr) +{ + Uint32 Ttckeyrec = regApiPtr.p->tckeyrec; + Uint32 TclientData = regTcPtr->clientData; + Uint32 Tnode = regTcPtr->tcNodedata[0]; + Uint32 Tlqhkeyreqrec = regApiPtr.p->lqhkeyreqrec; + Uint32 TsimpleReadCount = c_counters.csimpleReadCount; + ConnectionState state = regApiPtr.p->apiConnectstate; + + regApiPtr.p->tcSendArray[Ttckeyrec] = TclientData; + regApiPtr.p->tcSendArray[Ttckeyrec + 1] = TcKeyConf::SimpleReadBit | Tnode; + regApiPtr.p->tckeyrec = Ttckeyrec + 2; + unlinkReadyTcCon(signal); releaseTcCon(); @@ -3306,31 +3384,27 @@ void Dbtc::releaseSimpleRead(Signal* signal) * No LQHKEYCONF in Simple/Dirty read * Therefore decrese no LQHKEYCONF(REF) we are waiting for */ - ApiConnectRecord * const regApiPtr = apiConnectptr.p; - UintR TsimpleReadCount = c_counters.csimpleReadCount; - UintR Tlqhkeyreqrec = regApiPtr->lqhkeyreqrec; - c_counters.csimpleReadCount = TsimpleReadCount + 1; - regApiPtr->lqhkeyreqrec = Tlqhkeyreqrec - 1; - - /** - * If start committing and no operation in lists - * simply return - */ - if (regApiPtr->apiConnectstate == CS_START_COMMITTING && - regApiPtr->firstTcConnect == RNIL) { + regApiPtr.p->lqhkeyreqrec = --Tlqhkeyreqrec; + + if(Tlqhkeyreqrec == 0) + { + /** + * Special case of lqhKeyConf_checkTransactionState: + * - commit with zero operations: handle only for simple read + */ + sendtckeyconf(signal, state == CS_START_COMMITTING); + regApiPtr.p->apiConnectstate = + (state == CS_START_COMMITTING ? CS_CONNECTED : state); + setApiConTimer(regApiPtr.i, 0, __LINE__); - jam(); - setApiConTimer(apiConnectptr.i, 0, __LINE__); - regApiPtr->apiConnectstate = CS_CONNECTED; return; - }//if - + } + /** - * Else Emulate LQHKEYCONF + * Emulate LQHKEYCONF */ - lqhKeyConf_checkTransactionState(signal, regApiPtr); - + lqhKeyConf_checkTransactionState(signal, regApiPtr.p); }//Dbtc::releaseSimpleRead() /* ------------------------------------------------------------------------- */ @@ -3766,6 +3840,15 @@ Dbtc::lqhKeyConf_checkTransactionState(Signal * signal, void Dbtc::sendtckeyconf(Signal* signal, UintR TcommitFlag) { + if(ERROR_INSERTED(8049)){ + CLEAR_ERROR_INSERT_VALUE; + signal->theData[0] = TcContinueB::DelayTCKEYCONF; + signal->theData[1] = apiConnectptr.i; + signal->theData[2] = TcommitFlag; + sendSignalWithDelay(cownref, GSN_CONTINUEB, signal, 3000, 3); + return; + } + HostRecordPtr localHostptr; ApiConnectRecord * const regApiPtr = apiConnectptr.p; const UintR TopWords = (UintR)regApiPtr->tckeyrec; @@ -5024,27 +5107,15 @@ void Dbtc::execLQHKEYREF(Signal* signal) *---------------------------------------------------------------------*/ regApiPtr->lqhkeyreqrec--; if (regApiPtr->lqhkeyconfrec == regApiPtr->lqhkeyreqrec) { - if ((regApiPtr->lqhkeyconfrec == 0) && - (regApiPtr->apiConnectstate == CS_START_COMMITTING)) { - - if(abort == TcKeyReq::IgnoreError){ + if (regApiPtr->apiConnectstate == CS_START_COMMITTING) { + if(regApiPtr->lqhkeyconfrec) { jam(); - regApiPtr->returnsignal = RS_NO_RETURN; - abort010Lab(signal); - return; + diverify010Lab(signal); + } else { + jam(); + sendtckeyconf(signal, 1); + regApiPtr->apiConnectstate = CS_CONNECTED; } - - /*---------------------------------------------------------------- - * Not a single operation was successful. - * This we report as an aborted transaction - * to avoid performing a commit of zero operations. - *----------------------------------------------------------------*/ - TCKEY_abort(signal, 54); - return; - }//if - if (regApiPtr->apiConnectstate == CS_START_COMMITTING) { - jam(); - diverify010Lab(signal); return; } else if (regApiPtr->tckeyrec > 0 || regApiPtr->m_exec_flag) { jam(); @@ -6045,6 +6116,7 @@ void Dbtc::timeOutFoundLab(Signal* signal, Uint32 TapiConPtr) << " - place: " << c_apiConTimer_line[apiConnectptr.i]); switch (apiConnectptr.p->apiConnectstate) { case CS_STARTED: + ndbrequire(c_apiConTimer_line[apiConnectptr.i] != 3615); if(apiConnectptr.p->lqhkeyreqrec == apiConnectptr.p->lqhkeyconfrec){ jam(); /* @@ -6297,8 +6369,8 @@ void Dbtc::sendAbortedAfterTimeout(Signal* signal, int Tcheck) snprintf(buf, sizeof(buf), "TC %d: %d ops:", __LINE__, apiConnectptr.i); for(Uint32 i = 0; i<TloopCount; i++){ - snprintf(buf2, sizeof(buf2), "%s %d", buf, tmp[i]); - snprintf(buf, sizeof(buf), buf2); + BaseString::snprintf(buf2, sizeof(buf2), "%s %d", buf, tmp[i]); + BaseString::snprintf(buf, sizeof(buf), buf2); } warningEvent(buf); ndbout_c(buf); @@ -8406,7 +8478,8 @@ void Dbtc::execSCAN_TABREQ(Signal* signal) { const ScanTabReq * const scanTabReq = (ScanTabReq *)&signal->theData[0]; const Uint32 reqinfo = scanTabReq->requestInfo; - const Uint32 aiLength = scanTabReq->attrLen; + const Uint32 aiLength = (scanTabReq->attrLenKeyLen & 0xFFFF); + const Uint32 keyLen = scanTabReq->attrLenKeyLen >> 16; const Uint32 schemaVersion = scanTabReq->tableSchemaVersion; const Uint32 transid1 = scanTabReq->transId1; const Uint32 transid2 = scanTabReq->transId2; @@ -8444,6 +8517,10 @@ void Dbtc::execSCAN_TABREQ(Signal* signal) if (transP->apiConnectstate == CS_ABORTING && transP->abortState == AS_IDLE) { jam(); + } else if(transP->apiConnectstate == CS_STARTED && + transP->firstTcConnect == RNIL){ + jam(); + // left over from simple/dirty read } else { jam(); errCode = ZSTATE_ERROR; @@ -8480,8 +8557,12 @@ void Dbtc::execSCAN_TABREQ(Signal* signal) seizeTcConnect(signal); tcConnectptr.p->apiConnect = apiConnectptr.i; + tcConnectptr.p->tcConnectstate = OS_WAIT_SCAN; + apiConnectptr.p->lastTcConnect = tcConnectptr.i; seizeCacheRecord(signal); + cachePtr.p->keylen = keyLen; + cachePtr.p->save1 = 0; scanptr = seizeScanrec(signal); ndbrequire(transP->apiScanRec == RNIL); @@ -8558,21 +8639,27 @@ void Dbtc::initScanrec(ScanRecordPtr scanptr, UintR scanParallel, UintR noOprecPerFrag) { - const UintR reqinfo = scanTabReq->requestInfo; - scanptr.p->scanTcrec = tcConnectptr.i; scanptr.p->scanApiRec = apiConnectptr.i; - scanptr.p->scanAiLength = scanTabReq->attrLen; + scanptr.p->scanAiLength = scanTabReq->attrLenKeyLen & 0xFFFF; + scanptr.p->scanKeyLen = scanTabReq->attrLenKeyLen >> 16; scanptr.p->scanTableref = tabptr.i; scanptr.p->scanSchemaVersion = scanTabReq->tableSchemaVersion; scanptr.p->scanParallel = scanParallel; scanptr.p->noOprecPerFrag = noOprecPerFrag; scanptr.p->first_batch_size= scanTabReq->first_batch_size; scanptr.p->batch_byte_size= scanTabReq->batch_byte_size; - scanptr.p->scanLockMode = ScanTabReq::getLockMode(reqinfo); - scanptr.p->scanLockHold = ScanTabReq::getHoldLockFlag(reqinfo); - scanptr.p->readCommitted = ScanTabReq::getReadCommittedFlag(reqinfo); - scanptr.p->rangeScan = ScanTabReq::getRangeScanFlag(reqinfo); + + Uint32 tmp = 0; + const UintR ri = scanTabReq->requestInfo; + ScanFragReq::setLockMode(tmp, ScanTabReq::getLockMode(ri)); + ScanFragReq::setHoldLockFlag(tmp, ScanTabReq::getHoldLockFlag(ri)); + ScanFragReq::setKeyinfoFlag(tmp, ScanTabReq::getKeyinfoFlag(ri)); + ScanFragReq::setReadCommittedFlag(tmp,ScanTabReq::getReadCommittedFlag(ri)); + ScanFragReq::setRangeScanFlag(tmp, ScanTabReq::getRangeScanFlag(ri)); + ScanFragReq::setAttrLen(tmp, scanTabReq->attrLenKeyLen & 0xFFFF); + + scanptr.p->scanRequestInfo = tmp; scanptr.p->scanStoredProcId = scanTabReq->storedProcId; scanptr.p->scanState = ScanRecord::RUNNING; scanptr.p->m_queued_count = 0; @@ -8589,7 +8676,7 @@ void Dbtc::initScanrec(ScanRecordPtr scanptr, ptr.p->m_apiPtr = cdata[i]; }//for - (* (scanptr.p->rangeScan ? + (* (ScanTabReq::getRangeScanFlag(ri) ? &c_counters.c_range_scan_count : &c_counters.c_scan_count))++; }//Dbtc::initScanrec() @@ -8807,6 +8894,7 @@ void Dbtc::releaseScanResources(ScanRecordPtr scanPtr) if (apiConnectptr.p->cachePtr != RNIL) { cachePtr.i = apiConnectptr.p->cachePtr; ptrCheckGuard(cachePtr, ccacheFilesize, cacheRecord); + releaseKeys(); releaseAttrinfo(); }//if tcConnectptr.i = scanPtr.p->scanTcrec; @@ -9448,17 +9536,8 @@ void Dbtc::sendScanFragReq(Signal* signal, ScanRecord* scanP, ScanFragRec* scanFragP) { - Uint32 requestInfo = 0; ScanFragReq * const req = (ScanFragReq *)&signal->theData[0]; - ScanFragReq::setLockMode(requestInfo, scanP->scanLockMode); - ScanFragReq::setHoldLockFlag(requestInfo, scanP->scanLockHold); - if(scanP->scanLockMode == 1){ // Not read -> keyinfo - jam(); - ScanFragReq::setKeyinfoFlag(requestInfo, 1); - } - ScanFragReq::setReadCommittedFlag(requestInfo, scanP->readCommitted); - ScanFragReq::setRangeScanFlag(requestInfo, scanP->rangeScan); - ScanFragReq::setAttrLen(requestInfo, scanP->scanAiLength); + Uint32 requestInfo = scanP->scanRequestInfo; ScanFragReq::setScanPrio(requestInfo, 1); apiConnectptr.i = scanP->scanApiRec; req->tableId = scanP->scanTableref; @@ -9466,7 +9545,7 @@ void Dbtc::sendScanFragReq(Signal* signal, ptrCheckGuard(apiConnectptr, capiConnectFilesize, apiConnectRecord); req->senderData = scanFragptr.i; req->requestInfo = requestInfo; - req->fragmentNo = scanFragP->scanFragId; + req->fragmentNoKeyLen = scanFragP->scanFragId | (scanP->scanKeyLen << 16); req->resultRef = apiConnectptr.p->ndbapiBlockref; req->savePointId = apiConnectptr.p->currSavePointId; req->transId1 = apiConnectptr.p->transid[0]; @@ -9476,6 +9555,11 @@ void Dbtc::sendScanFragReq(Signal* signal, req->batch_size_bytes= scanP->batch_byte_size; sendSignal(scanFragP->lqhBlockref, GSN_SCAN_FRAGREQ, signal, ScanFragReq::SignalLength, JBB); + if(scanP->scanKeyLen > 0) + { + tcConnectptr.i = scanFragptr.i; + packKeyData000Lab(signal, scanFragP->lqhBlockref, scanP->scanKeyLen); + } updateBuddyTimer(apiConnectptr); scanFragP->startFragTimer(ctcTimer); }//Dbtc::sendScanFragReq() @@ -9586,6 +9670,7 @@ void Dbtc::initApiConnect(Signal* signal) apiConnectptr.p->ndbapiBlockref = 0xFFFFFFFF; // Invalid ref apiConnectptr.p->commitAckMarker = RNIL; apiConnectptr.p->firstTcConnect = RNIL; + apiConnectptr.p->lastTcConnect = RNIL; apiConnectptr.p->triggerPending = false; apiConnectptr.p->isIndexOp = false; apiConnectptr.p->accumulatingIndexOp = RNIL; @@ -9612,6 +9697,7 @@ void Dbtc::initApiConnect(Signal* signal) apiConnectptr.p->ndbapiBlockref = 0xFFFFFFFF; // Invalid ref apiConnectptr.p->commitAckMarker = RNIL; apiConnectptr.p->firstTcConnect = RNIL; + apiConnectptr.p->lastTcConnect = RNIL; apiConnectptr.p->triggerPending = false; apiConnectptr.p->isIndexOp = false; apiConnectptr.p->accumulatingIndexOp = RNIL; @@ -9638,6 +9724,7 @@ void Dbtc::initApiConnect(Signal* signal) apiConnectptr.p->ndbapiBlockref = 0xFFFFFFFF; // Invalid ref apiConnectptr.p->commitAckMarker = RNIL; apiConnectptr.p->firstTcConnect = RNIL; + apiConnectptr.p->lastTcConnect = RNIL; apiConnectptr.p->triggerPending = false; apiConnectptr.p->isIndexOp = false; apiConnectptr.p->accumulatingIndexOp = RNIL; @@ -10422,9 +10509,6 @@ Dbtc::execDUMP_STATE_ORD(Signal* signal) sp.p->scanSchemaVersion, sp.p->scanTableref, sp.p->scanStoredProcId); - infoEvent(" lhold=%d, lmode=%d", - sp.p->scanLockHold, - sp.p->scanLockMode); infoEvent(" apiRec=%d, next=%d", sp.p->scanApiRec, sp.p->nextScan); @@ -10995,9 +11079,11 @@ void Dbtc::execTCINDXREQ(Signal* signal) // Seize index operation TcIndexOperationPtr indexOpPtr; if ((startFlag == 1) && - ((regApiPtr->apiConnectstate == CS_CONNECTED) || - ((regApiPtr->apiConnectstate == CS_ABORTING) && - (regApiPtr->abortState == AS_IDLE)))) { + (regApiPtr->apiConnectstate == CS_CONNECTED || + (regApiPtr->apiConnectstate == CS_STARTED && + regApiPtr->firstTcConnect == RNIL)) || + (regApiPtr->apiConnectstate == CS_ABORTING && + regApiPtr->abortState == AS_IDLE)) { jam(); // This is a newly started transaction, clean-up releaseAllSeizedIndexOperations(regApiPtr); @@ -11652,7 +11738,7 @@ void Dbtc::readIndexTable(Signal* signal, tcKeyLength += MIN(keyLength, keyBufSize); tcKeyReq->tableSchemaVersion = indexOp->tcIndxReq.indexSchemaVersion; TcKeyReq::setOperationType(tcKeyRequestInfo, - opType == ZREAD ? opType : ZREAD_EX); + opType == ZREAD ? ZREAD : ZREAD_EX); TcKeyReq::setAIInTcKeyReq(tcKeyRequestInfo, 1); // Allways send one AttrInfo TcKeyReq::setExecutingTrigger(tcKeyRequestInfo, 0); BlockReference originalReceiver = regApiPtr->ndbapiBlockref; @@ -11677,6 +11763,9 @@ void Dbtc::readIndexTable(Signal* signal, AttributeHeader::init(dataPtr, indexData->primaryKeyPos, 0); tcKeyLength++; tcKeyReq->requestInfo = tcKeyRequestInfo; + + ndbassert(TcKeyReq::getDirtyFlag(tcKeyRequestInfo) == 0); + ndbassert(TcKeyReq::getSimpleFlag(tcKeyRequestInfo) == 0); EXECUTE_DIRECT(DBTC, GSN_TCKEYREQ, signal, tcKeyLength); /** @@ -11828,6 +11917,9 @@ void Dbtc::executeIndexOperation(Signal* signal, TcKeyReq::setExecutingTrigger(tcKeyRequestInfo, 0); tcKeyReq->requestInfo = tcKeyRequestInfo; + ndbassert(TcKeyReq::getDirtyFlag(tcKeyRequestInfo) == 0); + ndbassert(TcKeyReq::getSimpleFlag(tcKeyRequestInfo) == 0); + /** * Decrease lqhkeyreqrec to compensate for addition * during read of index table diff --git a/ndb/src/kernel/blocks/dbtup/Dbtup.hpp b/ndb/src/kernel/blocks/dbtup/Dbtup.hpp index 0e8dd5fbbe8..55ad1d0910a 100644 --- a/ndb/src/kernel/blocks/dbtup/Dbtup.hpp +++ b/ndb/src/kernel/blocks/dbtup/Dbtup.hpp @@ -35,14 +35,6 @@ #define ZMIN_PAGE_LIMIT_TUPKEYREQ 5 #define ZTUP_VERSION_BITS 15 -typedef bool (Dbtup::* ReadFunction)(Uint32*, - AttributeHeader*, - Uint32, - Uint32); -typedef bool (Dbtup::* UpdateFunction)(Uint32*, - Uint32, - Uint32); - #ifdef DBTUP_C //------------------------------------------------------------------ // Jam Handling: @@ -351,6 +343,14 @@ typedef bool (Dbtup::* UpdateFunction)(Uint32*, class Dbtup: public SimulatedBlock { public: + + typedef bool (Dbtup::* ReadFunction)(Uint32*, + AttributeHeader*, + Uint32, + Uint32); + typedef bool (Dbtup::* UpdateFunction)(Uint32*, + Uint32, + Uint32); // State values enum State { NOT_INITIALIZED = 0, diff --git a/ndb/src/kernel/blocks/dbtup/DbtupDebug.cpp b/ndb/src/kernel/blocks/dbtup/DbtupDebug.cpp index a50bb2fe52c..808cfd33696 100644 --- a/ndb/src/kernel/blocks/dbtup/DbtupDebug.cpp +++ b/ndb/src/kernel/blocks/dbtup/DbtupDebug.cpp @@ -353,11 +353,11 @@ operator<<(NdbOut& out, const Dbtup::Operationrec& op) out << " [interpretedExec " << dec << op.interpretedExec << "]"; out << " [opSimple " << dec << op.opSimple << "]"; // state - out << " [tupleState " << dec << op.tupleState << "]"; - out << " [transstate " << dec << op.transstate << "]"; + out << " [tupleState " << dec << (Uint32) op.tupleState << "]"; + out << " [transstate " << dec << (Uint32) op.transstate << "]"; out << " [inFragList " << dec << op.inFragList << "]"; out << " [inActiveOpList " << dec << op.inActiveOpList << "]"; - out << " [undoLogged " << dec << op.undoLogged << "]"; + out << " [undoLogged " << dec << (Uint32) op.undoLogged << "]"; // links out << " [prevActiveOp " << hex << op.prevActiveOp << "]"; out << " [nextActiveOp " << hex << op.nextActiveOp << "]"; diff --git a/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp b/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp index 0061ebe812d..49de0d80bcd 100644 --- a/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp +++ b/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp @@ -893,19 +893,19 @@ int Dbtup::handleReadReq(Signal* signal, if (regOperPtr->interpretedExec != 1) { jam(); - - Uint32 TnoOfDataRead = readAttributes(pagePtr, - Ttupheadoffset, - &cinBuffer[0], - regOperPtr->attrinbufLen, - dst, - dstLen, - false); - if (TnoOfDataRead != (Uint32)-1) { + int ret = readAttributes(pagePtr, + Ttupheadoffset, + &cinBuffer[0], + regOperPtr->attrinbufLen, + dst, + dstLen, + false); + if (ret != -1) { /* ------------------------------------------------------------------------- */ // We have read all data into coutBuffer. Now send it to the API. /* ------------------------------------------------------------------------- */ jam(); + Uint32 TnoOfDataRead= (Uint32) ret; regOperPtr->attroutbufLen = TnoOfDataRead; sendReadAttrinfo(signal, TnoOfDataRead, regOperPtr); return 0; @@ -1100,7 +1100,7 @@ Dbtup::updateStartLab(Signal* signal, Tablerec* const regTabPtr, Page* const pagePtr) { - Uint32 retValue; + int retValue; if (regOperPtr->optype == ZINSERT) { jam(); setNullBits(pagePtr, regTabPtr, regOperPtr->pageOffset); @@ -1111,7 +1111,7 @@ Dbtup::updateStartLab(Signal* signal, regOperPtr->pageOffset, &cinBuffer[0], regOperPtr->attrinbufLen); - if (retValue == (Uint32)-1) { + if (retValue == -1) { tupkeyErrorLab(signal); }//if } else { @@ -1215,7 +1215,7 @@ int Dbtup::interpreterStartLab(Signal* signal, { Operationrec * const regOperPtr = operPtr.p; Uint32 RtotalLen; - Uint32 TnoDataRW; + int TnoDataRW; Uint32 RinitReadLen = cinBuffer[0]; Uint32 RexecRegionLen = cinBuffer[1]; @@ -1273,7 +1273,7 @@ int Dbtup::interpreterStartLab(Signal* signal, &dst[0], dstLen, false); - if (TnoDataRW != (Uint32)-1) { + if (TnoDataRW != -1) { RattroutCounter = TnoDataRW; RinstructionCounter += RinitReadLen; } else { @@ -1300,7 +1300,7 @@ int Dbtup::interpreterStartLab(Signal* signal, RsubLen, &coutBuffer[0], sizeof(coutBuffer) / 4); - if (TnoDataRW != (Uint32)-1) { + if (TnoDataRW != -1) { RinstructionCounter += RexecRegionLen; RlogSize = TnoDataRW; } else { @@ -1319,7 +1319,7 @@ int Dbtup::interpreterStartLab(Signal* signal, TupHeadOffset, &cinBuffer[RinstructionCounter], RfinalUpdateLen); - if (TnoDataRW != (Uint32)-1) { + if (TnoDataRW != -1) { MEMCOPY_NO_WORDS(&clogMemBuffer[RlogSize], &cinBuffer[RinstructionCounter], RfinalUpdateLen); @@ -1347,7 +1347,7 @@ int Dbtup::interpreterStartLab(Signal* signal, &dst[RattroutCounter], (dstLen - RattroutCounter), false); - if (TnoDataRW != (Uint32)-1) { + if (TnoDataRW != -1) { RattroutCounter += TnoDataRW; } else { jam(); @@ -1480,14 +1480,13 @@ int Dbtup::interpreterNextLab(Signal* signal, /* ---------------------------------------------------------------- */ { Uint32 theAttrinfo = theInstruction; - Uint32 TnoDataRW; - TnoDataRW = readAttributes(pagePtr, - TupHeadOffset, - &theAttrinfo, - (Uint32)1, - &TregMemBuffer[theRegister], - (Uint32)3, - false); + int TnoDataRW= readAttributes(pagePtr, + TupHeadOffset, + &theAttrinfo, + (Uint32)1, + &TregMemBuffer[theRegister], + (Uint32)3, + false); if (TnoDataRW == 2) { /* ------------------------------------------------------------- */ // Two words read means that we get the instruction plus one 32 @@ -1511,7 +1510,7 @@ int Dbtup::interpreterNextLab(Signal* signal, TregMemBuffer[theRegister] = 0; TregMemBuffer[theRegister + 2] = 0; TregMemBuffer[theRegister + 3] = 0; - } else if (TnoDataRW == (Uint32)-1) { + } else if (TnoDataRW == -1) { jam(); tupkeyErrorLab(signal); return -1; @@ -1564,12 +1563,11 @@ int Dbtup::interpreterNextLab(Signal* signal, ah.setNULL(); Tlen = 1; }//if - Uint32 TnoDataRW; - TnoDataRW = updateAttributes(pagePtr, - TupHeadOffset, - &TdataForUpdate[0], - Tlen); - if (TnoDataRW != (Uint32)-1) { + int TnoDataRW= updateAttributes(pagePtr, + TupHeadOffset, + &TdataForUpdate[0], + Tlen); + if (TnoDataRW != -1) { /* --------------------------------------------------------- */ // Write the written data also into the log buffer so that it // will be logged. diff --git a/ndb/src/kernel/blocks/dbtup/DbtupIndex.cpp b/ndb/src/kernel/blocks/dbtup/DbtupIndex.cpp index 2dd707ebafc..5a8642c4d2e 100644 --- a/ndb/src/kernel/blocks/dbtup/DbtupIndex.cpp +++ b/ndb/src/kernel/blocks/dbtup/DbtupIndex.cpp @@ -166,7 +166,7 @@ Dbtup::tuxReadAttrs(Uint32 fragPtrI, Uint32 pageId, Uint32 pageOffset, Uint32 tu fragptr = fragptr_old; operPtr = operPtr_old; // done - if (ret == (Uint32)-1) { + if (ret == -1) { ret = terrorCode ? (-(int)terrorCode) : -1; } return ret; @@ -200,13 +200,14 @@ Dbtup::tuxReadPk(Uint32 fragPtrI, Uint32 pageId, Uint32 pageOffset, Uint32* data operPtr.i = RNIL; operPtr.p = NULL; // do it - int ret = readAttributes(pagePtr.p, pageOffset, attrIds, numAttrs, dataOut, ZNIL, true); + int ret = readAttributes(pagePtr.p, pageOffset, attrIds, + numAttrs, dataOut, ZNIL, true); // restore globals tabptr = tabptr_old; fragptr = fragptr_old; operPtr = operPtr_old; // done - if (ret != (Uint32)-1) { + if (ret != -1) { // remove headers Uint32 n = 0; Uint32 i = 0; @@ -220,7 +221,7 @@ Dbtup::tuxReadPk(Uint32 fragPtrI, Uint32 pageId, Uint32 pageOffset, Uint32* data n += 1; i += 1 + size; } - ndbrequire(i == ret); + ndbrequire((int)i == ret); ret -= numAttrs; } else { ret = terrorCode ? (-(int)terrorCode) : -1; diff --git a/ndb/src/kernel/blocks/dbtup/DbtupLCP.cpp b/ndb/src/kernel/blocks/dbtup/DbtupLCP.cpp index f8f2b9bdbd2..370ef4c4ba5 100644 --- a/ndb/src/kernel/blocks/dbtup/DbtupLCP.cpp +++ b/ndb/src/kernel/blocks/dbtup/DbtupLCP.cpp @@ -265,7 +265,8 @@ void Dbtup::lcpSaveCopyListLab(Signal* signal, CheckpointInfoPtr ciPtr) // We ensure that we have actually allocated the tuple header and // also found it. Otherwise we will fill the undo log with garbage. /* ---------------------------------------------------------------- */ - if (regOpPtr.p->optype == ZUPDATE) { + if (regOpPtr.p->optype == ZUPDATE || + (regOpPtr.p->optype == ZINSERT && regOpPtr.p->deleteInsertFlag)) { ljam(); if (regOpPtr.p->realPageIdC != RNIL) { /* ---------------------------------------------------------------- */ diff --git a/ndb/src/kernel/blocks/dbtup/DbtupRoutines.cpp b/ndb/src/kernel/blocks/dbtup/DbtupRoutines.cpp index a4e7cb47249..e6cc6f68842 100644 --- a/ndb/src/kernel/blocks/dbtup/DbtupRoutines.cpp +++ b/ndb/src/kernel/blocks/dbtup/DbtupRoutines.cpp @@ -156,12 +156,12 @@ Dbtup::setUpQueryRoutines(Tablerec* const regTabPtr) // tabptr.p Table record pointer /* ---------------------------------------------------------------- */ int Dbtup::readAttributes(Page* const pagePtr, - Uint32 tupHeadOffset, - const Uint32* inBuffer, - Uint32 inBufLen, - Uint32* outBuffer, - Uint32 maxRead, - bool xfrmFlag) + Uint32 tupHeadOffset, + const Uint32* inBuffer, + Uint32 inBufLen, + Uint32* outBuffer, + Uint32 maxRead, + bool xfrmFlag) { Tablerec* const regTabPtr = tabptr.p; Uint32 numAttributes = regTabPtr->noOfAttr; @@ -198,7 +198,7 @@ int Dbtup::readAttributes(Page* const pagePtr, attributeOffset)) { continue; } else { - return (Uint32)-1; + return -1; }//if } else if(attributeId & AttributeHeader::PSUEDO){ Uint32 sz = read_psuedo(attributeId, @@ -207,7 +207,7 @@ int Dbtup::readAttributes(Page* const pagePtr, tOutBufIndex = tmpAttrBufIndex + 1 + sz; } else { terrorCode = ZATTRIBUTE_ID_ERROR; - return (Uint32)-1; + return -1; }//if }//while return tOutBufIndex; @@ -256,11 +256,11 @@ int Dbtup::readAttributesWithoutHeader(Page* const pagePtr, attributeOffset)) { continue; } else { - return (Uint32)-1; + return -1; }//if } else { terrorCode = ZATTRIBUTE_ID_ERROR; - return (Uint32)-1; + return -1; }//if }//while ndbrequire(attrBufIndex == inBufLen); @@ -678,12 +678,12 @@ int Dbtup::updateAttributes(Page* const pagePtr, continue; } else { ljam(); - return (Uint32)-1; + return -1; }//if } else { ljam(); terrorCode = ZATTRIBUTE_ID_ERROR; - return (Uint32)-1; + return -1; }//if }//while return 0; diff --git a/ndb/src/kernel/blocks/dbtup/DbtupTrigger.cpp b/ndb/src/kernel/blocks/dbtup/DbtupTrigger.cpp index c0b49364ee6..aac5c326cad 100644 --- a/ndb/src/kernel/blocks/dbtup/DbtupTrigger.cpp +++ b/ndb/src/kernel/blocks/dbtup/DbtupTrigger.cpp @@ -652,6 +652,7 @@ void Dbtup::executeTrigger(Signal* signal, return; default: ndbrequire(false); + executeDirect= false; // remove warning }//switch regOperPtr->noFiredTriggers++; @@ -746,14 +747,15 @@ bool Dbtup::readTriggerInfo(TupTriggerData* const trigPtr, //-------------------------------------------------------------------- // Read Primary Key Values //-------------------------------------------------------------------- - noPrimKey = readAttributes(pagep.p, - tupheadoffset, - &tableDescriptor[regTabPtr->readKeyArray].tabDescr, - regTabPtr->noOfKeyAttr, - keyBuffer, - ZATTR_BUFFER_SIZE, - true); - ndbrequire(noPrimKey != (Uint32)-1); + int ret= readAttributes(pagep.p, + tupheadoffset, + &tableDescriptor[regTabPtr->readKeyArray].tabDescr, + regTabPtr->noOfKeyAttr, + keyBuffer, + ZATTR_BUFFER_SIZE, + true); + ndbrequire(ret != -1); + noPrimKey= ret; Uint32 numAttrsToRead; if ((regOperPtr->optype == ZUPDATE) && @@ -788,14 +790,15 @@ bool Dbtup::readTriggerInfo(TupTriggerData* const trigPtr, if ((regOperPtr->optype != ZDELETE) || (trigPtr->sendBeforeValues)) { ljam(); - noMainWords = readAttributes(pagep.p, - tupheadoffset, - &readBuffer[0], - numAttrsToRead, - mainBuffer, - ZATTR_BUFFER_SIZE, - true); - ndbrequire(noMainWords != (Uint32)-1); + int ret= readAttributes(pagep.p, + tupheadoffset, + &readBuffer[0], + numAttrsToRead, + mainBuffer, + ZATTR_BUFFER_SIZE, + true); + ndbrequire(ret != -1); + noMainWords= ret; } else { ljam(); noMainWords = 0; @@ -813,15 +816,16 @@ bool Dbtup::readTriggerInfo(TupTriggerData* const trigPtr, pagep.i = regOperPtr->realPageIdC; ptrCheckGuard(pagep, cnoOfPage, page); - noCopyWords = readAttributes(pagep.p, - tupheadoffset, - &readBuffer[0], - numAttrsToRead, - copyBuffer, - ZATTR_BUFFER_SIZE, - true); + int ret= readAttributes(pagep.p, + tupheadoffset, + &readBuffer[0], + numAttrsToRead, + copyBuffer, + ZATTR_BUFFER_SIZE, + true); - ndbrequire(noCopyWords != (Uint32)-1); + ndbrequire(ret != -1); + noCopyWords = ret; if ((noMainWords == noCopyWords) && (memcmp(mainBuffer, copyBuffer, noMainWords << 2) == 0)) { //-------------------------------------------------------------------- @@ -1074,6 +1078,7 @@ Dbtup::executeTuxCommitTriggers(Signal* signal, ndbrequire(tupVersion == regOperPtr->tupVersion); } else { ndbrequire(false); + tupVersion= 0; // remove warning } // fill in constant part req->tableId = regOperPtr->tableRef; @@ -1118,6 +1123,7 @@ Dbtup::executeTuxAbortTriggers(Signal* signal, return; } else { ndbrequire(false); + tupVersion= 0; // remove warning } // fill in constant part req->tableId = regOperPtr->tableRef; diff --git a/ndb/src/kernel/blocks/dbtux/Dbtux.hpp b/ndb/src/kernel/blocks/dbtux/Dbtux.hpp index 8dca52cec04..2b4c86e1394 100644 --- a/ndb/src/kernel/blocks/dbtux/Dbtux.hpp +++ b/ndb/src/kernel/blocks/dbtux/Dbtux.hpp @@ -32,7 +32,6 @@ // signal classes #include <signaldata/DictTabInfo.hpp> #include <signaldata/TuxContinueB.hpp> -#include <signaldata/BuildIndx.hpp> #include <signaldata/TupFrag.hpp> #include <signaldata/AlterIndx.hpp> #include <signaldata/DropTab.hpp> @@ -172,12 +171,21 @@ private: * Physical tuple address in TUP. Provides fast access to table tuple * or index node. Valid within the db node and across timeslices. * Not valid between db nodes or across restarts. + * + * To avoid wasting an Uint16 the pageid is split in two. */ struct TupLoc { - Uint32 m_pageId; // page i-value + private: + Uint16 m_pageId1; // page i-value (big-endian) + Uint16 m_pageId2; Uint16 m_pageOffset; // page offset in words + public: TupLoc(); TupLoc(Uint32 pageId, Uint16 pageOffset); + Uint32 getPageId() const; + void setPageId(Uint32 pageId); + Uint32 getPageOffset() const; + void setPageOffset(Uint32 pageOffset); bool operator==(const TupLoc& loc) const; bool operator!=(const TupLoc& loc) const; }; @@ -224,20 +232,15 @@ private: * work entry part 5 * * There are 3 links to other nodes: left child, right child, parent. - * These are in TupLoc format but the pageIds and pageOffsets are - * stored in separate arrays (saves 1 word). - * * Occupancy (number of entries) is at least 1 except temporarily when - * a node is about to be removed. If occupancy is 1, only max entry - * is present but both min and max prefixes are set. + * a node is about to be removed. */ struct TreeNode; friend struct TreeNode; struct TreeNode { - Uint32 m_linkPI[3]; // link to 0-left child 1-right child 2-parent - Uint16 m_linkPO[3]; // page offsets for above real page ids + TupLoc m_link[3]; // link to 0-left child 1-right child 2-parent unsigned m_side : 2; // we are 0-left child 1-right child 2-root - int m_balance : 2; // balance -1, 0, +1 + unsigned m_balance : 2; // balance -1, 0, +1 plus 1 for Solaris CC unsigned pad1 : 4; Uint8 m_occup; // current number of entries Uint32 m_nodeScan; // list of scans at this node @@ -246,8 +249,8 @@ private: static const unsigned NodeHeadSize = sizeof(TreeNode) >> 2; /* - * Tree nodes are not always accessed fully, for cache reasons. There - * are 3 access sizes. + * Tree node "access size" was for an early version with signal + * interface to TUP. It is now used only to compute sizes. */ enum AccSize { AccNone = 0, @@ -280,7 +283,7 @@ private: * m_occup), and whether the position is at an existing entry or * before one (if any). Position m_occup points past the node and is * also represented by position 0 of next node. Includes direction - * and copy of entry used by scan. + * used by scan. */ struct TreePos; friend struct TreePos; @@ -288,8 +291,7 @@ private: TupLoc m_loc; // physical node address Uint16 m_pos; // position 0 to m_occup Uint8 m_match; // at an existing entry - Uint8 m_dir; // from link (0-2) or within node (3) - TreeEnt m_ent; // copy of current entry + Uint8 m_dir; // see scanNext() TreePos(); }; @@ -370,6 +372,10 @@ private: * a separate lock wait flag. It may be for current entry or it may * be for an entry we were moved away from. In any case nothing * happens with current entry before lock wait flag is cleared. + * + * An unfinished scan is always linked to some tree node, and has + * current position and direction (see comments at scanNext). There + * is also a copy of latest entry found. */ struct ScanOp; friend struct ScanOp; @@ -398,8 +404,6 @@ private: Uint32 m_savePointId; // lock waited for or obtained and not yet passed to LQH Uint32 m_accLockOp; - // locks obtained and passed to LQH but not yet returned by LQH - Uint32 m_accLockOps[MaxAccLockOps]; Uint8 m_readCommitted; // no locking Uint8 m_lockMode; Uint8 m_keyInfo; @@ -408,13 +412,20 @@ private: ScanBound* m_bound[2]; // pointers to above 2 Uint16 m_boundCnt[2]; // number of bounds in each TreePos m_scanPos; // position - TreeEnt m_lastEnt; // last entry returned + TreeEnt m_scanEnt; // latest entry found Uint32 m_nodeScan; // next scan at node (single-linked) union { Uint32 nextPool; Uint32 nextList; }; Uint32 prevList; + /* + * Locks obtained and passed to LQH but not yet returned by LQH. + * The max was increased from 16 to 992 (default 64). Record max + * ever used in this scan. TODO fix quadratic behaviour + */ + Uint32 m_maxAccLockOps; + Uint32 m_accLockOps[MaxAccLockOps]; ScanOp(ScanBoundPool& scanBoundPool); }; typedef Ptr<ScanOp> ScanOpPtr; @@ -471,7 +482,7 @@ private: Uint16 m_numAttrs; bool m_storeNullKey; TreeHead m_tree; - TupLoc m_freeLoc; // one node pre-allocated for insert + TupLoc m_freeLoc; // list of free index nodes DLList<ScanOp> m_scanList; // current scans on this fragment Uint32 m_tupIndexFragPtrI; Uint32 m_tupTableFragPtrI[2]; @@ -515,7 +526,6 @@ private: Frag& m_frag; // fragment using the node TupLoc m_loc; // physical node address TreeNode* m_node; // pointer to node storage - AccSize m_acc; // accessed size NodeHandle(Frag& frag); NodeHandle(const NodeHandle& node); NodeHandle& operator=(const NodeHandle& node); @@ -576,18 +586,24 @@ private: * DbtuxNode.cpp */ int allocNode(Signal* signal, NodeHandle& node); - void accessNode(Signal* signal, NodeHandle& node, AccSize acc); - void selectNode(Signal* signal, NodeHandle& node, TupLoc loc, AccSize acc); - void insertNode(Signal* signal, NodeHandle& node, AccSize acc); - void deleteNode(Signal* signal, NodeHandle& node); - void setNodePref(Signal* signal, NodeHandle& node); + void selectNode(NodeHandle& node, TupLoc loc); + void insertNode(NodeHandle& node); + void deleteNode(NodeHandle& node); + void setNodePref(NodeHandle& node); // node operations - void nodePushUp(Signal* signal, NodeHandle& node, unsigned pos, const TreeEnt& ent); - void nodePopDown(Signal* signal, NodeHandle& node, unsigned pos, TreeEnt& ent); - void nodePushDown(Signal* signal, NodeHandle& node, unsigned pos, TreeEnt& ent); - void nodePopUp(Signal* signal, NodeHandle& node, unsigned pos, TreeEnt& ent); - void nodeSlide(Signal* signal, NodeHandle& dstNode, NodeHandle& srcNode, unsigned i); + void nodePushUp(NodeHandle& node, unsigned pos, const TreeEnt& ent, Uint32 scanList); + void nodePushUpScans(NodeHandle& node, unsigned pos); + void nodePopDown(NodeHandle& node, unsigned pos, TreeEnt& en, Uint32* scanList); + void nodePopDownScans(NodeHandle& node, unsigned pos); + void nodePushDown(NodeHandle& node, unsigned pos, TreeEnt& ent, Uint32& scanList); + void nodePushDownScans(NodeHandle& node, unsigned pos); + void nodePopUp(NodeHandle& node, unsigned pos, TreeEnt& ent, Uint32 scanList); + void nodePopUpScans(NodeHandle& node, unsigned pos); + void nodeSlide(NodeHandle& dstNode, NodeHandle& srcNode, unsigned cnt, unsigned i); // scans linked to node + void addScanList(NodeHandle& node, unsigned pos, Uint32 scanList); + void removeScanList(NodeHandle& node, unsigned pos, Uint32& scanList); + void moveScanList(NodeHandle& node, unsigned pos); void linkScan(NodeHandle& node, ScanOpPtr scanPtr); void unlinkScan(NodeHandle& node, ScanOpPtr scanPtr); bool islinkScan(NodeHandle& node, ScanOpPtr scanPtr); @@ -595,10 +611,21 @@ private: /* * DbtuxTree.cpp */ - void treeAdd(Signal* signal, Frag& frag, TreePos treePos, TreeEnt ent); - void treeRemove(Signal* signal, Frag& frag, TreePos treePos); - void treeRotateSingle(Signal* signal, Frag& frag, NodeHandle& node, unsigned i); - void treeRotateDouble(Signal* signal, Frag& frag, NodeHandle& node, unsigned i); + // add entry + void treeAdd(Frag& frag, TreePos treePos, TreeEnt ent); + void treeAddFull(Frag& frag, NodeHandle lubNode, unsigned pos, TreeEnt ent); + void treeAddNode(Frag& frag, NodeHandle lubNode, unsigned pos, TreeEnt ent, NodeHandle parentNode, unsigned i); + void treeAddRebalance(Frag& frag, NodeHandle node, unsigned i); + // remove entry + void treeRemove(Frag& frag, TreePos treePos); + void treeRemoveInner(Frag& frag, NodeHandle lubNode, unsigned pos); + void treeRemoveSemi(Frag& frag, NodeHandle node, unsigned i); + void treeRemoveLeaf(Frag& frag, NodeHandle node); + void treeRemoveNode(Frag& frag, NodeHandle node); + void treeRemoveRebalance(Frag& frag, NodeHandle node, unsigned i); + // rotate + void treeRotateSingle(Frag& frag, NodeHandle& node, unsigned i); + void treeRotateDouble(Frag& frag, NodeHandle& node, unsigned i); /* * DbtuxScan.cpp @@ -610,9 +637,9 @@ private: void execACCKEYCONF(Signal* signal); void execACCKEYREF(Signal* signal); void execACC_ABORTCONF(Signal* signal); - void scanFirst(Signal* signal, ScanOpPtr scanPtr); - void scanNext(Signal* signal, ScanOpPtr scanPtr); - bool scanVisible(Signal* signal, ScanOpPtr scanPtr, TreeEnt ent); + void scanFirst(ScanOpPtr scanPtr); + void scanNext(ScanOpPtr scanPtr); + bool scanVisible(ScanOpPtr scanPtr, TreeEnt ent); void scanClose(Signal* signal, ScanOpPtr scanPtr); void addAccLockOp(ScanOp& scan, Uint32 accLockOp); void removeAccLockOp(ScanOp& scan, Uint32 accLockOp); @@ -621,9 +648,9 @@ private: /* * DbtuxSearch.cpp */ - void searchToAdd(Signal* signal, Frag& frag, ConstData searchKey, TreeEnt searchEnt, TreePos& treePos); - void searchToRemove(Signal* signal, Frag& frag, ConstData searchKey, TreeEnt searchEnt, TreePos& treePos); - void searchToScan(Signal* signal, Frag& frag, ConstData boundInfo, unsigned boundCount, TreePos& treePos); + void searchToAdd(Frag& frag, ConstData searchKey, TreeEnt searchEnt, TreePos& treePos); + void searchToRemove(Frag& frag, ConstData searchKey, TreeEnt searchEnt, TreePos& treePos); + void searchToScan(Frag& frag, ConstData boundInfo, unsigned boundCount, TreePos& treePos); /* * DbtuxCmp.cpp @@ -647,7 +674,7 @@ private: PrintPar(); }; void printTree(Signal* signal, Frag& frag, NdbOut& out); - void printNode(Signal* signal, Frag& frag, NdbOut& out, TupLoc loc, PrintPar& par); + void printNode(Frag& frag, NdbOut& out, TupLoc loc, PrintPar& par); friend class NdbOut& operator<<(NdbOut&, const TupLoc&); friend class NdbOut& operator<<(NdbOut&, const TreeEnt&); friend class NdbOut& operator<<(NdbOut&, const TreeNode&); @@ -805,22 +832,52 @@ Dbtux::ConstData::operator=(Data data) inline Dbtux::TupLoc::TupLoc() : - m_pageId(RNIL), + m_pageId1(RNIL >> 16), + m_pageId2(RNIL & 0xFFFF), m_pageOffset(0) { } inline Dbtux::TupLoc::TupLoc(Uint32 pageId, Uint16 pageOffset) : - m_pageId(pageId), + m_pageId1(pageId >> 16), + m_pageId2(pageId & 0xFFFF), m_pageOffset(pageOffset) { } +inline Uint32 +Dbtux::TupLoc::getPageId() const +{ + return (m_pageId1 << 16) | m_pageId2; +} + +inline void +Dbtux::TupLoc::setPageId(Uint32 pageId) +{ + m_pageId1 = (pageId >> 16); + m_pageId2 = (pageId & 0xFFFF); +} + +inline Uint32 +Dbtux::TupLoc::getPageOffset() const +{ + return (Uint32)m_pageOffset; +} + +inline void +Dbtux::TupLoc::setPageOffset(Uint32 pageOffset) +{ + m_pageOffset = (Uint16)pageOffset; +} + inline bool Dbtux::TupLoc::operator==(const TupLoc& loc) const { - return m_pageId == loc.m_pageId && m_pageOffset == loc.m_pageOffset; + return + m_pageId1 == loc.m_pageId1 && + m_pageId2 == loc.m_pageId2 && + m_pageOffset == loc.m_pageOffset; } inline bool @@ -851,13 +908,13 @@ Dbtux::TreeEnt::eq(const TreeEnt ent) const inline int Dbtux::TreeEnt::cmp(const TreeEnt ent) const { - if (m_tupLoc.m_pageId < ent.m_tupLoc.m_pageId) + if (m_tupLoc.getPageId() < ent.m_tupLoc.getPageId()) return -1; - if (m_tupLoc.m_pageId > ent.m_tupLoc.m_pageId) + if (m_tupLoc.getPageId() > ent.m_tupLoc.getPageId()) return +1; - if (m_tupLoc.m_pageOffset < ent.m_tupLoc.m_pageOffset) + if (m_tupLoc.getPageOffset() < ent.m_tupLoc.getPageOffset()) return -1; - if (m_tupLoc.m_pageOffset > ent.m_tupLoc.m_pageOffset) + if (m_tupLoc.getPageOffset() > ent.m_tupLoc.getPageOffset()) return +1; if (m_tupVersion < ent.m_tupVersion) return -1; @@ -875,17 +932,14 @@ Dbtux::TreeEnt::cmp(const TreeEnt ent) const inline Dbtux::TreeNode::TreeNode() : m_side(2), - m_balance(0), + m_balance(0 + 1), pad1(0), m_occup(0), m_nodeScan(RNIL) { - m_linkPI[0] = NullTupLoc.m_pageId; - m_linkPO[0] = NullTupLoc.m_pageOffset; - m_linkPI[1] = NullTupLoc.m_pageId; - m_linkPO[1] = NullTupLoc.m_pageOffset; - m_linkPI[2] = NullTupLoc.m_pageId; - m_linkPO[2] = NullTupLoc.m_pageOffset; + m_link[0] = NullTupLoc; + m_link[1] = NullTupLoc; + m_link[2] = NullTupLoc; } // Dbtux::TreeHead @@ -913,7 +967,6 @@ Dbtux::TreeHead::getSize(AccSize acc) const case AccFull: return m_nodeSize; } - abort(); return 0; } @@ -938,8 +991,7 @@ Dbtux::TreePos::TreePos() : m_loc(), m_pos(ZNIL), m_match(false), - m_dir(255), - m_ent() + m_dir(255) { } @@ -980,16 +1032,19 @@ Dbtux::ScanOp::ScanOp(ScanBoundPool& scanBoundPool) : m_boundMin(scanBoundPool), m_boundMax(scanBoundPool), m_scanPos(), - m_lastEnt(), - m_nodeScan(RNIL) + m_scanEnt(), + m_nodeScan(RNIL), + m_maxAccLockOps(0) { m_bound[0] = &m_boundMin; m_bound[1] = &m_boundMax; m_boundCnt[0] = 0; m_boundCnt[1] = 0; +#ifdef VM_TRACE for (unsigned i = 0; i < MaxAccLockOps; i++) { - m_accLockOps[i] = RNIL; + m_accLockOps[i] = 0x1f1f1f1f; } +#endif } // Dbtux::Index @@ -1054,8 +1109,7 @@ inline Dbtux::NodeHandle::NodeHandle(Frag& frag) : m_frag(frag), m_loc(), - m_node(0), - m_acc(AccNone) + m_node(0) { } @@ -1063,8 +1117,7 @@ inline Dbtux::NodeHandle::NodeHandle(const NodeHandle& node) : m_frag(node.m_frag), m_loc(node.m_loc), - m_node(node.m_node), - m_acc(node.m_acc) + m_node(node.m_node) { } @@ -1074,7 +1127,6 @@ Dbtux::NodeHandle::operator=(const NodeHandle& node) ndbassert(&m_frag == &node.m_frag); m_loc = node.m_loc; m_node = node.m_node; - m_acc = node.m_acc; return *this; } @@ -1088,13 +1140,13 @@ inline Dbtux::TupLoc Dbtux::NodeHandle::getLink(unsigned i) { ndbrequire(i <= 2); - return TupLoc(m_node->m_linkPI[i], m_node->m_linkPO[i]); + return m_node->m_link[i]; } inline unsigned Dbtux::NodeHandle::getChilds() { - return (getLink(0) != NullTupLoc) + (getLink(1) != NullTupLoc); + return (m_node->m_link[0] != NullTupLoc) + (m_node->m_link[1] != NullTupLoc); } inline unsigned @@ -1112,7 +1164,7 @@ Dbtux::NodeHandle::getOccup() inline int Dbtux::NodeHandle::getBalance() { - return m_node->m_balance; + return (int)m_node->m_balance - 1; } inline Uint32 @@ -1125,8 +1177,7 @@ inline void Dbtux::NodeHandle::setLink(unsigned i, TupLoc loc) { ndbrequire(i <= 2); - m_node->m_linkPI[i] = loc.m_pageId; - m_node->m_linkPO[i] = loc.m_pageOffset; + m_node->m_link[i] = loc; } inline void @@ -1148,7 +1199,7 @@ inline void Dbtux::NodeHandle::setBalance(int b) { ndbrequire(abs(b) <= 1); - m_node->m_balance = b; + m_node->m_balance = (unsigned)(b + 1); } inline void @@ -1161,7 +1212,6 @@ inline Dbtux::Data Dbtux::NodeHandle::getPref() { TreeHead& tree = m_frag.m_tree; - ndbrequire(m_acc >= AccPref); return tree.getPref(m_node); } @@ -1172,11 +1222,6 @@ Dbtux::NodeHandle::getEnt(unsigned pos) TreeEnt* entList = tree.getEntList(m_node); const unsigned occup = m_node->m_occup; ndbrequire(pos < occup); - if (pos == 0 || pos == occup - 1) { - ndbrequire(m_acc >= AccPref) - } else { - ndbrequire(m_acc == AccFull) - } return entList[(1 + pos) % occup]; } @@ -1224,7 +1269,7 @@ Dbtux::getTupAddr(const Frag& frag, TreeEnt ent) const Uint32 tableFragPtrI = frag.m_tupTableFragPtrI[ent.m_fragBit]; const TupLoc tupLoc = ent.m_tupLoc; Uint32 tupAddr = NullTupAddr; - c_tup->tuxGetTupAddr(tableFragPtrI, tupLoc.m_pageId, tupLoc.m_pageOffset, tupAddr); + c_tup->tuxGetTupAddr(tableFragPtrI, tupLoc.getPageId(), tupLoc.getPageOffset(), tupAddr); jamEntry(); return tupAddr; } diff --git a/ndb/src/kernel/blocks/dbtux/DbtuxCmp.cpp b/ndb/src/kernel/blocks/dbtux/DbtuxCmp.cpp index 549720cc17c..ddab77b97b5 100644 --- a/ndb/src/kernel/blocks/dbtux/DbtuxCmp.cpp +++ b/ndb/src/kernel/blocks/dbtux/DbtuxCmp.cpp @@ -87,21 +87,23 @@ Dbtux::cmpSearchKey(const Frag& frag, unsigned& start, ConstData searchKey, Cons /* * Scan bound vs node prefix or entry. * - * Compare lower or upper bound and index attribute data. The attribute - * data may be partial in which case CmpUnknown may be returned. - * Returns -1 if the boundary is to the left of the compared key and +1 - * if the boundary is to the right of the compared key. + * Compare lower or upper bound and index entry data. The entry data + * may be partial in which case CmpUnknown may be returned. Otherwise + * returns -1 if the bound is to the left of the entry and +1 if the + * bound is to the right of the entry. * - * To get this behaviour we treat equality a little bit special. If the - * boundary is a lower bound then the boundary is to the left of all - * equal keys and if it is an upper bound then the boundary is to the - * right of all equal keys. + * The routine is similar to cmpSearchKey, but 0 is never returned. + * Suppose all attributes compare equal. Recall that all bounds except + * possibly the last one are non-strict. Use the given bound direction + * (0-lower 1-upper) and strictness of last bound to return -1 or +1. * - * When searching for the first key we are using the lower bound to try - * to find the first key that is to the right of the boundary. Then we - * start scanning from this tuple (including the tuple itself) until we - * find the first key which is to the right of the boundary. Then we - * stop and do not include that key in the scan result. + * Following example illustrates this. We are at (a=2, b=3). + * + * dir bounds strict return + * 0 a >= 2 and b >= 3 no -1 + * 0 a >= 2 and b > 3 yes +1 + * 1 a <= 2 and b <= 3 no +1 + * 1 a <= 2 and b < 3 yes -1 */ int Dbtux::cmpScanBound(const Frag& frag, unsigned dir, ConstData boundInfo, unsigned boundCount, ConstData entryData, unsigned maxlen) @@ -111,12 +113,7 @@ Dbtux::cmpScanBound(const Frag& frag, unsigned dir, ConstData boundInfo, unsigne ndbrequire(dir <= 1); // number of words of data left unsigned len2 = maxlen; - /* - * No boundary means full scan, low boundary is to the right of all - * keys. Thus we should always return -1. For upper bound we are to - * the right of all keys, thus we should always return +1. We achieve - * this behaviour by initializing type to 4. - */ + // in case of no bounds, init last type to something non-strict unsigned type = 4; while (boundCount != 0) { if (len2 <= AttributeHeaderSize) { @@ -124,7 +121,7 @@ Dbtux::cmpScanBound(const Frag& frag, unsigned dir, ConstData boundInfo, unsigne return NdbSqlUtil::CmpUnknown; } len2 -= AttributeHeaderSize; - // get and skip bound type + // get and skip bound type (it is used after the loop) type = boundInfo[0]; boundInfo += 1; if (! boundInfo.ah().isNULL()) { @@ -166,30 +163,7 @@ Dbtux::cmpScanBound(const Frag& frag, unsigned dir, ConstData boundInfo, unsigne entryData += AttributeHeaderSize + entryData.ah().getDataSize(); boundCount -= 1; } - if (dir == 0) { - jam(); - /* - * Looking for the lower bound. If strict lower bound then the - * boundary is to the right of the compared key and otherwise (equal - * included in range) then the boundary is to the left of the key. - */ - if (type == 1) { - jam(); - return +1; - } - return -1; - } else { - jam(); - /* - * Looking for the upper bound. If strict upper bound then the - * boundary is to the left of all equal keys and otherwise (equal - * included in the range) then the boundary is to the right of all - * equal keys. - */ - if (type == 3) { - jam(); - return -1; - } - return +1; - } + // all attributes were equal + const int strict = (type & 0x1); + return (dir == 0 ? (strict == 0 ? -1 : +1) : (strict == 0 ? +1 : -1)); } diff --git a/ndb/src/kernel/blocks/dbtux/DbtuxDebug.cpp b/ndb/src/kernel/blocks/dbtux/DbtuxDebug.cpp index 8d31d2c6a55..c5c22264460 100644 --- a/ndb/src/kernel/blocks/dbtux/DbtuxDebug.cpp +++ b/ndb/src/kernel/blocks/dbtux/DbtuxDebug.cpp @@ -98,7 +98,7 @@ Dbtux::printTree(Signal* signal, Frag& frag, NdbOut& out) strcpy(par.m_path, "."); par.m_side = 2; par.m_parent = NullTupLoc; - printNode(signal, frag, out, tree.m_root, par); + printNode(frag, out, tree.m_root, par); out.m_out->flush(); if (! par.m_ok) { if (debugFile == 0) { @@ -114,7 +114,7 @@ Dbtux::printTree(Signal* signal, Frag& frag, NdbOut& out) } void -Dbtux::printNode(Signal* signal, Frag& frag, NdbOut& out, TupLoc loc, PrintPar& par) +Dbtux::printNode(Frag& frag, NdbOut& out, TupLoc loc, PrintPar& par) { if (loc == NullTupLoc) { par.m_depth = 0; @@ -122,7 +122,7 @@ Dbtux::printNode(Signal* signal, Frag& frag, NdbOut& out, TupLoc loc, PrintPar& } TreeHead& tree = frag.m_tree; NodeHandle node(frag); - selectNode(signal, node, loc, AccFull); + selectNode(node, loc); out << par.m_path << " " << node << endl; // check children PrintPar cpar[2]; @@ -132,7 +132,7 @@ Dbtux::printNode(Signal* signal, Frag& frag, NdbOut& out, TupLoc loc, PrintPar& cpar[i].m_side = i; cpar[i].m_depth = 0; cpar[i].m_parent = loc; - printNode(signal, frag, out, node.getLink(i), cpar[i]); + printNode(frag, out, node.getLink(i), cpar[i]); if (! cpar[i].m_ok) { par.m_ok = false; } @@ -178,16 +178,19 @@ Dbtux::printNode(Signal* signal, Frag& frag, NdbOut& out, TupLoc loc, PrintPar& out << "occupancy " << node.getOccup() << " of interior node"; out << " less than min " << tree.m_minOccup << endl; } - // check missed half-leaf/leaf merge +#ifdef dbtux_totally_groks_t_trees + // check missed semi-leaf/leaf merge for (unsigned i = 0; i <= 1; i++) { if (node.getLink(i) != NullTupLoc && node.getLink(1 - i) == NullTupLoc && - node.getOccup() + cpar[i].m_occup <= tree.m_maxOccup) { + // our semi-leaf seems to satify interior minOccup condition + node.getOccup() < tree.m_minOccup) { par.m_ok = false; out << par.m_path << sep; out << "missed merge with child " << i << endl; } } +#endif // check inline prefix { ConstData data1 = node.getPref(); Uint32 data2[MaxPrefSize]; @@ -256,8 +259,8 @@ operator<<(NdbOut& out, const Dbtux::TupLoc& loc) if (loc == Dbtux::NullTupLoc) { out << "null"; } else { - out << dec << loc.m_pageId; - out << "." << dec << loc.m_pageOffset; + out << dec << loc.getPageId(); + out << "." << dec << loc.getPageOffset(); } return out; } @@ -274,16 +277,13 @@ operator<<(NdbOut& out, const Dbtux::TreeEnt& ent) NdbOut& operator<<(NdbOut& out, const Dbtux::TreeNode& node) { - Dbtux::TupLoc link0(node.m_linkPI[0], node.m_linkPO[0]); - Dbtux::TupLoc link1(node.m_linkPI[1], node.m_linkPO[1]); - Dbtux::TupLoc link2(node.m_linkPI[2], node.m_linkPO[2]); out << "[TreeNode " << hex << &node; - out << " [left " << link0 << "]"; - out << " [right " << link1 << "]"; - out << " [up " << link2 << "]"; + out << " [left " << node.m_link[0] << "]"; + out << " [right " << node.m_link[1] << "]"; + out << " [up " << node.m_link[2] << "]"; out << " [side " << dec << node.m_side << "]"; out << " [occup " << dec << node.m_occup << "]"; - out << " [balance " << dec << (int)node.m_balance << "]"; + out << " [balance " << dec << (int)node.m_balance - 1 << "]"; out << " [nodeScan " << hex << node.m_nodeScan << "]"; out << "]"; return out; @@ -313,7 +313,6 @@ operator<<(NdbOut& out, const Dbtux::TreePos& pos) out << " [pos " << dec << pos.m_pos << "]"; out << " [match " << dec << pos.m_match << "]"; out << " [dir " << dec << pos.m_dir << "]"; - out << " [ent " << pos.m_ent << "]"; out << "]"; return out; } @@ -350,6 +349,7 @@ operator<<(NdbOut& out, const Dbtux::ScanOp& scan) out << " [lockMode " << dec << scan.m_lockMode << "]"; out << " [keyInfo " << dec << scan.m_keyInfo << "]"; out << " [pos " << scan.m_scanPos << "]"; + out << " [ent " << scan.m_scanEnt << "]"; for (unsigned i = 0; i <= 1; i++) { out << " [bound " << dec << i; Dbtux::ScanBound& bound = *scan.m_bound[i]; @@ -410,27 +410,21 @@ operator<<(NdbOut& out, const Dbtux::NodeHandle& node) const Dbtux::TreeHead& tree = frag.m_tree; out << "[NodeHandle " << hex << &node; out << " [loc " << node.m_loc << "]"; - out << " [acc " << dec << node.m_acc << "]"; out << " [node " << *node.m_node << "]"; - if (node.m_acc >= Dbtux::AccPref) { - const Uint32* data; - out << " [pref"; - data = (const Uint32*)node.m_node + Dbtux::NodeHeadSize; - for (unsigned j = 0; j < tree.m_prefSize; j++) - out << " " << hex << data[j]; - out << "]"; - out << " [entList"; - unsigned numpos = node.m_node->m_occup; - if (node.m_acc < Dbtux::AccFull && numpos > 2) { - numpos = 2; - out << "(" << dec << numpos << ")"; - } - data = (const Uint32*)node.m_node + Dbtux::NodeHeadSize + tree.m_prefSize; - const Dbtux::TreeEnt* entList = (const Dbtux::TreeEnt*)data; - for (unsigned pos = 0; pos < numpos; pos++) - out << " " << entList[pos]; - out << "]"; - } + const Uint32* data; + out << " [pref"; + data = (const Uint32*)node.m_node + Dbtux::NodeHeadSize; + for (unsigned j = 0; j < tree.m_prefSize; j++) + out << " " << hex << data[j]; + out << "]"; + out << " [entList"; + unsigned numpos = node.m_node->m_occup; + data = (const Uint32*)node.m_node + Dbtux::NodeHeadSize + tree.m_prefSize; + const Dbtux::TreeEnt* entList = (const Dbtux::TreeEnt*)data; + // print entries in logical order + for (unsigned pos = 1; pos <= numpos; pos++) + out << " " << entList[pos % numpos]; + out << "]"; out << "]"; return out; } diff --git a/ndb/src/kernel/blocks/dbtux/DbtuxGen.cpp b/ndb/src/kernel/blocks/dbtux/DbtuxGen.cpp index 39cd8e25184..ded02696a89 100644 --- a/ndb/src/kernel/blocks/dbtux/DbtuxGen.cpp +++ b/ndb/src/kernel/blocks/dbtux/DbtuxGen.cpp @@ -245,7 +245,7 @@ Dbtux::readKeyAttrs(const Frag& frag, TreeEnt ent, unsigned start, Data keyData) const Uint32 numAttrs = frag.m_numAttrs - start; // skip to start position in keyAttrs only keyAttrs += start; - int ret = c_tup->tuxReadAttrs(tableFragPtrI, tupLoc.m_pageId, tupLoc.m_pageOffset, tupVersion, keyAttrs, numAttrs, keyData); + int ret = c_tup->tuxReadAttrs(tableFragPtrI, tupLoc.getPageId(), tupLoc.getPageOffset(), tupVersion, keyAttrs, numAttrs, keyData); jamEntry(); // TODO handle error ndbrequire(ret > 0); @@ -256,7 +256,7 @@ Dbtux::readTablePk(const Frag& frag, TreeEnt ent, Data pkData, unsigned& pkSize) { const Uint32 tableFragPtrI = frag.m_tupTableFragPtrI[ent.m_fragBit]; const TupLoc tupLoc = ent.m_tupLoc; - int ret = c_tup->tuxReadPk(tableFragPtrI, tupLoc.m_pageId, tupLoc.m_pageOffset, pkData); + int ret = c_tup->tuxReadPk(tableFragPtrI, tupLoc.getPageId(), tupLoc.getPageOffset(), pkData); jamEntry(); // TODO handle error ndbrequire(ret > 0); diff --git a/ndb/src/kernel/blocks/dbtux/DbtuxMaint.cpp b/ndb/src/kernel/blocks/dbtux/DbtuxMaint.cpp index 24b030bf8ec..30afb51e7d7 100644 --- a/ndb/src/kernel/blocks/dbtux/DbtuxMaint.cpp +++ b/ndb/src/kernel/blocks/dbtux/DbtuxMaint.cpp @@ -117,10 +117,10 @@ Dbtux::execTUX_MAINT_REQ(Signal* signal) switch (opCode) { case TuxMaintReq::OpAdd: jam(); - searchToAdd(signal, frag, c_searchKey, ent, treePos); + searchToAdd(frag, c_searchKey, ent, treePos); #ifdef VM_TRACE if (debugFlags & DebugMaint) { - debugOut << treePos << endl; + debugOut << treePos << (treePos.m_match ? " - error" : "") << endl; } #endif if (treePos.m_match) { @@ -133,8 +133,8 @@ Dbtux::execTUX_MAINT_REQ(Signal* signal) break; } /* - * At most one new node is inserted in the operation. We keep one - * free node pre-allocated so the operation cannot fail. + * At most one new node is inserted in the operation. Pre-allocate + * it so that the operation cannot fail. */ if (frag.m_freeLoc == NullTupLoc) { jam(); @@ -144,17 +144,19 @@ Dbtux::execTUX_MAINT_REQ(Signal* signal) jam(); break; } + // link to freelist + node.setLink(0, frag.m_freeLoc); frag.m_freeLoc = node.m_loc; ndbrequire(frag.m_freeLoc != NullTupLoc); } - treeAdd(signal, frag, treePos, ent); + treeAdd(frag, treePos, ent); break; case TuxMaintReq::OpRemove: jam(); - searchToRemove(signal, frag, c_searchKey, ent, treePos); + searchToRemove(frag, c_searchKey, ent, treePos); #ifdef VM_TRACE if (debugFlags & DebugMaint) { - debugOut << treePos << endl; + debugOut << treePos << (! treePos.m_match ? " - error" : "") << endl; } #endif if (! treePos.m_match) { @@ -166,7 +168,7 @@ Dbtux::execTUX_MAINT_REQ(Signal* signal) } break; } - treeRemove(signal, frag, treePos); + treeRemove(frag, treePos); break; default: ndbrequire(false); diff --git a/ndb/src/kernel/blocks/dbtux/DbtuxMeta.cpp b/ndb/src/kernel/blocks/dbtux/DbtuxMeta.cpp index 3c0af3ca79d..1577c5045e0 100644 --- a/ndb/src/kernel/blocks/dbtux/DbtuxMeta.cpp +++ b/ndb/src/kernel/blocks/dbtux/DbtuxMeta.cpp @@ -211,11 +211,7 @@ Dbtux::execTUX_ADD_ATTRREQ(Signal* signal) // make these configurable later tree.m_nodeSize = MAX_TTREE_NODE_SIZE; tree.m_prefSize = MAX_TTREE_PREF_SIZE; -#ifdef dbtux_min_occup_less_max_occup const unsigned maxSlack = MAX_TTREE_NODE_SLACK; -#else - const unsigned maxSlack = 0; -#endif // size up to and including first 2 entries const unsigned pref = tree.getSize(AccPref); if (! (pref <= tree.m_nodeSize)) { @@ -235,6 +231,20 @@ Dbtux::execTUX_ADD_ATTRREQ(Signal* signal) tree.m_minOccup = tree.m_maxOccup - maxSlack; // root node does not exist (also set by ctor) tree.m_root = NullTupLoc; +#ifdef VM_TRACE + if (debugFlags & DebugMeta) { + if (fragOpPtr.p->m_fragNo == 0) { + debugOut << "Index id=" << indexPtr.i; + debugOut << " nodeSize=" << tree.m_nodeSize; + debugOut << " headSize=" << NodeHeadSize; + debugOut << " prefSize=" << tree.m_prefSize; + debugOut << " entrySize=" << TreeEntSize; + debugOut << " minOccup=" << tree.m_minOccup; + debugOut << " maxOccup=" << tree.m_maxOccup; + debugOut << endl; + } + } +#endif // fragment is defined c_fragOpPool.release(fragOpPtr); } diff --git a/ndb/src/kernel/blocks/dbtux/DbtuxNode.cpp b/ndb/src/kernel/blocks/dbtux/DbtuxNode.cpp index a1bfa2179bb..389192fd0cf 100644 --- a/ndb/src/kernel/blocks/dbtux/DbtuxNode.cpp +++ b/ndb/src/kernel/blocks/dbtux/DbtuxNode.cpp @@ -24,8 +24,8 @@ int Dbtux::allocNode(Signal* signal, NodeHandle& node) { Frag& frag = node.m_frag; - Uint32 pageId = NullTupLoc.m_pageId; - Uint32 pageOffset = NullTupLoc.m_pageOffset; + Uint32 pageId = NullTupLoc.getPageId(); + Uint32 pageOffset = NullTupLoc.getPageOffset(); Uint32* node32 = 0; int errorCode = c_tup->tuxAllocNode(signal, frag.m_tupIndexFragPtrI, pageId, pageOffset, node32); jamEntry(); @@ -33,55 +33,39 @@ Dbtux::allocNode(Signal* signal, NodeHandle& node) jam(); node.m_loc = TupLoc(pageId, pageOffset); node.m_node = reinterpret_cast<TreeNode*>(node32); - node.m_acc = AccNone; ndbrequire(node.m_loc != NullTupLoc && node.m_node != 0); } return errorCode; } /* - * Access more of the node. - */ -void -Dbtux::accessNode(Signal* signal, NodeHandle& node, AccSize acc) -{ - ndbrequire(node.m_loc != NullTupLoc && node.m_node != 0); - if (node.m_acc >= acc) - return; - // XXX could do prefetch - node.m_acc = acc; -} - -/* * Set handle to point to existing node. */ void -Dbtux::selectNode(Signal* signal, NodeHandle& node, TupLoc loc, AccSize acc) +Dbtux::selectNode(NodeHandle& node, TupLoc loc) { Frag& frag = node.m_frag; ndbrequire(loc != NullTupLoc); - Uint32 pageId = loc.m_pageId; - Uint32 pageOffset = loc.m_pageOffset; + Uint32 pageId = loc.getPageId(); + Uint32 pageOffset = loc.getPageOffset(); Uint32* node32 = 0; c_tup->tuxGetNode(frag.m_tupIndexFragPtrI, pageId, pageOffset, node32); jamEntry(); node.m_loc = loc; node.m_node = reinterpret_cast<TreeNode*>(node32); - node.m_acc = AccNone; ndbrequire(node.m_loc != NullTupLoc && node.m_node != 0); - accessNode(signal, node, acc); } /* - * Set handle to point to new node. Uses the pre-allocated node. + * Set handle to point to new node. Uses a pre-allocated node. */ void -Dbtux::insertNode(Signal* signal, NodeHandle& node, AccSize acc) +Dbtux::insertNode(NodeHandle& node) { Frag& frag = node.m_frag; - TupLoc loc = frag.m_freeLoc; - frag.m_freeLoc = NullTupLoc; - selectNode(signal, node, loc, acc); + // unlink from freelist + selectNode(node, frag.m_freeLoc); + frag.m_freeLoc = node.getLink(0); new (node.m_node) TreeNode(); #ifdef VM_TRACE TreeHead& tree = frag.m_tree; @@ -92,20 +76,17 @@ Dbtux::insertNode(Signal* signal, NodeHandle& node, AccSize acc) } /* - * Delete existing node. + * Delete existing node. Simply put it on the freelist. */ void -Dbtux::deleteNode(Signal* signal, NodeHandle& node) +Dbtux::deleteNode(NodeHandle& node) { Frag& frag = node.m_frag; ndbrequire(node.getOccup() == 0); - TupLoc loc = node.m_loc; - Uint32 pageId = loc.m_pageId; - Uint32 pageOffset = loc.m_pageOffset; - Uint32* node32 = reinterpret_cast<Uint32*>(node.m_node); - c_tup->tuxFreeNode(signal, frag.m_tupIndexFragPtrI, pageId, pageOffset, node32); - jamEntry(); - // invalidate handle and storage + // link to freelist + node.setLink(0, frag.m_freeLoc); + frag.m_freeLoc = node.m_loc; + // invalidate the handle node.m_loc = NullTupLoc; node.m_node = 0; } @@ -115,7 +96,7 @@ Dbtux::deleteNode(Signal* signal, NodeHandle& node) * attribute headers for now. XXX use null mask instead */ void -Dbtux::setNodePref(Signal* signal, NodeHandle& node) +Dbtux::setNodePref(NodeHandle& node) { const Frag& frag = node.m_frag; const TreeHead& tree = frag.m_tree; @@ -133,18 +114,45 @@ Dbtux::setNodePref(Signal* signal, NodeHandle& node) * v * A B C D E _ _ => A B C X D E _ * 0 1 2 3 4 5 6 0 1 2 3 4 5 6 + * + * Add list of scans at the new entry. */ void -Dbtux::nodePushUp(Signal* signal, NodeHandle& node, unsigned pos, const TreeEnt& ent) +Dbtux::nodePushUp(NodeHandle& node, unsigned pos, const TreeEnt& ent, Uint32 scanList) { Frag& frag = node.m_frag; TreeHead& tree = frag.m_tree; const unsigned occup = node.getOccup(); ndbrequire(occup < tree.m_maxOccup && pos <= occup); - // fix scans + // fix old scans + if (node.getNodeScan() != RNIL) + nodePushUpScans(node, pos); + // fix node + TreeEnt* const entList = tree.getEntList(node.m_node); + entList[occup] = entList[0]; + TreeEnt* const tmpList = entList + 1; + for (unsigned i = occup; i > pos; i--) { + jam(); + tmpList[i] = tmpList[i - 1]; + } + tmpList[pos] = ent; + entList[0] = entList[occup + 1]; + node.setOccup(occup + 1); + // add new scans + if (scanList != RNIL) + addScanList(node, pos, scanList); + // fix prefix + if (occup == 0 || pos == 0) + setNodePref(node); +} + +void +Dbtux::nodePushUpScans(NodeHandle& node, unsigned pos) +{ + const unsigned occup = node.getOccup(); ScanOpPtr scanPtr; scanPtr.i = node.getNodeScan(); - while (scanPtr.i != RNIL) { + do { jam(); c_scanOpPool.getPtr(scanPtr); TreePos& scanPos = scanPtr.p->m_scanPos; @@ -160,21 +168,7 @@ Dbtux::nodePushUp(Signal* signal, NodeHandle& node, unsigned pos, const TreeEnt& scanPos.m_pos++; } scanPtr.i = scanPtr.p->m_nodeScan; - } - // fix node - TreeEnt* const entList = tree.getEntList(node.m_node); - entList[occup] = entList[0]; - TreeEnt* const tmpList = entList + 1; - for (unsigned i = occup; i > pos; i--) { - jam(); - tmpList[i] = tmpList[i - 1]; - } - tmpList[pos] = ent; - entList[0] = entList[occup + 1]; - node.setOccup(occup + 1); - // fix prefix - if (occup == 0 || pos == 0) - setNodePref(signal, node); + } while (scanPtr.i != RNIL); } /* @@ -185,42 +179,55 @@ Dbtux::nodePushUp(Signal* signal, NodeHandle& node, unsigned pos, const TreeEnt& * ^ ^ * A B C D E F _ => A B C E F _ _ * 0 1 2 3 4 5 6 0 1 2 3 4 5 6 + * + * Scans at removed entry are returned if non-zero location is passed or + * else moved forward. */ void -Dbtux::nodePopDown(Signal* signal, NodeHandle& node, unsigned pos, TreeEnt& ent) +Dbtux::nodePopDown(NodeHandle& node, unsigned pos, TreeEnt& ent, Uint32* scanList) { Frag& frag = node.m_frag; TreeHead& tree = frag.m_tree; const unsigned occup = node.getOccup(); ndbrequire(occup <= tree.m_maxOccup && pos < occup); - ScanOpPtr scanPtr; - // move scans whose entry disappears - scanPtr.i = node.getNodeScan(); - while (scanPtr.i != RNIL) { + if (node.getNodeScan() != RNIL) { + // remove or move scans at this position + if (scanList == 0) + moveScanList(node, pos); + else + removeScanList(node, pos, *scanList); + // fix other scans + if (node.getNodeScan() != RNIL) + nodePopDownScans(node, pos); + } + // fix node + TreeEnt* const entList = tree.getEntList(node.m_node); + entList[occup] = entList[0]; + TreeEnt* const tmpList = entList + 1; + ent = tmpList[pos]; + for (unsigned i = pos; i < occup - 1; i++) { jam(); - c_scanOpPool.getPtr(scanPtr); - TreePos& scanPos = scanPtr.p->m_scanPos; - ndbrequire(scanPos.m_loc == node.m_loc && scanPos.m_pos < occup); - const Uint32 nextPtrI = scanPtr.p->m_nodeScan; - if (scanPos.m_pos == pos) { - jam(); -#ifdef VM_TRACE - if (debugFlags & DebugScan) { - debugOut << "Move scan " << scanPtr.i << " " << *scanPtr.p << endl; - debugOut << "At popDown pos=" << pos << " " << node << endl; - } -#endif - scanNext(signal, scanPtr); - } - scanPtr.i = nextPtrI; + tmpList[i] = tmpList[i + 1]; } - // fix other scans + entList[0] = entList[occup - 1]; + node.setOccup(occup - 1); + // fix prefix + if (occup != 1 && pos == 0) + setNodePref(node); +} + +void +Dbtux::nodePopDownScans(NodeHandle& node, unsigned pos) +{ + const unsigned occup = node.getOccup(); + ScanOpPtr scanPtr; scanPtr.i = node.getNodeScan(); - while (scanPtr.i != RNIL) { + do { jam(); c_scanOpPool.getPtr(scanPtr); TreePos& scanPos = scanPtr.p->m_scanPos; ndbrequire(scanPos.m_loc == node.m_loc && scanPos.m_pos < occup); + // handled before ndbrequire(scanPos.m_pos != pos); if (scanPos.m_pos > pos) { jam(); @@ -233,21 +240,7 @@ Dbtux::nodePopDown(Signal* signal, NodeHandle& node, unsigned pos, TreeEnt& ent) scanPos.m_pos--; } scanPtr.i = scanPtr.p->m_nodeScan; - } - // fix node - TreeEnt* const entList = tree.getEntList(node.m_node); - entList[occup] = entList[0]; - TreeEnt* const tmpList = entList + 1; - ent = tmpList[pos]; - for (unsigned i = pos; i < occup - 1; i++) { - jam(); - tmpList[i] = tmpList[i + 1]; - } - entList[0] = entList[occup - 1]; - node.setOccup(occup - 1); - // fix prefix - if (occup != 1 && pos == 0) - setNodePref(signal, node); + } while (scanPtr.i != RNIL); } /* @@ -258,43 +251,52 @@ Dbtux::nodePopDown(Signal* signal, NodeHandle& node, unsigned pos, TreeEnt& ent) * ^ v ^ * A B C D E _ _ => B C D X E _ _ * 0 1 2 3 4 5 6 0 1 2 3 4 5 6 + * + * Return list of scans at the removed position 0. */ void -Dbtux::nodePushDown(Signal* signal, NodeHandle& node, unsigned pos, TreeEnt& ent) +Dbtux::nodePushDown(NodeHandle& node, unsigned pos, TreeEnt& ent, Uint32& scanList) { Frag& frag = node.m_frag; TreeHead& tree = frag.m_tree; const unsigned occup = node.getOccup(); ndbrequire(occup <= tree.m_maxOccup && pos < occup); - ScanOpPtr scanPtr; - // move scans whose entry disappears - scanPtr.i = node.getNodeScan(); - while (scanPtr.i != RNIL) { + if (node.getNodeScan() != RNIL) { + // remove scans at 0 + removeScanList(node, 0, scanList); + // fix other scans + if (node.getNodeScan() != RNIL) + nodePushDownScans(node, pos); + } + // fix node + TreeEnt* const entList = tree.getEntList(node.m_node); + entList[occup] = entList[0]; + TreeEnt* const tmpList = entList + 1; + TreeEnt oldMin = tmpList[0]; + for (unsigned i = 0; i < pos; i++) { jam(); - c_scanOpPool.getPtr(scanPtr); - TreePos& scanPos = scanPtr.p->m_scanPos; - ndbrequire(scanPos.m_loc == node.m_loc && scanPos.m_pos < occup); - const Uint32 nextPtrI = scanPtr.p->m_nodeScan; - if (scanPos.m_pos == 0) { - jam(); -#ifdef VM_TRACE - if (debugFlags & DebugScan) { - debugOut << "Move scan " << scanPtr.i << " " << *scanPtr.p << endl; - debugOut << "At pushDown pos=" << pos << " " << node << endl; - } -#endif - // here we may miss a valid entry "X" XXX known bug - scanNext(signal, scanPtr); - } - scanPtr.i = nextPtrI; + tmpList[i] = tmpList[i + 1]; } - // fix other scans + tmpList[pos] = ent; + ent = oldMin; + entList[0] = entList[occup]; + // fix prefix + if (true) + setNodePref(node); +} + +void +Dbtux::nodePushDownScans(NodeHandle& node, unsigned pos) +{ + const unsigned occup = node.getOccup(); + ScanOpPtr scanPtr; scanPtr.i = node.getNodeScan(); - while (scanPtr.i != RNIL) { + do { jam(); c_scanOpPool.getPtr(scanPtr); TreePos& scanPos = scanPtr.p->m_scanPos; ndbrequire(scanPos.m_loc == node.m_loc && scanPos.m_pos < occup); + // handled before ndbrequire(scanPos.m_pos != 0); if (scanPos.m_pos <= pos) { jam(); @@ -307,22 +309,7 @@ Dbtux::nodePushDown(Signal* signal, NodeHandle& node, unsigned pos, TreeEnt& ent scanPos.m_pos--; } scanPtr.i = scanPtr.p->m_nodeScan; - } - // fix node - TreeEnt* const entList = tree.getEntList(node.m_node); - entList[occup] = entList[0]; - TreeEnt* const tmpList = entList + 1; - TreeEnt oldMin = tmpList[0]; - for (unsigned i = 0; i < pos; i++) { - jam(); - tmpList[i] = tmpList[i + 1]; - } - tmpList[pos] = ent; - ent = oldMin; - entList[0] = entList[occup]; - // fix prefix - if (true) - setNodePref(signal, node); + } while (scanPtr.i != RNIL); } /* @@ -334,39 +321,50 @@ Dbtux::nodePushDown(Signal* signal, NodeHandle& node, unsigned pos, TreeEnt& ent * v ^ ^ * A B C D E _ _ => X A B C E _ _ * 0 1 2 3 4 5 6 0 1 2 3 4 5 6 + * + * Move scans at removed entry and add scans at the new entry. */ void -Dbtux::nodePopUp(Signal* signal, NodeHandle& node, unsigned pos, TreeEnt& ent) +Dbtux::nodePopUp(NodeHandle& node, unsigned pos, TreeEnt& ent, Uint32 scanList) { Frag& frag = node.m_frag; TreeHead& tree = frag.m_tree; const unsigned occup = node.getOccup(); ndbrequire(occup <= tree.m_maxOccup && pos < occup); - ScanOpPtr scanPtr; - // move scans whose entry disappears - scanPtr.i = node.getNodeScan(); - while (scanPtr.i != RNIL) { + if (node.getNodeScan() != RNIL) { + // move scans whose entry disappears + moveScanList(node, pos); + // fix other scans + if (node.getNodeScan() != RNIL) + nodePopUpScans(node, pos); + } + // fix node + TreeEnt* const entList = tree.getEntList(node.m_node); + entList[occup] = entList[0]; + TreeEnt* const tmpList = entList + 1; + TreeEnt newMin = ent; + ent = tmpList[pos]; + for (unsigned i = pos; i > 0; i--) { jam(); - c_scanOpPool.getPtr(scanPtr); - TreePos& scanPos = scanPtr.p->m_scanPos; - ndbrequire(scanPos.m_loc == node.m_loc && scanPos.m_pos < occup); - const Uint32 nextPtrI = scanPtr.p->m_nodeScan; - if (scanPos.m_pos == pos) { - jam(); -#ifdef VM_TRACE - if (debugFlags & DebugScan) { - debugOut << "Move scan " << scanPtr.i << " " << *scanPtr.p << endl; - debugOut << "At popUp pos=" << pos << " " << node << endl; - } -#endif - // here we may miss a valid entry "X" XXX known bug - scanNext(signal, scanPtr); - } - scanPtr.i = nextPtrI; + tmpList[i] = tmpList[i - 1]; } - // fix other scans + tmpList[0] = newMin; + entList[0] = entList[occup]; + // add scans + if (scanList != RNIL) + addScanList(node, 0, scanList); + // fix prefix + if (true) + setNodePref(node); +} + +void +Dbtux::nodePopUpScans(NodeHandle& node, unsigned pos) +{ + const unsigned occup = node.getOccup(); + ScanOpPtr scanPtr; scanPtr.i = node.getNodeScan(); - while (scanPtr.i != RNIL) { + do { jam(); c_scanOpPool.getPtr(scanPtr); TreePos& scanPos = scanPtr.p->m_scanPos; @@ -383,41 +381,123 @@ Dbtux::nodePopUp(Signal* signal, NodeHandle& node, unsigned pos, TreeEnt& ent) scanPos.m_pos++; } scanPtr.i = scanPtr.p->m_nodeScan; - } - // fix node - TreeEnt* const entList = tree.getEntList(node.m_node); - entList[occup] = entList[0]; - TreeEnt* const tmpList = entList + 1; - TreeEnt newMin = ent; - ent = tmpList[pos]; - for (unsigned i = pos; i > 0; i--) { - jam(); - tmpList[i] = tmpList[i - 1]; - } - tmpList[0] = newMin; - entList[0] = entList[occup]; - // fix prefix - if (true) - setNodePref(signal, node); + } while (scanPtr.i != RNIL); } /* - * Move all possible entries from another node before the min (i=0) or - * after the max (i=1). XXX can be optimized + * Move number of entries from another node to this node before the min + * (i=0) or after the max (i=1). Expensive but not often used. */ void -Dbtux::nodeSlide(Signal* signal, NodeHandle& dstNode, NodeHandle& srcNode, unsigned i) +Dbtux::nodeSlide(NodeHandle& dstNode, NodeHandle& srcNode, unsigned cnt, unsigned i) { Frag& frag = dstNode.m_frag; TreeHead& tree = frag.m_tree; ndbrequire(i <= 1); - while (dstNode.getOccup() < tree.m_maxOccup && srcNode.getOccup() != 0) { + while (cnt != 0) { TreeEnt ent; - nodePopDown(signal, srcNode, i == 0 ? srcNode.getOccup() - 1 : 0, ent); - nodePushUp(signal, dstNode, i == 0 ? 0 : dstNode.getOccup(), ent); + Uint32 scanList = RNIL; + nodePopDown(srcNode, i == 0 ? srcNode.getOccup() - 1 : 0, ent, &scanList); + nodePushUp(dstNode, i == 0 ? 0 : dstNode.getOccup(), ent, scanList); + cnt--; } } +// scans linked to node + + +/* + * Add list of scans to node at given position. + */ +void +Dbtux::addScanList(NodeHandle& node, unsigned pos, Uint32 scanList) +{ + ScanOpPtr scanPtr; + scanPtr.i = scanList; + do { + jam(); + c_scanOpPool.getPtr(scanPtr); +#ifdef VM_TRACE + if (debugFlags & DebugScan) { + debugOut << "Add scan " << scanPtr.i << " " << *scanPtr.p << endl; + debugOut << "To pos=" << pos << " " << node << endl; + } +#endif + const Uint32 nextPtrI = scanPtr.p->m_nodeScan; + scanPtr.p->m_nodeScan = RNIL; + linkScan(node, scanPtr); + TreePos& scanPos = scanPtr.p->m_scanPos; + // set position but leave direction alone + scanPos.m_loc = node.m_loc; + scanPos.m_pos = pos; + scanPtr.i = nextPtrI; + } while (scanPtr.i != RNIL); +} + +/* + * Remove list of scans from node at given position. The return + * location must point to existing list (in fact RNIL always). + */ +void +Dbtux::removeScanList(NodeHandle& node, unsigned pos, Uint32& scanList) +{ + ScanOpPtr scanPtr; + scanPtr.i = node.getNodeScan(); + do { + jam(); + c_scanOpPool.getPtr(scanPtr); + const Uint32 nextPtrI = scanPtr.p->m_nodeScan; + TreePos& scanPos = scanPtr.p->m_scanPos; + ndbrequire(scanPos.m_loc == node.m_loc); + if (scanPos.m_pos == pos) { + jam(); +#ifdef VM_TRACE + if (debugFlags & DebugScan) { + debugOut << "Remove scan " << scanPtr.i << " " << *scanPtr.p << endl; + debugOut << "Fron pos=" << pos << " " << node << endl; + } +#endif + unlinkScan(node, scanPtr); + scanPtr.p->m_nodeScan = scanList; + scanList = scanPtr.i; + // unset position but leave direction alone + scanPos.m_loc = NullTupLoc; + scanPos.m_pos = ZNIL; + } + scanPtr.i = nextPtrI; + } while (scanPtr.i != RNIL); +} + +/* + * Move list of scans away from entry about to be removed. Uses scan + * method scanNext(). + */ +void +Dbtux::moveScanList(NodeHandle& node, unsigned pos) +{ + ScanOpPtr scanPtr; + scanPtr.i = node.getNodeScan(); + do { + jam(); + c_scanOpPool.getPtr(scanPtr); + TreePos& scanPos = scanPtr.p->m_scanPos; + const Uint32 nextPtrI = scanPtr.p->m_nodeScan; + ndbrequire(scanPos.m_loc == node.m_loc); + if (scanPos.m_pos == pos) { + jam(); +#ifdef VM_TRACE + if (debugFlags & DebugScan) { + debugOut << "Move scan " << scanPtr.i << " " << *scanPtr.p << endl; + debugOut << "At pos=" << pos << " " << node << endl; + } +#endif + scanNext(scanPtr); + ndbrequire(! (scanPos.m_loc == node.m_loc && scanPos.m_pos == pos)); + } + scanPtr.i = nextPtrI; + } while (scanPtr.i != RNIL); +} + /* * Link scan to the list under the node. The list is single-linked and * ordering does not matter. diff --git a/ndb/src/kernel/blocks/dbtux/DbtuxScan.cpp b/ndb/src/kernel/blocks/dbtux/DbtuxScan.cpp index 5b161d3c4ce..afde88c47a2 100644 --- a/ndb/src/kernel/blocks/dbtux/DbtuxScan.cpp +++ b/ndb/src/kernel/blocks/dbtux/DbtuxScan.cpp @@ -108,15 +108,23 @@ Dbtux::execACC_SCANREQ(Signal* signal) /* * Receive bounds for scan in single direct call. The bounds can arrive * in any order. Attribute ids are those of index table. + * + * Replace EQ by equivalent LE + GE. Check for conflicting bounds. + * Check that sets of lower and upper bounds are on initial sequences of + * keys and that all but possibly last bound is non-strict. + * + * Finally save the sets of lower and upper bounds (i.e. start key and + * end key). Full bound type (< 4) is included but only the strict bit + * is used since lower and upper have now been separated. */ void Dbtux::execTUX_BOUND_INFO(Signal* signal) { jamEntry(); struct BoundInfo { + int type; unsigned offset; unsigned size; - int type; }; TuxBoundInfo* const sig = (TuxBoundInfo*)signal->getDataPtrSend(); const TuxBoundInfo reqCopy = *(const TuxBoundInfo*)sig; @@ -124,19 +132,12 @@ Dbtux::execTUX_BOUND_INFO(Signal* signal) // get records ScanOp& scan = *c_scanOpPool.getPtr(req->tuxScanPtrI); Index& index = *c_indexPool.getPtr(scan.m_indexId); - // collect bound info for each index attribute - BoundInfo boundInfo[MaxIndexAttributes][2]; + // collect lower and upper bounds + BoundInfo boundInfo[2][MaxIndexAttributes]; // largest attrId seen plus one - Uint32 maxAttrId = 0; - // skip 5 words - if (req->boundAiLength < 5) { - jam(); - scan.m_state = ScanOp::Invalid; - sig->errorCode = TuxBoundInfo::InvalidAttrInfo; - return; - } + Uint32 maxAttrId[2] = { 0, 0 }; + unsigned offset = 0; const Uint32* const data = (Uint32*)sig + TuxBoundInfo::SignalLength; - unsigned offset = 5; // walk through entries while (offset + 2 <= req->boundAiLength) { jam(); @@ -156,32 +157,35 @@ Dbtux::execTUX_BOUND_INFO(Signal* signal) sig->errorCode = TuxBoundInfo::InvalidAttrInfo; return; } - while (maxAttrId <= attrId) { - BoundInfo* b = boundInfo[maxAttrId++]; - b[0].type = b[1].type = -1; - } - BoundInfo* b = boundInfo[attrId]; - if (type == 0 || type == 1 || type == 4) { - if (b[0].type != -1) { - jam(); - scan.m_state = ScanOp::Invalid; - sig->errorCode = TuxBoundInfo::InvalidBounds; - return; + for (unsigned j = 0; j <= 1; j++) { + // check if lower/upper bit matches + const unsigned luBit = (j << 1); + if ((type & 0x2) != luBit && type != 4) + continue; + // EQ -> LE, GE + const unsigned type2 = (type & 0x1) | luBit; + // fill in any gap + while (maxAttrId[j] <= attrId) { + BoundInfo& b = boundInfo[j][maxAttrId[j]++]; + b.type = -1; } - b[0].offset = offset; - b[0].size = 2 + dataSize; - b[0].type = type; - } - if (type == 2 || type == 3 || type == 4) { - if (b[1].type != -1) { - jam(); - scan.m_state = ScanOp::Invalid; - sig->errorCode = TuxBoundInfo::InvalidBounds; - return; + BoundInfo& b = boundInfo[j][attrId]; + if (b.type != -1) { + // compare with previous bound + if (b.type != type2 || + b.size != 2 + dataSize || + memcmp(&data[b.offset + 2], &data[offset + 2], dataSize << 2) != 0) { + jam(); + scan.m_state = ScanOp::Invalid; + sig->errorCode = TuxBoundInfo::InvalidBounds; + return; + } + } else { + // enter new bound + b.type = type2; + b.offset = offset; + b.size = 2 + dataSize; } - b[1].offset = offset; - b[1].size = 2 + dataSize; - b[1].type = type; } // jump to next offset += 2 + dataSize; @@ -192,34 +196,27 @@ Dbtux::execTUX_BOUND_INFO(Signal* signal) sig->errorCode = TuxBoundInfo::InvalidAttrInfo; return; } - // save the bounds in index attribute id order - scan.m_boundCnt[0] = 0; - scan.m_boundCnt[1] = 0; - for (unsigned i = 0; i < maxAttrId; i++) { - jam(); - const BoundInfo* b = boundInfo[i]; - // current limitation - check all but last is equality - if (i + 1 < maxAttrId) { - if (b[0].type != 4 || b[1].type != 4) { + for (unsigned j = 0; j <= 1; j++) { + // save lower/upper bound in index attribute id order + for (unsigned i = 0; i < maxAttrId[j]; i++) { + jam(); + const BoundInfo& b = boundInfo[j][i]; + // check for gap or strict bound before last + if (b.type == -1 || (i + 1 < maxAttrId[j] && (b.type & 0x1))) { jam(); scan.m_state = ScanOp::Invalid; sig->errorCode = TuxBoundInfo::InvalidBounds; return; } - } - for (unsigned j = 0; j <= 1; j++) { - if (b[j].type != -1) { + bool ok = scan.m_bound[j]->append(&data[b.offset], b.size); + if (! ok) { jam(); - bool ok = scan.m_bound[j]->append(&data[b[j].offset], b[j].size); - if (! ok) { - jam(); - scan.m_state = ScanOp::Invalid; - sig->errorCode = TuxBoundInfo::OutOfBuffers; - return; - } - scan.m_boundCnt[j]++; + scan.m_state = ScanOp::Invalid; + sig->errorCode = TuxBoundInfo::OutOfBuffers; + return; } } + scan.m_boundCnt[j] = maxAttrId[j]; } // no error sig->errorCode = 0; @@ -278,7 +275,7 @@ Dbtux::execNEXT_SCANREQ(Signal* signal) jam(); const TupLoc loc = scan.m_scanPos.m_loc; NodeHandle node(frag); - selectNode(signal, node, loc, AccHead); + selectNode(node, loc); unlinkScan(node, scanPtr); scan.m_scanPos.m_loc = NullTupLoc; } @@ -353,7 +350,7 @@ Dbtux::execACC_CHECK_SCAN(Signal* signal) if (scan.m_lockwait) { jam(); // LQH asks if we are waiting for lock and we tell it to ask again - const TreeEnt ent = scan.m_scanPos.m_ent; + const TreeEnt ent = scan.m_scanEnt; NextScanConf* const conf = (NextScanConf*)signal->getDataPtrSend(); conf->scanPtr = scan.m_userPtr; conf->accOperationPtr = RNIL; // no tuple returned @@ -367,7 +364,7 @@ Dbtux::execACC_CHECK_SCAN(Signal* signal) if (scan.m_state == ScanOp::First) { jam(); // search is done only once in single range scan - scanFirst(signal, scanPtr); + scanFirst(scanPtr); #ifdef VM_TRACE if (debugFlags & DebugScan) { debugOut << "First scan " << scanPtr.i << " " << scan << endl; @@ -377,7 +374,7 @@ Dbtux::execACC_CHECK_SCAN(Signal* signal) if (scan.m_state == ScanOp::Next) { jam(); // look for next - scanNext(signal, scanPtr); + scanNext(scanPtr); } // for reading tuple key in Current or Locked state Data pkData = c_dataBuffer; @@ -388,7 +385,7 @@ Dbtux::execACC_CHECK_SCAN(Signal* signal) ndbrequire(scan.m_accLockOp == RNIL); if (! scan.m_readCommitted) { jam(); - const TreeEnt ent = scan.m_scanPos.m_ent; + const TreeEnt ent = scan.m_scanEnt; // read tuple key readTablePk(frag, ent, pkData, pkSize); // get read lock or exclusive lock @@ -476,7 +473,7 @@ Dbtux::execACC_CHECK_SCAN(Signal* signal) // we have lock or do not need one jam(); // read keys if not already done (uses signal) - const TreeEnt ent = scan.m_scanPos.m_ent; + const TreeEnt ent = scan.m_scanEnt; if (scan.m_keyInfo) { jam(); if (pkSize == 0) { @@ -539,8 +536,6 @@ Dbtux::execACC_CHECK_SCAN(Signal* signal) total += length; } } - // remember last entry returned - scan.m_lastEnt = ent; // next time look for next entry scan.m_state = ScanOp::Next; return; @@ -685,7 +680,7 @@ Dbtux::execACC_ABORTCONF(Signal* signal) * by scanNext. */ void -Dbtux::scanFirst(Signal* signal, ScanOpPtr scanPtr) +Dbtux::scanFirst(ScanOpPtr scanPtr) { ScanOp& scan = *scanPtr.p; Frag& frag = *c_fragPool.getPtr(scan.m_fragPtrI); @@ -703,7 +698,7 @@ Dbtux::scanFirst(Signal* signal, ScanOpPtr scanPtr) } // search for scan start position TreePos treePos; - searchToScan(signal, frag, c_dataBuffer, scan.m_boundCnt[0], treePos); + searchToScan(frag, c_dataBuffer, scan.m_boundCnt[0], treePos); if (treePos.m_loc == NullTupLoc) { // empty tree jam(); @@ -715,23 +710,27 @@ Dbtux::scanFirst(Signal* signal, ScanOpPtr scanPtr) scan.m_state = ScanOp::Next; // link the scan to node found NodeHandle node(frag); - selectNode(signal, node, treePos.m_loc, AccFull); + selectNode(node, treePos.m_loc); linkScan(node, scanPtr); } /* * Move to next entry. The scan is already linked to some node. When - * we leave, if any entry was found, it will be linked to a possibly - * different node. The scan has a direction, one of: + * we leave, if an entry was found, it will be linked to a possibly + * different node. The scan has a position, and a direction which tells + * from where we came to this position. This is one of: + * + * 0 - up from left child (scan this node next) + * 1 - up from right child (proceed to parent) + * 2 - up from root (the scan ends) + * 3 - left to right within node (at end proceed to right child) + * 4 - down from parent (proceed to left child) * - * 0 - coming up from left child - * 1 - coming up from right child (proceed to parent immediately) - * 2 - coming up from root (the scan ends) - * 3 - left to right within node - * 4 - coming down from parent to left or right child + * If an entry was found, scan direction is 3. Therefore tree + * re-organizations need not worry about scan direction. */ void -Dbtux::scanNext(Signal* signal, ScanOpPtr scanPtr) +Dbtux::scanNext(ScanOpPtr scanPtr) { ScanOp& scan = *scanPtr.p; Frag& frag = *c_fragPool.getPtr(scan.m_fragPtrI); @@ -740,22 +739,8 @@ Dbtux::scanNext(Signal* signal, ScanOpPtr scanPtr) debugOut << "Next in scan " << scanPtr.i << " " << scan << endl; } #endif - if (scan.m_state == ScanOp::Locked) { - jam(); - // version of a tuple locked by us cannot disappear (assert only) -#ifdef dbtux_wl_1942_is_done - ndbassert(false); -#endif - AccLockReq* const lockReq = (AccLockReq*)signal->getDataPtrSend(); - lockReq->returnCode = RNIL; - lockReq->requestInfo = AccLockReq::Unlock; - lockReq->accOpPtr = scan.m_accLockOp; - EXECUTE_DIRECT(DBACC, GSN_ACC_LOCKREQ, signal, AccLockReq::UndoSignalLength); - jamEntry(); - ndbrequire(lockReq->returnCode == AccLockReq::Success); - scan.m_accLockOp = RNIL; - scan.m_state = ScanOp::Current; - } + // cannot be moved away from tuple we have locked + ndbrequire(scan.m_state != ScanOp::Locked); // set up index keys for this operation setKeyAttrs(frag); // unpack upper bound into c_dataBuffer @@ -771,10 +756,12 @@ Dbtux::scanNext(Signal* signal, ScanOpPtr scanPtr) TreePos pos = scan.m_scanPos; // get and remember original node NodeHandle origNode(frag); - selectNode(signal, origNode, pos.m_loc, AccHead); + selectNode(origNode, pos.m_loc); ndbrequire(islinkScan(origNode, scanPtr)); // current node in loop NodeHandle node = origNode; + // copy of entry found + TreeEnt ent; while (true) { jam(); if (pos.m_dir == 2) { @@ -786,7 +773,7 @@ Dbtux::scanNext(Signal* signal, ScanOpPtr scanPtr) } if (node.m_loc != pos.m_loc) { jam(); - selectNode(signal, node, pos.m_loc, AccHead); + selectNode(node, pos.m_loc); } if (pos.m_dir == 4) { // coming down from parent proceed to left child @@ -802,7 +789,7 @@ Dbtux::scanNext(Signal* signal, ScanOpPtr scanPtr) pos.m_dir = 0; } if (pos.m_dir == 0) { - // coming from left child scan current node + // coming up from left child scan current node jam(); pos.m_pos = 0; pos.m_match = false; @@ -813,8 +800,6 @@ Dbtux::scanNext(Signal* signal, ScanOpPtr scanPtr) jam(); unsigned occup = node.getOccup(); ndbrequire(occup >= 1); - // access full node - accessNode(signal, node, AccFull); // advance position if (! pos.m_match) pos.m_match = true; @@ -822,10 +807,10 @@ Dbtux::scanNext(Signal* signal, ScanOpPtr scanPtr) pos.m_pos++; if (pos.m_pos < occup) { jam(); - pos.m_ent = node.getEnt(pos.m_pos); + ent = node.getEnt(pos.m_pos); pos.m_dir = 3; // unchanged // read and compare all attributes - readKeyAttrs(frag, pos.m_ent, 0, c_entryKey); + readKeyAttrs(frag, ent, 0, c_entryKey); int ret = cmpScanBound(frag, 1, c_dataBuffer, scan.m_boundCnt[1], c_entryKey); ndbrequire(ret != NdbSqlUtil::CmpUnknown); if (ret < 0) { @@ -836,7 +821,7 @@ Dbtux::scanNext(Signal* signal, ScanOpPtr scanPtr) break; } // can we see it - if (! scanVisible(signal, scanPtr, pos.m_ent)) { + if (! scanVisible(scanPtr, ent)) { jam(); continue; } @@ -856,7 +841,7 @@ Dbtux::scanNext(Signal* signal, ScanOpPtr scanPtr) pos.m_dir = 1; } if (pos.m_dir == 1) { - // coming from right child proceed to parent + // coming up from right child proceed to parent jam(); pos.m_loc = node.getLink(2); pos.m_dir = node.getSide(); @@ -868,12 +853,15 @@ Dbtux::scanNext(Signal* signal, ScanOpPtr scanPtr) scan.m_scanPos = pos; // relink if (scan.m_state == ScanOp::Current) { + ndbrequire(pos.m_match == true && pos.m_dir == 3); ndbrequire(pos.m_loc == node.m_loc); if (origNode.m_loc != node.m_loc) { jam(); unlinkScan(origNode, scanPtr); linkScan(node, scanPtr); } + // copy found entry + scan.m_scanEnt = ent; } else if (scan.m_state == ScanOp::Last) { jam(); ndbrequire(pos.m_loc == NullTupLoc); @@ -891,12 +879,12 @@ Dbtux::scanNext(Signal* signal, ScanOpPtr scanPtr) /* * Check if an entry is visible to the scan. * - * There is a special check to never return same tuple twice in a row. + * There is a special check to never accept same tuple twice in a row. * This is faster than asking TUP. It also fixes some special cases * which are not analyzed or handled yet. */ bool -Dbtux::scanVisible(Signal* signal, ScanOpPtr scanPtr, TreeEnt ent) +Dbtux::scanVisible(ScanOpPtr scanPtr, TreeEnt ent) { const ScanOp& scan = *scanPtr.p; const Frag& frag = *c_fragPool.getPtr(scan.m_fragPtrI); @@ -906,8 +894,8 @@ Dbtux::scanVisible(Signal* signal, ScanOpPtr scanPtr, TreeEnt ent) Uint32 tupAddr = getTupAddr(frag, ent); Uint32 tupVersion = ent.m_tupVersion; // check for same tuple twice in row - if (scan.m_lastEnt.m_tupLoc == ent.m_tupLoc && - scan.m_lastEnt.m_fragBit == fragBit) { + if (scan.m_scanEnt.m_tupLoc == ent.m_tupLoc && + scan.m_scanEnt.m_fragBit == fragBit) { jam(); return false; } @@ -929,7 +917,7 @@ Dbtux::scanClose(Signal* signal, ScanOpPtr scanPtr) ScanOp& scan = *scanPtr.p; ndbrequire(! scan.m_lockwait && scan.m_accLockOp == RNIL); // unlock all not unlocked by LQH - for (unsigned i = 0; i < MaxAccLockOps; i++) { + for (unsigned i = 0; i < scan.m_maxAccLockOps; i++) { if (scan.m_accLockOps[i] != RNIL) { jam(); AccLockReq* const lockReq = (AccLockReq*)signal->getDataPtrSend(); @@ -959,7 +947,7 @@ Dbtux::addAccLockOp(ScanOp& scan, Uint32 accLockOp) ndbrequire(accLockOp != RNIL); Uint32* list = scan.m_accLockOps; bool ok = false; - for (unsigned i = 0; i < MaxAccLockOps; i++) { + for (unsigned i = 0; i < scan.m_maxAccLockOps; i++) { ndbrequire(list[i] != accLockOp); if (! ok && list[i] == RNIL) { list[i] = accLockOp; @@ -967,6 +955,14 @@ Dbtux::addAccLockOp(ScanOp& scan, Uint32 accLockOp) // continue check for duplicates } } + if (! ok) { + unsigned i = scan.m_maxAccLockOps; + if (i < MaxAccLockOps) { + list[i] = accLockOp; + ok = true; + scan.m_maxAccLockOps = i + 1; + } + } ndbrequire(ok); } @@ -976,7 +972,7 @@ Dbtux::removeAccLockOp(ScanOp& scan, Uint32 accLockOp) ndbrequire(accLockOp != RNIL); Uint32* list = scan.m_accLockOps; bool ok = false; - for (unsigned i = 0; i < MaxAccLockOps; i++) { + for (unsigned i = 0; i < scan.m_maxAccLockOps; i++) { if (list[i] == accLockOp) { list[i] = RNIL; ok = true; diff --git a/ndb/src/kernel/blocks/dbtux/DbtuxSearch.cpp b/ndb/src/kernel/blocks/dbtux/DbtuxSearch.cpp index bffbb8f5594..7057d74c3ad 100644 --- a/ndb/src/kernel/blocks/dbtux/DbtuxSearch.cpp +++ b/ndb/src/kernel/blocks/dbtux/DbtuxSearch.cpp @@ -25,16 +25,17 @@ * TODO optimize for initial equal attrs in node min/max */ void -Dbtux::searchToAdd(Signal* signal, Frag& frag, ConstData searchKey, TreeEnt searchEnt, TreePos& treePos) +Dbtux::searchToAdd(Frag& frag, ConstData searchKey, TreeEnt searchEnt, TreePos& treePos) { const TreeHead& tree = frag.m_tree; const unsigned numAttrs = frag.m_numAttrs; NodeHandle currNode(frag); currNode.m_loc = tree.m_root; + // assume success + treePos.m_match = false; if (currNode.m_loc == NullTupLoc) { // empty tree jam(); - treePos.m_match = false; return; } NodeHandle glbNode(frag); // potential g.l.b of final node @@ -45,7 +46,7 @@ Dbtux::searchToAdd(Signal* signal, Frag& frag, ConstData searchKey, TreeEnt sear NodeHandle bottomNode(frag); while (true) { jam(); - selectNode(signal, currNode, currNode.m_loc, AccPref); + selectNode(currNode, currNode.m_loc); int ret; // compare prefix unsigned start = 0; @@ -93,16 +94,22 @@ Dbtux::searchToAdd(Signal* signal, Frag& frag, ConstData searchKey, TreeEnt sear jam(); treePos.m_loc = currNode.m_loc; treePos.m_pos = 0; + // failed treePos.m_match = true; return; } break; } - // access rest of current node - accessNode(signal, currNode, AccFull); - for (unsigned j = 0, occup = currNode.getOccup(); j < occup; j++) { + // anticipate + treePos.m_loc = currNode.m_loc; + // binary search + int lo = -1; + unsigned hi = currNode.getOccup(); + int ret; + while (1) { jam(); - int ret; + // hi - lo > 1 implies lo < j < hi + int j = (hi + lo) / 2; // read and compare attributes unsigned start = 0; readKeyAttrs(frag, currNode.getEnt(j), start, c_entryKey); @@ -113,25 +120,38 @@ Dbtux::searchToAdd(Signal* signal, Frag& frag, ConstData searchKey, TreeEnt sear // keys are equal, compare entry values ret = searchEnt.cmp(currNode.getEnt(j)); } - if (ret <= 0) { - jam(); - treePos.m_loc = currNode.m_loc; + if (ret < 0) + hi = j; + else if (ret > 0) + lo = j; + else { treePos.m_pos = j; - treePos.m_match = (ret == 0); + // failed + treePos.m_match = true; return; } + if (hi - lo == 1) + break; } - if (! bottomNode.isNull()) { + if (ret < 0) { jam(); - // backwards compatible for now - treePos.m_loc = bottomNode.m_loc; - treePos.m_pos = 0; - treePos.m_match = false; + treePos.m_pos = hi; return; } - treePos.m_loc = currNode.m_loc; - treePos.m_pos = currNode.getOccup(); - treePos.m_match = false; + if (hi < currNode.getOccup()) { + jam(); + treePos.m_pos = hi; + return; + } + if (bottomNode.isNull()) { + jam(); + treePos.m_pos = hi; + return; + } + jam(); + // backwards compatible for now + treePos.m_loc = bottomNode.m_loc; + treePos.m_pos = 0; } /* @@ -139,27 +159,30 @@ Dbtux::searchToAdd(Signal* signal, Frag& frag, ConstData searchKey, TreeEnt sear * * Compares search key to each node min. A move to right subtree can * overshoot target node. The last such node is saved. The final node - * is a half-leaf or leaf. If search key is less than final node min + * is a semi-leaf or leaf. If search key is less than final node min * then the saved node is the g.l.b of the final node and we move back * to it. */ void -Dbtux::searchToRemove(Signal* signal, Frag& frag, ConstData searchKey, TreeEnt searchEnt, TreePos& treePos) +Dbtux::searchToRemove(Frag& frag, ConstData searchKey, TreeEnt searchEnt, TreePos& treePos) { const TreeHead& tree = frag.m_tree; const unsigned numAttrs = frag.m_numAttrs; NodeHandle currNode(frag); currNode.m_loc = tree.m_root; + // assume success + treePos.m_match = true; if (currNode.m_loc == NullTupLoc) { // empty tree jam(); + // failed treePos.m_match = false; return; } NodeHandle glbNode(frag); // potential g.l.b of final node while (true) { jam(); - selectNode(signal, currNode, currNode.m_loc, AccPref); + selectNode(currNode, currNode.m_loc); int ret; // compare prefix unsigned start = 0; @@ -206,27 +229,24 @@ Dbtux::searchToRemove(Signal* signal, Frag& frag, ConstData searchKey, TreeEnt s jam(); treePos.m_loc = currNode.m_loc; treePos.m_pos = 0; - treePos.m_match = true; return; } break; } - // access rest of current node - accessNode(signal, currNode, AccFull); + // anticipate + treePos.m_loc = currNode.m_loc; // pos 0 was handled above for (unsigned j = 1, occup = currNode.getOccup(); j < occup; j++) { jam(); // compare only the entry if (searchEnt.eq(currNode.getEnt(j))) { jam(); - treePos.m_loc = currNode.m_loc; treePos.m_pos = j; - treePos.m_match = true; return; } } - treePos.m_loc = currNode.m_loc; treePos.m_pos = currNode.getOccup(); + // failed treePos.m_match = false; } @@ -236,7 +256,7 @@ Dbtux::searchToRemove(Signal* signal, Frag& frag, ConstData searchKey, TreeEnt s * Similar to searchToAdd. */ void -Dbtux::searchToScan(Signal* signal, Frag& frag, ConstData boundInfo, unsigned boundCount, TreePos& treePos) +Dbtux::searchToScan(Frag& frag, ConstData boundInfo, unsigned boundCount, TreePos& treePos) { const TreeHead& tree = frag.m_tree; NodeHandle currNode(frag); @@ -251,7 +271,7 @@ Dbtux::searchToScan(Signal* signal, Frag& frag, ConstData boundInfo, unsigned bo NodeHandle bottomNode(frag); while (true) { jam(); - selectNode(signal, currNode, currNode.m_loc, AccPref); + selectNode(currNode, currNode.m_loc); int ret; // compare prefix ret = cmpScanBound(frag, 0, boundInfo, boundCount, currNode.getPref(), tree.m_prefSize); @@ -300,8 +320,6 @@ Dbtux::searchToScan(Signal* signal, Frag& frag, ConstData boundInfo, unsigned bo } break; } - // access rest of current node - accessNode(signal, currNode, AccFull); for (unsigned j = 0, occup = currNode.getOccup(); j < occup; j++) { jam(); int ret; diff --git a/ndb/src/kernel/blocks/dbtux/DbtuxTree.cpp b/ndb/src/kernel/blocks/dbtux/DbtuxTree.cpp index 3baa62998db..b9e3b593a00 100644 --- a/ndb/src/kernel/blocks/dbtux/DbtuxTree.cpp +++ b/ndb/src/kernel/blocks/dbtux/DbtuxTree.cpp @@ -18,74 +18,105 @@ #include "Dbtux.hpp" /* - * Add entry. + * Add entry. Handle the case when there is room for one more. This + * is the common case given slack in nodes. */ void -Dbtux::treeAdd(Signal* signal, Frag& frag, TreePos treePos, TreeEnt ent) +Dbtux::treeAdd(Frag& frag, TreePos treePos, TreeEnt ent) { TreeHead& tree = frag.m_tree; - unsigned pos = treePos.m_pos; NodeHandle node(frag); - // check for empty tree - if (treePos.m_loc == NullTupLoc) { - jam(); - insertNode(signal, node, AccPref); - nodePushUp(signal, node, 0, ent); - node.setSide(2); - tree.m_root = node.m_loc; - return; - } - // access full node - selectNode(signal, node, treePos.m_loc, AccFull); - // check if it is bounding node - if (pos != 0 && pos != node.getOccup()) { + if (treePos.m_loc != NullTupLoc) { + // non-empty tree jam(); - // check if room for one more + selectNode(node, treePos.m_loc); + unsigned pos = treePos.m_pos; if (node.getOccup() < tree.m_maxOccup) { + // node has room jam(); - nodePushUp(signal, node, pos, ent); + nodePushUp(node, pos, ent, RNIL); return; } - // returns min entry - nodePushDown(signal, node, pos - 1, ent); - // find position to add the removed min entry - TupLoc childLoc = node.getLink(0); - if (childLoc == NullTupLoc) { + treeAddFull(frag, node, pos, ent); + return; + } + jam(); + insertNode(node); + nodePushUp(node, 0, ent, RNIL); + node.setSide(2); + tree.m_root = node.m_loc; +} + +/* + * Add entry when node is full. Handle the case when there is g.l.b + * node in left subtree with room for one more. It will receive the min + * entry of this node. The min entry could be the entry to add. + */ +void +Dbtux::treeAddFull(Frag& frag, NodeHandle lubNode, unsigned pos, TreeEnt ent) +{ + TreeHead& tree = frag.m_tree; + TupLoc loc = lubNode.getLink(0); + if (loc != NullTupLoc) { + // find g.l.b node + NodeHandle glbNode(frag); + do { jam(); - // left child will be added - pos = 0; - } else { + selectNode(glbNode, loc); + loc = glbNode.getLink(1); + } while (loc != NullTupLoc); + if (glbNode.getOccup() < tree.m_maxOccup) { + // g.l.b node has room jam(); - // find glb node - while (childLoc != NullTupLoc) { + Uint32 scanList = RNIL; + if (pos != 0) { jam(); - selectNode(signal, node, childLoc, AccHead); - childLoc = node.getLink(1); + // add the new entry and return min entry + nodePushDown(lubNode, pos - 1, ent, scanList); } - // access full node again - accessNode(signal, node, AccFull); - pos = node.getOccup(); + // g.l.b node receives min entry from l.u.b node + nodePushUp(glbNode, glbNode.getOccup(), ent, scanList); + return; } - // fall thru to next case - } - // adding new min or max - unsigned i = (pos == 0 ? 0 : 1); - ndbrequire(node.getLink(i) == NullTupLoc); - // check if the half-leaf/leaf has room for one more - if (node.getOccup() < tree.m_maxOccup) { - jam(); - nodePushUp(signal, node, pos, ent); + treeAddNode(frag, lubNode, pos, ent, glbNode, 1); return; } - // add a new node - NodeHandle childNode(frag); - insertNode(signal, childNode, AccPref); - nodePushUp(signal, childNode, 0, ent); + treeAddNode(frag, lubNode, pos, ent, lubNode, 0); +} + +/* + * Add entry when there is no g.l.b node in left subtree or the g.l.b + * node is full. We must add a new left or right child node which + * becomes the new g.l.b node. + */ +void +Dbtux::treeAddNode(Frag& frag, NodeHandle lubNode, unsigned pos, TreeEnt ent, NodeHandle parentNode, unsigned i) +{ + NodeHandle glbNode(frag); + insertNode(glbNode); // connect parent and child - node.setLink(i, childNode.m_loc); - childNode.setLink(2, node.m_loc); - childNode.setSide(i); - // re-balance tree at each node + parentNode.setLink(i, glbNode.m_loc); + glbNode.setLink(2, parentNode.m_loc); + glbNode.setSide(i); + Uint32 scanList = RNIL; + if (pos != 0) { + jam(); + // add the new entry and return min entry + nodePushDown(lubNode, pos - 1, ent, scanList); + } + // g.l.b node receives min entry from l.u.b node + nodePushUp(glbNode, 0, ent, scanList); + // re-balance the tree + treeAddRebalance(frag, parentNode, i); +} + +/* + * Re-balance tree after adding a node. The process starts with the + * parent of the added node. + */ +void +Dbtux::treeAddRebalance(Frag& frag, NodeHandle node, unsigned i) +{ while (true) { // height of subtree i has increased by 1 int j = (i == 0 ? -1 : +1); @@ -105,14 +136,14 @@ Dbtux::treeAdd(Signal* signal, Frag& frag, TreePos treePos, TreeEnt ent) // height of longer subtree increased jam(); NodeHandle childNode(frag); - selectNode(signal, childNode, node.getLink(i), AccHead); + selectNode(childNode, node.getLink(i)); int b2 = childNode.getBalance(); if (b2 == b) { jam(); - treeRotateSingle(signal, frag, node, i); + treeRotateSingle(frag, node, i); } else if (b2 == -b) { jam(); - treeRotateDouble(signal, frag, node, i); + treeRotateDouble(frag, node, i); } else { // height of subtree increased so it cannot be perfectly balanced ndbrequire(false); @@ -129,118 +160,169 @@ Dbtux::treeAdd(Signal* signal, Frag& frag, TreePos treePos, TreeEnt ent) break; } i = node.getSide(); - selectNode(signal, node, parentLoc, AccHead); + selectNode(node, parentLoc); } } /* - * Remove entry. + * Remove entry. Optimize for nodes with slack. Handle the case when + * there is no underflow i.e. occupancy remains at least minOccup. For + * interior nodes this is a requirement. For others it means that we do + * not need to consider merge of semi-leaf and leaf. */ void -Dbtux::treeRemove(Signal* signal, Frag& frag, TreePos treePos) +Dbtux::treeRemove(Frag& frag, TreePos treePos) { TreeHead& tree = frag.m_tree; unsigned pos = treePos.m_pos; NodeHandle node(frag); - // access full node - selectNode(signal, node, treePos.m_loc, AccFull); + selectNode(node, treePos.m_loc); TreeEnt ent; - // check interior node first - if (node.getChilds() == 2) { + if (node.getOccup() > tree.m_minOccup) { + // no underflow in any node type jam(); - ndbrequire(node.getOccup() >= tree.m_minOccup); - // check if no underflow - if (node.getOccup() > tree.m_minOccup) { - jam(); - nodePopDown(signal, node, pos, ent); - return; - } - // save current handle - NodeHandle parentNode = node; - // find glb node - TupLoc childLoc = node.getLink(0); - while (childLoc != NullTupLoc) { - jam(); - selectNode(signal, node, childLoc, AccHead); - childLoc = node.getLink(1); - } - // access full node again - accessNode(signal, node, AccFull); - // use glb max as new parent min - ent = node.getEnt(node.getOccup() - 1); - nodePopUp(signal, parentNode, pos, ent); - // set up to remove glb max - pos = node.getOccup() - 1; - // fall thru to next case + nodePopDown(node, pos, ent, 0); + return; } - // remove the element - nodePopDown(signal, node, pos, ent); - ndbrequire(node.getChilds() <= 1); - // handle half-leaf - unsigned i; - for (i = 0; i <= 1; i++) { + if (node.getChilds() == 2) { + // underflow in interior node jam(); - TupLoc childLoc = node.getLink(i); - if (childLoc != NullTupLoc) { - // move to child - selectNode(signal, node, childLoc, AccFull); - // balance of half-leaf parent requires child to be leaf - break; - } + treeRemoveInner(frag, node, pos); + return; } - ndbrequire(node.getChilds() == 0); - // get parent if any - TupLoc parentLoc = node.getLink(2); - NodeHandle parentNode(frag); - i = node.getSide(); - // move all that fits into parent - if (parentLoc != NullTupLoc) { + // remove entry in semi/leaf + nodePopDown(node, pos, ent, 0); + if (node.getLink(0) != NullTupLoc) { jam(); - selectNode(signal, parentNode, node.getLink(2), AccFull); - nodeSlide(signal, parentNode, node, i); - // fall thru to next case + treeRemoveSemi(frag, node, 0); + return; } - // non-empty leaf - if (node.getOccup() >= 1) { + if (node.getLink(1) != NullTupLoc) { jam(); + treeRemoveSemi(frag, node, 1); return; } - // remove empty leaf - deleteNode(signal, node); - if (parentLoc == NullTupLoc) { + treeRemoveLeaf(frag, node); +} + +/* + * Remove entry when interior node underflows. There is g.l.b node in + * left subtree to borrow an entry from. The max entry of the g.l.b + * node becomes the min entry of this node. + */ +void +Dbtux::treeRemoveInner(Frag& frag, NodeHandle lubNode, unsigned pos) +{ + TreeHead& tree = frag.m_tree; + TreeEnt ent; + // find g.l.b node + NodeHandle glbNode(frag); + TupLoc loc = lubNode.getLink(0); + do { + jam(); + selectNode(glbNode, loc); + loc = glbNode.getLink(1); + } while (loc != NullTupLoc); + // borrow max entry from semi/leaf + Uint32 scanList = RNIL; + nodePopDown(glbNode, glbNode.getOccup() - 1, ent, &scanList); + nodePopUp(lubNode, pos, ent, scanList); + if (glbNode.getLink(0) != NullTupLoc) { jam(); - // tree is now empty - tree.m_root = NullTupLoc; + treeRemoveSemi(frag, glbNode, 0); return; } - node = parentNode; - node.setLink(i, NullTupLoc); -#ifdef dbtux_min_occup_less_max_occup - // check if we created a half-leaf - if (node.getBalance() == 0) { + treeRemoveLeaf(frag, glbNode); +} + +/* + * Handle semi-leaf after removing an entry. Move entries from leaf to + * semi-leaf to bring semi-leaf occupancy above minOccup, if possible. + * The leaf may become empty. + */ +void +Dbtux::treeRemoveSemi(Frag& frag, NodeHandle semiNode, unsigned i) +{ + TreeHead& tree = frag.m_tree; + ndbrequire(semiNode.getChilds() < 2); + TupLoc leafLoc = semiNode.getLink(i); + NodeHandle leafNode(frag); + selectNode(leafNode, leafLoc); + if (semiNode.getOccup() < tree.m_minOccup) { + jam(); + unsigned cnt = min(leafNode.getOccup(), tree.m_minOccup - semiNode.getOccup()); + nodeSlide(semiNode, leafNode, cnt, i); + if (leafNode.getOccup() == 0) { + // remove empty leaf + jam(); + treeRemoveNode(frag, leafNode); + } + } +} + +/* + * Handle leaf after removing an entry. If parent is semi-leaf, move + * entries to it as in the semi-leaf case. If parent is interior node, + * do nothing. + */ +void +Dbtux::treeRemoveLeaf(Frag& frag, NodeHandle leafNode) +{ + TreeHead& tree = frag.m_tree; + TupLoc parentLoc = leafNode.getLink(2); + if (parentLoc != NullTupLoc) { jam(); - // move entries from the other child - TupLoc childLoc = node.getLink(1 - i); - NodeHandle childNode(frag); - selectNode(signal, childNode, childLoc, AccFull); - nodeSlide(signal, node, childNode, 1 - i); - if (childNode.getOccup() == 0) { + NodeHandle parentNode(frag); + selectNode(parentNode, parentLoc); + unsigned i = leafNode.getSide(); + if (parentNode.getLink(1 - i) == NullTupLoc) { + // parent is semi-leaf jam(); - deleteNode(signal, childNode); - node.setLink(1 - i, NullTupLoc); - // we are balanced again but our parent balance changes by -1 - parentLoc = node.getLink(2); - if (parentLoc == NullTupLoc) { + if (parentNode.getOccup() < tree.m_minOccup) { jam(); - return; + unsigned cnt = min(leafNode.getOccup(), tree.m_minOccup - parentNode.getOccup()); + nodeSlide(parentNode, leafNode, cnt, i); } - // fix side and become parent - i = node.getSide(); - selectNode(signal, node, parentLoc, AccHead); } } -#endif - // re-balance tree at each node + if (leafNode.getOccup() == 0) { + jam(); + // remove empty leaf + treeRemoveNode(frag, leafNode); + } +} + +/* + * Remove empty leaf. + */ +void +Dbtux::treeRemoveNode(Frag& frag, NodeHandle leafNode) +{ + TreeHead& tree = frag.m_tree; + ndbrequire(leafNode.getChilds() == 0); + TupLoc parentLoc = leafNode.getLink(2); + unsigned i = leafNode.getSide(); + deleteNode(leafNode); + if (parentLoc != NullTupLoc) { + jam(); + NodeHandle parentNode(frag); + selectNode(parentNode, parentLoc); + parentNode.setLink(i, NullTupLoc); + // re-balance the tree + treeRemoveRebalance(frag, parentNode, i); + return; + } + // tree is now empty + tree.m_root = NullTupLoc; +} + +/* + * Re-balance tree after removing a node. The process starts with the + * parent of the removed node. + */ +void +Dbtux::treeRemoveRebalance(Frag& frag, NodeHandle node, unsigned i) +{ while (true) { // height of subtree i has decreased by 1 int j = (i == 0 ? -1 : +1); @@ -261,19 +343,19 @@ Dbtux::treeRemove(Signal* signal, Frag& frag, TreePos treePos) jam(); // child on the other side NodeHandle childNode(frag); - selectNode(signal, childNode, node.getLink(1 - i), AccHead); + selectNode(childNode, node.getLink(1 - i)); int b2 = childNode.getBalance(); if (b2 == b) { jam(); - treeRotateSingle(signal, frag, node, 1 - i); + treeRotateSingle(frag, node, 1 - i); // height of tree decreased and propagates up } else if (b2 == -b) { jam(); - treeRotateDouble(signal, frag, node, 1 - i); + treeRotateDouble(frag, node, 1 - i); // height of tree decreased and propagates up } else { jam(); - treeRotateSingle(signal, frag, node, 1 - i); + treeRotateSingle(frag, node, 1 - i); // height of tree did not change - done return; } @@ -287,7 +369,7 @@ Dbtux::treeRemove(Signal* signal, Frag& frag, TreePos treePos) return; } i = node.getSide(); - selectNode(signal, node, parentLoc, AccHead); + selectNode(node, parentLoc); } } @@ -308,10 +390,7 @@ Dbtux::treeRemove(Signal* signal, Frag& frag, TreePos treePos) * all optional. If 4 are there it changes side. */ void -Dbtux::treeRotateSingle(Signal* signal, - Frag& frag, - NodeHandle& node, - unsigned i) +Dbtux::treeRotateSingle(Frag& frag, NodeHandle& node, unsigned i) { ndbrequire(i <= 1); /* @@ -331,7 +410,7 @@ Dbtux::treeRotateSingle(Signal* signal, */ TupLoc loc3 = node5.getLink(i); NodeHandle node3(frag); - selectNode(signal, node3, loc3, AccHead); + selectNode(node3, loc3); const int bal3 = node3.getBalance(); /* 2 must always be there but is not changed. Thus we mereley check that it @@ -348,7 +427,7 @@ Dbtux::treeRotateSingle(Signal* signal, NodeHandle node4(frag); if (loc4 != NullTupLoc) { jam(); - selectNode(signal, node4, loc4, AccHead); + selectNode(node4, loc4); ndbrequire(node4.getSide() == (1 - i) && node4.getLink(2) == loc3); node4.setSide(i); @@ -383,7 +462,7 @@ Dbtux::treeRotateSingle(Signal* signal, if (loc0 != NullTupLoc) { jam(); NodeHandle node0(frag); - selectNode(signal, node0, loc0, AccHead); + selectNode(node0, loc0); node0.setLink(side5, loc3); } else { jam(); @@ -520,8 +599,10 @@ Dbtux::treeRotateSingle(Signal* signal, * */ void -Dbtux::treeRotateDouble(Signal* signal, Frag& frag, NodeHandle& node, unsigned i) +Dbtux::treeRotateDouble(Frag& frag, NodeHandle& node, unsigned i) { + TreeHead& tree = frag.m_tree; + // old top node NodeHandle node6 = node; const TupLoc loc6 = node6.m_loc; @@ -532,13 +613,13 @@ Dbtux::treeRotateDouble(Signal* signal, Frag& frag, NodeHandle& node, unsigned i // level 1 TupLoc loc2 = node6.getLink(i); NodeHandle node2(frag); - selectNode(signal, node2, loc2, AccHead); + selectNode(node2, loc2); const int bal2 = node2.getBalance(); // level 2 TupLoc loc4 = node2.getLink(1 - i); NodeHandle node4(frag); - selectNode(signal, node4, loc4, AccHead); + selectNode(node4, loc4); const int bal4 = node4.getBalance(); ndbrequire(i <= 1); @@ -555,25 +636,26 @@ Dbtux::treeRotateDouble(Signal* signal, Frag& frag, NodeHandle& node, unsigned i // fill up leaf before it becomes internal if (loc3 == NullTupLoc && loc5 == NullTupLoc) { jam(); - TreeHead& tree = frag.m_tree; - accessNode(signal, node2, AccFull); - accessNode(signal, node4, AccFull); - nodeSlide(signal, node4, node2, i); - // implied by rule of merging half-leaves with leaves - ndbrequire(node4.getOccup() >= tree.m_minOccup); - ndbrequire(node2.getOccup() != 0); + if (node4.getOccup() < tree.m_minOccup) { + jam(); + unsigned cnt = tree.m_minOccup - node4.getOccup(); + ndbrequire(cnt < node2.getOccup()); + nodeSlide(node4, node2, cnt, i); + ndbrequire(node4.getOccup() >= tree.m_minOccup); + ndbrequire(node2.getOccup() != 0); + } } else { if (loc3 != NullTupLoc) { jam(); NodeHandle node3(frag); - selectNode(signal, node3, loc3, AccHead); + selectNode(node3, loc3); node3.setLink(2, loc2); node3.setSide(1 - i); } if (loc5 != NullTupLoc) { jam(); NodeHandle node5(frag); - selectNode(signal, node5, loc5, AccHead); + selectNode(node5, loc5); node5.setLink(2, node6.m_loc); node5.setSide(i); } @@ -596,7 +678,7 @@ Dbtux::treeRotateDouble(Signal* signal, Frag& frag, NodeHandle& node, unsigned i if (loc0 != NullTupLoc) { jam(); - selectNode(signal, node0, loc0, AccHead); + selectNode(node0, loc0); node0.setLink(side6, loc4); } else { jam(); diff --git a/ndb/src/kernel/blocks/dbtux/Times.txt b/ndb/src/kernel/blocks/dbtux/Times.txt index 03473353a52..1e6d0a0a329 100644 --- a/ndb/src/kernel/blocks/dbtux/Times.txt +++ b/ndb/src/kernel/blocks/dbtux/Times.txt @@ -13,7 +13,7 @@ case c: full scan: index on PK Unsigned testOIBasic -case v -table 1 -index 1 -fragtype small -threads 10 -rows 100000 -subloop 1 -nologging case d: scan 1 tuple via EQ: index on PK Unsigned -testOIBasic -case w -table 1 -index 1 -fragtype small -threads 10 -rows 100000 -samples 10000 -subloop 1 -nologging -v2 +testOIBasic -case w -table 1 -index 1 -fragtype small -threads 10 -rows 100000 -samples 50000 -subloop 1 -nologging -v2 a, b 1 million rows, pk update without index, pk update with index @@ -29,6 +29,7 @@ shows ms / 1000 rows for each and index time overhead samples 10% of all PKs (100,000 pk reads, 100,000 scans) the "pct" values are from more accurate total times (not shown) +comments [ ... ] are after the case 040616 mc02/a 40 ms 87 ms 114 pct mc02/b 51 ms 128 ms 148 pct @@ -76,13 +77,12 @@ optim 13 mc02/a 40 ms 57 ms 42 pct mc02/c 9 ms 13 ms 50 pct mc02/d 170 ms 256 ms 50 pct -after wl-1884 store all-NULL keys (the tests have pctnull=10 per column) - optim 13 mc02/a 39 ms 59 ms 50 pct mc02/b 47 ms 77 ms 61 pct mc02/c 9 ms 12 ms 44 pct mc02/d 246 ms 289 ms 17 pct +[ after wl-1884 store all-NULL keys (the tests have pctnull=10 per column) ] [ case d: bug in testOIBasic killed PK read performance ] optim 14 mc02/a 41 ms 60 ms 44 pct @@ -98,8 +98,7 @@ none mc02/a 35 ms 60 ms 71 pct mc02/c 5 ms 12 ms 106 pct mc02/d 165 ms 238 ms 44 pct -[ johan re-installed mc02 as fedora gcc-3.3.2 ] -[ case c: table scan has improved... ] +[ johan re-installed mc02 as fedora gcc-3.3.2, tux uses more C++ stuff than tup] charsets mc02/a 35 ms 60 ms 71 pct mc02/b 42 ms 84 ms 97 pct @@ -108,4 +107,37 @@ charsets mc02/a 35 ms 60 ms 71 pct [ case b: TUX can no longer use pointers to TUP data ] +optim 15 mc02/a 34 ms 60 ms 72 pct + mc02/b 42 ms 85 ms 100 pct + mc02/c 5 ms 12 ms 110 pct + mc02/d 178 ms 242 ms 35 pct + +[ corrected wasted space in index node ] + +optim 16 mc02/a 34 ms 53 ms 53 pct + mc02/b 42 ms 75 ms 75 pct + +[ binary search of bounding node when adding entry ] + +none mc02/a 35 ms 53 ms 51 pct + mc02/b 42 ms 75 ms 76 pct + +[ rewrote treeAdd / treeRemove ] + +optim 17 mc02/a 35 ms 52 ms 49 pct + mc02/b 43 ms 75 ms 75 pct + +[ allow slack (2) in interior nodes - almost no effect?? ] + +wl-1942 mc02/a 35 ms 52 ms 49 pct + mc02/b 42 ms 75 ms 76 pct + +before mc02/c 5 ms 13 ms 126 pct + mc02/d 134 ms 238 ms 78 pct + +after mc02/c 5 ms 10 ms 70 pct + mc02/d 178 ms 242 ms 69 pct + +[ prelim preformance fix for max batch size 16 -> 992 ] + vim: set et: diff --git a/ndb/src/kernel/blocks/dbutil/DbUtil.cpp b/ndb/src/kernel/blocks/dbutil/DbUtil.cpp index 554fc693fb8..f5379689a5f 100644 --- a/ndb/src/kernel/blocks/dbutil/DbUtil.cpp +++ b/ndb/src/kernel/blocks/dbutil/DbUtil.cpp @@ -1059,6 +1059,7 @@ DbUtil::prepareOperation(Signal* signal, PreparePtr prepPtr) ndbrequire(prepPagesReader.getValueLen() <= MAX_ATTR_NAME_SIZE); prepPagesReader.getString(attrNameRequested); + attrIdRequested= ~0u; } else { jam(); attrIdRequested = prepPagesReader.getUint32(); diff --git a/ndb/src/kernel/blocks/ndbcntr/NdbcntrInit.cpp b/ndb/src/kernel/blocks/ndbcntr/NdbcntrInit.cpp index 1069cf93b06..43044eeebcd 100644 --- a/ndb/src/kernel/blocks/ndbcntr/NdbcntrInit.cpp +++ b/ndb/src/kernel/blocks/ndbcntr/NdbcntrInit.cpp @@ -37,10 +37,10 @@ void Ndbcntr::initRecords() Ndbcntr::Ndbcntr(const class Configuration & conf): SimulatedBlock(NDBCNTR, conf), - c_stopRec(* this), - c_missra(* this), cnoWaitrep6(0), - cnoWaitrep7(0) + cnoWaitrep7(0), + c_stopRec(* this), + c_missra(* this) { BLOCK_CONSTRUCTOR(Ndbcntr); diff --git a/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp b/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp index 568ed6c6566..089cf613b03 100644 --- a/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp +++ b/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp @@ -135,42 +135,42 @@ void Ndbcntr::execSYSTEM_ERROR(Signal* signal) jamEntry(); switch (sysErr->errorCode){ case SystemError::StartInProgressError: - snprintf(buf, sizeof(buf), + BaseString::snprintf(buf, sizeof(buf), "Node %d killed this node because " "master start in progress error", killingNode); break; case SystemError::GCPStopDetected: - snprintf(buf, sizeof(buf), + BaseString::snprintf(buf, sizeof(buf), "Node %d killed this node because " "GCP stop was detected", killingNode); break; case SystemError::ScanfragTimeout: - snprintf(buf, sizeof(buf), + BaseString::snprintf(buf, sizeof(buf), "Node %d killed this node because " "a fragment scan timed out and could not be stopped", killingNode); break; case SystemError::ScanfragStateError: - snprintf(buf, sizeof(buf), + BaseString::snprintf(buf, sizeof(buf), "Node %d killed this node because " "the state of a fragment scan was out of sync.", killingNode); break; case SystemError::CopyFragRefError: - snprintf(buf, sizeof(buf), + BaseString::snprintf(buf, sizeof(buf), "Node %d killed this node because " "it could not copy a fragment during node restart", killingNode); break; default: - snprintf(buf, sizeof(buf), "System error %d, " + BaseString::snprintf(buf, sizeof(buf), "System error %d, " " this node was killed by node %d", sysErr->errorCode, killingNode); break; diff --git a/ndb/src/kernel/blocks/ndbfs/AsyncFile.cpp b/ndb/src/kernel/blocks/ndbfs/AsyncFile.cpp index c61fccad22a..a02bfd459b3 100644 --- a/ndb/src/kernel/blocks/ndbfs/AsyncFile.cpp +++ b/ndb/src/kernel/blocks/ndbfs/AsyncFile.cpp @@ -119,7 +119,7 @@ AsyncFile::doStart(Uint32 nodeId, char buf[16]; numAsyncFiles++; - snprintf(buf, sizeof(buf), "AsyncFile%d", numAsyncFiles); + BaseString::snprintf(buf, sizeof(buf), "AsyncFile%d", numAsyncFiles); theStartMutexPtr = NdbMutex_Create(); theStartConditionPtr = NdbCondition_Create(); @@ -816,7 +816,7 @@ AsyncFile::rmrfReq(Request * request, char * path, bool removePath){ struct dirent * dp; while ((dp = readdir(dirp)) != NULL){ if ((strcmp(".", dp->d_name) != 0) && (strcmp("..", dp->d_name) != 0)) { - snprintf(path_add, (size_t)path_max_copy, "%s%s", + BaseString::snprintf(path_add, (size_t)path_max_copy, "%s%s", DIR_SEPARATOR, dp->d_name); if(remove((const char*)path) == 0){ path[path_len] = 0; diff --git a/ndb/src/kernel/blocks/ndbfs/Filename.cpp b/ndb/src/kernel/blocks/ndbfs/Filename.cpp index 28aa1d23df4..15158ec19ef 100644 --- a/ndb/src/kernel/blocks/ndbfs/Filename.cpp +++ b/ndb/src/kernel/blocks/ndbfs/Filename.cpp @@ -56,7 +56,7 @@ Filename::init(Uint32 nodeid, return; } - snprintf(theFileSystemDirectory, sizeof(theFileSystemDirectory), + BaseString::snprintf(theFileSystemDirectory, sizeof(theFileSystemDirectory), "%sndb_%u_fs%s", pFileSystemPath, nodeid, DIR_SEPARATOR); strncpy(theBackupDirectory, pBackupDirPath, sizeof(theBackupDirectory)); @@ -101,7 +101,7 @@ Filename::set(BlockReference blockReference, const Uint32 P_val = FsOpenReq::v1_getP(filenumber); if (diskNo < 0xff){ - snprintf(buf, sizeof(buf), "D%d%s", diskNo, DIR_SEPARATOR); + BaseString::snprintf(buf, sizeof(buf), "D%d%s", diskNo, DIR_SEPARATOR); strcat(theName, buf); theLevelDepth++; } @@ -112,31 +112,31 @@ Filename::set(BlockReference blockReference, ERROR_SET(ecError, AFS_ERROR_PARAMETER,"","No Block Name"); return; } - snprintf(buf, sizeof(buf), "%s%s", blockName, DIR_SEPARATOR); + BaseString::snprintf(buf, sizeof(buf), "%s%s", blockName, DIR_SEPARATOR); strcat(theName, buf); theLevelDepth++; } if (table < 0xffffffff){ - snprintf(buf, sizeof(buf), "T%d%s", table, DIR_SEPARATOR); + BaseString::snprintf(buf, sizeof(buf), "T%d%s", table, DIR_SEPARATOR); strcat(theName, buf); theLevelDepth++; } if (frag < 0xffffffff){ - snprintf(buf, sizeof(buf), "F%d%s", frag, DIR_SEPARATOR); + BaseString::snprintf(buf, sizeof(buf), "F%d%s", frag, DIR_SEPARATOR); strcat(theName, buf); theLevelDepth++; } if (S_val < 0xffffffff){ - snprintf(buf, sizeof(buf), "S%d", S_val); + BaseString::snprintf(buf, sizeof(buf), "S%d", S_val); strcat(theName, buf); } if (P_val < 0xff){ - snprintf(buf, sizeof(buf), "P%d", P_val); + BaseString::snprintf(buf, sizeof(buf), "P%d", P_val); strcat(theName, buf); } @@ -147,14 +147,14 @@ Filename::set(BlockReference blockReference, const Uint32 nodeId = FsOpenReq::v2_getNodeId(filenumber); const Uint32 count = FsOpenReq::v2_getCount(filenumber); - snprintf(buf, sizeof(buf), "BACKUP%sBACKUP-%d%s", + BaseString::snprintf(buf, sizeof(buf), "BACKUP%sBACKUP-%d%s", DIR_SEPARATOR, seq, DIR_SEPARATOR); strcat(theName, buf); if(count == 0xffffffff) { - snprintf(buf, sizeof(buf), "BACKUP-%d.%d", + BaseString::snprintf(buf, sizeof(buf), "BACKUP-%d.%d", seq, nodeId); strcat(theName, buf); } else { - snprintf(buf, sizeof(buf), "BACKUP-%d-%d.%d", + BaseString::snprintf(buf, sizeof(buf), "BACKUP-%d-%d.%d", seq, count, nodeId); strcat(theName, buf); } theLevelDepth = 2; @@ -168,7 +168,7 @@ Filename::set(BlockReference blockReference, ERROR_SET(ecError, AFS_ERROR_PARAMETER,"","Invalid disk specification"); } - snprintf(buf, sizeof(buf), "D%d%s", diskNo, DIR_SEPARATOR); + BaseString::snprintf(buf, sizeof(buf), "D%d%s", diskNo, DIR_SEPARATOR); strcat(theName, buf); theLevelDepth++; } diff --git a/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp b/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp index 6017365a463..41deb3403c8 100644 --- a/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp +++ b/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp @@ -592,7 +592,7 @@ void Qmgr::execCM_REGCONF(Signal* signal) if (!ndbCompatible_ndb_ndb(NDB_VERSION, cmRegConf->presidentVersion)) { jam(); char buf[128]; - snprintf(buf,sizeof(buf),"incompatible version own=0x%x other=0x%x, shutting down", NDB_VERSION, cmRegConf->presidentVersion); + BaseString::snprintf(buf,sizeof(buf),"incompatible version own=0x%x other=0x%x, shutting down", NDB_VERSION, cmRegConf->presidentVersion); systemErrorLab(signal, buf); return; } @@ -1666,7 +1666,7 @@ void Qmgr::checkStartInterface(Signal* signal) } else { if(((nodePtr.p->alarmCount + 1) % 60) == 0){ char buf[100]; - snprintf(buf, sizeof(buf), + BaseString::snprintf(buf, sizeof(buf), "Failure handling of node %d has not completed in %d min." " - state = %d", nodePtr.i, @@ -1760,8 +1760,8 @@ void Qmgr::execAPI_FAILCONF(Signal* signal) } else { jam(); #ifdef VM_TRACE - ndbout << "failedNodePtr.p->failState = " << failedNodePtr.p->failState - << endl; + ndbout << "failedNodePtr.p->failState = " + << (Uint32)(failedNodePtr.p->failState) << endl; #endif systemErrorLab(signal); }//if @@ -1932,10 +1932,6 @@ void Qmgr::execAPI_REGREQ(Signal* signal) bool compatability_check; switch(getNodeInfo(apiNodePtr.i).getType()){ - case NodeInfo::DB: - case NodeInfo::INVALID: - sendApiRegRef(signal, ref, ApiRegRef::WrongType); - return; case NodeInfo::API: compatability_check = ndbCompatible_ndb_api(NDB_VERSION, version); break; @@ -1945,6 +1941,11 @@ void Qmgr::execAPI_REGREQ(Signal* signal) case NodeInfo::REP: compatability_check = ndbCompatible_ndb_api(NDB_VERSION, version); break; + case NodeInfo::DB: + case NodeInfo::INVALID: + default: + sendApiRegRef(signal, ref, ApiRegRef::WrongType); + return; } if (!compatability_check) { @@ -2672,7 +2673,7 @@ void Qmgr::systemErrorBecauseOtherNodeFailed(Signal* signal, failReport(signal, getOwnNodeId(), (UintR)ZTRUE, FailRep::ZOWN_FAILURE); char buf[100]; - snprintf(buf, 100, + BaseString::snprintf(buf, 100, "Node was shutdown during startup because node %d failed", failedNodeId); diff --git a/ndb/src/kernel/blocks/suma/Suma.cpp b/ndb/src/kernel/blocks/suma/Suma.cpp index 052809cb084..d11d5f7176a 100644 --- a/ndb/src/kernel/blocks/suma/Suma.cpp +++ b/ndb/src/kernel/blocks/suma/Suma.cpp @@ -98,7 +98,7 @@ Suma::getNodeGroupMembers(Signal* signal) { } // ndbout_c("c_noNodesInGroup=%d", c_noNodesInGroup); - ndbrequire(c_noNodesInGroup >= 0); // at least 1 node in the nodegroup + ndbrequire(c_noNodesInGroup > 0); // at least 1 node in the nodegroup #ifdef NODEFAIL_DEBUG for (Uint32 i = 0; i < c_noNodesInGroup; i++) { @@ -1891,7 +1891,7 @@ SumaParticipant::SyncRecord::nextScan(Signal* signal){ ScanFragReq::setHoldLockFlag(req->requestInfo, 0); ScanFragReq::setKeyinfoFlag(req->requestInfo, 0); ScanFragReq::setAttrLen(req->requestInfo, attrLen); - req->fragmentNo = fd.m_fragDesc.m_fragmentNo; + req->fragmentNoKeyLen = fd.m_fragDesc.m_fragmentNo; req->schemaVersion = tabPtr.p->m_schemaVersion; req->transId1 = 0; req->transId2 = (SUMA << 20) + (suma.getOwnNodeId() << 8); @@ -2713,6 +2713,7 @@ Suma::getResponsibleSumaNodeId(Uint32 D) id = RNIL; } else { jam(); + id = RNIL; const Uint32 n = c_noNodesInGroup; // Number nodes in node group const Uint32 C1 = D / n; const Uint32 C2 = D - C1*n; // = D % n; diff --git a/ndb/src/kernel/error/ErrorReporter.cpp b/ndb/src/kernel/error/ErrorReporter.cpp index d43001ef1f5..35c99b30994 100644 --- a/ndb/src/kernel/error/ErrorReporter.cpp +++ b/ndb/src/kernel/error/ErrorReporter.cpp @@ -60,7 +60,7 @@ ErrorReporter::formatTimeStampString(){ DateTime.setTimeStamp(); - snprintf(theDateTimeString, 39, "%s %d %s %d - %s:%s:%s", + BaseString::snprintf(theDateTimeString, 39, "%s %d %s %d - %s:%s:%s", DateTime.getDayName(), DateTime.getDayOfMonth(), DateTime.getMonthName(), DateTime.getYear(), DateTime.getHour(), DateTime.getMinute(), DateTime.getSecond()); @@ -126,7 +126,7 @@ ErrorReporter::formatMessage(ErrorCategory type, processId = NdbHost_GetProcessId(); - snprintf(messptr, MESSAGE_LENGTH, + BaseString::snprintf(messptr, MESSAGE_LENGTH, "Date/Time: %s\nType of error: %s\n" "Message: %s\nFault ID: %d\nProblem data: %s" "\nObject of reference: %s\nProgramName: %s\n" @@ -157,13 +157,13 @@ ErrorReporter::handleAssert(const char* message, const char* file, int line) char refMessage[100]; #ifdef NO_EMULATED_JAM - snprintf(refMessage, 100, "file: %s lineNo: %d", + BaseString::snprintf(refMessage, 100, "file: %s lineNo: %d", file, line); #else const Uint32 blockNumber = theEmulatedJamBlockNumber; const char *blockName = getBlockName(blockNumber); - snprintf(refMessage, 100, "%s line: %d (block: %s)", + BaseString::snprintf(refMessage, 100, "%s line: %d (block: %s)", file, line, blockName); #endif WriteMessage(assert, ERR_ERROR_PRGERR, message, refMessage, @@ -178,7 +178,7 @@ ErrorReporter::handleThreadAssert(const char* message, int line) { char refMessage[100]; - snprintf(refMessage, 100, "file: %s lineNo: %d - %s", + BaseString::snprintf(refMessage, 100, "file: %s lineNo: %d - %s", file, line, message); NdbShutdown(NST_ErrorHandler); diff --git a/ndb/src/kernel/main.cpp b/ndb/src/kernel/main.cpp index 9c25da79065..fa44704807d 100644 --- a/ndb/src/kernel/main.cpp +++ b/ndb/src/kernel/main.cpp @@ -363,6 +363,6 @@ handler_error(int signum){ g_eventLogger.info("Received signal %d. Running error handler.", signum); // restart the system char errorData[40]; - snprintf(errorData, 40, "Signal %d received", signum); + BaseString::snprintf(errorData, 40, "Signal %d received", signum); ERROR_SET_SIGNAL(fatal, 0, errorData, __FILE__); } diff --git a/ndb/src/kernel/vm/ClusterConfiguration.cpp b/ndb/src/kernel/vm/ClusterConfiguration.cpp index 3a6478380d1..d5bd03f69d5 100644 --- a/ndb/src/kernel/vm/ClusterConfiguration.cpp +++ b/ndb/src/kernel/vm/ClusterConfiguration.cpp @@ -358,7 +358,7 @@ void ClusterConfiguration::init(const Properties & p, const Properties & db){ for(int i = 0; i<sz; i++){ if(!db.get(tmp[i].attrib, tmp[i].storage)){ char buf[255]; - snprintf(buf, sizeof(buf), "%s not found", tmp[i].attrib); + BaseString::snprintf(buf, sizeof(buf), "%s not found", tmp[i].attrib); ERROR_SET(fatal, ERR_INVALID_CONFIG, msg, buf); } } @@ -406,7 +406,7 @@ void ClusterConfiguration::init(const Properties & p, const Properties & db){ for(unsigned j = 0; j<nodeNo; j++){ if(cd.nodeData[j].nodeId == nodeId){ char buf[255]; - snprintf(buf, sizeof(buf), "Two node can not have the same node id"); + BaseString::snprintf(buf, sizeof(buf), "Two node can not have the same node id"); ERROR_SET(fatal, ERR_INVALID_CONFIG, msg, buf); } } @@ -429,12 +429,12 @@ void ClusterConfiguration::init(const Properties & p, const Properties & db){ if(nodeId > MAX_NDB_NODES){ char buf[255]; - snprintf(buf, sizeof(buf), "Maximum node id for a ndb node is: %d", MAX_NDB_NODES); + BaseString::snprintf(buf, sizeof(buf), "Maximum node id for a ndb node is: %d", MAX_NDB_NODES); ERROR_SET(fatal, ERR_INVALID_CONFIG, msg, buf); } if(cd.SizeAltData.noOfNDBNodes > MAX_NDB_NODES){ char buf[255]; - snprintf(buf, sizeof(buf), + BaseString::snprintf(buf, sizeof(buf), "Maximum %d ndb nodes is allowed in the cluster", MAX_NDB_NODES); ERROR_SET(fatal, ERR_INVALID_CONFIG, msg, buf); diff --git a/ndb/src/kernel/vm/Configuration.cpp b/ndb/src/kernel/vm/Configuration.cpp index fd5d79b92e7..706f60fd9cf 100644 --- a/ndb/src/kernel/vm/Configuration.cpp +++ b/ndb/src/kernel/vm/Configuration.cpp @@ -203,7 +203,7 @@ Configuration::fetch_configuration(LocalConfig &local_config){ /* Set stop on error to true otherwise NDB will go into an restart loop... */ - ERROR_SET(fatal, ERR_INVALID_CONFIG, "Could connect to ndb_mgmd", s); + ERROR_SET(fatal, ERR_INVALID_CONFIG, "Could not connect to ndb_mgmd", s); } m_mgmd_port= m_config_retriever->get_mgmd_port(); @@ -487,7 +487,7 @@ Configuration::calcSizeAlt(ConfigValues * ownConfig){ if (tmp[i].computable) { *tmp[i].storage = 0; } else { - snprintf(buf, sizeof(buf),"ConfigParam: %d not found", tmp[i].paramId); + BaseString::snprintf(buf, sizeof(buf),"ConfigParam: %d not found", tmp[i].paramId); ERROR_SET(fatal, ERR_INVALID_CONFIG, msg, buf); } } @@ -497,12 +497,12 @@ Configuration::calcSizeAlt(ConfigValues * ownConfig){ ndb_mgm_get_int64_parameter(&db, CFG_DB_DATA_MEM, &dataMem); ndb_mgm_get_int64_parameter(&db, CFG_DB_INDEX_MEM, &indexMem); if(dataMem == 0){ - snprintf(buf, sizeof(buf), "ConfigParam: %d not found", CFG_DB_DATA_MEM); + BaseString::snprintf(buf, sizeof(buf), "ConfigParam: %d not found", CFG_DB_DATA_MEM); ERROR_SET(fatal, ERR_INVALID_CONFIG, msg, buf); } if(indexMem == 0){ - snprintf(buf, sizeof(buf), "ConfigParam: %d not found", CFG_DB_INDEX_MEM); + BaseString::snprintf(buf, sizeof(buf), "ConfigParam: %d not found", CFG_DB_INDEX_MEM); ERROR_SET(fatal, ERR_INVALID_CONFIG, msg, buf); } @@ -535,13 +535,13 @@ Configuration::calcSizeAlt(ConfigValues * ownConfig){ } if(nodeId > MAX_NODES || nodeId == 0){ - snprintf(buf, sizeof(buf), + BaseString::snprintf(buf, sizeof(buf), "Invalid node id: %d", nodeId); ERROR_SET(fatal, ERR_INVALID_CONFIG, msg, buf); } if(nodes.get(nodeId)){ - snprintf(buf, sizeof(buf), "Two node can not have the same node id: %d", + BaseString::snprintf(buf, sizeof(buf), "Two node can not have the same node id: %d", nodeId); ERROR_SET(fatal, ERR_INVALID_CONFIG, msg, buf); } @@ -568,7 +568,7 @@ Configuration::calcSizeAlt(ConfigValues * ownConfig){ case NODE_TYPE_EXT_REP: break; default: - snprintf(buf, sizeof(buf), "Unknown node type: %d", nodeType); + BaseString::snprintf(buf, sizeof(buf), "Unknown node type: %d", nodeType); ERROR_SET(fatal, ERR_INVALID_CONFIG, msg, buf); } } diff --git a/ndb/src/kernel/vm/SignalCounter.hpp b/ndb/src/kernel/vm/SignalCounter.hpp index ea770324aa6..62242cb65bd 100644 --- a/ndb/src/kernel/vm/SignalCounter.hpp +++ b/ndb/src/kernel/vm/SignalCounter.hpp @@ -151,7 +151,7 @@ const char * SignalCounter::getText() const { static char buf[255]; static char nodes[NodeBitmask::TextLength+1]; - snprintf(buf, sizeof(buf), "[SignalCounter: m_count=%d %s]", m_count, m_nodes.getText(nodes)); + BaseString::snprintf(buf, sizeof(buf), "[SignalCounter: m_count=%d %s]", m_count, m_nodes.getText(nodes)); return buf; } diff --git a/ndb/src/kernel/vm/SimulatedBlock.cpp b/ndb/src/kernel/vm/SimulatedBlock.cpp index 18b7f474ddc..e6b97771d36 100644 --- a/ndb/src/kernel/vm/SimulatedBlock.cpp +++ b/ndb/src/kernel/vm/SimulatedBlock.cpp @@ -68,25 +68,25 @@ SimulatedBlock::SimulatedBlock(BlockNumber blockNumber, char buf[255]; count = 10; - snprintf(buf, 255, "%s.FragmentSendPool", getBlockName(blockNumber)); + BaseString::snprintf(buf, 255, "%s.FragmentSendPool", getBlockName(blockNumber)); if(!p->get(buf, &count)) p->get("FragmentSendPool", &count); c_fragmentSendPool.setSize(count); count = 10; - snprintf(buf, 255, "%s.FragmentInfoPool", getBlockName(blockNumber)); + BaseString::snprintf(buf, 255, "%s.FragmentInfoPool", getBlockName(blockNumber)); if(!p->get(buf, &count)) p->get("FragmentInfoPool", &count); c_fragmentInfoPool.setSize(count); count = 10; - snprintf(buf, 255, "%s.FragmentInfoHash", getBlockName(blockNumber)); + BaseString::snprintf(buf, 255, "%s.FragmentInfoHash", getBlockName(blockNumber)); if(!p->get(buf, &count)) p->get("FragmentInfoHash", &count); c_fragmentInfoHash.setSize(count); count = 5; - snprintf(buf, 255, "%s.ActiveMutexes", getBlockName(blockNumber)); + BaseString::snprintf(buf, 255, "%s.ActiveMutexes", getBlockName(blockNumber)); if(!p->get(buf, &count)) p->get("ActiveMutexes", &count); c_mutexMgr.setSize(count); @@ -147,7 +147,7 @@ SimulatedBlock::addRecSignalImpl(GlobalSignalNumber gsn, ExecFunction f, bool force){ if(gsn > MAX_GSN || (!force && theExecArray[gsn] != 0)){ char errorMsg[255]; - snprintf(errorMsg, 255, + BaseString::snprintf(errorMsg, 255, "Illeagal signal (%d %d)", gsn, MAX_GSN); ERROR_SET(fatal, ERR_ERROR_PRGERR, errorMsg, errorMsg); } @@ -159,9 +159,9 @@ SimulatedBlock::signal_error(Uint32 gsn, Uint32 len, Uint32 recBlockNo, const char* filename, int lineno) const { char objRef[255]; - snprintf(objRef, 255, "%s:%d", filename, lineno); + BaseString::snprintf(objRef, 255, "%s:%d", filename, lineno); char probData[255]; - snprintf(probData, 255, + BaseString::snprintf(probData, 255, "Signal (GSN: %d, Length: %d, Rec Block No: %d)", gsn, len, recBlockNo); @@ -664,9 +664,9 @@ SimulatedBlock::allocRecord(const char * type, size_t s, size_t n, bool clear) if (p == NULL){ char buf1[255]; char buf2[255]; - snprintf(buf1, sizeof(buf1), "%s could not allocate memory for %s", + BaseString::snprintf(buf1, sizeof(buf1), "%s could not allocate memory for %s", getBlockName(number()), type); - snprintf(buf2, sizeof(buf2), "Requested: %ux%u = %u bytes", + BaseString::snprintf(buf2, sizeof(buf2), "Requested: %ux%u = %u bytes", (Uint32)s, (Uint32)n, (Uint32)size); ERROR_SET(fatal, ERR_MEMALLOC, buf1, buf2); } @@ -722,7 +722,7 @@ SimulatedBlock::progError(int line, int err_code, const char* extra) const { /* Add line number to block name */ char buf[100]; - snprintf(&buf[0], 100, "%s (Line: %d) 0x%.8x", + BaseString::snprintf(&buf[0], 100, "%s (Line: %d) 0x%.8x", aBlockName, line, magicStatus); ErrorReporter::handleError(ecError, err_code, extra, buf); @@ -740,7 +740,7 @@ SimulatedBlock::infoEvent(const char * msg, ...) const { va_list ap; va_start(ap, msg); - vsnprintf(buf, 96, msg, ap); // 96 = 100 - 4 + BaseString::vsnprintf(buf, 96, msg, ap); // 96 = 100 - 4 va_end(ap); int len = strlen(buf) + 1; @@ -781,7 +781,7 @@ SimulatedBlock::warningEvent(const char * msg, ...) const { va_list ap; va_start(ap, msg); - vsnprintf(buf, 96, msg, ap); // 96 = 100 - 4 + BaseString::vsnprintf(buf, 96, msg, ap); // 96 = 100 - 4 va_end(ap); int len = strlen(buf) + 1; diff --git a/ndb/src/kernel/vm/SimulatedBlock.hpp b/ndb/src/kernel/vm/SimulatedBlock.hpp index 6d46e9cc377..7972cb39746 100644 --- a/ndb/src/kernel/vm/SimulatedBlock.hpp +++ b/ndb/src/kernel/vm/SimulatedBlock.hpp @@ -472,11 +472,11 @@ SimulatedBlock::executeFunction(GlobalSignalNumber gsn, Signal* signal){ */ char errorMsg[255]; if (!(gsn <= MAX_GSN)) { - snprintf(errorMsg, 255, "Illegal signal received (GSN %d too high)", gsn); + BaseString::snprintf(errorMsg, 255, "Illegal signal received (GSN %d too high)", gsn); ERROR_SET(fatal, ERR_ERROR_PRGERR, errorMsg, errorMsg); } if (!(theExecArray[gsn] != 0)) { - snprintf(errorMsg, 255, "Illegal signal received (GSN %d not added)", gsn); + BaseString::snprintf(errorMsg, 255, "Illegal signal received (GSN %d not added)", gsn); ERROR_SET(fatal, ERR_ERROR_PRGERR, errorMsg, errorMsg); } ndbrequire(false); diff --git a/ndb/src/mgmapi/mgmapi.cpp b/ndb/src/mgmapi/mgmapi.cpp index fccd5c7983b..4b62df968b3 100644 --- a/ndb/src/mgmapi/mgmapi.cpp +++ b/ndb/src/mgmapi/mgmapi.cpp @@ -15,6 +15,9 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include <ndb_global.h> +#include <my_sys.h> + +#include <NdbAutoPtr.hpp> #include <NdbTCP.h> #include "mgmapi.h" @@ -107,7 +110,7 @@ setError(NdbMgmHandle h, int error, int error_line, const char * msg, ...){ va_list ap; va_start(ap, msg); - vsnprintf(h->last_error_desc, sizeof(h->last_error_desc), msg, ap); + BaseString::vsnprintf(h->last_error_desc, sizeof(h->last_error_desc), msg, ap); va_end(ap); } @@ -137,7 +140,8 @@ extern "C" NdbMgmHandle ndb_mgm_create_handle() { - NdbMgmHandle h = (NdbMgmHandle)malloc(sizeof(ndb_mgm_handle)); + NdbMgmHandle h = + (NdbMgmHandle)my_malloc(sizeof(ndb_mgm_handle),MYF(MY_WME)); h->connected = 0; h->last_error = 0; h->last_error_line = 0; @@ -166,16 +170,14 @@ ndb_mgm_destroy_handle(NdbMgmHandle * handle) if((* handle)->connected){ ndb_mgm_disconnect(* handle); } - if((* handle)->hostname != 0){ - free((* handle)->hostname); - } + my_free((* handle)->hostname,MYF(MY_ALLOW_ZERO_PTR)); #ifdef MGMAPI_LOG if ((* handle)->logfile != 0){ fclose((* handle)->logfile); (* handle)->logfile = 0; } #endif - free(* handle); + my_free((char*)* handle,MYF(MY_ALLOW_ZERO_PTR)); * handle = 0; } @@ -228,7 +230,8 @@ parse_connect_string(const char * connect_string, return -1; } - char * line = strdup(connect_string); + char * line = my_strdup(connect_string,MYF(MY_WME)); + My_auto_ptr<char> ap1(line); if(line == 0){ SET_ERROR(handle, NDB_MGM_OUT_OF_MEMORY, ""); return -1; @@ -236,7 +239,6 @@ parse_connect_string(const char * connect_string, char * tmp = strchr(line, ':'); if(tmp == 0){ - free(line); SET_ERROR(handle, NDB_MGM_OUT_OF_MEMORY, ""); return -1; } @@ -244,17 +246,13 @@ parse_connect_string(const char * connect_string, int port = 0; if(sscanf(tmp, "%d", &port) != 1){ - free(line); SET_ERROR(handle, NDB_MGM_ILLEGAL_PORT_NUMBER, ""); return -1; } - if(handle->hostname != 0) - free(handle->hostname); - - handle->hostname = strdup(line); + my_free(handle->hostname,MYF(MY_ALLOW_ZERO_PTR)); + handle->hostname = my_strdup(line,MYF(MY_WME)); handle->port = port; - free(line); return 0; } @@ -361,7 +359,7 @@ ndb_mgm_connect(NdbMgmHandle handle, const char * mgmsrv) * Open the log file */ char logname[64]; - snprintf(logname, 64, "mgmapi.log"); + BaseString::snprintf(logname, 64, "mgmapi.log"); handle->logfile = fopen(logname, "w"); #endif @@ -1153,11 +1151,14 @@ ndb_mgm_dump_state(NdbMgmHandle handle, int nodeId, int* _args, CHECK_CONNECTED(handle, -1); char buf[256]; - char buf2[6]; buf[0] = 0; for (int i = 0; i < _num_args; i++){ - snprintf(buf2, 6, "%d ", _args[i]); - strncat(buf, buf2, 256); + unsigned n = strlen(buf); + if (n + 20 > sizeof(buf)) { + SET_ERROR(handle, NDB_MGM_USAGE_ERROR, "arguments too long"); + return -1; + } + sprintf(buf + n, "%s%d", i ? " " : "", _args[i]); } Properties args; @@ -1653,8 +1654,11 @@ ndb_mgm_alloc_nodeid(NdbMgmHandle handle, unsigned int version, unsigned *pnodei do { const char * buf; if(!prop->get("result", &buf) || strcmp(buf, "Ok") != 0){ + BaseString err; + err.assfmt("Could not alloc node id at %s port %d: %s", + handle->hostname, handle->port, buf); setError(handle, NDB_MGM_COULD_NOT_CONNECT_TO_SOCKET, __LINE__, - "Could not alloc node id: %s",buf); + err.c_str()); break; } if(!prop->get("nodeid", pnodeid) != 0){ diff --git a/ndb/src/mgmclient/CommandInterpreter.cpp b/ndb/src/mgmclient/CommandInterpreter.cpp index 7560a59a1ef..e0935c2104e 100644 --- a/ndb/src/mgmclient/CommandInterpreter.cpp +++ b/ndb/src/mgmclient/CommandInterpreter.cpp @@ -828,6 +828,8 @@ CommandInterpreter::executeShow(char* parameters) case NDB_MGM_NODE_TYPE_UNKNOWN: ndbout << "Error: Unknown Node Type" << endl; return; + case NDB_MGM_NODE_TYPE_REP: + abort(); } } @@ -1363,36 +1365,29 @@ CommandInterpreter::executeLog(int processId, if (! parseBlockSpecification(parameters, blocks)) { return; } - int len=0; + int len=1; Uint32 i; for(i=0; i<blocks.size(); i++) { - ndbout_c("blocks %s %d",blocks[i], strlen(blocks[i])); - len += strlen(blocks[i]); + len += strlen(blocks[i]) + 1; } - len += blocks.size()*2; char * blockNames = (char*)my_malloc(len,MYF(MY_WME)); My_auto_ptr<char> ap1(blockNames); + blockNames[0] = 0; for(i=0; i<blocks.size(); i++) { strcat(blockNames, blocks[i]); strcat(blockNames, "|"); } - strcat(blockNames, "\0"); - ndbout_c("blocknames %s", blockNames); - /*int res =*/ndb_mgm_log_signals(m_mgmsrv, + int result = ndb_mgm_log_signals(m_mgmsrv, processId, NDB_MGM_SIGNAL_LOG_MODE_INOUT, blockNames, &reply); - -#if 0 - int result = - _mgmtSrvr.setSignalLoggingMode(processId, MgmtSrvr::InOut, blocks); if (result != 0) { - ndbout << _mgmtSrvr.getErrorText(result) << endl; + ndbout_c("Execute LOG on node %d failed.", processId); + printError(); } -#endif } //***************************************************************************** @@ -1401,17 +1396,7 @@ void CommandInterpreter::executeLogIn(int /* processId */, const char* parameters, bool /* all */) { - Vector<const char*> blocks; - if (! parseBlockSpecification(parameters, blocks)) { - return; - } - -#if 0 - int result = _mgmtSrvr.setSignalLoggingMode(processId, MgmtSrvr::In, blocks); - if (result != 0) { - ndbout << _mgmtSrvr.getErrorText(result) << endl; - } -#endif + ndbout << "Command LOGIN not implemented." << endl; } //***************************************************************************** @@ -1420,19 +1405,7 @@ void CommandInterpreter::executeLogOut(int /*processId*/, const char* parameters, bool /*all*/) { - Vector<const char*> blocks; - if (! parseBlockSpecification(parameters, blocks)) { - return; - } - - -#if 0 - int result = _mgmtSrvr.setSignalLoggingMode(processId, MgmtSrvr::Out, - blocks); - if (result != 0) { - ndbout << _mgmtSrvr.getErrorText(result) << endl; - } -#endif + ndbout << "Command LOGOUT not implemented." << endl; } //***************************************************************************** @@ -1441,57 +1414,45 @@ void CommandInterpreter::executeLogOff(int /*processId*/, const char* parameters, bool /*all*/) { - Vector<const char*> blocks; - if (! parseBlockSpecification(parameters, blocks)) { - return; - } - - -#if 0 - int result = _mgmtSrvr.setSignalLoggingMode(processId, MgmtSrvr::Off, - blocks); - if (result != 0) { - ndbout << _mgmtSrvr.getErrorText(result) << endl; - } -#endif + ndbout << "Command LOGOFF not implemented." << endl; } //***************************************************************************** //***************************************************************************** void -CommandInterpreter::executeTestOn(int /*processId*/, +CommandInterpreter::executeTestOn(int processId, const char* parameters, bool /*all*/) { if (! emptyString(parameters)) { ndbout << "No parameters expected to this command." << endl; return; } - -#if 0 - int result = _mgmtSrvr.startSignalTracing(processId); + connect(); + struct ndb_mgm_reply reply; + int result = ndb_mgm_start_signallog(m_mgmsrv, processId, &reply); if (result != 0) { - ndbout << _mgmtSrvr.getErrorText(result) << endl; + ndbout_c("Execute TESTON failed."); + printError(); } -#endif } //***************************************************************************** //***************************************************************************** void -CommandInterpreter::executeTestOff(int /*processId*/, +CommandInterpreter::executeTestOff(int processId, const char* parameters, bool /*all*/) { if (! emptyString(parameters)) { ndbout << "No parameters expected to this command." << endl; return; } - -#if 0 - int result = _mgmtSrvr.stopSignalTracing(processId); + connect(); + struct ndb_mgm_reply reply; + int result = ndb_mgm_stop_signallog(m_mgmsrv, processId, &reply); if (result != 0) { - ndbout << _mgmtSrvr.getErrorText(result) << endl; + ndbout_c("Execute TESTOFF failed."); + printError(); } -#endif } @@ -1679,7 +1640,7 @@ CommandInterpreter::executeStartBackup(char* /*parameters*/) if(tmp) { ndbout << tmp; - int id; + unsigned int id; if(sscanf(tmp, "%*[^:]: Backup %d ", &id) == 1 && id == backupId){ count++; } @@ -2059,46 +2020,46 @@ CmdBackupCallback(const MgmtSrvr::BackupEvent & event){ switch(event.Event){ case MgmtSrvr::BackupEvent::BackupStarted: ok = true; - snprintf(str, sizeof(str), + BaseString::snprintf(str, sizeof(str), "Backup %d started", event.Started.BackupId); break; case MgmtSrvr::BackupEvent::BackupFailedToStart: ok = true; - snprintf(str, sizeof(str), + BaseString::snprintf(str, sizeof(str), "Backup failed to start (Error %d)", event.FailedToStart.ErrorCode); break; case MgmtSrvr::BackupEvent::BackupCompleted: ok = true; - snprintf(str, sizeof(str), + BaseString::snprintf(str, sizeof(str), "Backup %d completed", event.Completed.BackupId); ndbout << str << endl; - snprintf(str, sizeof(str), + BaseString::snprintf(str, sizeof(str), " StartGCP: %d StopGCP: %d", event.Completed.startGCP, event.Completed.stopGCP); ndbout << str << endl; - snprintf(str, sizeof(str), + BaseString::snprintf(str, sizeof(str), " #Records: %d #LogRecords: %d", event.Completed.NoOfRecords, event.Completed.NoOfLogRecords); ndbout << str << endl; - snprintf(str, sizeof(str), + BaseString::snprintf(str, sizeof(str), " Data: %d bytes Log: %d bytes", event.Completed.NoOfBytes, event.Completed.NoOfLogBytes); break; case MgmtSrvr::BackupEvent::BackupAborted: ok = true; - snprintf(str, sizeof(str), + BaseString::snprintf(str, sizeof(str), "Backup %d has been aborted reason %d", event.Aborted.BackupId, event.Aborted.Reason); break; } if(!ok){ - snprintf(str, sizeof(str), + BaseString::snprintf(str, sizeof(str), "Unknown backup event: %d", event.Event); diff --git a/ndb/src/mgmclient/main.cpp b/ndb/src/mgmclient/main.cpp index 69f968677cd..cc6d4bf600e 100644 --- a/ndb/src/mgmclient/main.cpp +++ b/ndb/src/mgmclient/main.cpp @@ -85,7 +85,7 @@ int main(int argc, const char** argv){ } char buf[MAXHOSTNAMELEN+10]; - snprintf(buf, sizeof(buf), "%s:%d", _host, _port); + BaseString::snprintf(buf, sizeof(buf), "%s:%d", _host, _port); ndbout << "-- NDB Cluster -- Management Client --" << endl; printf("Connecting to Management Server: %s\n", buf); diff --git a/ndb/src/mgmsrv/CommandInterpreter.cpp b/ndb/src/mgmsrv/CommandInterpreter.cpp index 2c2aeda21ed..2a054a01f1e 100644 --- a/ndb/src/mgmsrv/CommandInterpreter.cpp +++ b/ndb/src/mgmsrv/CommandInterpreter.cpp @@ -647,6 +647,7 @@ versionCallback(int nodeId, int version, void * anyData, int errCode){ } break; case NDB_MGM_NODE_TYPE_UNKNOWN: + case NDB_MGM_NODE_TYPE_REP: abort(); }; diff --git a/ndb/src/mgmsrv/Config.cpp b/ndb/src/mgmsrv/Config.cpp index b8a494cb759..f9c6a23f909 100644 --- a/ndb/src/mgmsrv/Config.cpp +++ b/ndb/src/mgmsrv/Config.cpp @@ -85,6 +85,9 @@ Config::printAllNameValuePairs(NdbOut &out, MGM_REQUIRE(prop->get(n, &str_value)); out << str_value; break; + case ConfigInfo::SECTION: + out << "SECTION"; + break; } out << endl; } diff --git a/ndb/src/mgmsrv/ConfigInfo.cpp b/ndb/src/mgmsrv/ConfigInfo.cpp index bff7f9be0e6..ad346b30ead 100644 --- a/ndb/src/mgmsrv/ConfigInfo.cpp +++ b/ndb/src/mgmsrv/ConfigInfo.cpp @@ -2189,7 +2189,7 @@ ConfigInfo::ConfigInfo() break; } case SECTION: - pinfo.put("SectionType", (Uint32)param._default); + pinfo.put("SectionType", (Uint32)UintPtr(param._default)); break; case STRING: break; @@ -2504,7 +2504,7 @@ transformNode(InitConfigFileParser::Context & ctx, const char * data){ } ctx.m_userProperties.put("AllocatedNodeId_", id, id); - snprintf(ctx.pname, sizeof(ctx.pname), "Node_%d", id); + BaseString::snprintf(ctx.pname, sizeof(ctx.pname), "Node_%d", id); ctx.m_currentSection->put("Type", ctx.fname); @@ -2569,7 +2569,7 @@ fixNodeHostname(InitConfigFileParser::Context & ctx, const char * data){ const Properties * computer; char tmp[255]; - snprintf(tmp, sizeof(tmp), "Computer_%s", compId); + BaseString::snprintf(tmp, sizeof(tmp), "Computer_%s", compId); if(!ctx.m_config->get(tmp, &computer)){ ctx.reportError("Computer \"%s\" not declared" "- [%s] starting at line: %d", @@ -2647,7 +2647,7 @@ transformExtNode(InitConfigFileParser::Context & ctx, const char * data){ ctx.m_userProperties.get("ExtNoOfNodes", &nodes); require(ctx.m_userProperties.put("ExtNoOfNodes",++nodes, true)); - snprintf(ctx.pname, sizeof(ctx.pname), "EXTERNAL SYSTEM_%s:Node_%d", + BaseString::snprintf(ctx.pname, sizeof(ctx.pname), "EXTERNAL SYSTEM_%s:Node_%d", systemName, id); return true; @@ -2661,7 +2661,7 @@ transformConnection(InitConfigFileParser::Context & ctx, const char * data){ Uint32 connections = 0; ctx.m_userProperties.get("NoOfConnections", &connections); - snprintf(ctx.pname, sizeof(ctx.pname), "Connection_%d", connections); + BaseString::snprintf(ctx.pname, sizeof(ctx.pname), "Connection_%d", connections); ctx.m_userProperties.put("NoOfConnections", ++connections, true); ctx.m_currentSection->put("Type", ctx.fname); @@ -2684,7 +2684,7 @@ transformSystem(InitConfigFileParser::Context & ctx, const char * data){ ndbout << "transformSystem " << name << endl; - snprintf(ctx.pname, sizeof(ctx.pname), "SYSTEM_%s", name); + BaseString::snprintf(ctx.pname, sizeof(ctx.pname), "SYSTEM_%s", name); return true; } @@ -2701,7 +2701,7 @@ transformExternalSystem(InitConfigFileParser::Context & ctx, const char * data){ ctx.fname, ctx.m_sectionLineno); return false; } - snprintf(ctx.pname, sizeof(ctx.pname), "EXTERNAL SYSTEM_%s", name); + BaseString::snprintf(ctx.pname, sizeof(ctx.pname), "EXTERNAL SYSTEM_%s", name); return true; } @@ -2718,7 +2718,7 @@ transformComputer(InitConfigFileParser::Context & ctx, const char * data){ ctx.fname, ctx.m_sectionLineno); return false; } - snprintf(ctx.pname, sizeof(ctx.pname), "Computer_%s", id); + BaseString::snprintf(ctx.pname, sizeof(ctx.pname), "Computer_%s", id); Uint32 computers = 0; ctx.m_userProperties.get("NoOfComputers", &computers); @@ -2894,7 +2894,7 @@ fixExtConnection(InitConfigFileParser::Context & ctx, const char * data){ require(ctx.m_userProperties.put("ExtNoOfConnections",++connections, true)); char tmpLine1[MAX_LINE_LENGTH]; - snprintf(tmpLine1, MAX_LINE_LENGTH, "Connection_%d", connections-1); + BaseString::snprintf(tmpLine1, MAX_LINE_LENGTH, "Connection_%d", connections-1); /** * Section: EXTERNAL SYSTEM_<Ext System Name> @@ -3405,9 +3405,9 @@ add_node_connections(Vector<ConfigInfo::ConfigRuleSection>§ions, s.m_sectionType= BaseString("TCP"); s.m_sectionData= new Properties(true); char buf[16]; - snprintf(buf, sizeof(buf), "%u", nodeId1); + BaseString::snprintf(buf, sizeof(buf), "%u", nodeId1); s.m_sectionData->put("NodeId1", buf); - snprintf(buf, sizeof(buf), "%u", nodeId2); + BaseString::snprintf(buf, sizeof(buf), "%u", nodeId2); s.m_sectionData->put("NodeId2", buf); sections.push_back(s); } @@ -3422,9 +3422,9 @@ add_node_connections(Vector<ConfigInfo::ConfigRuleSection>§ions, s.m_sectionType= BaseString("TCP"); s.m_sectionData= new Properties(true); char buf[16]; - snprintf(buf, sizeof(buf), "%u", nodeId1); + BaseString::snprintf(buf, sizeof(buf), "%u", nodeId1); s.m_sectionData->put("NodeId1", buf); - snprintf(buf, sizeof(buf), "%u", nodeId2); + BaseString::snprintf(buf, sizeof(buf), "%u", nodeId2); s.m_sectionData->put("NodeId2", buf); sections.push_back(s); } @@ -3559,7 +3559,7 @@ check_node_vs_replicas(Vector<ConfigInfo::ConfigRuleSection>§ions, { unsigned c= 0; p_db_hosts.get(str.c_str(),&c); - if (c+1 == (1 << (replicas-1))) // all nodes on same machine + if (c+1 == (1u << (replicas-1))) // all nodes on same machine node_group_warning.append(".\n Host failure will " "cause complete cluster shutdown."); else if (c > 0) diff --git a/ndb/src/mgmsrv/InitConfigFileParser.cpp b/ndb/src/mgmsrv/InitConfigFileParser.cpp index 652e0f96190..fdfe7823fc2 100644 --- a/ndb/src/mgmsrv/InitConfigFileParser.cpp +++ b/ndb/src/mgmsrv/InitConfigFileParser.cpp @@ -42,7 +42,7 @@ InitConfigFileParser::~InitConfigFileParser() { // Read Config File //**************************************************************************** InitConfigFileParser::Context::Context(const ConfigInfo * info) - : m_configValues(1000, 20), m_userProperties(true) { + : m_userProperties(true), m_configValues(1000, 20) { m_config = new Properties(true); m_defaults = new Properties(true); @@ -110,7 +110,7 @@ InitConfigFileParser::parseConfig(FILE * file) { "of configuration file."); return 0; } - snprintf(ctx.fname, sizeof(ctx.fname), section); free(section); + BaseString::snprintf(ctx.fname, sizeof(ctx.fname), section); free(section); ctx.type = InitConfigFileParser::DefaultSection; ctx.m_sectionLineno = ctx.m_lineno; ctx.m_currentSection = new Properties(true); @@ -130,7 +130,7 @@ InitConfigFileParser::parseConfig(FILE * file) { "of configuration file."); return 0; } - snprintf(ctx.fname, sizeof(ctx.fname), section); + BaseString::snprintf(ctx.fname, sizeof(ctx.fname), section); free(section); ctx.type = InitConfigFileParser::Section; ctx.m_sectionLineno = ctx.m_lineno; @@ -172,7 +172,7 @@ InitConfigFileParser::parseConfig(FILE * file) { return 0; for(size_t j = 0; j<tmp.size(); j++){ - snprintf(ctx.fname, sizeof(ctx.fname), tmp[j].m_sectionType.c_str()); + BaseString::snprintf(ctx.fname, sizeof(ctx.fname), tmp[j].m_sectionType.c_str()); ctx.type = InitConfigFileParser::Section; ctx.m_currentSection = tmp[j].m_sectionData; ctx.m_userDefaults = getSection(ctx.fname, ctx.m_defaults); @@ -198,7 +198,7 @@ InitConfigFileParser::parseConfig(FILE * file) { ctx.m_config->put("NoOfNodes", nNodes); char tmpLine[MAX_LINE_LENGTH]; - snprintf(tmpLine, MAX_LINE_LENGTH, "EXTERNAL SYSTEM_"); + BaseString::snprintf(tmpLine, MAX_LINE_LENGTH, "EXTERNAL SYSTEM_"); strncat(tmpLine, system, MAX_LINE_LENGTH); strncat(tmpLine, ":NoOfConnections", MAX_LINE_LENGTH); ctx.m_config->put(tmpLine, nExtConnections); @@ -349,6 +349,8 @@ InitConfigFileParser::storeNameValuePair(Context& ctx, case ConfigInfo::STRING: MGM_REQUIRE(ctx.m_currentSection->put(pname, value)); break; + case ConfigInfo::SECTION: + abort(); } return true; } @@ -547,13 +549,13 @@ InitConfigFileParser::storeSection(Context& ctx){ for(int i = strlen(ctx.fname) - 1; i>=0; i--){ ctx.fname[i] = toupper(ctx.fname[i]); } - snprintf(ctx.pname, sizeof(ctx.pname), ctx.fname); + BaseString::snprintf(ctx.pname, sizeof(ctx.pname), ctx.fname); char buf[255]; if(ctx.type == InitConfigFileParser::Section) - snprintf(buf, sizeof(buf), "%s", ctx.fname); + BaseString::snprintf(buf, sizeof(buf), "%s", ctx.fname); if(ctx.type == InitConfigFileParser::DefaultSection) - snprintf(buf, sizeof(buf), "%s DEFAULT", ctx.fname); - snprintf(ctx.fname, sizeof(ctx.fname), buf); + BaseString::snprintf(buf, sizeof(buf), "%s DEFAULT", ctx.fname); + BaseString::snprintf(ctx.fname, sizeof(ctx.fname), buf); if(ctx.type == InitConfigFileParser::Section){ for(int i = 0; i<m_info->m_NoOfRules; i++){ const ConfigInfo::SectionRule & rule = m_info->m_SectionRules[i]; @@ -579,7 +581,7 @@ InitConfigFileParser::Context::reportError(const char * fmt, ...){ va_start(ap, fmt); if (fmt != 0) - vsnprintf(buf, sizeof(buf)-1, fmt, ap); + BaseString::vsnprintf(buf, sizeof(buf)-1, fmt, ap); ndbout << "Error line " << m_lineno << ": " << buf << endl; va_end(ap); @@ -593,7 +595,7 @@ InitConfigFileParser::Context::reportWarning(const char * fmt, ...){ va_start(ap, fmt); if (fmt != 0) - vsnprintf(buf, sizeof(buf)-1, fmt, ap); + BaseString::vsnprintf(buf, sizeof(buf)-1, fmt, ap); ndbout << "Warning line " << m_lineno << ": " << buf << endl; va_end(ap); } diff --git a/ndb/src/mgmsrv/MgmtSrvr.cpp b/ndb/src/mgmsrv/MgmtSrvr.cpp index 92a8025295f..fdaa61973d8 100644 --- a/ndb/src/mgmsrv/MgmtSrvr.cpp +++ b/ndb/src/mgmsrv/MgmtSrvr.cpp @@ -123,7 +123,7 @@ MgmtSrvr::signalRecvThreadRun() while(!_isStopThread) { SigMatch *handler = NULL; NdbApiSignal *signal = NULL; - if(m_signalRecvQueue.waitFor(siglist, handler, signal)) { + if(m_signalRecvQueue.waitFor(siglist, handler, signal, DEFAULT_TIMEOUT)) { if(handler->function != 0) (this->*handler->function)(signal); } @@ -1825,7 +1825,7 @@ const char* MgmtSrvr::getErrorText(int errorCode) } } - snprintf(text, 255, "Unknown management server error code %d", errorCode); + BaseString::snprintf(text, 255, "Unknown management server error code %d", errorCode); return text; } diff --git a/ndb/src/mgmsrv/Services.cpp b/ndb/src/mgmsrv/Services.cpp index 5242237a638..201168c1726 100644 --- a/ndb/src/mgmsrv/Services.cpp +++ b/ndb/src/mgmsrv/Services.cpp @@ -1008,8 +1008,9 @@ MgmApiSession::stop(Parser<MgmApiSession>::Context &, } int stop_self= 0; + size_t i; - for(size_t i=0; i < nodes.size(); i++) { + for(i=0; i < nodes.size(); i++) { if (nodes[i] == m_mgmsrv.getOwnNodeId()) { stop_self= 1; if (i != nodes.size()-1) { @@ -1023,7 +1024,7 @@ MgmApiSession::stop(Parser<MgmApiSession>::Context &, int stopped = 0, result = 0; - for(size_t i=0; i < nodes.size(); i++) + for(i=0; i < nodes.size(); i++) if (nodes[i] != m_mgmsrv.getOwnNodeId()) { if((result = m_mgmsrv.stopNode(nodes[i], abort != 0)) == 0) stopped++; @@ -1122,7 +1123,7 @@ MgmApiSession::logSignals(Parser<MgmApiSession>::Context &, args.get("blocks", blockList); // fast fix - pekka char buf[200]; - snprintf(buf, 200, "%s", blockList.c_str()); + BaseString::snprintf(buf, 200, "%s", blockList.c_str()); Vector<BaseString> blocks; blockName=strtok(buf,"|"); @@ -1252,8 +1253,9 @@ MgmStatService::log(int eventType, const Uint32* theData, NodeId nodeId){ Uint32 threshold = 0; LogLevel::EventCategory cat; - - for(unsigned i = 0; i<EventLogger::matrixSize; i++){ + int i; + + for(i = 0; (unsigned)i<EventLogger::matrixSize; i++){ if(EventLogger::matrix[i].eventType == eventType){ cat = EventLogger::matrix[i].eventCategory; threshold = EventLogger::matrix[i].threshold; @@ -1266,7 +1268,6 @@ MgmStatService::log(int eventType, const Uint32* theData, NodeId nodeId){ Vector<NDB_SOCKET_TYPE> copy; m_clients.lock(); - int i; for(i = m_clients.size() - 1; i >= 0; i--){ if(threshold <= m_clients[i].m_logLevel.getLogLevel(cat)){ if(m_clients[i].m_socket >= 0 && @@ -1279,14 +1280,14 @@ MgmStatService::log(int eventType, const Uint32* theData, NodeId nodeId){ } m_clients.unlock(); - for(i = 0; (unsigned)i<copy.size(); i++){ + for(i = 0; (unsigned)i < copy.size(); i++){ NDB_CLOSE_SOCKET(copy[i]); } if(copy.size()){ LogLevel tmp; tmp.clear(); m_clients.lock(); - for(i = 0; i < m_clients.size(); i++){ + for(i = 0; (unsigned)i < m_clients.size(); i++){ tmp.set_max(m_clients[i].m_logLevel); } m_clients.unlock(); diff --git a/ndb/src/mgmsrv/SignalQueue.cpp b/ndb/src/mgmsrv/SignalQueue.cpp index 7003f5c0a89..08ad5f363a6 100644 --- a/ndb/src/mgmsrv/SignalQueue.cpp +++ b/ndb/src/mgmsrv/SignalQueue.cpp @@ -14,8 +14,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include <string.h> - +#include <ndb_global.h> #include "SignalQueue.hpp" SignalQueue::SignalQueue() { diff --git a/ndb/src/mgmsrv/main.cpp b/ndb/src/mgmsrv/main.cpp index 1a2b95391a9..51282416c24 100644 --- a/ndb/src/mgmsrv/main.cpp +++ b/ndb/src/mgmsrv/main.cpp @@ -131,6 +131,7 @@ int num_args = sizeof(args) / sizeof(args[0]); */ 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 @@ -266,12 +267,12 @@ NDB_MAIN(mgmsrv){ mapi->setMgm(glob.mgmObject); char msg[256]; - snprintf(msg, sizeof(msg), + BaseString::snprintf(msg, sizeof(msg), "NDB Cluster Management Server. %s", NDB_VERSION_STRING); ndbout_c(msg); g_EventLogger.info(msg); - snprintf(msg, 256, "Id: %d, Command port: %d", + BaseString::snprintf(msg, 256, "Id: %d, Command port: %d", glob.localNodeId, glob.port); ndbout_c(msg); g_EventLogger.info(msg); diff --git a/ndb/src/ndbapi/Ndb.cpp b/ndb/src/ndbapi/Ndb.cpp index be8ba86c817..be0445bceb3 100644 --- a/ndb/src/ndbapi/Ndb.cpp +++ b/ndb/src/ndbapi/Ndb.cpp @@ -330,7 +330,7 @@ Ndb::startTransaction(Uint32 aPriority, const char * keyData, Uint32 keyLen) { NdbConnection *trans= startTransactionLocal(aPriority, nodeId); DBUG_PRINT("exit",("start trans: 0x%x transid: 0x%llx", - trans, trans->getTransactionId())); + trans, trans ? trans->getTransactionId() : 0)); DBUG_RETURN(trans); } } else { @@ -371,6 +371,7 @@ Ndb::hupp(NdbConnection* pBuddyTrans) // We could not get a connection to the desired node // release the connection and return NULL closeTransaction(pCon); + theError.code = 4006; DBUG_RETURN(NULL); } pCon->setTransactionId(pBuddyTrans->getTransactionId()); @@ -1157,10 +1158,10 @@ const char * Ndb::getCatalogName() const void Ndb::setCatalogName(const char * a_catalog_name) { if (a_catalog_name) { - snprintf(theDataBase, sizeof(theDataBase), "%s", + BaseString::snprintf(theDataBase, sizeof(theDataBase), "%s", a_catalog_name ? a_catalog_name : ""); - int len = snprintf(prefixName, sizeof(prefixName), "%s%c%s%c", + int len = BaseString::snprintf(prefixName, sizeof(prefixName), "%s%c%s%c", theDataBase, table_name_separator, theDataBaseSchema, table_name_separator); prefixEnd = prefixName + (len < (int) sizeof(prefixName) ? len : @@ -1176,10 +1177,10 @@ const char * Ndb::getSchemaName() const void Ndb::setSchemaName(const char * a_schema_name) { if (a_schema_name) { - snprintf(theDataBaseSchema, sizeof(theDataBase), "%s", + BaseString::snprintf(theDataBaseSchema, sizeof(theDataBase), "%s", a_schema_name ? a_schema_name : ""); - int len = snprintf(prefixName, sizeof(prefixName), "%s%c%s%c", + int len = BaseString::snprintf(prefixName, sizeof(prefixName), "%s%c%s%c", theDataBase, table_name_separator, theDataBaseSchema, table_name_separator); prefixEnd = prefixName + (len < (int) sizeof(prefixName) ? len : diff --git a/ndb/src/ndbapi/NdbApiSignal.cpp b/ndb/src/ndbapi/NdbApiSignal.cpp index d7b2b74b2bf..a1d34896968 100644 --- a/ndb/src/ndbapi/NdbApiSignal.cpp +++ b/ndb/src/ndbapi/NdbApiSignal.cpp @@ -168,7 +168,7 @@ NdbApiSignal::setSignal(int aNdbSignalType) theTrace = TestOrd::TraceAPI; theReceiversBlockNumber = DBTC; theVerId_signalNumber = GSN_TC_COMMITREQ; - theLength = 5; + theLength = 3; } break; diff --git a/ndb/src/ndbapi/NdbBlob.cpp b/ndb/src/ndbapi/NdbBlob.cpp index 7939f54d846..feab95d8ca5 100644 --- a/ndb/src/ndbapi/NdbBlob.cpp +++ b/ndb/src/ndbapi/NdbBlob.cpp @@ -867,7 +867,7 @@ NdbBlob::readParts(char* buf, Uint32 part, Uint32 count) while (n < count) { NdbOperation* tOp = theNdbCon->getNdbOperation(theBlobTable); if (tOp == NULL || - tOp->readTuple() == -1 || + tOp->committedRead() == -1 || setPartKeyValue(tOp, part + n) == -1 || tOp->getValue((Uint32)3, buf) == NULL) { setErrorCode(tOp); @@ -1440,11 +1440,11 @@ NdbOut& operator<<(NdbOut& out, const NdbBlob& blob) { ndbout << dec << "o=" << blob.getOperationType(); - ndbout << dec << " s=" << blob.theState; + ndbout << dec << " s=" << (Uint32) blob.theState; ndbout << dec << " n=" << blob.theNullFlag;; ndbout << dec << " l=" << blob.theLength; ndbout << dec << " p=" << blob.thePos; - ndbout << dec << " u=" << blob.theHeadInlineUpdateFlag; + ndbout << dec << " u=" << (Uint32) blob.theHeadInlineUpdateFlag; return out; } #endif diff --git a/ndb/src/ndbapi/NdbConnection.cpp b/ndb/src/ndbapi/NdbConnection.cpp index 8ab0d13c67f..1457792cf28 100644 --- a/ndb/src/ndbapi/NdbConnection.cpp +++ b/ndb/src/ndbapi/NdbConnection.cpp @@ -83,6 +83,11 @@ NdbConnection::NdbConnection( Ndb* aNdb ) : theListState = NotInList; theError.code = 0; theId = theNdb->theNdbObjectIdMap->map(this); + +#define CHECK_SZ(mask, sz) assert((sizeof(mask)/sizeof(mask[0])) == sz) + + CHECK_SZ(m_db_nodes, NdbNodeBitmask::Size); + CHECK_SZ(m_failed_db_nodes, NdbNodeBitmask::Size); }//NdbConnection::NdbConnection() /***************************************************************************** @@ -308,8 +313,8 @@ NdbConnection::execute(ExecType aTypeOfExec, tPrepOp = tPrepOp->next(); } // save rest of prepared ops if batch - NdbOperation* tRestOp; - NdbOperation* tLastOp; + NdbOperation* tRestOp= 0; + NdbOperation* tLastOp= 0; if (tPrepOp != NULL) { tRestOp = tPrepOp->next(); tPrepOp->next(NULL); @@ -490,11 +495,6 @@ NdbConnection::executeAsynchPrepare( ExecType aTypeOfExec, theListState = InPreparedList; tNdb->theNoOfPreparedTransactions = tnoOfPreparedTransactions + 1; - if(tCommitStatus == Committed){ - tCommitStatus = Started; - tTransactionIsStarted = false; - } - if ((tCommitStatus != Started) || (aTypeOfExec == Rollback)) { /***************************************************************************** @@ -503,7 +503,7 @@ NdbConnection::executeAsynchPrepare( ExecType aTypeOfExec, * same action. ****************************************************************************/ if (aTypeOfExec == Rollback) { - if (theTransactionIsStarted == false) { + if (theTransactionIsStarted == false || theSimpleState) { theCommitStatus = Aborted; theSendStatus = sendCompleted; } else { @@ -528,7 +528,7 @@ NdbConnection::executeAsynchPrepare( ExecType aTypeOfExec, tLastOp->theCommitIndicator = 1; }//if } else { - if (aTypeOfExec == Commit) { + if (aTypeOfExec == Commit && !theSimpleState) { /********************************************************************** * A Transaction have been started and no more operations exist. * We will use the commit method. @@ -610,6 +610,8 @@ NdbConnection::executeAsynchPrepare( ExecType aTypeOfExec, theNoOfOpSent = 0; theNoOfOpCompleted = 0; theSendStatus = sendOperations; + NdbNodeBitmask::clear(m_db_nodes); + NdbNodeBitmask::clear(m_failed_db_nodes); DBUG_VOID_RETURN; }//NdbConnection::executeAsynchPrepare() @@ -728,7 +730,8 @@ NdbConnection::doSend() theNdb->insert_completed_list(this); DBUG_RETURN(0); default: - ndbout << "Inconsistent theSendStatus = " << theSendStatus << endl; + ndbout << "Inconsistent theSendStatus = " + << (Uint32) theSendStatus << endl; abort(); break; }//switch @@ -1115,15 +1118,8 @@ NdbConnection::getNdbScanOperation(const NdbTableImpl * tab) if (tOp == NULL) goto getNdbOp_error1; - // Link scan operation into list of cursor operations - if (m_theLastScanOperation == NULL) - m_theFirstScanOperation = m_theLastScanOperation = tOp; - else { - m_theLastScanOperation->next(tOp); - m_theLastScanOperation = tOp; - } - tOp->next(NULL); if (tOp->init(tab, this) != -1) { + define_scan_op(tOp); return tOp; } else { theNdb->releaseScanOperation(tOp); @@ -1135,6 +1131,31 @@ getNdbOp_error1: return NULL; }//NdbConnection::getNdbScanOperation() +void +NdbConnection::remove_list(NdbOperation*& list, NdbOperation* op){ + NdbOperation* tmp= list; + if(tmp == op) + list = op->next(); + else { + while(tmp && tmp->next() != op) tmp = tmp->next(); + if(tmp) + tmp->next(op->next()); + } + op->next(NULL); +} + +void +NdbConnection::define_scan_op(NdbIndexScanOperation * tOp){ + // Link scan operation into list of cursor operations + if (m_theLastScanOperation == NULL) + m_theFirstScanOperation = m_theLastScanOperation = tOp; + else { + m_theLastScanOperation->next(tOp); + m_theLastScanOperation = tOp; + } + tOp->next(NULL); +} + NdbScanOperation* NdbConnection::getNdbScanOperation(const NdbDictionary::Table * table) { @@ -1517,12 +1538,21 @@ from other transactions. const Uint32* tPtr = (Uint32 *)&keyConf->operations[0]; Uint32 tNoComp = theNoOfOpCompleted; for (Uint32 i = 0; i < tNoOfOperations ; i++) { - tOp = theNdb->void2rec(theNdb->int2void(*tPtr)); - tPtr++; - const Uint32 tAttrInfoLen = *tPtr; - tPtr++; + tOp = theNdb->void2rec(theNdb->int2void(*tPtr++)); + const Uint32 tAttrInfoLen = *tPtr++; if (tOp && tOp->checkMagicNumber()) { - tNoComp += tOp->execTCOPCONF(tAttrInfoLen); + Uint32 done = tOp->execTCOPCONF(tAttrInfoLen); + if(tAttrInfoLen > TcKeyConf::SimpleReadBit){ + Uint32 node = tAttrInfoLen & (~TcKeyConf::SimpleReadBit); + NdbNodeBitmask::set(m_db_nodes, node); + if(NdbNodeBitmask::get(m_failed_db_nodes, node) && !done) + { + done = 1; + tOp->setErrorCode(4119); + theCompletionStatus = CompletedFailure; + } + } + tNoComp += done; } else { return -1; }//if @@ -1614,6 +1644,10 @@ NdbConnection::receiveTCKEY_FAILCONF(const TcKeyFailConf * failConf) setOperationErrorCodeAbort(4115); tOp = NULL; break; + case NdbOperation::NotDefined: + case NdbOperation::NotDefined2: + assert(false); + break; }//if }//while theReleaseOnClose = true; @@ -1772,7 +1806,7 @@ Parameters: aErrorCode: The error code. Remark: An operation was completed with failure. *******************************************************************************/ int -NdbConnection::OpCompleteFailure() +NdbConnection::OpCompleteFailure(Uint8 abortOption) { Uint32 tNoComp = theNoOfOpCompleted; Uint32 tNoSent = theNoOfOpSent; @@ -1786,10 +1820,7 @@ NdbConnection::OpCompleteFailure() //decide the success of the whole transaction since a simple //operation is not really part of that transaction. //------------------------------------------------------------------------ - if (theSimpleState == 1) { - theCommitStatus = NdbConnection::Aborted; - }//if - if (m_abortOption == IgnoreError){ + if (abortOption == IgnoreError){ /** * There's always a TCKEYCONF when using IgnoreError */ @@ -1824,9 +1855,6 @@ NdbConnection::OpCompleteSuccess() tNoComp++; theNoOfOpCompleted = tNoComp; if (tNoComp == tNoSent) { // Last operation completed - if (theSimpleState == 1) { - theCommitStatus = NdbConnection::Committed; - }//if return 0; } else if (tNoComp < tNoSent) { return -1; // Continue waiting for more signals @@ -1901,14 +1929,14 @@ NdbConnection::printState() CASE(Connected); CASE(DisConnecting); CASE(ConnectFailure); - default: ndbout << theStatus; + default: ndbout << (Uint32) theStatus; } switch (theListState) { CASE(NotInList); CASE(InPreparedList); CASE(InSendList); CASE(InCompletedList); - default: ndbout << theListState; + default: ndbout << (Uint32) theListState; } switch (theSendStatus) { CASE(NotInit); @@ -1921,7 +1949,7 @@ NdbConnection::printState() CASE(sendTC_ROLLBACK); CASE(sendTC_COMMIT); CASE(sendTC_OP); - default: ndbout << theSendStatus; + default: ndbout << (Uint32) theSendStatus; } switch (theCommitStatus) { CASE(NotStarted); @@ -1929,16 +1957,56 @@ NdbConnection::printState() CASE(Committed); CASE(Aborted); CASE(NeedAbort); - default: ndbout << theCommitStatus; + default: ndbout << (Uint32) theCommitStatus; } switch (theCompletionStatus) { CASE(NotCompleted); CASE(CompletedSuccess); CASE(CompletedFailure); CASE(DefinitionFailure); - default: ndbout << theCompletionStatus; + default: ndbout << (Uint32) theCompletionStatus; } ndbout << endl; } #undef CASE #endif + +int +NdbConnection::report_node_failure(Uint32 id){ + NdbNodeBitmask::set(m_failed_db_nodes, id); + if(!NdbNodeBitmask::get(m_db_nodes, id)) + { + return 0; + } + + /** + * Arrived + * TCKEYCONF TRANSIDAI + * 1) - - + * 2) - X + * 3) X - + * 4) X X + */ + NdbOperation* tmp = theFirstExecOpInList; + const Uint32 len = TcKeyConf::SimpleReadBit | id; + Uint32 tNoComp = theNoOfOpCompleted; + Uint32 tNoSent = theNoOfOpSent; + while(tmp != 0) + { + if(tmp->theReceiver.m_expected_result_length == len && + tmp->theReceiver.m_received_result_length == 0) + { + tNoComp++; + tmp->theError.code = 4119; + } + tmp = tmp->next(); + } + theNoOfOpCompleted = tNoComp; + if(tNoComp == tNoSent) + { + theError.code = 4119; + theCompletionStatus = NdbConnection::CompletedFailure; + return 1; + } + return 0; +} diff --git a/ndb/src/ndbapi/NdbDictionaryImpl.cpp b/ndb/src/ndbapi/NdbDictionaryImpl.cpp index 5e640cdebd5..cf51a30fe0b 100644 --- a/ndb/src/ndbapi/NdbDictionaryImpl.cpp +++ b/ndb/src/ndbapi/NdbDictionaryImpl.cpp @@ -148,6 +148,9 @@ NdbColumnImpl::init(Type t) m_length = 4; m_cs = default_cs; break; + case Undefined: + assert(false); + break; } m_pk = false; m_nullable = false; @@ -1466,7 +1469,7 @@ NdbDictInterface::createOrAlterTable(Ndb & ndb, impl.m_internalName.assign(internalName); UtilBufferWriter w(m_buffer); DictTabInfo::Table tmpTab; tmpTab.init(); - snprintf(tmpTab.TableName, + BaseString::snprintf(tmpTab.TableName, sizeof(tmpTab.TableName), internalName); @@ -1522,7 +1525,7 @@ NdbDictInterface::createOrAlterTable(Ndb & ndb, continue; DictTabInfo::Attribute tmpAttr; tmpAttr.init(); - snprintf(tmpAttr.AttributeName, sizeof(tmpAttr.AttributeName), + BaseString::snprintf(tmpAttr.AttributeName, sizeof(tmpAttr.AttributeName), col->m_name.c_str()); tmpAttr.AttributeId = i; tmpAttr.AttributeKeyFlag = col->m_pk || col->m_tupleKey; @@ -1557,7 +1560,7 @@ NdbDictInterface::createOrAlterTable(Ndb & ndb, (void)tmpAttr.translateExtType(); tmpAttr.AttributeAutoIncrement = col->m_autoIncrement; - snprintf(tmpAttr.AttributeDefaultValue, + BaseString::snprintf(tmpAttr.AttributeDefaultValue, sizeof(tmpAttr.AttributeDefaultValue), col->m_defaultValue.c_str()); s = SimpleProperties::pack(w, diff --git a/ndb/src/ndbapi/NdbIndexOperation.cpp b/ndb/src/ndbapi/NdbIndexOperation.cpp index c62f6962e25..83de6d9ef87 100644 --- a/ndb/src/ndbapi/NdbIndexOperation.cpp +++ b/ndb/src/ndbapi/NdbIndexOperation.cpp @@ -87,7 +87,19 @@ NdbIndexOperation::indxInit(const NdbIndexImpl * anIndex, int NdbIndexOperation::readTuple(NdbOperation::LockMode lm) { - return NdbOperation::readTuple(lm); + switch(lm) { + case LM_Read: + return readTuple(); + break; + case LM_Exclusive: + return readTupleExclusive(); + break; + case LM_CommittedRead: + return readTuple(); + break; + default: + return -1; + }; } int NdbIndexOperation::readTuple() @@ -108,21 +120,21 @@ int NdbIndexOperation::simpleRead() { // First check that index is unique - return NdbOperation::simpleRead(); + return NdbOperation::readTuple(); } int NdbIndexOperation::dirtyRead() { // First check that index is unique - return NdbOperation::dirtyRead(); + return NdbOperation::readTuple(); } int NdbIndexOperation::committedRead() { // First check that index is unique - return NdbOperation::committedRead(); + return NdbOperation::readTuple(); } int NdbIndexOperation::updateTuple() @@ -536,7 +548,7 @@ NdbIndexOperation::prepareSend(Uint32 aTC_ConnectPtr, Uint64 aTransactionId) //------------------------------------------------------------- Uint8 tReadInd = (theOperationType == ReadRequest); Uint8 tSimpleState = tReadInd & tSimpleAlt; - theNdbCon->theSimpleState = tSimpleState; + //theNdbCon->theSimpleState = tSimpleState; tcIndxReq->transId1 = tTransId1; tcIndxReq->transId2 = tTransId2; @@ -723,23 +735,10 @@ NdbIndexOperation::receiveTCINDXREF( NdbApiSignal* aSignal) theStatus = Finished; theNdbCon->theReturnStatus = NdbConnection::ReturnFailure; - //--------------------------------------------------------------------------// - // If the transaction this operation belongs to consists only of simple reads - // we set the error code on the transaction object. - // If the transaction consists of other types of operations we set - // the error code only on the operation since the simple read is not really - // part of this transaction and we can not decide the status of the whole - // transaction based on this operation. - //--------------------------------------------------------------------------// Uint32 errorCode = tcIndxRef->errorCode; - if (theNdbCon->theSimpleState == 0) { - theError.code = errorCode; - theNdbCon->setOperationErrorCodeAbort(errorCode); - return theNdbCon->OpCompleteFailure(); - } else { - theError.code = errorCode; - return theNdbCon->OpCompleteSuccess(); - } + theError.code = errorCode; + theNdbCon->setOperationErrorCodeAbort(errorCode); + return theNdbCon->OpCompleteFailure(theNdbCon->m_abortOption); }//NdbIndexOperation::receiveTCINDXREF() diff --git a/ndb/src/ndbapi/NdbOperation.cpp b/ndb/src/ndbapi/NdbOperation.cpp index 53a94d98a5a..b0b95d0ff43 100644 --- a/ndb/src/ndbapi/NdbOperation.cpp +++ b/ndb/src/ndbapi/NdbOperation.cpp @@ -78,7 +78,6 @@ NdbOperation::NdbOperation(Ndb* aNdb) : m_tcReqGSN(GSN_TCKEYREQ), m_keyInfoGSN(GSN_KEYINFO), m_attrInfoGSN(GSN_ATTRINFO), - theBoundATTRINFO(NULL), theBlobList(NULL) { theReceiver.init(NdbReceiver::NDB_OPERATION, this); @@ -167,7 +166,6 @@ NdbOperation::init(const NdbTableImpl* tab, NdbConnection* myConnection){ theScanInfo = 0; theTotalNrOfKeyWordInSignal = 8; theMagicNumber = 0xABCDEF01; - theBoundATTRINFO = NULL; theBlobList = NULL; tSignal = theNdb->getSignal(); @@ -263,14 +261,6 @@ NdbOperation::release() tSubroutine = tSubroutine->theNext; theNdb->releaseNdbSubroutine(tSaveSubroutine); } - tSignal = theBoundATTRINFO; - while (tSignal != NULL) - { - tSaveSignal = tSignal; - tSignal = tSignal->next(); - theNdb->releaseSignal(tSaveSignal); - } - theBoundATTRINFO = NULL; } tBlob = theBlobList; while (tBlob != NULL) diff --git a/ndb/src/ndbapi/NdbOperationDefine.cpp b/ndb/src/ndbapi/NdbOperationDefine.cpp index 1cbfedd21b1..35abb15b00d 100644 --- a/ndb/src/ndbapi/NdbOperationDefine.cpp +++ b/ndb/src/ndbapi/NdbOperationDefine.cpp @@ -55,6 +55,7 @@ NdbOperation::insertTuple() theOperationType = InsertRequest; tNdbCon->theSimpleState = 0; theErrorLine = tErrorLine++; + theLockMode = LM_Exclusive; return 0; } else { setErrorCode(4200); @@ -74,6 +75,7 @@ NdbOperation::updateTuple() tNdbCon->theSimpleState = 0; theOperationType = UpdateRequest; theErrorLine = tErrorLine++; + theLockMode = LM_Exclusive; return 0; } else { setErrorCode(4200); @@ -93,6 +95,7 @@ NdbOperation::writeTuple() tNdbCon->theSimpleState = 0; theOperationType = WriteRequest; theErrorLine = tErrorLine++; + theLockMode = LM_Exclusive; return 0; } else { setErrorCode(4200); @@ -113,8 +116,10 @@ NdbOperation::readTuple(NdbOperation::LockMode lm) return readTupleExclusive(); break; case LM_CommittedRead: - return readTuple(); + return committedRead(); break; + default: + return -1; }; } /****************************************************************************** @@ -130,6 +135,7 @@ NdbOperation::readTuple() tNdbCon->theSimpleState = 0; theOperationType = ReadRequest; theErrorLine = tErrorLine++; + theLockMode = LM_Read; return 0; } else { setErrorCode(4200); @@ -150,6 +156,7 @@ NdbOperation::deleteTuple() tNdbCon->theSimpleState = 0; theOperationType = DeleteRequest; theErrorLine = tErrorLine++; + theLockMode = LM_Exclusive; return 0; } else { setErrorCode(4200); @@ -170,6 +177,7 @@ NdbOperation::readTupleExclusive() tNdbCon->theSimpleState = 0; theOperationType = ReadExclusive; theErrorLine = tErrorLine++; + theLockMode = LM_Exclusive; return 0; } else { setErrorCode(4200); @@ -183,17 +191,24 @@ NdbOperation::readTupleExclusive() int NdbOperation::simpleRead() { + /** + * Currently/still disabled + */ + return readTuple(); +#if 0 int tErrorLine = theErrorLine; if (theStatus == Init) { theStatus = OperationDefined; theOperationType = ReadRequest; theSimpleIndicator = 1; theErrorLine = tErrorLine++; + theLockMode = LM_Read; return 0; } else { setErrorCode(4200); return -1; }//if +#endif }//NdbOperation::simpleRead() /***************************************************************************** @@ -218,6 +233,7 @@ NdbOperation::committedRead() theSimpleIndicator = 1; theDirtyIndicator = 1; theErrorLine = tErrorLine++; + theLockMode = LM_CommittedRead; return 0; } else { setErrorCode(4200); @@ -240,6 +256,7 @@ NdbOperation::dirtyUpdate() theSimpleIndicator = 1; theDirtyIndicator = 1; theErrorLine = tErrorLine++; + theLockMode = LM_CommittedRead; return 0; } else { setErrorCode(4200); @@ -262,6 +279,7 @@ NdbOperation::dirtyWrite() theSimpleIndicator = 1; theDirtyIndicator = 1; theErrorLine = tErrorLine++; + theLockMode = LM_CommittedRead; return 0; } else { setErrorCode(4200); @@ -282,7 +300,7 @@ NdbOperation::interpretedUpdateTuple() tNdbCon->theSimpleState = 0; theOperationType = UpdateRequest; theAI_LenInCurrAI = 25; - + theLockMode = LM_Exclusive; theErrorLine = tErrorLine++; initInterpreter(); return 0; @@ -307,7 +325,7 @@ NdbOperation::interpretedDeleteTuple() theErrorLine = tErrorLine++; theAI_LenInCurrAI = 25; - + theLockMode = LM_Exclusive; initInterpreter(); return 0; } else { @@ -334,10 +352,6 @@ NdbOperation::getValue_impl(const NdbColumnImpl* tAttrInfo, char* aValue) if ((tAttrInfo != NULL) && (!tAttrInfo->m_indexOnly) && (theStatus != Init)){ - if (theStatus == SetBound) { - ((NdbIndexScanOperation*)this)->saveBoundATTRINFO(); - theStatus = GetValue; - } if (theStatus != GetValue) { if (theInterpretIndicator == 1) { if (theStatus == FinalGetValue) { diff --git a/ndb/src/ndbapi/NdbOperationExec.cpp b/ndb/src/ndbapi/NdbOperationExec.cpp index cd89f953213..f1338ae01e4 100644 --- a/ndb/src/ndbapi/NdbOperationExec.cpp +++ b/ndb/src/ndbapi/NdbOperationExec.cpp @@ -161,28 +161,17 @@ NdbOperation::prepareSend(Uint32 aTC_ConnectPtr, Uint64 aTransId) tTransId1 = (Uint32) aTransId; tTransId2 = (Uint32) (aTransId >> 32); -//------------------------------------------------------------- -// Simple is simple if simple or both start and commit is set. -//------------------------------------------------------------- -// Temporarily disable simple stuff - Uint8 tSimpleIndicator = 0; -// Uint8 tSimpleIndicator = theSimpleIndicator; + Uint8 tSimpleIndicator = theSimpleIndicator; Uint8 tCommitIndicator = theCommitIndicator; Uint8 tStartIndicator = theStartIndicator; -// if ((theNdbCon->theLastOpInList == this) && (theCommitIndicator == 0)) -// abort(); -// Temporarily disable simple stuff - Uint8 tSimpleAlt = 0; -// Uint8 tSimpleAlt = tStartIndicator & tCommitIndicator; - tSimpleIndicator = tSimpleIndicator | tSimpleAlt; + Uint8 tInterpretIndicator = theInterpretIndicator; //------------------------------------------------------------- // Simple state is set if start and commit is set and it is // a read request. Otherwise it is set to zero. //------------------------------------------------------------- Uint8 tReadInd = (theOperationType == ReadRequest); - Uint8 tSimpleState = tReadInd & tSimpleAlt; - theNdbCon->theSimpleState = tSimpleState; + Uint8 tSimpleState = tReadInd & tSimpleIndicator; tcKeyReq->transId1 = tTransId1; tcKeyReq->transId2 = tTransId2; @@ -197,7 +186,6 @@ NdbOperation::prepareSend(Uint32 aTC_ConnectPtr, Uint64 aTransId) tcKeyReq->setSimpleFlag(tReqInfo, tSimpleIndicator); tcKeyReq->setCommitFlag(tReqInfo, tCommitIndicator); tcKeyReq->setStartFlag(tReqInfo, tStartIndicator); - const Uint8 tInterpretIndicator = theInterpretIndicator; tcKeyReq->setInterpretedFlag(tReqInfo, tInterpretIndicator); Uint8 tDirtyIndicator = theDirtyIndicator; @@ -208,6 +196,9 @@ NdbOperation::prepareSend(Uint32 aTC_ConnectPtr, Uint64 aTransId) tcKeyReq->setDirtyFlag(tReqInfo, tDirtyIndicator); tcKeyReq->setOperationType(tReqInfo, tOperationType); tcKeyReq->setKeyLength(tReqInfo, tTupKeyLen); + + // A simple read is always ignore error + abortOption = tSimpleIndicator ? IgnoreError : abortOption; tcKeyReq->setAbortOption(tReqInfo, abortOption); Uint8 tDistrKeyIndicator = theDistrKeyIndicator; @@ -550,27 +541,29 @@ NdbOperation::receiveTCKEYREF( NdbApiSignal* aSignal) return -1; }//if + AbortOption ao = (AbortOption)theNdbCon->m_abortOption; + theReceiver.m_received_result_length = ~0; + theStatus = Finished; - theNdbCon->theReturnStatus = NdbConnection::ReturnFailure; - //-------------------------------------------------------------------------// - // If the transaction this operation belongs to consists only of simple reads - // we set the error code on the transaction object. - // If the transaction consists of other types of operations we set - // the error code only on the operation since the simple read is not really - // part of this transaction and we can not decide the status of the whole - // transaction based on this operation. - //-------------------------------------------------------------------------// - if (theNdbCon->theSimpleState == 0) { - theError.code = aSignal->readData(4); - theNdbCon->setOperationErrorCodeAbort(aSignal->readData(4)); - return theNdbCon->OpCompleteFailure(); - } else { - theError.code = aSignal->readData(4); - return theNdbCon->OpCompleteSuccess(); + + theError.code = aSignal->readData(4); + theNdbCon->setOperationErrorCodeAbort(aSignal->readData(4)); + + if(theOperationType != ReadRequest || !theSimpleIndicator) // not simple read + return theNdbCon->OpCompleteFailure(ao); + + /** + * If TCKEYCONF has arrived + * op has completed (maybe trans has completed) + */ + if(theReceiver.m_expected_result_length) + { + return theNdbCon->OpCompleteFailure(AbortOnError); } -}//NdbOperation::receiveTCKEYREF() + return -1; +} void diff --git a/ndb/src/ndbapi/NdbOperationInt.cpp b/ndb/src/ndbapi/NdbOperationInt.cpp index f5d334fd79a..ee7b8132cd1 100644 --- a/ndb/src/ndbapi/NdbOperationInt.cpp +++ b/ndb/src/ndbapi/NdbOperationInt.cpp @@ -216,10 +216,6 @@ int NdbOperation::initial_interpreterCheck() { if ((theInterpretIndicator == 1)) { - if (theStatus == SetBound) { - ((NdbIndexScanOperation*)this)->saveBoundATTRINFO(); - theStatus = GetValue; - } if (theStatus == ExecInterpretedValue) { return 0; // Simply continue with interpretation } else if (theStatus == GetValue) { diff --git a/ndb/src/ndbapi/NdbOperationSearch.cpp b/ndb/src/ndbapi/NdbOperationSearch.cpp index e5166fc4a82..0d3130fffd0 100644 --- a/ndb/src/ndbapi/NdbOperationSearch.cpp +++ b/ndb/src/ndbapi/NdbOperationSearch.cpp @@ -543,7 +543,8 @@ NdbOperation::getKeyFromTCREQ(Uint32* data, unsigned size) assert(m_accessTable->m_sizeOfKeysInWords == size); unsigned pos = 0; while (pos < 8 && pos < size) { - data[pos++] = theKEYINFOptr[pos]; + data[pos] = theKEYINFOptr[pos]; + pos++; } NdbApiSignal* tSignal = theFirstKEYINFO; unsigned n = 0; diff --git a/ndb/src/ndbapi/NdbReceiver.cpp b/ndb/src/ndbapi/NdbReceiver.cpp index caeeac80093..14f8d4b8440 100644 --- a/ndb/src/ndbapi/NdbReceiver.cpp +++ b/ndb/src/ndbapi/NdbReceiver.cpp @@ -22,6 +22,7 @@ #include <AttributeHeader.hpp> #include <NdbConnection.hpp> #include <TransporterFacade.hpp> +#include <signaldata/TcKeyConf.hpp> NdbReceiver::NdbReceiver(Ndb *aNdb) : theMagicNumber(0), @@ -91,7 +92,7 @@ NdbReceiver::getValue(const NdbColumnImpl* tAttrInfo, char * user_dst_ptr){ return 0; } -#define KEY_ATTR_ID (~0) +#define KEY_ATTR_ID (~(Uint32)0) void NdbReceiver::calculate_batch_size(Uint32 key_size, @@ -249,10 +250,11 @@ NdbReceiver::execTRANSID_AI(const Uint32* aDataPtr, Uint32 aLength) /** * Update m_received_result_length */ + Uint32 exp = m_expected_result_length; Uint32 tmp = m_received_result_length + aLength; m_received_result_length = tmp; - return (tmp == m_expected_result_length ? 1 : 0); + return (tmp == exp || (exp > TcKeyConf::SimpleReadBit) ? 1 : 0); } int @@ -272,3 +274,11 @@ NdbReceiver::execKEYINFO20(Uint32 info, const Uint32* aDataPtr, Uint32 aLength) return (tmp == m_expected_result_length ? 1 : 0); } + +void +NdbReceiver::setErrorCode(int code) +{ + theMagicNumber = 0; + NdbOperation* op = (NdbOperation*)getOwner(); + op->setErrorCode(code); +} diff --git a/ndb/src/ndbapi/NdbScanOperation.cpp b/ndb/src/ndbapi/NdbScanOperation.cpp index 3ff2a32d418..fd63ce96f25 100644 --- a/ndb/src/ndbapi/NdbScanOperation.cpp +++ b/ndb/src/ndbapi/NdbScanOperation.cpp @@ -32,6 +32,7 @@ #include <signaldata/ScanTab.hpp> #include <signaldata/KeyInfo.hpp> +#include <signaldata/AttrInfo.hpp> #include <signaldata/TcKeyReq.hpp> NdbScanOperation::NdbScanOperation(Ndb* aNdb) : @@ -116,10 +117,8 @@ NdbScanOperation::init(const NdbTableImpl* tab, NdbConnection* myConnection) theStatus = GetValue; theOperationType = OpenScanRequest; - - theTotalBoundAI_Len = 0; - theBoundATTRINFO = NULL; - + theNdbCon->theMagicNumber = 0xFE11DF; + return 0; } @@ -145,6 +144,7 @@ NdbResultSet* NdbScanOperation::readTuples(NdbScanOperation::LockMode lm, } theNdbCon->theScanningOp = this; + theLockMode = lm; bool lockExcl, lockHoldMode, readCommitted; switch(lm){ @@ -168,7 +168,7 @@ NdbResultSet* NdbScanOperation::readTuples(NdbScanOperation::LockMode lm, return 0; } - m_keyInfo = lockExcl; + m_keyInfo = lockExcl ? 1 : 0; bool range = false; if (m_accessTable->m_indexType == NdbDictionary::Index::OrderedIndex || @@ -181,7 +181,7 @@ NdbResultSet* NdbScanOperation::readTuples(NdbScanOperation::LockMode lm, } assert (m_currentTable != m_accessTable); // Modify operation state - theStatus = SetBound; + theStatus = GetValue; theOperationType = OpenRangeScanRequest; range = true; } @@ -219,8 +219,17 @@ NdbResultSet* NdbScanOperation::readTuples(NdbScanOperation::LockMode lm, req->transId1 = (Uint32) transId; req->transId2 = (Uint32) (transId >> 32); - getFirstATTRINFOScan(); + NdbApiSignal* tSignal = + theFirstKEYINFO; + theFirstKEYINFO = (tSignal ? tSignal : tSignal = theNdb->getSignal()); + theLastKEYINFO = tSignal; + + tSignal->setSignal(GSN_KEYINFO); + theKEYINFOptr = ((KeyInfo*)tSignal->getDataPtrSend())->keyData; + theTotalNrOfKeyWordInSignal= 0; + + getFirstATTRINFOScan(); return getResultSet(); } @@ -256,18 +265,7 @@ NdbScanOperation::fix_receivers(Uint32 parallel){ m_allocated_receivers = parallel; } - for(Uint32 i = 0; i<parallel; i++){ - m_receivers[i]->m_list_index = i; - m_prepared_receivers[i] = m_receivers[i]->getId(); - m_sent_receivers[i] = m_receivers[i]; - m_conf_receivers[i] = 0; - m_api_receivers[i] = 0; - } - - m_api_receivers_count = 0; - m_current_api_receiver = 0; - m_sent_receivers_count = parallel; - m_conf_receivers_count = 0; + reset_receivers(parallel, 0); return 0; } @@ -355,6 +353,7 @@ NdbScanOperation::getFirstATTRINFOScan() * After setBound() are done, move the accumulated ATTRINFO signals to * a separate list. Then continue with normal scan. */ +#if 0 int NdbIndexScanOperation::saveBoundATTRINFO() { @@ -401,6 +400,7 @@ NdbIndexScanOperation::saveBoundATTRINFO() } return res; } +#endif #define WAITFOR_SCAN_TIMEOUT 120000 @@ -409,14 +409,22 @@ NdbScanOperation::executeCursor(int nodeId){ NdbConnection * tCon = theNdbCon; TransporterFacade* tp = TransporterFacade::instance(); Guard guard(tp->theMutexPtr); + + Uint32 magic = tCon->theMagicNumber; Uint32 seq = tCon->theNodeSequence; + if (tp->get_node_alive(nodeId) && (tp->getNodeSequence(nodeId) == seq)) { - - if(prepareSendScan(tCon->theTCConPtr, tCon->theTransactionId) == -1) - return -1; + /** + * Only call prepareSendScan first time (incase of restarts) + * - check with theMagicNumber + */ tCon->theMagicNumber = 0x37412619; + if(magic != 0x37412619 && + prepareSendScan(tCon->theTCConPtr, tCon->theTransactionId) == -1) + return -1; + if (doSendScan(nodeId) == -1) return -1; @@ -428,7 +436,6 @@ NdbScanOperation::executeCursor(int nodeId){ TRACE_DEBUG("The node is hard dead when attempting to start a scan"); setErrorCode(4029); tCon->theReleaseOnClose = true; - abort(); } else { TRACE_DEBUG("The node is stopping when attempting to start a scan"); setErrorCode(4030); @@ -559,6 +566,8 @@ int NdbScanOperation::nextResult(bool fetchAllowed) setErrorCode(4028); // Node fail break; case -3: // send_next_scan -> return fail (set error-code self) + if(theError.code == 0) + setErrorCode(4028); // seq changed = Node fail break; } @@ -635,7 +644,7 @@ NdbScanOperation::doSend(int ProcessorId) void NdbScanOperation::closeScan() { - if(m_transConnection) do { + if(m_transConnection){ if(DEBUG_NEXT_RESULT) ndbout_c("closeScan() theError.code = %d " "m_api_receivers_count = %d " @@ -648,55 +657,8 @@ void NdbScanOperation::closeScan() TransporterFacade* tp = TransporterFacade::instance(); Guard guard(tp->theMutexPtr); - - Uint32 seq = theNdbCon->theNodeSequence; - Uint32 nodeId = theNdbCon->theDBnode; - - if(seq != tp->getNodeSequence(nodeId)){ - theNdbCon->theReleaseOnClose = true; - break; - } - - while(theError.code == 0 && m_sent_receivers_count){ - theNdb->theWaiter.m_node = nodeId; - theNdb->theWaiter.m_state = WAIT_SCAN; - int return_code = theNdb->receiveResponse(WAITFOR_SCAN_TIMEOUT); - switch(return_code){ - case 0: - break; - case -1: - setErrorCode(4008); - case -2: - m_api_receivers_count = 0; - m_conf_receivers_count = 0; - m_sent_receivers_count = 0; - theNdbCon->theReleaseOnClose = true; - } - } - - if(m_api_receivers_count+m_conf_receivers_count){ - // Send close scan - send_next_scan(0, true); // Close scan - } + close_impl(tp); - /** - * wait for close scan conf - */ - while(m_sent_receivers_count+m_api_receivers_count+m_conf_receivers_count){ - theNdb->theWaiter.m_node = nodeId; - theNdb->theWaiter.m_state = WAIT_SCAN; - int return_code = theNdb->receiveResponse(WAITFOR_SCAN_TIMEOUT); - switch(return_code){ - case 0: - break; - case -1: - setErrorCode(4008); - case -2: - m_api_receivers_count = 0; - m_conf_receivers_count = 0; - m_sent_receivers_count = 0; - } - } } while(0); theNdbCon->theScanningOp = 0; @@ -750,11 +712,6 @@ int NdbScanOperation::prepareSendScan(Uint32 aTC_ConnectPtr, return -1; } - if (theStatus == SetBound) { - ((NdbIndexScanOperation*)this)->saveBoundATTRINFO(); - theStatus = GetValue; - } - theErrorLine = 0; // In preapareSendInterpreted we set the sizes (word 4-8) in the @@ -766,26 +723,7 @@ int NdbScanOperation::prepareSendScan(Uint32 aTC_ConnectPtr, ((NdbIndexScanOperation*)this)->fix_get_values(); } - const Uint32 transId1 = (Uint32) (aTransactionId & 0xFFFFFFFF); - const Uint32 transId2 = (Uint32) (aTransactionId >> 32); - - if (theOperationType == OpenRangeScanRequest) { - NdbApiSignal* tSignal = theBoundATTRINFO; - do{ - tSignal->setData(aTC_ConnectPtr, 1); - tSignal->setData(transId1, 2); - tSignal->setData(transId2, 3); - tSignal = tSignal->next(); - } while (tSignal != NULL); - } theCurrentATTRINFO->setLength(theAI_LenInCurrAI); - NdbApiSignal* tSignal = theFirstATTRINFO; - do{ - tSignal->setData(aTC_ConnectPtr, 1); - tSignal->setData(transId1, 2); - tSignal->setData(transId2, 3); - tSignal = tSignal->next(); - } while (tSignal != NULL); /** * Prepare all receivers @@ -808,20 +746,28 @@ int NdbScanOperation::prepareSendScan(Uint32 aTC_ConnectPtr, req->batch_byte_size= batch_byte_size; req->first_batch_size= first_batch_size; + /** + * Set keyinfo flag + * (Always keyinfo when using blobs) + */ + Uint32 reqInfo = req->requestInfo; + ScanTabReq::setKeyinfoFlag(reqInfo, keyInfo); + req->requestInfo = reqInfo; + for(Uint32 i = 0; i<theParallelism; i++){ m_receivers[i]->do_get_value(&theReceiver, batch_size, key_size); } return 0; } -/****************************************************************************** +/***************************************************************************** int doSend() Return Value: Return >0 : send was succesful, returns number of signals sent Return -1: In all other case. Parameters: aProcessorId: Receiving processor node Remark: Sends the ATTRINFO signal(s) -******************************************************************************/ +*****************************************************************************/ int NdbScanOperation::doSendScan(int aProcessorId) { @@ -841,13 +787,18 @@ NdbScanOperation::doSendScan(int aProcessorId) setErrorCode(4001); return -1; } + + Uint32 tupKeyLen = theTupKeyLen; + Uint32 len = theTotalNrOfKeyWordInSignal; + Uint32 aTC_ConnectPtr = theNdbCon->theTCConPtr; + Uint64 transId = theNdbCon->theTransactionId; + // Update the "attribute info length in words" in SCAN_TABREQ before // sending it. This could not be done in openScan because // we created the ATTRINFO signals after the SCAN_TABREQ signal. ScanTabReq * const req = CAST_PTR(ScanTabReq, tSignal->getDataPtrSend()); - req->attrLen = theTotalCurrAI_Len; - if (theOperationType == OpenRangeScanRequest) - req->attrLen += theTotalBoundAI_Len; + req->attrLenKeyLen = (tupKeyLen << 16) | theTotalCurrAI_Len; + TransporterFacade *tp = TransporterFacade::instance(); LinearSectionPtr ptr[3]; ptr[0].p = m_prepared_receivers; @@ -856,22 +807,41 @@ NdbScanOperation::doSendScan(int aProcessorId) setErrorCode(4002); return -1; } - if (theOperationType == OpenRangeScanRequest) { + + if (tupKeyLen > 0){ // must have at least one signal since it contains attrLen for bounds - assert(theBoundATTRINFO != NULL); - tSignal = theBoundATTRINFO; - while (tSignal != NULL) { + assert(theLastKEYINFO != NULL); + tSignal = theLastKEYINFO; + tSignal->setLength(KeyInfo::HeaderLength + theTotalNrOfKeyWordInSignal); + + assert(theFirstKEYINFO != NULL); + tSignal = theFirstKEYINFO; + + NdbApiSignal* last; + do { + KeyInfo * keyInfo = CAST_PTR(KeyInfo, tSignal->getDataPtrSend()); + keyInfo->connectPtr = aTC_ConnectPtr; + keyInfo->transId[0] = Uint32(transId); + keyInfo->transId[1] = Uint32(transId >> 32); + if (tp->sendSignal(tSignal,aProcessorId) == -1){ - setErrorCode(4002); - return -1; + setErrorCode(4002); + return -1; } + tSignalCount++; + last = tSignal; tSignal = tSignal->next(); - } + } while(last != theLastKEYINFO); } tSignal = theFirstATTRINFO; while (tSignal != NULL) { + AttrInfo * attrInfo = CAST_PTR(AttrInfo, tSignal->getDataPtrSend()); + attrInfo->connectPtr = aTC_ConnectPtr; + attrInfo->transId[0] = Uint32(transId); + attrInfo->transId[1] = Uint32(transId >> 32); + if (tp->sendSignal(tSignal,aProcessorId) == -1){ setErrorCode(4002); return -1; @@ -883,7 +853,7 @@ NdbScanOperation::doSendScan(int aProcessorId) return tSignalCount; }//NdbOperation::doSendScan() -/****************************************************************************** +/***************************************************************************** * NdbOperation* takeOverScanOp(NdbConnection* updateTrans); * * Parameters: The update transactions NdbConnection pointer. @@ -902,7 +872,7 @@ NdbScanOperation::doSendScan(int aProcessorId) * This means that the updating transactions can be placed * in separate threads and thus increasing the parallelism during * the scan process. - *****************************************************************************/ + ****************************************************************************/ int NdbScanOperation::getKeyFromKEYINFO20(Uint32* data, unsigned size) { @@ -940,6 +910,7 @@ NdbScanOperation::takeOverScanOp(OperationType opType, NdbConnection* pTrans){ if (newOp == NULL){ return NULL; } + pTrans->theSimpleState = 0; const Uint32 len = (tRecAttr->attrSize() * tRecAttr->arraySize() + 3)/4-1; @@ -1011,6 +982,7 @@ NdbScanOperation::takeOverScanOp(OperationType opType, NdbConnection* pTrans){ NdbBlob* NdbScanOperation::getBlobHandle(const char* anAttrName) { + m_keyInfo = 1; return NdbOperation::getBlobHandle(m_transConnection, m_currentTable->getColumn(anAttrName)); } @@ -1018,6 +990,7 @@ NdbScanOperation::getBlobHandle(const char* anAttrName) NdbBlob* NdbScanOperation::getBlobHandle(Uint32 anAttrId) { + m_keyInfo = 1; return NdbOperation::getBlobHandle(m_transConnection, m_currentTable->getColumn(anAttrId)); } @@ -1031,13 +1004,15 @@ NdbIndexScanOperation::~NdbIndexScanOperation(){ } int -NdbIndexScanOperation::setBound(const char* anAttrName, int type, const void* aValue, Uint32 len) +NdbIndexScanOperation::setBound(const char* anAttrName, int type, + const void* aValue, Uint32 len) { return setBound(m_accessTable->getColumn(anAttrName), type, aValue, len); } int -NdbIndexScanOperation::setBound(Uint32 anAttrId, int type, const void* aValue, Uint32 len) +NdbIndexScanOperation::setBound(Uint32 anAttrId, int type, + const void* aValue, Uint32 len) { return setBound(m_accessTable->getColumn(anAttrId), type, aValue, len); } @@ -1056,11 +1031,6 @@ NdbIndexScanOperation::getValue_impl(const NdbColumnImpl* attrInfo, return NdbScanOperation::getValue_impl(attrInfo, aValue); } - if (theStatus == SetBound) { - saveBoundATTRINFO(); - theStatus = GetValue; - } - int id = attrInfo->m_attrId; // In "real" table assert(m_accessTable->m_index); int sz = (int)m_accessTable->m_index->m_key_ids.size(); @@ -1101,12 +1071,13 @@ NdbIndexScanOperation::setBound(const NdbColumnImpl* tAttrInfo, int type, const void* aValue, Uint32 len) { if (theOperationType == OpenRangeScanRequest && - theStatus == SetBound && (0 <= type && type <= 4) && len <= 8000) { // insert bound type - insertATTRINFO(type); + Uint32 currLen = theTotalNrOfKeyWordInSignal; + Uint32 remaining = KeyInfo::DataLength - currLen; Uint32 sizeInBytes = tAttrInfo->m_attrSize * tAttrInfo->m_arraySize; + // normalize char bound CHARSET_INFO* cs = tAttrInfo->m_cs; Uint32 xfrmData[2000]; @@ -1130,19 +1101,34 @@ NdbIndexScanOperation::setBound(const NdbColumnImpl* tAttrInfo, Uint32 tIndexAttrId = tAttrInfo->m_attrId; Uint32 sizeInWords = (len + 3) / 4; AttributeHeader ah(tIndexAttrId, sizeInWords); - insertATTRINFO(ah.m_value); - if (len != 0) { - // insert attribute data - if ((UintPtr(aValue) & 0x3) == 0 && (len & 0x3) == 0) - insertATTRINFOloop((const Uint32*)aValue, sizeInWords); - else { - Uint32 tempData[2000]; - memcpy(tempData, aValue, len); + const Uint32 ahValue = ah.m_value; + + const bool aligned = (UintPtr(aValue) & 3) == 0; + const bool nobytes = (len & 0x3) == 0; + const Uint32 totalLen = 2 + sizeInWords; + Uint32 tupKeyLen = theTupKeyLen; + if(remaining > totalLen && aligned && nobytes){ + Uint32 * dst = theKEYINFOptr + currLen; + * dst ++ = type; + * dst ++ = ahValue; + memcpy(dst, aValue, 4 * sizeInWords); + theTotalNrOfKeyWordInSignal = currLen + totalLen; + } else { + if(!aligned || !nobytes){ + Uint32 tempData[2002]; + tempData[0] = type; + tempData[1] = ahValue; + memcpy(tempData+2, aValue, len); while ((len & 0x3) != 0) - ((char*)tempData)[len++] = 0; - insertATTRINFOloop(tempData, sizeInWords); + ((char*)&tempData[2])[len++] = 0; + insertBOUNDS(tempData, 2+sizeInWords); + } else { + Uint32 buf[2] = { type, ahValue }; + insertBOUNDS(buf, 2); + insertBOUNDS((Uint32*)aValue, sizeInWords); } } + theTupKeyLen = tupKeyLen + totalLen; /** * Do sorted stuff @@ -1165,6 +1151,46 @@ NdbIndexScanOperation::setBound(const NdbColumnImpl* tAttrInfo, } } +int +NdbIndexScanOperation::insertBOUNDS(Uint32 * data, Uint32 sz){ + Uint32 len; + Uint32 remaining = KeyInfo::DataLength - theTotalNrOfKeyWordInSignal; + Uint32 * dst = theKEYINFOptr + theTotalNrOfKeyWordInSignal; + do { + len = (sz < remaining ? sz : remaining); + memcpy(dst, data, 4 * len); + + if(sz >= remaining){ + NdbApiSignal* tCurr = theLastKEYINFO; + tCurr->setLength(KeyInfo::MaxSignalLength); + NdbApiSignal* tSignal = tCurr->next(); + if(tSignal) + ; + else if((tSignal = theNdb->getSignal()) != 0) + { + tCurr->next(tSignal); + tSignal->setSignal(GSN_KEYINFO); + } else { + goto error; + } + theLastKEYINFO = tSignal; + theKEYINFOptr = dst = ((KeyInfo*)tSignal->getDataPtrSend())->keyData; + remaining = KeyInfo::DataLength; + sz -= len; + data += len; + } else { + len = (KeyInfo::DataLength - remaining) + len; + break; + } + } while(true); + theTotalNrOfKeyWordInSignal = len; + return 0; + +error: + setErrorCodeAbort(4228); // XXX wrong code + return -1; +} + NdbResultSet* NdbIndexScanOperation::readTuples(LockMode lm, Uint32 batch, @@ -1173,9 +1199,23 @@ NdbIndexScanOperation::readTuples(LockMode lm, NdbResultSet * rs = NdbScanOperation::readTuples(lm, batch, 0); if(rs && order_by){ m_ordered = 1; - m_sort_columns = m_accessTable->getNoOfColumns() - 1; // -1 for NDB$NODE + Uint32 cnt = m_accessTable->getNoOfColumns() - 1; + m_sort_columns = cnt; // -1 for NDB$NODE m_current_api_receiver = m_sent_receivers_count; m_api_receivers_count = m_sent_receivers_count; + + m_sort_columns = cnt; + for(Uint32 i = 0; i<cnt; i++){ + 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; + theTupleKeyDefined[i][1] = (newVal & 0xFFFFFFFF); +#if (SIZEOF_CHARP == 8) + theTupleKeyDefined[i][2] = (newVal >> 32); +#endif + } } return rs; } @@ -1396,10 +1436,7 @@ NdbIndexScanOperation::send_next_scan_ordered(Uint32 idx){ } int -NdbScanOperation::restart(){ - TransporterFacade* tp = TransporterFacade::instance(); - Guard guard(tp->theMutexPtr); - +NdbScanOperation::close_impl(TransporterFacade* tp){ Uint32 seq = theNdbCon->theNodeSequence; Uint32 nodeId = theNdbCon->theDBnode; @@ -1407,8 +1444,8 @@ NdbScanOperation::restart(){ theNdbCon->theReleaseOnClose = true; return -1; } - - while(m_sent_receivers_count){ + + while(theError.code == 0 && m_sent_receivers_count){ theNdb->theWaiter.m_node = nodeId; theNdb->theWaiter.m_state = WAIT_SCAN; int return_code = theNdb->receiveResponse(WAITFOR_SCAN_TIMEOUT); @@ -1421,14 +1458,17 @@ NdbScanOperation::restart(){ m_api_receivers_count = 0; m_conf_receivers_count = 0; m_sent_receivers_count = 0; + theNdbCon->theReleaseOnClose = true; return -1; } } if(m_api_receivers_count+m_conf_receivers_count){ // Send close scan - if(send_next_scan(0, true) == -1) // Close scan + if(send_next_scan(0, true) == -1){ // Close scan + theNdbCon->theReleaseOnClose = true; return -1; + } } /** @@ -1447,15 +1487,15 @@ NdbScanOperation::restart(){ m_api_receivers_count = 0; m_conf_receivers_count = 0; m_sent_receivers_count = 0; + theNdbCon->theReleaseOnClose = true; return -1; } } + return 0; +} - /** - * Reset receivers - */ - const Uint32 parallell = theParallelism; - +void +NdbScanOperation::reset_receivers(Uint32 parallell, Uint32 ordered){ for(Uint32 i = 0; i<parallell; i++){ m_receivers[i]->m_list_index = i; m_prepared_receivers[i] = m_receivers[i]->getId(); @@ -1470,13 +1510,64 @@ NdbScanOperation::restart(){ m_sent_receivers_count = parallell; m_conf_receivers_count = 0; - if(m_ordered){ + if(ordered){ m_current_api_receiver = parallell; m_api_receivers_count = parallell; } +} + +int +NdbScanOperation::restart() +{ + + TransporterFacade* tp = TransporterFacade::instance(); + Guard guard(tp->theMutexPtr); + Uint32 nodeId = theNdbCon->theDBnode; + + { + int res; + if((res= close_impl(tp))) + { + return res; + } + } + + /** + * Reset receivers + */ + reset_receivers(theParallelism, m_ordered); + theError.code = 0; if (doSendScan(nodeId) == -1) return -1; return 0; } + +int +NdbIndexScanOperation::reset_bounds(){ + int res; + + { + TransporterFacade* tp = TransporterFacade::instance(); + Guard guard(tp->theMutexPtr); + res= close_impl(tp); + } + + if(!res) + { + theError.code = 0; + reset_receivers(theParallelism, m_ordered); + + theLastKEYINFO = theFirstKEYINFO; + theKEYINFOptr = ((KeyInfo*)theFirstKEYINFO->getDataPtrSend())->keyData; + theTupKeyLen = 0; + theTotalNrOfKeyWordInSignal = 0; + m_transConnection + ->remove_list((NdbOperation*&)m_transConnection->m_firstExecutedScanOp, + this); + m_transConnection->define_scan_op(this); + return 0; + } + return res; +} diff --git a/ndb/src/ndbapi/Ndbif.cpp b/ndb/src/ndbapi/Ndbif.cpp index 5c91467f2e5..c011c1a6a26 100644 --- a/ndb/src/ndbapi/Ndbif.cpp +++ b/ndb/src/ndbapi/Ndbif.cpp @@ -249,6 +249,7 @@ Ndb::report_node_failure(Uint32 node_id) */ the_release_ind[node_id] = 1; theWaiter.nodeFail(node_id); + return; }//Ndb::report_node_failure() @@ -271,9 +272,10 @@ Ndb::abortTransactionsAfterNodeFailure(Uint16 aNodeId) Uint32 tNoSentTransactions = theNoOfSentTransactions; for (int i = tNoSentTransactions - 1; i >= 0; i--) { NdbConnection* localCon = theSentTransactionsArray[i]; - if (localCon->getConnectedNodeId() == aNodeId ) { + if (localCon->getConnectedNodeId() == aNodeId) { const NdbConnection::SendStatusType sendStatus = localCon->theSendStatus; - if (sendStatus == NdbConnection::sendTC_OP || sendStatus == NdbConnection::sendTC_COMMIT) { + if (sendStatus == NdbConnection::sendTC_OP || + sendStatus == NdbConnection::sendTC_COMMIT) { /* A transaction was interrupted in the prepare phase by a node failure. Since the transaction was not found in the phase @@ -293,7 +295,7 @@ Ndb::abortTransactionsAfterNodeFailure(Uint16 aNodeId) printState("abortTransactionsAfterNodeFailure %x", this); abort(); #endif - }// + } /* All transactions arriving here have no connection to the kernel intact since the node was failing and they were aborted. Thus we @@ -302,7 +304,11 @@ Ndb::abortTransactionsAfterNodeFailure(Uint16 aNodeId) localCon->theCommitStatus = NdbConnection::Aborted; localCon->theReleaseOnClose = true; completedTransaction(localCon); - }//if + } + else if(localCon->report_node_failure(aNodeId)) + { + completedTransaction(localCon); + } }//for return; }//Ndb::abortTransactionsAfterNodeFailure() diff --git a/ndb/src/ndbapi/Ndbinit.cpp b/ndb/src/ndbapi/Ndbinit.cpp index 8589158ae6a..b8927f2abba 100644 --- a/ndb/src/ndbapi/Ndbinit.cpp +++ b/ndb/src/ndbapi/Ndbinit.cpp @@ -107,8 +107,6 @@ void Ndb::setup(Ndb_cluster_connection *ndb_cluster_connection, theOpIdleList= NULL; theScanOpIdleList= NULL; theIndexOpIdleList= NULL; -// theSchemaConIdleList= NULL; -// theSchemaConToNdbList= NULL; theTransactionList= NULL; theConnectionArray= NULL; theRecAttrIdleList= NULL; @@ -134,10 +132,13 @@ void Ndb::setup(Ndb_cluster_connection *ndb_cluster_connection, fullyQualifiedNames = true; +#ifdef POORMANSPURIFY cgetSignals =0; cfreeSignals = 0; cnewSignals = 0; creleaseSignals = 0; +#endif + theError.code = 0; theNdbObjectIdMap = new NdbObjectIdMap(1024,1024); @@ -159,12 +160,12 @@ void Ndb::setup(Ndb_cluster_connection *ndb_cluster_connection, theLastTupleId[i] = 0; }//for - snprintf(theDataBase, sizeof(theDataBase), "%s", + BaseString::snprintf(theDataBase, sizeof(theDataBase), "%s", aDataBase ? aDataBase : ""); - snprintf(theDataBaseSchema, sizeof(theDataBaseSchema), "%s", + BaseString::snprintf(theDataBaseSchema, sizeof(theDataBaseSchema), "%s", aSchema ? aSchema : ""); - int len = snprintf(prefixName, sizeof(prefixName), "%s%c%s%c", + int len = BaseString::snprintf(prefixName, sizeof(prefixName), "%s%c%s%c", theDataBase, table_name_separator, theDataBaseSchema, table_name_separator); prefixEnd = prefixName + (len < (int) sizeof(prefixName) ? len : diff --git a/ndb/src/ndbapi/Ndblist.cpp b/ndb/src/ndbapi/Ndblist.cpp index af98aa09280..a5f2a4801d5 100644 --- a/ndb/src/ndbapi/Ndblist.cpp +++ b/ndb/src/ndbapi/Ndblist.cpp @@ -33,7 +33,7 @@ Ndb::checkFailedNode() DBUG_PRINT("enter", ("theNoOfDBnodes: %d", theNoOfDBnodes)); DBUG_ASSERT(theNoOfDBnodes < MAX_NDB_NODES); - for (int i = 0; i < theNoOfDBnodes; i++){ + for (Uint32 i = 0; i < theNoOfDBnodes; i++){ const NodeId node_id = theDBnodes[i]; DBUG_PRINT("info", ("i: %d, node_id: %d", i, node_id)); @@ -432,11 +432,15 @@ Ndb::getSignal() theSignalIdleList = tSignalNext; } else { tSignal = new NdbApiSignal(theMyRef); +#ifdef POORMANSPURIFY cnewSignals++; +#endif if (tSignal != NULL) tSignal->next(NULL); } +#ifdef POORMANSPURIFY cgetSignals++; +#endif return tSignal; } @@ -605,7 +609,9 @@ Ndb::releaseSignal(NdbApiSignal* aSignal) } #endif #endif +#ifdef POORMANSPURIFY creleaseSignals++; +#endif aSignal->next(theSignalIdleList); theSignalIdleList = aSignal; } @@ -649,8 +655,8 @@ Remark: Always release the first item in the free list void Ndb::freeScanOperation() { - NdbScanOperation* tOp = theScanOpIdleList; - theScanOpIdleList = (NdbIndexScanOperation *) theScanOpIdleList->next(); + NdbIndexScanOperation* tOp = theScanOpIdleList; + theScanOpIdleList = (NdbIndexScanOperation *)tOp->next(); delete tOp; } @@ -769,7 +775,9 @@ Ndb::freeSignal() NdbApiSignal* tSignal = theSignalIdleList; theSignalIdleList = tSignal->next(); delete tSignal; +#ifdef POORMANSPURIFY cfreeSignals++; +#endif } void diff --git a/ndb/src/ndbapi/ndberror.c b/ndb/src/ndbapi/ndberror.c index fdfd8a15fb0..20661b89517 100644 --- a/ndb/src/ndbapi/ndberror.c +++ b/ndb/src/ndbapi/ndberror.c @@ -16,7 +16,6 @@ #include <ndb_global.h> - #include <ndberror.h> typedef struct ErrorBundle { @@ -92,9 +91,10 @@ ErrorBundle ErrorCodes[] = { { 4031, NR, "Node failure caused abort of transaction" }, { 4033, NR, "Send to NDB failed" }, { 4115, NR, - "Transaction was committed but all read information was not " - "received due to node crash" }, - + "Transaction was committed but all read information was not " + "received due to node crash" }, + { 4119, NR, "Simple/dirty read failed due to node failure" }, + /** * Node shutdown */ @@ -171,7 +171,7 @@ ErrorBundle ErrorCodes[] = { { 677, OL, "Index UNDO buffers overloaded" }, { 891, OL, "Data UNDO buffers overloaded" }, { 1221, OL, "REDO log buffers overloaded" }, - { 4006, AE, "Connect failure - out of connection objects" }, + { 4006, OL, "Connect failure - out of connection objects" }, @@ -491,6 +491,7 @@ static const int NbClassification = sizeof(StatusClassificationMapping)/sizeof(ErrorStatusClassification); +#ifdef NOT_USED /** * Complete all fields of an NdbError given the error code * and details @@ -506,7 +507,7 @@ set(ndberror_struct * error, int code, const char * details, ...){ va_end(ap); } } - +#endif void ndberror_update(ndberror_struct * error){ @@ -592,8 +593,10 @@ int ndb_error_string(int err_no, char *str, unsigned int size) error.code = err_no; ndberror_update(&error); - len = snprintf(str, size-1, "%s: %s: %s", error.message, - ndberror_status_message(error.status), ndberror_classification_message(error.classification)); + len = + snprintf(str, size-1, "%s: %s: %s", error.message, + ndberror_status_message(error.status), + ndberror_classification_message(error.classification)); str[size-1]= '\0'; return len; diff --git a/ndb/test/include/HugoOperations.hpp b/ndb/test/include/HugoOperations.hpp index 6bd8f7204b2..fe22e4b5649 100644 --- a/ndb/test/include/HugoOperations.hpp +++ b/ndb/test/include/HugoOperations.hpp @@ -38,16 +38,8 @@ public: int pkReadRecord(Ndb*, int recordNo, - bool exclusive = false, - int numRecords = 1); - - int pkSimpleReadRecord(Ndb*, - int recordNo, - int numRecords = 1); - - int pkDirtyReadRecord(Ndb*, - int recordNo, - int numRecords = 1); + int numRecords = 1, + NdbOperation::LockMode lm = NdbOperation::LM_Read); int pkUpdateRecord(Ndb*, int recordNo, diff --git a/ndb/test/include/HugoTransactions.hpp b/ndb/test/include/HugoTransactions.hpp index 280d9490f15..19e4cb43336 100644 --- a/ndb/test/include/HugoTransactions.hpp +++ b/ndb/test/include/HugoTransactions.hpp @@ -48,8 +48,8 @@ public: int pkReadRecords(Ndb*, int records, int batchsize = 1, - bool dirty = false); - + NdbOperation::LockMode = NdbOperation::LM_Read); + int scanUpdateRecords(Ndb*, int records, int abort = 0, diff --git a/ndb/test/include/NDBT_ResultRow.hpp b/ndb/test/include/NDBT_ResultRow.hpp index aa54e892da3..6072d0ea510 100644 --- a/ndb/test/include/NDBT_ResultRow.hpp +++ b/ndb/test/include/NDBT_ResultRow.hpp @@ -24,8 +24,9 @@ public: NDBT_ResultRow(const NdbDictionary::Table &tab, char attrib_delimiter='\t'); ~NDBT_ResultRow(); NdbRecAttr * & attributeStore(int i); - const NdbRecAttr * attributeStore(const char* name); - + const NdbRecAttr * attributeStore(int i) const ; + const NdbRecAttr * attributeStore(const char* name) const ; + BaseString c_str(); NdbOut & header (NdbOut &) const; diff --git a/ndb/test/include/NDBT_Test.hpp b/ndb/test/include/NDBT_Test.hpp index 6a968c491ae..b0b5fe15960 100644 --- a/ndb/test/include/NDBT_Test.hpp +++ b/ndb/test/include/NDBT_Test.hpp @@ -82,6 +82,12 @@ public: */ int getNoOfRunningSteps() const ; int getNoOfCompletedSteps() const ; + + /** + * Thread sync + */ + void sync_down(const char * key); + void sync_up_and_wait(const char * key, Uint32 count = 0); private: friend class NDBT_Step; friend class NDBT_TestSuite; @@ -245,7 +251,7 @@ public: // Convert to Uint32 in order to be able to print it to screen Uint32 lapTime = (Uint32)m_ticks; Uint32 secTime = lapTime/1000; - snprintf(buf, 255, "%d secs (%d ms)", secTime, lapTime); + BaseString::snprintf(buf, 255, "%d secs (%d ms)", secTime, lapTime); return buf; } private: diff --git a/ndb/test/include/UtilTransactions.hpp b/ndb/test/include/UtilTransactions.hpp index 1298028d591..37cd99550a5 100644 --- a/ndb/test/include/UtilTransactions.hpp +++ b/ndb/test/include/UtilTransactions.hpp @@ -87,19 +87,30 @@ private: int verifyUniqueIndex(Ndb*, - const char* indexName, + const NdbDictionary::Index *, int parallelism = 0, bool transactional = false); - + int scanAndCompareUniqueIndex(Ndb* pNdb, - const char * indexName, + const NdbDictionary::Index *, int parallelism, bool transactional); int readRowFromTableAndIndex(Ndb* pNdb, NdbConnection* pTrans, - const char * indexName, + const NdbDictionary::Index *, NDBT_ResultRow& row ); + + int verifyOrderedIndex(Ndb*, + const NdbDictionary::Index *, + int parallelism = 0, + bool transactional = false); + + + int get_values(NdbOperation* op, NDBT_ResultRow& dst); + int equal(const NdbDictionary::Table*, NdbOperation*, const NDBT_ResultRow&); + int equal(const NdbDictionary::Index*, NdbOperation*, const NDBT_ResultRow&); + protected: int m_defaultClearMethod; const NdbDictionary::Table& tab; diff --git a/ndb/test/ndbapi/asyncGenerator.cpp b/ndb/test/ndbapi/asyncGenerator.cpp index 84a93414712..d91e38dff1a 100644 --- a/ndb/test/ndbapi/asyncGenerator.cpp +++ b/ndb/test/ndbapi/asyncGenerator.cpp @@ -248,7 +248,7 @@ doTransaction_T1(Ndb * pNDB, ThreadData * td, int async) /*----------------*/ getRandomSubscriberNumber(td->transactionData.number); getRandomChangedBy(td->transactionData.changed_by); - snprintf(td->transactionData.changed_time, + BaseString::snprintf(td->transactionData.changed_time, sizeof(td->transactionData.changed_time), "%ld - %d", td->changedTime++, myRandom48(65536*1024)); //getRandomChangedTime(td->transactionData.changed_time); diff --git a/ndb/test/ndbapi/bulk_copy.cpp b/ndb/test/ndbapi/bulk_copy.cpp index 8821a92fb27..b53654ce0fb 100644 --- a/ndb/test/ndbapi/bulk_copy.cpp +++ b/ndb/test/ndbapi/bulk_copy.cpp @@ -263,7 +263,7 @@ int main(int argc, const char** argv){ } char buf[255]; - snprintf(buf, sizeof(buf), "%s.data", (const char*)_tabname); + BaseString::snprintf(buf, sizeof(buf), "%s.data", (const char*)_tabname); if (insertFile(&MyNdb, pTab, buf) != 0){ return NDBT_ProgramExit(NDBT_FAILED); } diff --git a/ndb/test/ndbapi/cdrserver.cpp b/ndb/test/ndbapi/cdrserver.cpp index 8d15061e94b..976319034bf 100644 --- a/ndb/test/ndbapi/cdrserver.cpp +++ b/ndb/test/ndbapi/cdrserver.cpp @@ -501,11 +501,11 @@ server(long int servernum) /* that this program could easily be ported to a host */ /* that does require it. */ - snprintf(msg,sizeof(msg),"Startup from %s port %u",hostname,ntohs(peeraddr_in.sin_port)); + BaseString::snprintf(msg,sizeof(msg),"Startup from %s port %u",hostname,ntohs(peeraddr_in.sin_port)); if ((checkchangelog(fi,temp))==0) c2log(fi,msg); n2log(log,msg); - snprintf(msg,sizeof(msg),"For further information, see log(%s)",lognamn); + BaseString::snprintf(msg,sizeof(msg),"For further information, see log(%s)",lognamn); if ((checkchangelog(fi,temp))==0) c2log(fi,msg); @@ -516,7 +516,7 @@ server(long int servernum) linger.l_onoff =1; linger.l_linger =0; if (setsockopt(s, SOL_SOCKET, SO_LINGER,(const char*)&linger,sizeof(linger)) == -1) { - snprintf(msg,sizeof(msg),"Setting SO_LINGER, l_onoff=%d, l_linger=%d",linger.l_onoff,linger.l_linger); + BaseString::snprintf(msg,sizeof(msg),"Setting SO_LINGER, l_onoff=%d, l_linger=%d",linger.l_onoff,linger.l_linger); if ((checkchangelog(log,lognamn))==0) n2log(log,msg); goto errout; @@ -529,7 +529,7 @@ server(long int servernum) rcvbuf_size=64*1024; if (setsockopt(s, SOL_SOCKET, SO_RCVBUF,(const char*) &rcvbuf_size,sizeof(rcvbuf_size)) == -1) { - snprintf(msg,sizeof(msg),"Setting SO_RCVBUF = %d",rcvbuf_size); + BaseString::snprintf(msg,sizeof(msg),"Setting SO_RCVBUF = %d",rcvbuf_size); if ((checkchangelog(log,lognamn))==0) n2log(log,msg); goto errout; @@ -913,7 +913,7 @@ server(long int servernum) tmpcdrptr->USED_FIELDS |= B_ReroutingIndicator; break; default : - snprintf(msg,sizeof(msg),"ERROR: Redirection information has wrong length %d\n",parmlen); + BaseString::snprintf(msg,sizeof(msg),"ERROR: Redirection information has wrong length %d\n",parmlen); if ((checkchangelog(log,lognamn))==0) n2log(log,msg); break; @@ -1060,7 +1060,7 @@ server(long int servernum) tmpcdrptr->USED_FIELDS |= B_RINParameter; break; default : - snprintf(msg,sizeof(msg),"ERROR: Rin parameter has wrong length %d\n",parmlen); + BaseString::snprintf(msg,sizeof(msg),"ERROR: Rin parameter has wrong length %d\n",parmlen); if ((checkchangelog(log,lognamn))==0) n2log(log,msg); break; @@ -1088,7 +1088,7 @@ server(long int servernum) tmpcdrptr->USED_FIELDS |= B_OriginatingPointCode; break; default : - snprintf(msg,sizeof(msg),"ERROR: OriginatingPointCode parameter has wrong length %d\n",parmlen); + BaseString::snprintf(msg,sizeof(msg),"ERROR: OriginatingPointCode parameter has wrong length %d\n",parmlen); if ((checkchangelog(log,lognamn))==0) n2log(log,msg); break; @@ -1119,7 +1119,7 @@ server(long int servernum) tmpcdrptr->USED_FIELDS |= B_DestinationPointCode; break; default : - snprintf(msg,sizeof(msg),"ERROR: DestinationPointCode parameter has wrong length %d\n",parmlen); + BaseString::snprintf(msg,sizeof(msg),"ERROR: DestinationPointCode parameter has wrong length %d\n",parmlen); if ((checkchangelog(log,lognamn))==0) n2log(log,msg); break; @@ -1146,7 +1146,7 @@ server(long int servernum) break; default: printf("ERROR: Undefined parmtype %d , previous %d, length %d\n",parmtype,parmtype_prev,parmlen); - snprintf(msg,sizeof(msg),"ERROR: Undefined parmtype %d , previous %d, length %d\n",parmtype,parmtype_prev,parmlen); + BaseString::snprintf(msg,sizeof(msg),"ERROR: Undefined parmtype %d , previous %d, length %d\n",parmtype,parmtype_prev,parmlen); if ((checkchangelog(log,lognamn))==0) n2log(log,msg); if (parmlen == 0) { @@ -1289,17 +1289,17 @@ server(long int servernum) /* that this program could easily be ported to a host */ /* that does require it. */ - snprintf(msg,sizeof(msg),"Completed %s port %u, %d requests",hostname,ntohs(peeraddr_in.sin_port), reqcnt); + BaseString::snprintf(msg,sizeof(msg),"Completed %s port %u, %d requests",hostname,ntohs(peeraddr_in.sin_port), reqcnt); if ((checkchangelog(fi,temp))==0) c2log(fi,msg); error_from_client = 1; - snprintf(msg,sizeof(msg),"Communicate with threads"); + BaseString::snprintf(msg,sizeof(msg),"Communicate with threads"); if ((checkchangelog(log,lognamn))==0) n2log(log,msg); - snprintf(msg,sizeof(msg),"Waiting for threads to return from work"); + BaseString::snprintf(msg,sizeof(msg),"Waiting for threads to return from work"); if ((checkchangelog(log,lognamn))==0) n2log(log,msg); - snprintf(msg,sizeof(msg),"Closing down"); + BaseString::snprintf(msg,sizeof(msg),"Closing down"); if ((checkchangelog(log,lognamn))==0) n2log(log,msg); close(s); @@ -1307,19 +1307,19 @@ server(long int servernum) return EXIT_SUCCESS; errout: - snprintf(msg,sizeof(msg),"Connection with %s aborted on error\n", hostname); + BaseString::snprintf(msg,sizeof(msg),"Connection with %s aborted on error\n", hostname); if ((checkchangelog(log,lognamn))==0) n2log(log,msg); if ((checkchangelog(fi,temp))==0) c2log(fi,msg); error_from_client = 1; - snprintf(msg,sizeof(msg),"Communicate with threads"); + BaseString::snprintf(msg,sizeof(msg),"Communicate with threads"); if ((checkchangelog(log,lognamn))==0) n2log(log,msg); - snprintf(msg,sizeof(msg),"Waiting for threads to return from work"); + BaseString::snprintf(msg,sizeof(msg),"Waiting for threads to return from work"); if ((checkchangelog(log,lognamn))==0) n2log(log,msg); - snprintf(msg,sizeof(msg),"Closing down"); + BaseString::snprintf(msg,sizeof(msg),"Closing down"); if ((checkchangelog(log,lognamn))==0) n2log(log,msg); close(s); diff --git a/ndb/test/ndbapi/flexAsynch.cpp b/ndb/test/ndbapi/flexAsynch.cpp index 8c0ba46130c..1953444d640 100644 --- a/ndb/test/ndbapi/flexAsynch.cpp +++ b/ndb/test/ndbapi/flexAsynch.cpp @@ -710,7 +710,7 @@ static void setAttrNames() int i; for (i = 0; i < MAXATTR ; i++){ - snprintf(attrName[i], MAXSTRLEN, "COL%d", i); + BaseString::snprintf(attrName[i], MAXSTRLEN, "COL%d", i); } } @@ -722,10 +722,10 @@ static void setTableNames() int i; for (i = 0; i < MAXTABLES ; i++){ if (theStdTableNameFlag==0){ - snprintf(tableName[i], MAXSTRLEN, "TAB%d_%d", i, + BaseString::snprintf(tableName[i], MAXSTRLEN, "TAB%d_%d", i, (int)(NdbTick_CurrentMillisecond()/1000)); } else { - snprintf(tableName[i], MAXSTRLEN, "TAB%d", i); + BaseString::snprintf(tableName[i], MAXSTRLEN, "TAB%d", i); } } } diff --git a/ndb/test/ndbapi/flexBench.cpp b/ndb/test/ndbapi/flexBench.cpp index b19944498f4..2a2388109a1 100644 --- a/ndb/test/ndbapi/flexBench.cpp +++ b/ndb/test/ndbapi/flexBench.cpp @@ -1032,7 +1032,7 @@ static int readArguments(int argc, const char** argv) const char *q = strrchr(p, ':'); if (q == 0) return -1; - snprintf(statHost, sizeof(statHost), "%.*s", q-p, p); + BaseString::snprintf(statHost, sizeof(statHost), "%.*s", q-p, p); statPort = atoi(q+1); statEnable = true; argc -= 1; @@ -1068,17 +1068,17 @@ static int createTables(Ndb* pMyNdb){ int i; for (i = 0; i < tNoOfAttributes; i++){ - snprintf(attrName[i], MAXSTRLEN, "COL%d", i); + BaseString::snprintf(attrName[i], MAXSTRLEN, "COL%d", i); } // Note! Uses only uppercase letters in table name's // so that we can look at the tables with SQL for (i = 0; i < tNoOfTables; i++){ if (theStdTableNameFlag == 0){ - snprintf(tableName[i], MAXSTRLEN, "TAB%d_%d", i, + BaseString::snprintf(tableName[i], MAXSTRLEN, "TAB%d_%d", i, (int)(NdbTick_CurrentMillisecond() / 1000)); } else { - snprintf(tableName[i], MAXSTRLEN, "TAB%d", i); + BaseString::snprintf(tableName[i], MAXSTRLEN, "TAB%d", i); } } diff --git a/ndb/test/ndbapi/flexHammer.cpp b/ndb/test/ndbapi/flexHammer.cpp index 80cc7c5a53f..688e70d501a 100644 --- a/ndb/test/ndbapi/flexHammer.cpp +++ b/ndb/test/ndbapi/flexHammer.cpp @@ -840,7 +840,7 @@ static int setAttrNames() int retVal = 0; for (i = 0; i < MAXATTR ; i++) { - retVal = snprintf(attrName[i], MAXSTRLEN, "COL%d", i); + retVal = BaseString::snprintf(attrName[i], MAXSTRLEN, "COL%d", i); if (retVal < 0) { // Error in conversion return(-1); @@ -859,11 +859,11 @@ static int setTableNames() for (i = 0; i < MAXTABLES ; i++) { if (theStandardTableNameFlag == 0) { - retVal = snprintf(tableName[i], MAXSTRLEN, "TAB%d_%d", i, + retVal = BaseString::snprintf(tableName[i], MAXSTRLEN, "TAB%d_%d", i, NdbTick_CurrentMillisecond()/1000); } // if else { - retVal = snprintf(tableName[i], MAXSTRLEN, "TAB%d", i); + retVal = BaseString::snprintf(tableName[i], MAXSTRLEN, "TAB%d", i); } // else if (retVal < 0) { // Error in conversion diff --git a/ndb/test/ndbapi/flexScan.cpp b/ndb/test/ndbapi/flexScan.cpp index b09d71fb010..c7f4041a525 100644 --- a/ndb/test/ndbapi/flexScan.cpp +++ b/ndb/test/ndbapi/flexScan.cpp @@ -713,7 +713,7 @@ static int setAttrNames() int retVal = 0; for (i = 0; i < MAXATTR ; i++) { - retVal = snprintf(attrName[i], MAXSTRLEN, "COL%d", i); + retVal = BaseString::snprintf(attrName[i], MAXSTRLEN, "COL%d", i); if (retVal < 0) { return(-1); } // if @@ -733,11 +733,11 @@ static int setTableNames() for (i = 0; i < MAXTABLES ; i++) { if (theStdTableNameFlag == 0) { - retVal = snprintf(tableName[i], MAXSTRLEN, "TAB%d_%d", i, + retVal = BaseString::snprintf(tableName[i], MAXSTRLEN, "TAB%d_%d", i, (int)(NdbTick_CurrentMillisecond() / 1000)); } // if else { - retVal = snprintf(tableName[i], MAXSTRLEN, "TAB%d", i); + retVal = BaseString::snprintf(tableName[i], MAXSTRLEN, "TAB%d", i); } // if else if (retVal < 0) { diff --git a/ndb/test/ndbapi/flexTT.cpp b/ndb/test/ndbapi/flexTT.cpp index 162fc080218..3b976f9f87e 100644 --- a/ndb/test/ndbapi/flexTT.cpp +++ b/ndb/test/ndbapi/flexTT.cpp @@ -641,17 +641,17 @@ defineOperation(NdbConnection* localNdbConnection, TransNdb* transNdbRef, static void setAttrNames() { - snprintf(attrName[0], MAXSTRLEN, "VPN_ID"); - snprintf(attrName[1], MAXSTRLEN, "VPN_NB"); - snprintf(attrName[2], MAXSTRLEN, "DIRECTORY_NB"); - snprintf(attrName[3], MAXSTRLEN, "LAST_CALL_PARTY"); - snprintf(attrName[4], MAXSTRLEN, "DESCR"); + BaseString::snprintf(attrName[0], MAXSTRLEN, "VPN_ID"); + BaseString::snprintf(attrName[1], MAXSTRLEN, "VPN_NB"); + BaseString::snprintf(attrName[2], MAXSTRLEN, "DIRECTORY_NB"); + BaseString::snprintf(attrName[3], MAXSTRLEN, "LAST_CALL_PARTY"); + BaseString::snprintf(attrName[4], MAXSTRLEN, "DESCR"); } static void setTableNames() { - snprintf(tableName[0], MAXSTRLEN, "VPN_USERS"); + BaseString::snprintf(tableName[0], MAXSTRLEN, "VPN_USERS"); } static diff --git a/ndb/test/ndbapi/flex_bench_mysql.cpp b/ndb/test/ndbapi/flex_bench_mysql.cpp index 8e1fbcd9058..c8d4d85bedf 100644 --- a/ndb/test/ndbapi/flex_bench_mysql.cpp +++ b/ndb/test/ndbapi/flex_bench_mysql.cpp @@ -1552,7 +1552,7 @@ static int readArguments(int argc, const char** argv) const char *q = strrchr(p, ':'); if (q == 0) return -1; - snprintf(statHost, sizeof(statHost), "%.*s", q-p, p); + BaseString::snprintf(statHost, sizeof(statHost), "%.*s", q-p, p); statPort = atoi(q+1); statEnable = true; argc -= 1; @@ -1618,17 +1618,17 @@ static int createTables(MYSQL* mysqlp){ for (Uint32 i = 0; i < tNoOfAttributes; i++){ - snprintf(attrName[i], MAXSTRLEN, "COL%d", i); + BaseString::snprintf(attrName[i], MAXSTRLEN, "COL%d", i); } // Note! Uses only uppercase letters in table name's // so that we can look at the tables with SQL for (Uint32 i = 0; i < tNoOfTables; i++){ if (theStdTableNameFlag == 0){ - snprintf(tableName[i], MAXSTRLEN, "TAB%d_%d", i, + BaseString::snprintf(tableName[i], MAXSTRLEN, "TAB%d_%d", i, (int)(NdbTick_CurrentMillisecond() / 1000)); } else { - snprintf(tableName[i], MAXSTRLEN, "TAB%d", i); + BaseString::snprintf(tableName[i], MAXSTRLEN, "TAB%d", i); } } @@ -1663,17 +1663,17 @@ static int createTables(Ndb* pMyNdb){ for (Uint32 i = 0; i < tNoOfAttributes; i++){ - snprintf(attrName[i], MAXSTRLEN, "COL%d", i); + BaseString::snprintf(attrName[i], MAXSTRLEN, "COL%d", i); } // Note! Uses only uppercase letters in table name's // so that we can look at the tables with SQL for (Uint32 i = 0; i < tNoOfTables; i++){ if (theStdTableNameFlag == 0){ - snprintf(tableName[i], MAXSTRLEN, "TAB%d_%d", i, + BaseString::snprintf(tableName[i], MAXSTRLEN, "TAB%d_%d", i, (int)(NdbTick_CurrentMillisecond() / 1000)); } else { - snprintf(tableName[i], MAXSTRLEN, "TAB%d", i); + BaseString::snprintf(tableName[i], MAXSTRLEN, "TAB%d", i); } } diff --git a/ndb/test/ndbapi/interpreterInTup.cpp b/ndb/test/ndbapi/interpreterInTup.cpp index 20d84e6e96d..a07d5898213 100644 --- a/ndb/test/ndbapi/interpreterInTup.cpp +++ b/ndb/test/ndbapi/interpreterInTup.cpp @@ -1507,12 +1507,12 @@ void delete_rows(Ndb* pMyNdb, int tupleTest, int opType) { inline void setAttrNames(){ for (int i = 0; i < MAXATTR; i++){ - snprintf(attrName[i], MAXSTRLEN, "COL%d", i); + BaseString::snprintf(attrName[i], MAXSTRLEN, "COL%d", i); } } inline void setTableNames(){ - snprintf(tableName, MAXSTRLEN, "TAB1"); + BaseString::snprintf(tableName, MAXSTRLEN, "TAB1"); } diff --git a/ndb/test/ndbapi/testBasic.cpp b/ndb/test/ndbapi/testBasic.cpp index 7d03016b87a..4d64b15ecfa 100644 --- a/ndb/test/ndbapi/testBasic.cpp +++ b/ndb/test/ndbapi/testBasic.cpp @@ -160,8 +160,8 @@ int runPkDirtyRead(NDBT_Context* ctx, NDBT_Step* step){ HugoTransactions hugoTrans(*ctx->getTab()); while (i<loops) { g_info << i << ": "; - if (hugoTrans.pkReadRecords(GETNDB(step), records, - batchSize, dirty) != NDBT_OK){ + if (hugoTrans.pkReadRecords(GETNDB(step), records, batchSize, + NdbOperation::LM_CommittedRead) != NDBT_OK){ g_info << endl; return NDBT_FAILED; } @@ -398,14 +398,14 @@ int runNoCommitSleep(NDBT_Context* ctx, NDBT_Step* step){ for (int i = 2; i < 8; i++){ CHECK(hugoOps.startTransaction(pNdb) == 0); - CHECK(hugoOps.pkReadRecord(pNdb, 1, true) == 0); + CHECK(hugoOps.pkReadRecord(pNdb, 1, 1, NdbOperation::LM_Exclusive) == 0); CHECK(hugoOps.execute_NoCommit(pNdb) == 0); ndbout << i <<": Sleeping for " << sleepTime << " ms" << endl; NdbSleep_MilliSleep(sleepTime); // Dont care about result of these ops - hugoOps.pkReadRecord(pNdb, 1, true); + hugoOps.pkReadRecord(pNdb, 1, 1, NdbOperation::LM_Exclusive); hugoOps.closeTransaction(pNdb); sleepTime = sleepTime *i; @@ -424,16 +424,16 @@ int runCommit626(NDBT_Context* ctx, NDBT_Step* step){ do{ // Commit transaction CHECK(hugoOps.startTransaction(pNdb) == 0); - CHECK(hugoOps.pkReadRecord(pNdb, 1, true) == 0); + CHECK(hugoOps.pkReadRecord(pNdb, 1, 1, NdbOperation::LM_Exclusive) == 0); CHECK(hugoOps.execute_Commit(pNdb) == 626); CHECK(hugoOps.closeTransaction(pNdb) == 0); // Commit transaction // Multiple operations CHECK(hugoOps.startTransaction(pNdb) == 0); - CHECK(hugoOps.pkReadRecord(pNdb, 1, true) == 0); - CHECK(hugoOps.pkReadRecord(pNdb, 2, true) == 0); - CHECK(hugoOps.pkReadRecord(pNdb, 3, true) == 0); + CHECK(hugoOps.pkReadRecord(pNdb, 1, 1, NdbOperation::LM_Exclusive) == 0); + CHECK(hugoOps.pkReadRecord(pNdb, 2, 1, NdbOperation::LM_Exclusive) == 0); + CHECK(hugoOps.pkReadRecord(pNdb, 3, 1, NdbOperation::LM_Exclusive) == 0); CHECK(hugoOps.execute_Commit(pNdb) == 626); }while(false); @@ -467,7 +467,7 @@ int runCommit_TryCommit626(NDBT_Context* ctx, NDBT_Step* step){ do{ // Commit transaction, TryCommit CHECK(hugoOps.startTransaction(pNdb) == 0); - CHECK(hugoOps.pkReadRecord(pNdb, 1, true) == 0); + CHECK(hugoOps.pkReadRecord(pNdb, 1, 1, NdbOperation::LM_Exclusive) == 0); CHECK(hugoOps.execute_Commit(pNdb, TryCommit) == 626); CHECK(hugoOps.closeTransaction(pNdb) == 0); @@ -475,11 +475,11 @@ int runCommit_TryCommit626(NDBT_Context* ctx, NDBT_Step* step){ // Several operations in one transaction // The insert is OK CHECK(hugoOps.startTransaction(pNdb) == 0); - CHECK(hugoOps.pkReadRecord(pNdb, 1, true) == 0); - CHECK(hugoOps.pkReadRecord(pNdb, 2, true) == 0); - CHECK(hugoOps.pkReadRecord(pNdb, 3, true) == 0); + CHECK(hugoOps.pkReadRecord(pNdb, 1, 1, NdbOperation::LM_Exclusive) == 0); + CHECK(hugoOps.pkReadRecord(pNdb, 2, 1, NdbOperation::LM_Exclusive) == 0); + CHECK(hugoOps.pkReadRecord(pNdb, 3, 1, NdbOperation::LM_Exclusive) == 0); CHECK(hugoOps.pkInsertRecord(pNdb, 1) == 0); - CHECK(hugoOps.pkReadRecord(pNdb, 4, true) == 0); + CHECK(hugoOps.pkReadRecord(pNdb, 4, 1, NdbOperation::LM_Exclusive) == 0); CHECK(hugoOps.execute_Commit(pNdb, TryCommit) == 626); }while(false); @@ -513,20 +513,23 @@ int runCommit_CommitAsMuchAsPossible626(NDBT_Context* ctx, NDBT_Step* step){ do{ // Commit transaction, CommitAsMuchAsPossible CHECK(hugoOps.startTransaction(pNdb) == 0); - CHECK(hugoOps.pkReadRecord(pNdb, 1, true) == 0); + CHECK(hugoOps.pkReadRecord(pNdb, 1, 1, NdbOperation::LM_Exclusive) == 0); CHECK(hugoOps.execute_Commit(pNdb, CommitAsMuchAsPossible) == 626); CHECK(hugoOps.closeTransaction(pNdb) == 0); // Commit transaction, CommitAsMuchAsPossible CHECK(hugoOps.startTransaction(pNdb) == 0); - CHECK(hugoOps.pkReadRecord(pNdb, 1, true) == 0); - CHECK(hugoOps.pkReadRecord(pNdb, 2, true) == 0); - CHECK(hugoOps.pkReadRecord(pNdb, 3, true) == 0); + CHECK(hugoOps.pkReadRecord(pNdb, 2, 1, NdbOperation::LM_Exclusive) == 0); + CHECK(hugoOps.pkReadRecord(pNdb, 3, 1, NdbOperation::LM_Exclusive) == 0); CHECK(hugoOps.pkInsertRecord(pNdb, 1) == 0); - CHECK(hugoOps.pkReadRecord(pNdb, 4, true) == 0); CHECK(hugoOps.execute_Commit(pNdb, CommitAsMuchAsPossible) == 626); CHECK(hugoOps.closeTransaction(pNdb) == 0); - }while(false); + + CHECK(hugoOps.startTransaction(pNdb) == 0); + CHECK(hugoOps.pkReadRecord(pNdb, 1) == 0); + CHECK(hugoOps.execute_Commit(pNdb) == 0); + CHECK(hugoOps.closeTransaction(pNdb) == 0); + } while(false); hugoOps.closeTransaction(pNdb); @@ -542,8 +545,14 @@ int runCommit_CommitAsMuchAsPossible630(NDBT_Context* ctx, NDBT_Step* step){ // Commit transaction, CommitAsMuchAsPossible CHECK(hugoOps.startTransaction(pNdb) == 0); CHECK(hugoOps.pkInsertRecord(pNdb, 1) == 0); + CHECK(hugoOps.pkDeleteRecord(pNdb, 2) == 0); CHECK(hugoOps.execute_Commit(pNdb, CommitAsMuchAsPossible) == 630); - }while(false); + CHECK(hugoOps.closeTransaction(pNdb) == 0); + + CHECK(hugoOps.startTransaction(pNdb) == 0); + CHECK(hugoOps.pkReadRecord(pNdb, 2) == 0); + CHECK(hugoOps.execute_Commit(pNdb) == 0); + } while(false); hugoOps.closeTransaction(pNdb); @@ -558,13 +567,13 @@ int runNoCommit626(NDBT_Context* ctx, NDBT_Step* step){ do{ // No commit transaction, readTuple CHECK(hugoOps.startTransaction(pNdb) == 0); - CHECK(hugoOps.pkReadRecord(pNdb, 1, false) == 0); + CHECK(hugoOps.pkReadRecord(pNdb, 1, 1, NdbOperation::LM_Read) == 0); CHECK(hugoOps.execute_NoCommit(pNdb) == 626); CHECK(hugoOps.closeTransaction(pNdb) == 0); // No commit transaction, readTupleExcluive CHECK(hugoOps.startTransaction(pNdb) == 0); - CHECK(hugoOps.pkReadRecord(pNdb, 1, true) == 0); + CHECK(hugoOps.pkReadRecord(pNdb, 1, 1, NdbOperation::LM_Exclusive) == 0); CHECK(hugoOps.execute_NoCommit(pNdb) == 626); }while(false); @@ -598,7 +607,7 @@ int runNoCommitRollback626(NDBT_Context* ctx, NDBT_Step* step){ do{ // No commit transaction, rollback CHECK(hugoOps.startTransaction(pNdb) == 0); - CHECK(hugoOps.pkReadRecord(pNdb, 1, true) == 0); + CHECK(hugoOps.pkReadRecord(pNdb, 1, 1, NdbOperation::LM_Exclusive) == 0); CHECK(hugoOps.execute_NoCommit(pNdb) == 626); CHECK(hugoOps.execute_Rollback(pNdb) == 0); CHECK(hugoOps.closeTransaction(pNdb) == 0); @@ -606,10 +615,10 @@ int runNoCommitRollback626(NDBT_Context* ctx, NDBT_Step* step){ // No commit transaction, rollback // Multiple operations CHECK(hugoOps.startTransaction(pNdb) == 0); - CHECK(hugoOps.pkReadRecord(pNdb, 1, true) == 0); - CHECK(hugoOps.pkReadRecord(pNdb, 2, true) == 0); - CHECK(hugoOps.pkReadRecord(pNdb, 3, true) == 0); - CHECK(hugoOps.pkReadRecord(pNdb, 4, true) == 0); + CHECK(hugoOps.pkReadRecord(pNdb, 1, 1, NdbOperation::LM_Exclusive) == 0); + CHECK(hugoOps.pkReadRecord(pNdb, 2, 1, NdbOperation::LM_Exclusive) == 0); + CHECK(hugoOps.pkReadRecord(pNdb, 3, 1, NdbOperation::LM_Exclusive) == 0); + CHECK(hugoOps.pkReadRecord(pNdb, 4, 1, NdbOperation::LM_Exclusive) == 0); CHECK(hugoOps.execute_NoCommit(pNdb) == 626); CHECK(hugoOps.execute_Rollback(pNdb) == 0); }while(false); @@ -647,7 +656,7 @@ int runNoCommitAndClose(NDBT_Context* ctx, NDBT_Step* step){ // Read CHECK(hugoOps.startTransaction(pNdb) == 0); for (i = 0; i < 10; i++) - CHECK(hugoOps.pkReadRecord(pNdb, i, true) == 0); + CHECK(hugoOps.pkReadRecord(pNdb, i, 1, NdbOperation::LM_Exclusive) == 0); CHECK(hugoOps.execute_NoCommit(pNdb) == 0); CHECK(hugoOps.closeTransaction(pNdb) == 0); @@ -701,7 +710,7 @@ int runCheckRollbackDelete(NDBT_Context* ctx, NDBT_Step* step){ CHECK(hugoOps.execute_NoCommit(pNdb) == 0); // Check record is deleted - CHECK(hugoOps.pkReadRecord(pNdb, 5, true) == 0); + CHECK(hugoOps.pkReadRecord(pNdb, 5, 1, NdbOperation::LM_Exclusive) == 0); CHECK(hugoOps.execute_NoCommit(pNdb) == 626); CHECK(hugoOps.execute_Rollback(pNdb) == 0); @@ -709,13 +718,13 @@ int runCheckRollbackDelete(NDBT_Context* ctx, NDBT_Step* step){ // Check record is not deleted CHECK(hugoOps.startTransaction(pNdb) == 0); - CHECK(hugoOps.pkReadRecord(pNdb, 5, true) == 0); + CHECK(hugoOps.pkReadRecord(pNdb, 5, 1, NdbOperation::LM_Exclusive) == 0); CHECK(hugoOps.execute_Commit(pNdb) == 0); CHECK(hugoOps.closeTransaction(pNdb) == 0); // Check record is back to original value CHECK(hugoOps.startTransaction(pNdb) == 0); - CHECK(hugoOps.pkReadRecord(pNdb, 5, true) == 0); + CHECK(hugoOps.pkReadRecord(pNdb, 5, 1, NdbOperation::LM_Exclusive) == 0); CHECK(hugoOps.execute_Commit(pNdb) == 0); CHECK(hugoOps.compareRecordToCopy() == NDBT_OK); @@ -736,7 +745,7 @@ int runCheckRollbackUpdate(NDBT_Context* ctx, NDBT_Step* step){ // Read value and save it for later CHECK(hugoOps.startTransaction(pNdb) == 0); - CHECK(hugoOps.pkReadRecord(pNdb, 1, false, numRecords) == 0); + CHECK(hugoOps.pkReadRecord(pNdb, 1, numRecords) == 0); CHECK(hugoOps.execute_Commit(pNdb) == 0); CHECK(hugoOps.verifyUpdatesValue(0) == NDBT_OK); // Update value 0 CHECK(hugoOps.closeTransaction(pNdb) == 0); @@ -747,7 +756,7 @@ int runCheckRollbackUpdate(NDBT_Context* ctx, NDBT_Step* step){ CHECK(hugoOps.execute_NoCommit(pNdb) == 0); // Check record is updated - CHECK(hugoOps.pkReadRecord(pNdb, 1, true, numRecords) == 0); + CHECK(hugoOps.pkReadRecord(pNdb, 1, numRecords, NdbOperation::LM_Exclusive) == 0); CHECK(hugoOps.execute_NoCommit(pNdb) == 0); CHECK(hugoOps.verifyUpdatesValue(5) == NDBT_OK); // Updates value 5 CHECK(hugoOps.execute_Rollback(pNdb) == 0); @@ -756,7 +765,7 @@ int runCheckRollbackUpdate(NDBT_Context* ctx, NDBT_Step* step){ // Check record is back to original value CHECK(hugoOps.startTransaction(pNdb) == 0); - CHECK(hugoOps.pkReadRecord(pNdb, 1, true, numRecords) == 0); + CHECK(hugoOps.pkReadRecord(pNdb, 1, numRecords, NdbOperation::LM_Exclusive) == 0); CHECK(hugoOps.execute_Commit(pNdb) == 0); CHECK(hugoOps.verifyUpdatesValue(0) == NDBT_OK); // Updates value 0 @@ -775,7 +784,7 @@ int runCheckRollbackDeleteMultiple(NDBT_Context* ctx, NDBT_Step* step){ do{ // Read value and save it for later CHECK(hugoOps.startTransaction(pNdb) == 0); - CHECK(hugoOps.pkReadRecord(pNdb, 5, false, 10) == 0); + CHECK(hugoOps.pkReadRecord(pNdb, 5, 10) == 0); CHECK(hugoOps.execute_Commit(pNdb) == 0); CHECK(hugoOps.verifyUpdatesValue(0) == NDBT_OK); CHECK(hugoOps.closeTransaction(pNdb) == 0); @@ -785,7 +794,7 @@ int runCheckRollbackDeleteMultiple(NDBT_Context* ctx, NDBT_Step* step){ for(Uint32 i = 0; i<1; i++){ // Read record 5 - 10 CHECK(hugoOps.startTransaction(pNdb) == 0); - CHECK(hugoOps.pkReadRecord(pNdb, 5, true, 10) == 0); + CHECK(hugoOps.pkReadRecord(pNdb, 5, 10, NdbOperation::LM_Exclusive) == 0); CHECK(hugoOps.execute_NoCommit(pNdb) == 0); for(j = 0; j<10; j++){ @@ -794,7 +803,7 @@ int runCheckRollbackDeleteMultiple(NDBT_Context* ctx, NDBT_Step* step){ CHECK(hugoOps.pkUpdateRecord(pNdb, 5, 10, updatesValue) == 0); CHECK(hugoOps.execute_NoCommit(pNdb) == 0); - CHECK(hugoOps.pkReadRecord(pNdb, 5, true, 10) == 0); + CHECK(hugoOps.pkReadRecord(pNdb, 5, 10, NdbOperation::LM_Exclusive) == 0); CHECK(hugoOps.execute_NoCommit(pNdb) == 0); CHECK(hugoOps.verifyUpdatesValue(updatesValue) == 0); } @@ -806,7 +815,7 @@ int runCheckRollbackDeleteMultiple(NDBT_Context* ctx, NDBT_Step* step){ #if 0 // Check records are deleted - CHECK(hugoOps.pkReadRecord(pNdb, 5, true, 10) == 0); + CHECK(hugoOps.pkReadRecord(pNdb, 5, 10, NdbOperation::LM_Exclusive) == 0); CHECK(hugoOps.execute_NoCommit(pNdb) == 626); #endif @@ -814,7 +823,7 @@ int runCheckRollbackDeleteMultiple(NDBT_Context* ctx, NDBT_Step* step){ CHECK(hugoOps.pkInsertRecord(pNdb, 5, 10, updatesValue) == 0); CHECK(hugoOps.execute_NoCommit(pNdb) == 0); - CHECK(hugoOps.pkReadRecord(pNdb, 5, true, 10) == 0); + CHECK(hugoOps.pkReadRecord(pNdb, 5, 10, NdbOperation::LM_Exclusive) == 0); CHECK(hugoOps.execute_NoCommit(pNdb) == 0); CHECK(hugoOps.verifyUpdatesValue(updatesValue) == 0); } @@ -823,7 +832,7 @@ int runCheckRollbackDeleteMultiple(NDBT_Context* ctx, NDBT_Step* step){ CHECK(hugoOps.execute_NoCommit(pNdb) == 0); // Check records are deleted - CHECK(hugoOps.pkReadRecord(pNdb, 5, true, 10) == 0); + CHECK(hugoOps.pkReadRecord(pNdb, 5, 10, NdbOperation::LM_Exclusive) == 0); CHECK(hugoOps.execute_NoCommit(pNdb) == 626); CHECK(hugoOps.execute_Rollback(pNdb) == 0); @@ -833,7 +842,7 @@ int runCheckRollbackDeleteMultiple(NDBT_Context* ctx, NDBT_Step* step){ // Check records are not deleted // after rollback CHECK(hugoOps.startTransaction(pNdb) == 0); - CHECK(hugoOps.pkReadRecord(pNdb, 5, true, 10) == 0); + CHECK(hugoOps.pkReadRecord(pNdb, 5, 10, NdbOperation::LM_Exclusive) == 0); CHECK(hugoOps.execute_Commit(pNdb) == 0); CHECK(hugoOps.verifyUpdatesValue(0) == NDBT_OK); @@ -853,7 +862,7 @@ int runCheckImplicitRollbackDelete(NDBT_Context* ctx, NDBT_Step* step){ do{ // Read record 5 CHECK(hugoOps.startTransaction(pNdb) == 0); - CHECK(hugoOps.pkReadRecord(pNdb, 5, true) == 0); + CHECK(hugoOps.pkReadRecord(pNdb, 5, 1, NdbOperation::LM_Exclusive) == 0); CHECK(hugoOps.execute_NoCommit(pNdb) == 0); CHECK(hugoOps.closeTransaction(pNdb) == 0); @@ -872,7 +881,7 @@ int runCheckImplicitRollbackDelete(NDBT_Context* ctx, NDBT_Step* step){ // Check record is not deleted // Close transaction should have rollbacked CHECK(hugoOps.startTransaction(pNdb) == 0); - CHECK(hugoOps.pkReadRecord(pNdb, 5, true) == 0); + CHECK(hugoOps.pkReadRecord(pNdb, 5, 1, NdbOperation::LM_Exclusive) == 0); CHECK(hugoOps.execute_Commit(pNdb) == 0); }while(false); @@ -889,7 +898,7 @@ int runCheckCommitDelete(NDBT_Context* ctx, NDBT_Step* step){ do{ // Read 10 records CHECK(hugoOps.startTransaction(pNdb) == 0); - CHECK(hugoOps.pkReadRecord(pNdb, 5, true, 10) == 0); + CHECK(hugoOps.pkReadRecord(pNdb, 5, 10, NdbOperation::LM_Exclusive) == 0); CHECK(hugoOps.execute_NoCommit(pNdb) == 0); // Update 10 records @@ -905,7 +914,7 @@ int runCheckCommitDelete(NDBT_Context* ctx, NDBT_Step* step){ // Check record's are deleted CHECK(hugoOps.startTransaction(pNdb) == 0); - CHECK(hugoOps.pkReadRecord(pNdb, 5, true, 10) == 0); + CHECK(hugoOps.pkReadRecord(pNdb, 5, 10, NdbOperation::LM_Exclusive) == 0); CHECK(hugoOps.execute_Commit(pNdb) == 626); }while(false); @@ -930,7 +939,7 @@ int runRollbackNothing(NDBT_Context* ctx, NDBT_Step* step){ // Check records are not deleted CHECK(hugoOps.startTransaction(pNdb) == 0); - CHECK(hugoOps.pkReadRecord(pNdb, 5, true, 10) == 0); + CHECK(hugoOps.pkReadRecord(pNdb, 5, 10, NdbOperation::LM_Exclusive) == 0); CHECK(hugoOps.execute_Commit(pNdb) == 0); CHECK(hugoOps.closeTransaction(pNdb) == 0); @@ -964,8 +973,8 @@ int runMassiveRollback(NDBT_Context* ctx, NDBT_Step* step){ for(int row = 0; row < records; row++){ int res; CHECK(hugoOps.startTransaction(pNdb) == 0); - for(int i = 0; i<OPS_TOTAL; i += OPS_PER_TRANS){ - for(int j = 0; j<OPS_PER_TRANS; j++){ + for(Uint32 i = 0; i<OPS_TOTAL; i += OPS_PER_TRANS){ + for(Uint32 j = 0; j<OPS_PER_TRANS; j++){ CHECK(hugoOps.pkUpdateRecord(pNdb, row, 1, i) == 0); } g_info << "Performed " << (i+OPS_PER_TRANS) << " updates on row: " << row @@ -1007,9 +1016,9 @@ runMassiveRollback2(NDBT_Context* ctx, NDBT_Step* step){ const Uint32 OPS_TOTAL = 4096; const Uint32 LOOPS = 10; - for(int loop = 0; loop<LOOPS; loop++){ + for(Uint32 loop = 0; loop<LOOPS; loop++){ CHECK(hugoOps.startTransaction(pNdb) == 0); - for(int i = 0; i<OPS_TOTAL-1; i ++){ + for(Uint32 i = 0; i<OPS_TOTAL-1; i ++){ if((i & 1) == 0){ CHECK(hugoOps.pkUpdateRecord(pNdb, 0, 1, loop) == 0); } else { @@ -1110,13 +1119,6 @@ TESTCASE("ReadWithLocksAndInserts", STEP(runInsertUntilStopped); FINALIZER(runClearTable); } -TESTCASE("ReadConsistency", - "Check that a read within a transaction returns the " \ - "same result no matter"){ - STEP(runInsertOne); - STEP(runReadOne); - FINALIZER(runClearTable2); -} TESTCASE("PkInsertTwice", "Verify that we can't insert an already inserted record." "Error should be returned" ){ @@ -1124,12 +1126,6 @@ TESTCASE("PkInsertTwice", STEP(runInsertTwice); FINALIZER(runClearTable); } -TESTCASE("Fill", - "Verify what happens when we fill the db" ){ - INITIALIZER(runFillTable); - INITIALIZER(runPkRead); - FINALIZER(runClearTable2); -} TESTCASE("NoCommitSleep", "Verify what happens when a NoCommit transaction is aborted by " "NDB because the application is sleeping" ){ @@ -1275,8 +1271,24 @@ TESTCASE("MassiveTransaction", INITIALIZER(runLoadTable2); FINALIZER(runClearTable2); } +TESTCASE("Fill", + "Verify what happens when we fill the db" ){ + INITIALIZER(runFillTable); + INITIALIZER(runPkRead); + FINALIZER(runClearTable2); +} NDBT_TESTSUITE_END(testBasic); +#if 0 +TESTCASE("ReadConsistency", + "Check that a read within a transaction returns the " \ + "same result no matter"){ + STEP(runInsertOne); + STEP(runReadOne); + FINALIZER(runClearTable2); +} +#endif + int main(int argc, const char** argv){ ndb_init(); return testBasic.execute(argc, argv); diff --git a/ndb/test/ndbapi/testBlobs.cpp b/ndb/test/ndbapi/testBlobs.cpp index e18f4a8bd1a..41bb82f3e06 100644 --- a/ndb/test/ndbapi/testBlobs.cpp +++ b/ndb/test/ndbapi/testBlobs.cpp @@ -1030,7 +1030,7 @@ readScan(int style, bool idx) } else { CHK((g_ops = g_con->getNdbIndexScanOperation(g_opt.m_x2name, g_opt.m_tname)) != 0); } - CHK((rs = g_ops->readTuples(NdbScanOperation::LM_Exclusive)) != 0); + CHK((rs = g_ops->readTuples(NdbScanOperation::LM_Read)) != 0); CHK(g_ops->getValue("PK1", (char*)&tup.m_pk1) != 0); if (g_opt.m_pk2len != 0) CHK(g_ops->getValue("PK2", tup.m_pk2) != 0); diff --git a/ndb/test/ndbapi/testDataBuffers.cpp b/ndb/test/ndbapi/testDataBuffers.cpp index 94658d5c6b9..04602f51d5f 100644 --- a/ndb/test/ndbapi/testDataBuffers.cpp +++ b/ndb/test/ndbapi/testDataBuffers.cpp @@ -93,7 +93,7 @@ ndberror(char const* fmt, ...) va_list ap; char buf[200]; va_start(ap, fmt); - vsnprintf(buf, sizeof(buf), fmt, ap); + BaseString::vsnprintf(buf, sizeof(buf), fmt, ap); va_end(ap); ndbout << buf << " --" << endl; if (ndb) @@ -115,7 +115,7 @@ chkerror(char const* fmt, ...) va_list ap; char buf[200]; va_start(ap, fmt); - vsnprintf(buf, sizeof(buf), fmt, ap); + BaseString::vsnprintf(buf, sizeof(buf), fmt, ap); va_end(ap); ndbout << "*** check failed: " << buf << " ***" << endl; return -1; diff --git a/ndb/test/ndbapi/testDict.cpp b/ndb/test/ndbapi/testDict.cpp index 7cba5ce4cc8..89232de2535 100644 --- a/ndb/test/ndbapi/testDict.cpp +++ b/ndb/test/ndbapi/testDict.cpp @@ -55,7 +55,7 @@ int runCreateInvalidTables(NDBT_Context* ctx, NDBT_Step* step){ char failTabName[256]; for (int i = 0; i < 10; i++){ - snprintf(failTabName, 256, "F%d", i); + BaseString::snprintf(failTabName, 256, "F%d", i); const NdbDictionary::Table* pFailTab = NDBT_Tables::getTable(failTabName); if (pFailTab != NULL){ @@ -425,7 +425,7 @@ int runCreateMaxTables(NDBT_Context* ctx, NDBT_Step* step){ Ndb* pNdb = GETNDB(step); for (int i = 0; i < numTables && failures < 5; i++){ - snprintf(tabName, 256, "MAXTAB%d", i); + BaseString::snprintf(tabName, 256, "MAXTAB%d", i); if (pNdb->waitUntilReady(30) != 0){ // Db is not ready, return with failure @@ -491,7 +491,7 @@ int runDropMaxTables(NDBT_Context* ctx, NDBT_Step* step){ Ndb* pNdb = GETNDB(step); for (int i = 0; i < numTables; i++){ - snprintf(tabName, 256, "MAXTAB%d", i); + BaseString::snprintf(tabName, 256, "MAXTAB%d", i); if (pNdb->waitUntilReady(30) != 0){ // Db is not ready, return with failure @@ -707,7 +707,7 @@ int runPkSizes(NDBT_Context* ctx, NDBT_Step* step){ int numRecords = ctx->getNumRecords(); for (int i = minPkSize; i < maxPkSize; i++){ - snprintf(tabName, 256, "TPK_%d", i); + BaseString::snprintf(tabName, 256, "TPK_%d", i); int records = numRecords; int max = ~0; diff --git a/ndb/test/ndbapi/testIndex.cpp b/ndb/test/ndbapi/testIndex.cpp index bef3b310c96..ed9e114fd92 100644 --- a/ndb/test/ndbapi/testIndex.cpp +++ b/ndb/test/ndbapi/testIndex.cpp @@ -150,7 +150,7 @@ int create_index(NDBT_Context* ctx, int indxNum, } // Create index - snprintf(idxName, 255, "IDC%d", indxNum); + BaseString::snprintf(idxName, 255, "IDC%d", indxNum); if (orderedIndex) ndbout << "Creating " << ((logged)?"logged ": "temporary ") << "ordered index "<<idxName << " ("; else @@ -194,7 +194,7 @@ int drop_index(int indxNum, Ndb* pNdb, if (attr->indexCreated == false) return NDBT_OK; - snprintf(idxName, 255, "IDC%d", indxNum); + BaseString::snprintf(idxName, 255, "IDC%d", indxNum); // Drop index ndbout << "Dropping index "<<idxName<<"(" << pTab->getName() << ") "; @@ -284,7 +284,7 @@ int createRandomIndex_Drop(NDBT_Context* ctx, NDBT_Step* step){ Uint32 i = ctx->getProperty("createRandomIndex"); - snprintf(idxName, 255, "IDC%d", i); + BaseString::snprintf(idxName, 255, "IDC%d", i); // Drop index ndbout << "Dropping index " << idxName << " "; @@ -309,7 +309,7 @@ int createPkIndex(NDBT_Context* ctx, NDBT_Step* step){ bool logged = ctx->getProperty("LoggedIndexes", 1); // Create index - snprintf(pkIdxName, 255, "IDC_PK_%s", pTab->getName()); + BaseString::snprintf(pkIdxName, 255, "IDC_PK_%s", pTab->getName()); if (orderedIndex) ndbout << "Creating " << ((logged)?"logged ": "temporary ") << "ordered index " << pkIdxName << " ("; @@ -381,27 +381,6 @@ runVerifyIndex(NDBT_Context* ctx, NDBT_Step* step){ } int -sync_down(NDBT_Context* ctx){ - Uint32 threads = ctx->getProperty("PauseThreads", (unsigned)0); - if(threads){ - ctx->decProperty("PauseThreads"); - } - return 0; -} - -int -sync_up_and_wait(NDBT_Context* ctx){ - Uint32 threads = ctx->getProperty("Threads", (unsigned)0); - ndbout_c("Setting PauseThreads to %d", threads); - ctx->setProperty("PauseThreads", threads); - ctx->getPropertyWait("PauseThreads", (unsigned)0); - if(threads){ - ndbout_c("wait completed"); - } - return 0; -} - -int runTransactions1(NDBT_Context* ctx, NDBT_Step* step){ // Verify that data in index match // table data @@ -416,7 +395,7 @@ runTransactions1(NDBT_Context* ctx, NDBT_Step* step){ return NDBT_FAILED; } - sync_down(ctx); + ctx->sync_down("PauseThreads"); if(ctx->isTestStopped()) break; @@ -425,7 +404,7 @@ runTransactions1(NDBT_Context* ctx, NDBT_Step* step){ return NDBT_FAILED; } - sync_down(ctx); + ctx->sync_down("PauseThreads"); } return NDBT_OK; } @@ -446,7 +425,7 @@ runTransactions2(NDBT_Context* ctx, NDBT_Step* step){ return NDBT_FAILED; } #endif - sync_down(ctx); + ctx->sync_down("PauseThreads"); if(ctx->isTestStopped()) break; #if 1 @@ -455,7 +434,7 @@ runTransactions2(NDBT_Context* ctx, NDBT_Step* step){ return NDBT_FAILED; } #endif - sync_down(ctx); + ctx->sync_down("PauseThreads"); } return NDBT_OK; } @@ -476,7 +455,7 @@ runTransactions3(NDBT_Context* ctx, NDBT_Step* step){ g_err << "Load table failed" << endl; return NDBT_FAILED; } - sync_down(ctx); + ctx->sync_down("PauseThreads"); if(ctx->isTestStopped()) break; @@ -485,7 +464,7 @@ runTransactions3(NDBT_Context* ctx, NDBT_Step* step){ return NDBT_FAILED; } - sync_down(ctx); + ctx->sync_down("PauseThreads"); if(ctx->isTestStopped()) break; @@ -494,7 +473,7 @@ runTransactions3(NDBT_Context* ctx, NDBT_Step* step){ return NDBT_FAILED; } - sync_down(ctx); + ctx->sync_down("PauseThreads"); if(ctx->isTestStopped()) break; @@ -503,7 +482,7 @@ runTransactions3(NDBT_Context* ctx, NDBT_Step* step){ return NDBT_FAILED; } - sync_down(ctx); + ctx->sync_down("PauseThreads"); if(ctx->isTestStopped()) break; @@ -512,7 +491,7 @@ runTransactions3(NDBT_Context* ctx, NDBT_Step* step){ return NDBT_FAILED; } - sync_down(ctx); + ctx->sync_down("PauseThreads"); if(ctx->isTestStopped()) break; @@ -521,14 +500,14 @@ runTransactions3(NDBT_Context* ctx, NDBT_Step* step){ return NDBT_FAILED; } - sync_down(ctx); + ctx->sync_down("PauseThreads"); if(ctx->isTestStopped()) break; int count = -1; if(utilTrans.selectCount(pNdb, 64, &count) != 0 || count != 0) return NDBT_FAILED; - sync_down(ctx); + ctx->sync_down("PauseThreads"); } return NDBT_OK; } @@ -540,6 +519,7 @@ int runRestarts(NDBT_Context* ctx, NDBT_Step* step){ NdbRestarts restarts; int i = 0; int timeout = 240; + int sync_threads = ctx->getProperty("Threads", (unsigned)0); while(i<loops && result != NDBT_FAILED && !ctx->isTestStopped()){ if(restarts.executeRestart("RestartRandomNodeAbort", timeout) != 0){ @@ -547,7 +527,7 @@ int runRestarts(NDBT_Context* ctx, NDBT_Step* step){ result = NDBT_FAILED; break; } - sync_up_and_wait(ctx); + ctx->sync_up_and_wait("PauseThreads", sync_threads); i++; } ctx->stopTest(); @@ -1088,7 +1068,7 @@ runUniqueNullTransactions(NDBT_Context* ctx, NDBT_Step* step){ const NdbDictionary::Table* pTab = ctx->getTab(); // Create index char nullIndex[255]; - snprintf(nullIndex, 255, "IDC_PK_%s_NULL", pTab->getName()); + BaseString::snprintf(nullIndex, 255, "IDC_PK_%s_NULL", pTab->getName()); if (orderedIndex) ndbout << "Creating " << ((logged)?"logged ": "temporary ") << "ordered index " << pkIdxName << " ("; diff --git a/ndb/test/ndbapi/testNdbApi.cpp b/ndb/test/ndbapi/testNdbApi.cpp index 47987629fe3..74cb1f8bcd0 100644 --- a/ndb/test/ndbapi/testNdbApi.cpp +++ b/ndb/test/ndbapi/testNdbApi.cpp @@ -229,7 +229,7 @@ int runTestMaxOperations(NDBT_Context* ctx, NDBT_Step* step){ int i = 0; while (errors < maxErrors){ - if(hugoOps.pkReadRecord(pNdb,1, false, 1) != NDBT_OK){ + if(hugoOps.pkReadRecord(pNdb,1, 1) != NDBT_OK){ errors++; continue; } diff --git a/ndb/test/ndbapi/testNodeRestart.cpp b/ndb/test/ndbapi/testNodeRestart.cpp index 6bfe59f8d3f..e844f227034 100644 --- a/ndb/test/ndbapi/testNodeRestart.cpp +++ b/ndb/test/ndbapi/testNodeRestart.cpp @@ -100,11 +100,16 @@ int runScanReadUntilStopped(NDBT_Context* ctx, NDBT_Step* step){ int runPkReadUntilStopped(NDBT_Context* ctx, NDBT_Step* step){ int result = NDBT_OK; int records = ctx->getNumRecords(); + NdbOperation::LockMode lm = + (NdbOperation::LockMode)ctx->getProperty("ReadLockMode", + (Uint32)NdbOperation::LM_Read); int i = 0; HugoTransactions hugoTrans(*ctx->getTab()); while (ctx->isTestStopped() == false) { g_info << i << ": "; - if (hugoTrans.pkReadRecords(GETNDB(step), records, 128) != 0){ + int rows = (rand()%records)+1; + int batch = (rand()%rows)+1; + if (hugoTrans.pkReadRecords(GETNDB(step), rows, batch, lm) != 0){ return NDBT_FAILED; } i++; @@ -119,7 +124,9 @@ int runPkUpdateUntilStopped(NDBT_Context* ctx, NDBT_Step* step){ HugoTransactions hugoTrans(*ctx->getTab()); while (ctx->isTestStopped() == false) { g_info << i << ": "; - if (hugoTrans.pkUpdateRecords(GETNDB(step), records) != 0){ + int rows = (rand()%records)+1; + int batch = (rand()%rows)+1; + if (hugoTrans.pkUpdateRecords(GETNDB(step), rows, batch) != 0){ return NDBT_FAILED; } i++; @@ -127,6 +134,60 @@ int runPkUpdateUntilStopped(NDBT_Context* ctx, NDBT_Step* step){ return result; } +int runPkReadPkUpdateUntilStopped(NDBT_Context* ctx, NDBT_Step* step){ + int result = NDBT_OK; + int records = ctx->getNumRecords(); + Ndb* pNdb = GETNDB(step); + int i = 0; + HugoOperations hugoOps(*ctx->getTab()); + while (ctx->isTestStopped() == false) { + g_info << i++ << ": "; + int rows = (rand()%records)+1; + int batch = (rand()%rows)+1; + int row = (records - rows) ? rand() % (records - rows) : 0; + + int j,k; + for(j = 0; j<rows; j += batch) + { + k = batch; + if(j+k > rows) + k = rows - j; + + if(hugoOps.startTransaction(pNdb) != 0) + goto err; + + if(hugoOps.pkReadRecord(pNdb, row+j, k, NdbOperation::LM_Exclusive) != 0) + goto err; + + if(hugoOps.execute_NoCommit(pNdb) != 0) + goto err; + + if(hugoOps.pkUpdateRecord(pNdb, row+j, k, rand()) != 0) + goto err; + + if(hugoOps.execute_Commit(pNdb) != 0) + goto err; + + if(hugoOps.closeTransaction(pNdb) != 0) + return NDBT_FAILED; + } + + continue; +err: + NdbConnection* pCon = hugoOps.getTransaction(); + if(pCon == 0) + continue; + NdbError error = pCon->getNdbError(); + hugoOps.closeTransaction(pNdb); + if (error.status == NdbError::TemporaryError){ + NdbSleep_MilliSleep(50); + continue; + } + return NDBT_FAILED; + } + return NDBT_OK; +} + int runScanUpdateUntilStopped(NDBT_Context* ctx, NDBT_Step* step){ int result = NDBT_OK; int records = ctx->getNumRecords(); @@ -158,6 +219,7 @@ int runScanReadVerify(NDBT_Context* ctx, NDBT_Step* step){ int runRestarter(NDBT_Context* ctx, NDBT_Step* step){ int result = NDBT_OK; int loops = ctx->getNumLoops(); + int sync_threads = ctx->getProperty("SyncThreads", (unsigned)0); NdbRestarter restarter; int i = 0; int lastId = 0; @@ -174,11 +236,11 @@ int runRestarter(NDBT_Context* ctx, NDBT_Step* step){ loops *= restarter.getNumDbNodes(); while(i<loops && result != NDBT_FAILED && !ctx->isTestStopped()){ - + int id = lastId % restarter.getNumDbNodes(); int nodeId = restarter.getDbNodeId(id); ndbout << "Restart node " << nodeId << endl; - if(restarter.restartOneDbNode(nodeId) != 0){ + if(restarter.restartOneDbNode(nodeId, false, false, true) != 0){ g_err << "Failed to restartNextDbNode" << endl; result = NDBT_FAILED; break; @@ -190,7 +252,7 @@ int runRestarter(NDBT_Context* ctx, NDBT_Step* step){ break; } - NdbSleep_SecSleep(1); + ctx->sync_up_and_wait("PauseThreads", sync_threads); lastId++; i++; @@ -234,6 +296,54 @@ int runRestarts(NDBT_Context* ctx, NDBT_Step* step){ return result; } +int runDirtyRead(NDBT_Context* ctx, NDBT_Step* step){ + int result = NDBT_OK; + int loops = ctx->getNumLoops(); + int records = ctx->getNumRecords(); + NdbRestarter restarter; + HugoOperations hugoOps(*ctx->getTab()); + Ndb* pNdb = GETNDB(step); + + int i = 0; + while(i<loops && result != NDBT_FAILED && !ctx->isTestStopped()){ + g_info << i << ": "; + + int id = i % restarter.getNumDbNodes(); + int nodeId = restarter.getDbNodeId(id); + ndbout << "Restart node " << nodeId << endl; + restarter.insertErrorInAllNodes(5041); + restarter.insertErrorInAllNodes(8048 + (i & 1)); + + for(int j = 0; j<records; j++){ + if(hugoOps.startTransaction(pNdb) != 0) + return NDBT_FAILED; + + if(hugoOps.pkReadRecord(pNdb, j, 1, NdbOperation::LM_CommittedRead) != 0) + goto err; + + int res; + if((res = hugoOps.execute_Commit(pNdb)) == 4119) + goto done; + + if(res != 0) + goto err; + + if(hugoOps.closeTransaction(pNdb) != 0) + return NDBT_FAILED; + } +done: + if(hugoOps.closeTransaction(pNdb) != 0) + return NDBT_FAILED; + + i++; + restarter.waitClusterStarted(60) ; + } + return result; +err: + hugoOps.closeTransaction(pNdb); + return NDBT_FAILED; +} + NDBT_TESTSUITE(testNodeRestart); TESTCASE("NoLoad", "Test that one node at a time can be stopped and then restarted "\ @@ -246,6 +356,27 @@ TESTCASE("NoLoad", TESTCASE("PkRead", "Test that one node at a time can be stopped and then restarted "\ "perform pk read while restarting. Do this loop number of times"){ + TC_PROPERTY("ReadLockMode", NdbOperation::LM_Read); + INITIALIZER(runCheckAllNodesStarted); + INITIALIZER(runLoadTable); + STEP(runRestarter); + STEP(runPkReadUntilStopped); + FINALIZER(runClearTable); +} +TESTCASE("PkReadCommitted", + "Test that one node at a time can be stopped and then restarted "\ + "perform pk read while restarting. Do this loop number of times"){ + TC_PROPERTY("ReadLockMode", NdbOperation::LM_CommittedRead); + INITIALIZER(runCheckAllNodesStarted); + INITIALIZER(runLoadTable); + STEP(runRestarter); + STEP(runPkReadUntilStopped); + FINALIZER(runClearTable); +} +TESTCASE("MixedPkRead", + "Test that one node at a time can be stopped and then restarted "\ + "perform pk read while restarting. Do this loop number of times"){ + TC_PROPERTY("ReadLockMode", -1); INITIALIZER(runCheckAllNodesStarted); INITIALIZER(runLoadTable); STEP(runRestarter); @@ -255,14 +386,31 @@ TESTCASE("PkRead", TESTCASE("PkReadPkUpdate", "Test that one node at a time can be stopped and then restarted "\ "perform pk read and pk update while restarting. Do this loop number of times"){ + TC_PROPERTY("ReadLockMode", NdbOperation::LM_Read); INITIALIZER(runCheckAllNodesStarted); INITIALIZER(runLoadTable); STEP(runRestarter); STEP(runPkReadUntilStopped); + STEP(runPkUpdateUntilStopped); + STEP(runPkReadPkUpdateUntilStopped); STEP(runPkReadUntilStopped); + STEP(runPkUpdateUntilStopped); + STEP(runPkReadPkUpdateUntilStopped); + FINALIZER(runClearTable); +} +TESTCASE("MixedPkReadPkUpdate", + "Test that one node at a time can be stopped and then restarted "\ + "perform pk read and pk update while restarting. Do this loop number of times"){ + TC_PROPERTY("ReadLockMode", -1); + INITIALIZER(runCheckAllNodesStarted); + INITIALIZER(runLoadTable); + STEP(runRestarter); STEP(runPkReadUntilStopped); + STEP(runPkUpdateUntilStopped); + STEP(runPkReadPkUpdateUntilStopped); STEP(runPkReadUntilStopped); STEP(runPkUpdateUntilStopped); + STEP(runPkReadPkUpdateUntilStopped); FINALIZER(runClearTable); } TESTCASE("ReadUpdateScan", @@ -273,6 +421,21 @@ TESTCASE("ReadUpdateScan", STEP(runRestarter); STEP(runPkReadUntilStopped); STEP(runPkUpdateUntilStopped); + STEP(runPkReadPkUpdateUntilStopped); + STEP(runScanReadUntilStopped); + STEP(runScanUpdateUntilStopped); + FINALIZER(runClearTable); +} +TESTCASE("MixedReadUpdateScan", + "Test that one node at a time can be stopped and then restarted "\ + "perform pk read, pk update and scan reads while restarting. Do this loop number of times"){ + TC_PROPERTY("ReadLockMode", -1); + INITIALIZER(runCheckAllNodesStarted); + INITIALIZER(runLoadTable); + STEP(runRestarter); + STEP(runPkReadUntilStopped); + STEP(runPkUpdateUntilStopped); + STEP(runPkReadPkUpdateUntilStopped); STEP(runScanReadUntilStopped); STEP(runScanUpdateUntilStopped); FINALIZER(runClearTable); @@ -431,6 +594,12 @@ TESTCASE("StopOnError", FINALIZER(runScanReadVerify); FINALIZER(runClearTable); } +TESTCASE("CommittedRead", + "Test committed read"){ + INITIALIZER(runLoadTable); + STEP(runDirtyRead); + FINALIZER(runClearTable); +} NDBT_TESTSUITE_END(testNodeRestart); int main(int argc, const char** argv){ diff --git a/ndb/test/ndbapi/testOIBasic.cpp b/ndb/test/ndbapi/testOIBasic.cpp index f9eb3514926..1c611d2b8ff 100644 --- a/ndb/test/ndbapi/testOIBasic.cpp +++ b/ndb/test/ndbapi/testOIBasic.cpp @@ -40,18 +40,21 @@ struct Opt { bool m_core; const char* m_csname; CHARSET_INFO* m_cs; + int m_die; bool m_dups; NdbDictionary::Object::FragmentType m_fragtype; - unsigned m_idxloop; + unsigned m_subsubloop; const char* m_index; unsigned m_loop; - bool m_nologging; bool m_msglock; + bool m_nologging; + bool m_noverify; unsigned m_pctnull; unsigned m_rows; unsigned m_samples; - unsigned m_scanrd; - unsigned m_scanex; + unsigned m_scanbat; + unsigned m_scanpar; + unsigned m_scanstop; unsigned m_seed; unsigned m_subloop; const char* m_table; @@ -64,22 +67,25 @@ struct Opt { m_core(false), m_csname("latin1_bin"), m_cs(0), + m_die(0), m_dups(false), m_fragtype(NdbDictionary::Object::FragUndefined), - m_idxloop(4), + m_subsubloop(4), m_index(0), m_loop(1), - m_nologging(false), m_msglock(true), + m_nologging(false), + m_noverify(false), m_pctnull(10), m_rows(1000), m_samples(0), - m_scanrd(240), - m_scanex(240), + m_scanbat(0), + m_scanpar(0), + m_scanstop(0), m_seed(0), m_subloop(4), m_table(0), - m_threads(4), + m_threads(10), m_v(1) { } }; @@ -100,16 +106,18 @@ printhelp() << " -case abc only given test cases (letters a-z)" << endl << " -core core dump on error [" << d.m_core << "]" << endl << " -csname S charset (collation) of non-pk char column [" << d.m_csname << "]" << endl + << " -die nnn exit immediately on NDB error code nnn" << endl << " -dups allow duplicate tuples from index scan [" << d.m_dups << "]" << endl << " -fragtype T fragment type single/small/medium/large" << endl << " -index xyz only given index numbers (digits 1-9)" << endl << " -loop N loop count full suite 0=forever [" << d.m_loop << "]" << endl << " -nologging create tables in no-logging mode" << endl + << " -noverify skip index verifications" << endl << " -pctnull N pct NULL values in nullable column [" << d.m_pctnull << "]" << endl << " -rows N rows per thread [" << d.m_rows << "]" << endl << " -samples N samples for some timings (0=all) [" << d.m_samples << "]" << endl - << " -scanrd N scan read parallelism [" << d.m_scanrd << "]" << endl - << " -scanex N scan exclusive parallelism [" << d.m_scanex << "]" << endl + << " -scanbat N scan batch per fragment (ignored by ndb api) [" << d.m_scanbat << "]" << endl + << " -scanpar N scan parallelism [" << d.m_scanpar << "]" << endl << " -seed N srandom seed 0=loop number[" << d.m_seed << "]" << endl << " -subloop N subtest loop count [" << d.m_subloop << "]" << endl << " -table xyz only given table numbers (digits 1-9)" << endl @@ -208,10 +216,14 @@ struct Par : public Opt { Set& set() const { assert(m_set != 0); return *m_set; } Tmr* m_tmr; Tmr& tmr() const { assert(m_tmr != 0); return *m_tmr; } + unsigned m_lno; + unsigned m_slno; unsigned m_totrows; // value calculation unsigned m_range; unsigned m_pctrange; + // choice of key + bool m_randomkey; // do verify after read bool m_verify; // deadlock possible @@ -224,9 +236,12 @@ struct Par : public Opt { m_tab(0), m_set(0), m_tmr(0), + m_lno(0), + m_slno(0), m_totrows(m_threads * m_rows), m_range(m_rows), m_pctrange(0), + m_randomkey(false), m_verify(false), m_deadlock(false) { } @@ -688,13 +703,14 @@ struct Con { int setBound(int num, int type, const void* value); int execute(ExecType t); int execute(ExecType t, bool& deadlock); - int openScanRead(unsigned parallelism); - int openScanExclusive(unsigned parallelism); + int openScanRead(unsigned scanbat, unsigned scanpar); + int openScanExclusive(unsigned scanbat, unsigned scanpar); int executeScan(); int nextScanResult(bool fetchAllowed); int nextScanResult(bool fetchAllowed, bool& deadlock); int updateScanTuple(Con& con2); int deleteScanTuple(Con& con2); + void closeScan(); void closeTransaction(); void printerror(NdbOut& out); }; @@ -815,18 +831,20 @@ Con::execute(ExecType t, bool& deadlock) } int -Con::openScanRead(unsigned parallelism) +Con::openScanRead(unsigned scanbat, unsigned scanpar) { assert(m_tx != 0 && m_op != 0); - CHKCON((m_resultset = m_scanop->readTuples(parallelism)) != 0, *this); + NdbOperation::LockMode lm = NdbOperation::LM_Read; + CHKCON((m_resultset = m_scanop->readTuples(lm, scanbat, scanpar)) != 0, *this); return 0; } int -Con::openScanExclusive(unsigned parallelism) +Con::openScanExclusive(unsigned scanbat, unsigned scanpar) { assert(m_tx != 0 && m_op != 0); - CHKCON((m_resultset = m_scanop->readTuplesExclusive(parallelism)) != 0, *this); + NdbOperation::LockMode lm = NdbOperation::LM_Exclusive; + CHKCON((m_resultset = m_scanop->readTuples(lm, scanbat, scanpar)) != 0, *this); return 0; } @@ -880,11 +898,21 @@ Con::deleteScanTuple(Con& con2) } void +Con::closeScan() +{ + assert(m_resultset != 0); + m_resultset->close(); + m_scanop = 0, m_indexscanop = 0, m_resultset = 0; + +} + +void Con::closeTransaction() { assert(m_ndb != 0 && m_tx != 0); m_ndb->closeTransaction(m_tx); m_tx = 0, m_op = 0; + m_scanop = 0, m_indexscanop = 0, m_resultset = 0; } void @@ -893,27 +921,37 @@ Con::printerror(NdbOut& out) m_errtype = ErrOther; unsigned any = 0; int code; + int die = 0; if (m_ndb) { if ((code = m_ndb->getNdbError().code) != 0) { LL0(++any << " ndb: error " << m_ndb->getNdbError()); + die += (code == g_opt.m_die); } if (m_dic && (code = m_dic->getNdbError().code) != 0) { LL0(++any << " dic: error " << m_dic->getNdbError()); + die += (code == g_opt.m_die); } if (m_tx) { if ((code = m_tx->getNdbError().code) != 0) { LL0(++any << " con: error " << m_tx->getNdbError()); + die += (code == g_opt.m_die); if (code == 266 || code == 274 || code == 296 || code == 297 || code == 499) m_errtype = ErrDeadlock; } if (m_op && m_op->getNdbError().code != 0) { LL0(++any << " op : error " << m_op->getNdbError()); + die += (code == g_opt.m_die); } } } if (! any) { LL0("failed but no NDB error code"); } + if (die) { + if (g_opt.m_core) + abort(); + exit(1); + } } // dictionary operations @@ -1965,9 +2003,21 @@ BSet::calcpk(Par par, unsigned i) int BSet::setbnd(Par par) const { - for (unsigned j = 0; j < m_bvals; j++) { - const BVal& bval = *m_bval[j]; - CHK(bval.setbnd(par) == 0); + if (m_bvals != 0) { + unsigned p1 = urandom(m_bvals); + unsigned p2 = 10009; // prime + // random order + for (unsigned j = 0; j < m_bvals; j++) { + unsigned k = p1 + p2 * j; + const BVal& bval = *m_bval[k % m_bvals]; + CHK(bval.setbnd(par) == 0); + } + // duplicate + if (urandom(5) == 0) { + unsigned k = urandom(m_bvals); + const BVal& bval = *m_bval[k]; + CHK(bval.setbnd(par) == 0); + } } return 0; } @@ -2054,7 +2104,8 @@ pkinsert(Par par) CHK(con.startTransaction() == 0); Lst lst; for (unsigned j = 0; j < par.m_rows; j++) { - unsigned i = thrrow(par, j); + unsigned j2 = ! par.m_randomkey ? j : urandom(par.m_rows); + unsigned i = thrrow(par, j2); set.lock(); if (set.exist(i) || set.pending(i)) { set.unlock(); @@ -2107,7 +2158,8 @@ pkupdate(Par par) Lst lst; bool deadlock = false; for (unsigned j = 0; j < par.m_rows; j++) { - unsigned i = thrrow(par, j); + unsigned j2 = ! par.m_randomkey ? j : urandom(par.m_rows); + unsigned i = thrrow(par, j2); set.lock(); if (! set.exist(i) || set.pending(i)) { set.unlock(); @@ -2158,7 +2210,8 @@ pkdelete(Par par) Lst lst; bool deadlock = false; for (unsigned j = 0; j < par.m_rows; j++) { - unsigned i = thrrow(par, j); + unsigned j2 = ! par.m_randomkey ? j : urandom(par.m_rows); + unsigned i = thrrow(par, j2); set.lock(); if (! set.exist(i) || set.pending(i)) { set.unlock(); @@ -2268,7 +2321,7 @@ scanreadtable(Par par) Set set2(tab, set.m_rows); CHK(con.startTransaction() == 0); CHK(con.getNdbScanOperation(tab) == 0); - CHK(con.openScanRead(par.m_scanrd) == 0); + CHK(con.openScanRead(par.m_scanbat, par.m_scanpar) == 0); set2.getval(par); CHK(con.executeScan() == 0); while (1) { @@ -2296,7 +2349,7 @@ scanreadtablefast(Par par, unsigned countcheck) LL3("scanfast " << tab.m_name); CHK(con.startTransaction() == 0); CHK(con.getNdbScanOperation(tab) == 0); - CHK(con.openScanRead(par.m_scanrd) == 0); + CHK(con.openScanRead(par.m_scanbat, par.m_scanpar) == 0); // get 1st column NdbRecAttr* rec; CHK(con.getValue((Uint32)0, rec) == 0); @@ -2328,7 +2381,7 @@ scanreadindex(Par par, const ITab& itab, const BSet& bset) Set set2(tab, set.m_rows); CHK(con.startTransaction() == 0); CHK(con.getNdbScanOperation(itab, tab) == 0); - CHK(con.openScanRead(par.m_scanrd) == 0); + CHK(con.openScanRead(par.m_scanbat, par.m_scanpar) == 0); CHK(bset.setbnd(par) == 0); set2.getval(par); CHK(con.executeScan() == 0); @@ -2359,7 +2412,7 @@ scanreadindexfast(Par par, const ITab& itab, const BSet& bset, unsigned countche LL4(bset); CHK(con.startTransaction() == 0); CHK(con.getNdbScanOperation(itab, tab) == 0); - CHK(con.openScanRead(par.m_scanrd) == 0); + CHK(con.openScanRead(par.m_scanbat, par.m_scanpar) == 0); CHK(bset.setbnd(par) == 0); // get 1st column NdbRecAttr* rec; @@ -2382,7 +2435,7 @@ static int scanreadindex(Par par, const ITab& itab) { const Tab& tab = par.tab(); - for (unsigned i = 0; i < par.m_idxloop; i++) { + for (unsigned i = 0; i < par.m_subsubloop; i++) { BSet bset(tab, itab, par.m_rows); bset.calc(par); CHK(scanreadindex(par, itab, bset) == 0); @@ -2478,7 +2531,7 @@ scanupdatetable(Par par) Set set2(tab, set.m_rows); CHK(con.startTransaction() == 0); CHK(con.getNdbScanOperation(tab) == 0); - CHK(con.openScanExclusive(par.m_scanex) == 0); + CHK(con.openScanExclusive(par.m_scanbat, par.m_scanpar) == 0); set2.getval(par); CHK(con.executeScan() == 0); unsigned count = 0; @@ -2498,6 +2551,10 @@ scanupdatetable(Par par) LL1("scanupdatetable: stop on deadlock"); break; } + if (par.m_scanstop != 0 && urandom(par.m_scanstop) == 0) { + con.closeScan(); + break; + } do { unsigned i = (unsigned)-1; CHK(set2.getkey(par, &i) == 0); @@ -2557,7 +2614,7 @@ scanupdateindex(Par par, const ITab& itab, const BSet& bset) Set set2(tab, set.m_rows); CHK(con.startTransaction() == 0); CHK(con.getNdbScanOperation(itab, tab) == 0); - CHK(con.openScanExclusive(par.m_scanex) == 0); + CHK(con.openScanExclusive(par.m_scanbat, par.m_scanpar) == 0); CHK(bset.setbnd(par) == 0); set2.getval(par); CHK(con.executeScan() == 0); @@ -2578,6 +2635,10 @@ scanupdateindex(Par par, const ITab& itab, const BSet& bset) LL1("scanupdateindex: stop on deadlock"); break; } + if (par.m_scanstop != 0 && urandom(par.m_scanstop) == 0) { + con.closeScan(); + break; + } do { unsigned i = (unsigned)-1; CHK(set2.getkey(par, &i) == 0); @@ -2629,7 +2690,7 @@ static int scanupdateindex(Par par, const ITab& itab) { const Tab& tab = par.tab(); - for (unsigned i = 0; i < par.m_idxloop; i++) { + for (unsigned i = 0; i < par.m_subsubloop; i++) { BSet bset(tab, itab, par.m_rows); bset.calc(par); CHK(scanupdateindex(par, itab, bset) == 0); @@ -2663,6 +2724,8 @@ scanupdateall(Par par) static int readverify(Par par) { + if (par.m_noverify) + return 0; par.m_verify = true; CHK(pkread(par) == 0); CHK(scanreadall(par) == 0); @@ -2670,6 +2733,55 @@ readverify(Par par) } static int +readverifyfull(Par par) +{ + if (par.m_noverify) + return 0; + par.m_verify = true; + if (par.m_no == 0) + CHK(scanreadtable(par) == 0); + else { + const Tab& tab = par.tab(); + unsigned i = par.m_no; + if (i <= tab.m_itabs && useindex(i)) { + const ITab& itab = tab.m_itab[i - 1]; + BSet bset(tab, itab, par.m_rows); + CHK(scanreadindex(par, itab, bset) == 0); + } + } + return 0; +} + +static int +pkops(Par par) +{ + par.m_randomkey = true; + for (unsigned i = 0; i < par.m_subsubloop; i++) { + unsigned sel = urandom(10); + if (par.m_slno % 2 == 0) { + // favor insert + if (sel < 8) { + CHK(pkinsert(par) == 0); + } else if (sel < 9) { + CHK(pkupdate(par) == 0); + } else { + CHK(pkdelete(par) == 0); + } + } else { + // favor delete + if (sel < 1) { + CHK(pkinsert(par) == 0); + } else if (sel < 2) { + CHK(pkupdate(par) == 0); + } else { + CHK(pkdelete(par) == 0); + } + } + } + return 0; +} + +static int pkupdatescanread(Par par) { par.m_dups = true; @@ -2691,6 +2803,7 @@ mixedoperations(Par par) { par.m_dups = true; par.m_deadlock = true; + par.m_scanstop = par.m_totrows; // randomly close scans unsigned sel = urandom(10); if (sel < 2) { CHK(pkdelete(par) == 0); @@ -2710,6 +2823,7 @@ pkupdateindexbuild(Par par) if (par.m_no == 0) { CHK(createindex(par) == 0); } else { + par.m_randomkey = true; CHK(pkupdate(par) == 0); } return 0; @@ -2913,6 +3027,8 @@ runstep(Par par, const char* fname, TFunc func, unsigned mode) thr.m_par.m_tab = par.m_tab; thr.m_par.m_set = par.m_set; thr.m_par.m_tmr = par.m_tmr; + thr.m_par.m_lno = par.m_lno; + thr.m_par.m_slno = par.m_slno; thr.m_func = func; thr.start(); } @@ -2936,8 +3052,8 @@ tbuild(Par par) RUNSTEP(par, droptable, ST); RUNSTEP(par, createtable, ST); RUNSTEP(par, invalidatetable, MT); - for (unsigned i = 0; i < par.m_subloop; i++) { - if (i % 2 == 0) { + for (par.m_slno = 0; par.m_slno < par.m_subloop; par.m_slno++) { + if (par.m_slno % 2 == 0) { RUNSTEP(par, createindex, ST); RUNSTEP(par, invalidateindex, MT); RUNSTEP(par, pkinsert, MT); @@ -2946,9 +3062,10 @@ tbuild(Par par) RUNSTEP(par, createindex, ST); RUNSTEP(par, invalidateindex, MT); } - RUNSTEP(par, readverify, MT); + RUNSTEP(par, pkupdate, MT); + RUNSTEP(par, readverifyfull, MT); RUNSTEP(par, pkdelete, MT); - RUNSTEP(par, readverify, MT); + RUNSTEP(par, readverifyfull, MT); RUNSTEP(par, dropindex, ST); } return 0; @@ -2960,11 +3077,27 @@ tpkops(Par par) RUNSTEP(par, droptable, ST); RUNSTEP(par, createtable, ST); RUNSTEP(par, invalidatetable, MT); + RUNSTEP(par, createindex, ST); + RUNSTEP(par, invalidateindex, MT); + for (par.m_slno = 0; par.m_slno < par.m_subloop; par.m_slno++) { + RUNSTEP(par, pkops, MT); + LL2("rows=" << par.set().count()); + RUNSTEP(par, readverifyfull, MT); + } + return 0; +} + +static int +tpkopsread(Par par) +{ + RUNSTEP(par, droptable, ST); + RUNSTEP(par, createtable, ST); + RUNSTEP(par, invalidatetable, MT); RUNSTEP(par, pkinsert, MT); RUNSTEP(par, createindex, ST); RUNSTEP(par, invalidateindex, MT); RUNSTEP(par, readverify, ST); - for (unsigned i = 0; i < par.m_subloop; i++) { + for (par.m_slno = 0; par.m_slno < par.m_subloop; par.m_slno++) { RUNSTEP(par, pkupdatescanread, MT); RUNSTEP(par, readverify, ST); } @@ -2983,7 +3116,7 @@ tmixedops(Par par) RUNSTEP(par, createindex, ST); RUNSTEP(par, invalidateindex, MT); RUNSTEP(par, readverify, ST); - for (unsigned i = 0; i < par.m_subloop; i++) { + for (par.m_slno = 0; par.m_slno < par.m_subloop; par.m_slno++) { RUNSTEP(par, mixedoperations, MT); RUNSTEP(par, readverify, ST); } @@ -2997,7 +3130,7 @@ tbusybuild(Par par) RUNSTEP(par, createtable, ST); RUNSTEP(par, invalidatetable, MT); RUNSTEP(par, pkinsert, MT); - for (unsigned i = 0; i < par.m_subloop; i++) { + for (par.m_slno = 0; par.m_slno < par.m_subloop; par.m_slno++) { RUNSTEP(par, pkupdateindexbuild, MT); RUNSTEP(par, invalidateindex, MT); RUNSTEP(par, readverify, ST); @@ -3013,7 +3146,7 @@ ttimebuild(Par par) RUNSTEP(par, droptable, ST); RUNSTEP(par, createtable, ST); RUNSTEP(par, invalidatetable, MT); - for (unsigned i = 0; i < par.m_subloop; i++) { + for (par.m_slno = 0; par.m_slno < par.m_subloop; par.m_slno++) { RUNSTEP(par, pkinsert, MT); t1.on(); RUNSTEP(par, createindex, ST); @@ -3032,7 +3165,7 @@ ttimemaint(Par par) RUNSTEP(par, droptable, ST); RUNSTEP(par, createtable, ST); RUNSTEP(par, invalidatetable, MT); - for (unsigned i = 0; i < par.m_subloop; i++) { + for (par.m_slno = 0; par.m_slno < par.m_subloop; par.m_slno++) { RUNSTEP(par, pkinsert, MT); t1.on(); RUNSTEP(par, pkupdate, MT); @@ -3057,7 +3190,7 @@ ttimescan(Par par) RUNSTEP(par, droptable, ST); RUNSTEP(par, createtable, ST); RUNSTEP(par, invalidatetable, MT); - for (unsigned i = 0; i < par.m_subloop; i++) { + for (par.m_slno = 0; par.m_slno < par.m_subloop; par.m_slno++) { RUNSTEP(par, pkinsert, MT); RUNSTEP(par, createindex, ST); par.m_tmr = &t1; @@ -3079,7 +3212,7 @@ ttimepkread(Par par) RUNSTEP(par, droptable, ST); RUNSTEP(par, createtable, ST); RUNSTEP(par, invalidatetable, MT); - for (unsigned i = 0; i < par.m_subloop; i++) { + for (par.m_slno = 0; par.m_slno < par.m_subloop; par.m_slno++) { RUNSTEP(par, pkinsert, MT); RUNSTEP(par, createindex, ST); par.m_tmr = &t1; @@ -3115,9 +3248,10 @@ struct TCase { static const TCase tcaselist[] = { TCase("a", tbuild, "index build"), - TCase("b", tpkops, "pk operations and scan reads"), - TCase("c", tmixedops, "pk operations and scan operations"), - TCase("d", tbusybuild, "pk operations and index build"), + TCase("b", tpkops, "pk operations"), + TCase("c", tpkopsread, "pk operations and scan reads"), + TCase("d", tmixedops, "pk operations and scan operations"), + TCase("e", tbusybuild, "pk operations and index build"), TCase("t", ttimebuild, "time index build"), TCase("u", ttimemaint, "time index maintenance"), TCase("v", ttimescan, "time full scan table vs index on pk"), @@ -3175,10 +3309,10 @@ runtest(Par par) Thr& thr = *g_thrlist[n]; assert(thr.m_thread != 0); } - for (unsigned l = 0; par.m_loop == 0 || l < par.m_loop; l++) { - LL1("loop " << l); + for (par.m_lno = 0; par.m_loop == 0 || par.m_lno < par.m_loop; par.m_lno++) { + LL1("loop " << par.m_lno); if (par.m_seed == 0) - srandom(l); + srandom(par.m_lno); for (unsigned i = 0; i < tcasecount; i++) { const TCase& tcase = tcaselist[i]; if (par.m_case != 0 && strchr(par.m_case, tcase.m_name[0]) == 0) @@ -3252,6 +3386,12 @@ NDB_COMMAND(testOIBasic, "testOIBasic", "testOIBasic", "testOIBasic", 65535) continue; } } + if (strcmp(arg, "-die") == 0) { + if (++argv, --argc > 0) { + g_opt.m_die = atoi(argv[0]); + continue; + } + } if (strcmp(arg, "-dups") == 0) { g_opt.m_dups = true; continue; @@ -3292,6 +3432,10 @@ NDB_COMMAND(testOIBasic, "testOIBasic", "testOIBasic", "testOIBasic", 65535) g_opt.m_nologging = true; continue; } + if (strcmp(arg, "-noverify") == 0) { + g_opt.m_noverify = true; + continue; + } if (strcmp(arg, "-pctnull") == 0) { if (++argv, --argc > 0) { g_opt.m_pctnull = atoi(argv[0]); @@ -3310,15 +3454,15 @@ NDB_COMMAND(testOIBasic, "testOIBasic", "testOIBasic", "testOIBasic", 65535) continue; } } - if (strcmp(arg, "-scanrd") == 0) { + if (strcmp(arg, "-scanbat") == 0) { if (++argv, --argc > 0) { - g_opt.m_scanrd = atoi(argv[0]); + g_opt.m_scanbat = atoi(argv[0]); continue; } } - if (strcmp(arg, "-scanex") == 0) { + if (strcmp(arg, "-scanpar") == 0) { if (++argv, --argc > 0) { - g_opt.m_scanex = atoi(argv[0]); + g_opt.m_scanpar = atoi(argv[0]); continue; } } diff --git a/ndb/test/ndbapi/testOperations.cpp b/ndb/test/ndbapi/testOperations.cpp index ba41e1d1c40..f31906dd737 100644 --- a/ndb/test/ndbapi/testOperations.cpp +++ b/ndb/test/ndbapi/testOperations.cpp @@ -86,7 +86,7 @@ OperationTestCase matrix[] = { { "DeleteRead", true, "DELETE", 0, 0, "READ", 626, 0, 0, 0 }, { "DeleteReadEx", true, "DELETE", 0, 0, "READ-EX", 626, 0, 0, 0 }, { "DeleteSimpleRead", true, "DELETE", 0, 0, "S-READ", 626, 0, 0, 0 }, - { "DeleteDirtyRead", true, "DELETE", 0, 0, "D-READ", 626, 0, 0, 0 }, + { "DeleteDirtyRead", true, "DELETE", 0, 0, "D-READ", 626, 0, 626, 0 }, { "DeleteInsert", true, "DELETE", 0, 0, "INSERT", 0, 1, 0, 1 }, { "DeleteUpdate", true, "DELETE", 0, 0, "UPDATE", 626, 1, 0, 0 }, { "DeleteDelete", true, "DELETE", 0, 0, "DELETE", 626, 0, 0, 0 } @@ -110,13 +110,13 @@ runOp(HugoOperations & hugoOps, return NDBT_FAILED; }} if(strcmp(op, "READ") == 0){ - C2(hugoOps.pkReadRecord(pNdb, 1, false, 1), 0); + C2(hugoOps.pkReadRecord(pNdb, 1, 1, NdbOperation::LM_Read), 0); } else if(strcmp(op, "READ-EX") == 0){ - C2(hugoOps.pkReadRecord(pNdb, 1, true, 1), 0); + C2(hugoOps.pkReadRecord(pNdb, 1, 1, NdbOperation::LM_Exclusive), 0); } else if(strcmp(op, "S-READ") == 0){ - C2(hugoOps.pkSimpleReadRecord(pNdb, 1, 1), 0); + C2(hugoOps.pkReadRecord(pNdb, 1, 1, NdbOperation::LM_Read), 0); } else if(strcmp(op, "D-READ") == 0){ - C2(hugoOps.pkDirtyReadRecord(pNdb, 1, 1), 0); + C2(hugoOps.pkReadRecord(pNdb, 1, 1, NdbOperation::LM_CommittedRead), 0); } else if(strcmp(op, "INSERT") == 0){ C2(hugoOps.pkInsertRecord(pNdb, 1, 1, value), 0); } else if(strcmp(op, "UPDATE") == 0){ diff --git a/ndb/test/ndbapi/testReadPerf.cpp b/ndb/test/ndbapi/testReadPerf.cpp index 7cf3755d66f..8d0d78cbe8c 100644 --- a/ndb/test/ndbapi/testReadPerf.cpp +++ b/ndb/test/ndbapi/testReadPerf.cpp @@ -130,9 +130,9 @@ main(int argc, const char** argv){ for(int i = optind; i<argc; i++){ const char * T = argv[i]; g_info << "Testing " << T << endl; - snprintf(g_table, sizeof(g_table), T); - snprintf(g_ordered, sizeof(g_ordered), "IDX_O_%s", T); - snprintf(g_unique, sizeof(g_unique), "IDX_U_%s", T); + BaseString::snprintf(g_table, sizeof(g_table), T); + BaseString::snprintf(g_ordered, sizeof(g_ordered), "IDX_O_%s", T); + BaseString::snprintf(g_unique, sizeof(g_unique), "IDX_U_%s", T); if(create_table()) goto error; if(load_table()) diff --git a/ndb/test/ndbapi/testRestartGci.cpp b/ndb/test/ndbapi/testRestartGci.cpp index 4cdfca29e6f..e817245af55 100644 --- a/ndb/test/ndbapi/testRestartGci.cpp +++ b/ndb/test/ndbapi/testRestartGci.cpp @@ -63,7 +63,7 @@ int runInsertRememberGci(NDBT_Context* ctx, NDBT_Step* step){ result = NDBT_FAILED; break; } - CHECK(hugoOps.pkReadRecord(pNdb, i, false) == 0); + CHECK(hugoOps.pkReadRecord(pNdb, i) == 0); if (hugoOps.execute_Commit(pNdb) != 0){ ndbout << "Did not find record in DB " << i << endl; result = NDBT_FAILED; @@ -146,7 +146,7 @@ int runVerifyInserts(NDBT_Context* ctx, NDBT_Step* step){ // gci as in the vector for (unsigned i = 0; i < savedRecords.size(); i++){ CHECK(hugoOps.startTransaction(pNdb) == 0); - CHECK(hugoOps.pkReadRecord(pNdb, i, false) == 0); + CHECK(hugoOps.pkReadRecord(pNdb, i) == 0); if (hugoOps.execute_Commit(pNdb) != 0){ // Record was not found in db' diff --git a/ndb/test/ndbapi/testScanInterpreter.cpp b/ndb/test/ndbapi/testScanInterpreter.cpp index 3a5ef22b613..5a7ca30cd2a 100644 --- a/ndb/test/ndbapi/testScanInterpreter.cpp +++ b/ndb/test/ndbapi/testScanInterpreter.cpp @@ -90,7 +90,7 @@ int runCreateResultTable(NDBT_Context* ctx, NDBT_Step* step){ const NdbDictionary::Table* pTab = ctx->getTab(); char newTabName[256]; - snprintf(newTabName, 256, "%s_RES", pTab->getName()); + BaseString::snprintf(newTabName, 256, "%s_RES", pTab->getName()); ctx->setProperty("ResultTabName", newTabName); NdbDictionary::Table resTab(* pTab); diff --git a/ndb/test/ndbapi/testScanPerf.cpp b/ndb/test/ndbapi/testScanPerf.cpp index 8c1a41047ca..c1334125978 100644 --- a/ndb/test/ndbapi/testScanPerf.cpp +++ b/ndb/test/ndbapi/testScanPerf.cpp @@ -110,8 +110,8 @@ main(int argc, const char** argv){ for(int i = optind; i<argc; i++){ const char * T = argv[i]; g_info << "Testing " << T << endl; - snprintf(g_tablename, sizeof(g_tablename), T); - snprintf(g_indexname, sizeof(g_indexname), "IDX_%s", T); + BaseString::snprintf(g_tablename, sizeof(g_tablename), T); + BaseString::snprintf(g_indexname, sizeof(g_indexname), "IDX_%s", T); if(create_table()) goto error; if(load_table()) diff --git a/ndb/test/ndbapi/testTimeout.cpp b/ndb/test/ndbapi/testTimeout.cpp index 5cabb86541d..e310e12df81 100644 --- a/ndb/test/ndbapi/testTimeout.cpp +++ b/ndb/test/ndbapi/testTimeout.cpp @@ -108,7 +108,7 @@ int runTimeoutTrans(NDBT_Context* ctx, NDBT_Step* step){ do{ // Commit transaction CHECK(hugoOps.startTransaction(pNdb) == 0); - CHECK(hugoOps.pkReadRecord(pNdb, stepNo, true) == 0); + CHECK(hugoOps.pkReadRecord(pNdb, stepNo) == 0); CHECK(hugoOps.execute_NoCommit(pNdb) == 0); int sleep = minSleep + myRandom48(maxSleep-minSleep); @@ -162,25 +162,25 @@ int runTimeoutTrans2(NDBT_Context* ctx, NDBT_Step* step){ case 0: break; case 1: - if(hugoOps.pkReadRecord(pNdb, stepNo, true) != 0){ + if(hugoOps.pkReadRecord(pNdb, stepNo) != 0){ g_err << stepNo << ": Fail" << __LINE__ << endl; result = NDBT_FAILED; break; } break; case 2: - if(hugoOps.pkUpdateRecord(pNdb, stepNo, true) != 0){ + if(hugoOps.pkUpdateRecord(pNdb, stepNo) != 0){ g_err << stepNo << ": Fail" << __LINE__ << endl; result = NDBT_FAILED; break; } break; case 3: - if(hugoOps.pkDeleteRecord(pNdb, stepNo, true) != 0){ + if(hugoOps.pkDeleteRecord(pNdb, stepNo) != 0){ g_err << stepNo << ": Fail" << __LINE__ << endl; result = NDBT_FAILED; break; } break; case 4: - if(hugoOps.pkInsertRecord(pNdb, stepNo+records+l, true) != 0){ + if(hugoOps.pkInsertRecord(pNdb, stepNo+records+l) != 0){ g_err << stepNo << ": Fail" << __LINE__ << endl; result = NDBT_FAILED; break; } @@ -204,25 +204,25 @@ int runTimeoutTrans2(NDBT_Context* ctx, NDBT_Step* step){ case 0: break; case 1: - if(hugoOps.pkReadRecord(pNdb, stepNo, true) != 0){ + if(hugoOps.pkReadRecord(pNdb, stepNo) != 0){ g_err << stepNo << ": Fail" << __LINE__ << endl; result = NDBT_FAILED; break; } break; case 2: - if(hugoOps.pkUpdateRecord(pNdb, stepNo, true) != 0){ + if(hugoOps.pkUpdateRecord(pNdb, stepNo) != 0){ g_err << stepNo << ": Fail" << __LINE__ << endl; result = NDBT_FAILED; break; } break; case 3: - if(hugoOps.pkDeleteRecord(pNdb, stepNo, true) != 0){ + if(hugoOps.pkDeleteRecord(pNdb, stepNo) != 0){ g_err << stepNo << ": Fail" << __LINE__ << endl; result = NDBT_FAILED; break; } break; case 4: - if(hugoOps.pkInsertRecord(pNdb, stepNo+2*records+l, true) != 0){ + if(hugoOps.pkInsertRecord(pNdb, stepNo+2*records+l) != 0){ g_err << stepNo << ": Fail" << __LINE__ << endl; result = NDBT_FAILED; break; } @@ -263,7 +263,7 @@ int runDontTimeoutTrans(NDBT_Context* ctx, NDBT_Step* step){ do{ // Commit transaction CHECK(hugoOps.startTransaction(pNdb) == 0); - CHECK(hugoOps.pkReadRecord(pNdb, stepNo, true) == 0); + CHECK(hugoOps.pkReadRecord(pNdb, stepNo) == 0); CHECK(hugoOps.execute_NoCommit(pNdb) == 0); int sleep = myRandom48(maxSleep); @@ -299,7 +299,7 @@ int runBuddyTransNoTimeout(NDBT_Context* ctx, NDBT_Step* step){ // Start an insert trans CHECK(hugoOps.startTransaction(pNdb) == 0); int recordNo = records + (stepNo*loops) + l; - CHECK(hugoOps.pkInsertRecord(pNdb, recordNo, true) == 0); + CHECK(hugoOps.pkInsertRecord(pNdb, recordNo) == 0); CHECK(hugoOps.execute_NoCommit(pNdb) == 0); for (int i = 0; i < 3; i++){ diff --git a/ndb/test/ndbapi/testTransactions.cpp b/ndb/test/ndbapi/testTransactions.cpp index 2dca9e24fb4..46be808d8a5 100644 --- a/ndb/test/ndbapi/testTransactions.cpp +++ b/ndb/test/ndbapi/testTransactions.cpp @@ -190,13 +190,13 @@ runOp(HugoOperations & hugoOps, return NDBT_FAILED; } if(strcmp(op, "READ") == 0){ - C2(hugoOps.pkReadRecord(pNdb, 1, false, 1) == 0); + C2(hugoOps.pkReadRecord(pNdb, 1, 1, NdbOperation::LM_Read) == 0); } else if(strcmp(op, "READ-EX") == 0){ - C2(hugoOps.pkReadRecord(pNdb, 1, true, 1) == 0); + C2(hugoOps.pkReadRecord(pNdb, 1, 1, NdbOperation::LM_Exclusive) == 0); } else if(strcmp(op, "S-READ") == 0){ - C2(hugoOps.pkSimpleReadRecord(pNdb, 1, 1) == 0); + C2(hugoOps.pkReadRecord(pNdb, 1, 1, NdbOperation::LM_Read) == 0); } else if(strcmp(op, "D-READ") == 0){ - C2(hugoOps.pkDirtyReadRecord(pNdb, 1, 1) == 0); + C2(hugoOps.pkReadRecord(pNdb, 1, 1, NdbOperation::LM_CommittedRead) == 0); } else if(strcmp(op, "INSERT") == 0){ C2(hugoOps.pkInsertRecord(pNdb, 1, 1, value) == 0); } else if(strcmp(op, "UPDATE") == 0){ diff --git a/ndb/test/ndbapi/userInterface.cpp b/ndb/test/ndbapi/userInterface.cpp index fdbc229cc98..2f77c0f4857 100644 --- a/ndb/test/ndbapi/userInterface.cpp +++ b/ndb/test/ndbapi/userInterface.cpp @@ -103,7 +103,7 @@ void showTime() now = ::time((time_t*)NULL); tm_now = ::gmtime(&now); - ::snprintf(buf, 128, + BaseString::snprintf(buf, 128, "%d-%.2d-%.2d %.2d:%.2d:%.2d", tm_now->tm_year + 1900, tm_now->tm_mon, diff --git a/ndb/test/run-test/daily-devel-tests.txt b/ndb/test/run-test/daily-devel-tests.txt index f2abc961807..5c0b2821d85 100644 --- a/ndb/test/run-test/daily-devel-tests.txt +++ b/ndb/test/run-test/daily-devel-tests.txt @@ -52,26 +52,30 @@ args: -n SR4 T6 # max-time: 1500 cmd: testSystemRestart -args: -n SR_FULLDB T1 +args: -n SR_FULLDB T6 # # NODE RESTARTS # max-time: 2500 cmd: testNodeRestart -args: -n NoLoad T6 T8 T13 +args: -n NoLoad T6 max-time: 2500 cmd: testNodeRestart -args: -n PkRead T6 T8 T13 +args: -n MixedPkRead T6 T8 T13 max-time: 2500 cmd: testNodeRestart -args: -l 1 -n PkReadPkUpdate +args: -l 1 -n MixedPkReadPkUpdate max-time: 2500 cmd: testNodeRestart -args: -l 1 -n ReadUpdateScan +args: -l 1 -n MixedReadUpdateScan + +max-time: 2500 +cmd: testNodeRestart +args: -n CommittedRead T1 max-time: 2500 cmd: testNodeRestart @@ -186,10 +190,6 @@ max-time: 2500 cmd: testDict args: -n NF1 T1 T6 T13 -max-time: 2500 -cmd: test_event -args: -n BasicEventOperation T1 T6 - # max-time: 1500 cmd: testSystemRestart @@ -206,3 +206,9 @@ args: -l 1 -n SR8 T1 max-time: 1500 cmd: testSystemRestart args: -l 1 -n SR9 T1 + +# +max-time: 2500 +cmd: test_event +args: -n BasicEventOperation T1 T6 + diff --git a/ndb/test/src/HugoCalculator.cpp b/ndb/test/src/HugoCalculator.cpp index 147c8b104d8..62c35c54a7a 100644 --- a/ndb/test/src/HugoCalculator.cpp +++ b/ndb/test/src/HugoCalculator.cpp @@ -96,7 +96,7 @@ HugoCalculator::calcValue(int record, // of the string, then fill with other chars // The string length is set to the same size as the attribute len = attr->getLength(); - snprintf(buf, len, "%d", val); + BaseString::snprintf(buf, len, "%d", val); for(int i=strlen(buf); i < len; i++) buf[i] = a[((val^i)%25)]; } else{ diff --git a/ndb/test/src/HugoOperations.cpp b/ndb/test/src/HugoOperations.cpp index 7c05cb86a93..e8e2d992345 100644 --- a/ndb/test/src/HugoOperations.cpp +++ b/ndb/test/src/HugoOperations.cpp @@ -52,8 +52,8 @@ NdbConnection* HugoOperations::getTransaction(){ int HugoOperations::pkReadRecord(Ndb* pNdb, int recordNo, - bool exclusive, - int numRecords){ + int numRecords, + NdbOperation::LockMode lm){ int a; allocRows(numRecords); int check; @@ -64,94 +64,22 @@ int HugoOperations::pkReadRecord(Ndb* pNdb, return NDBT_FAILED; } - if (exclusive == true) - check = pOp->readTupleExclusive(); - else +rand_lock_mode: + switch(lm){ + case NdbOperation::LM_Read: check = pOp->readTuple(); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - return NDBT_FAILED; - } - - // Define primary keys - for(a = 0; a<tab.getNoOfColumns(); a++){ - if (tab.getColumn(a)->getPrimaryKey() == true){ - if(equalForAttr(pOp, a, r+recordNo) != 0){ - ERR(pTrans->getNdbError()); - return NDBT_FAILED; - } - } - } - - // Define attributes to read - for(a = 0; a<tab.getNoOfColumns(); a++){ - if((rows[r]->attributeStore(a) = - pOp->getValue(tab.getColumn(a)->getName())) == 0) { - ERR(pTrans->getNdbError()); - return NDBT_FAILED; - } - } - } - return NDBT_OK; -} - -int HugoOperations::pkDirtyReadRecord(Ndb* pNdb, - int recordNo, - int numRecords){ - int a; - allocRows(numRecords); - int check; - for(int r=0; r < numRecords; r++){ - NdbOperation* pOp = pTrans->getNdbOperation(tab.getName()); - if (pOp == NULL) { - ERR(pTrans->getNdbError()); - return NDBT_FAILED; - } - - check = pOp->dirtyRead(); - - if( check == -1 ) { - ERR(pTrans->getNdbError()); - return NDBT_FAILED; - } - - // Define primary keys - for(a = 0; a<tab.getNoOfColumns(); a++){ - if (tab.getColumn(a)->getPrimaryKey() == true){ - if(equalForAttr(pOp, a, r+recordNo) != 0){ - ERR(pTrans->getNdbError()); - return NDBT_FAILED; - } - } - } - - // Define attributes to read - for(a = 0; a<tab.getNoOfColumns(); a++){ - if((rows[r]->attributeStore(a) = - pOp->getValue(tab.getColumn(a)->getName())) == 0) { - ERR(pTrans->getNdbError()); - return NDBT_FAILED; - } - } - } - return NDBT_OK; -} - -int HugoOperations::pkSimpleReadRecord(Ndb* pNdb, - int recordNo, - int numRecords){ - int a; - allocRows(numRecords); - int check; - for(int r=0; r < numRecords; r++){ - NdbOperation* pOp = pTrans->getNdbOperation(tab.getName()); - if (pOp == NULL) { - ERR(pTrans->getNdbError()); - return NDBT_FAILED; + break; + case NdbOperation::LM_Exclusive: + check = pOp->readTupleExclusive(); + break; + case NdbOperation::LM_CommittedRead: + check = pOp->dirtyRead(); + break; + default: + lm = (NdbOperation::LockMode)((rand() >> 16) & 3); + goto rand_lock_mode; } - check = pOp->simpleRead(); - if( check == -1 ) { ERR(pTrans->getNdbError()); return NDBT_FAILED; diff --git a/ndb/test/src/HugoTransactions.cpp b/ndb/test/src/HugoTransactions.cpp index 994a45de3dc..456bfffbb77 100644 --- a/ndb/test/src/HugoTransactions.cpp +++ b/ndb/test/src/HugoTransactions.cpp @@ -1230,7 +1230,7 @@ int HugoTransactions::pkReadRecords(Ndb* pNdb, int records, int batchsize, - bool dirty){ + NdbOperation::LockMode lm){ int reads = 0; int r = 0; int retryAttempt = 0; @@ -1275,11 +1275,22 @@ HugoTransactions::pkReadRecords(Ndb* pNdb, return NDBT_FAILED; } - if (dirty == true){ - check = pOp->dirtyRead(); - } else { + rand_lock_mode: + switch(lm){ + case NdbOperation::LM_Read: check = pOp->readTuple(); + break; + case NdbOperation::LM_Exclusive: + check = pOp->readTupleExclusive(); + break; + case NdbOperation::LM_CommittedRead: + check = pOp->dirtyRead(); + break; + default: + lm = (NdbOperation::LockMode)((rand() >> 16) & 3); + goto rand_lock_mode; } + if( check == -1 ) { ERR(pTrans->getNdbError()); pNdb->closeTransaction(pTrans); diff --git a/ndb/test/src/NDBT_ResultRow.cpp b/ndb/test/src/NDBT_ResultRow.cpp index 7c419444760..f82963901b1 100644 --- a/ndb/test/src/NDBT_ResultRow.cpp +++ b/ndb/test/src/NDBT_ResultRow.cpp @@ -58,10 +58,14 @@ NDBT_ResultRow::attributeStore(int i){ return data[i]; } +const NdbRecAttr* +NDBT_ResultRow::attributeStore(int i) const { + return data[i]; +} const NdbRecAttr * -NDBT_ResultRow::attributeStore(const char* name){ +NDBT_ResultRow::attributeStore(const char* name) const { for(int i = 0; i<cols; i++){ if (strcmp(names[i], name) == 0) return data[i]; diff --git a/ndb/test/src/NDBT_Table.cpp b/ndb/test/src/NDBT_Table.cpp index d283cdf5912..8d398b75d81 100644 --- a/ndb/test/src/NDBT_Table.cpp +++ b/ndb/test/src/NDBT_Table.cpp @@ -24,7 +24,7 @@ operator <<(class NdbOut& ndbout, const NDBT_Table & tab) ndbout << "-- " << tab.getName() << " --" << endl; ndbout << "Version: " << tab.getObjectVersion() << endl; - ndbout << "Fragment type: " << tab.getFragmentType() << endl; + ndbout << "Fragment type: " << (unsigned) tab.getFragmentType() << endl; ndbout << "K Value: " << tab.getKValue()<< endl; ndbout << "Min load factor: " << tab.getMinLoadFactor()<< endl; ndbout << "Max load factor: " << tab.getMaxLoadFactor()<< endl; @@ -47,7 +47,7 @@ operator <<(class NdbOut& ndbout, const NDBT_Table & tab) ndbout << "Retrieved" << endl; break; default: - ndbout << "Unknown(" << tab.getObjectStatus() << ")" << endl; + ndbout << "Unknown(" << (unsigned) tab.getObjectStatus() << ")" << endl; } ndbout << "-- Attributes -- " << endl; @@ -81,7 +81,7 @@ class NdbOut& operator <<(class NdbOut&, const NdbDictionary::Index & idx) ndbout << "OrderedIndex"; break; default: - ndbout << "Type " << idx.getType(); + ndbout << "Type " << (unsigned) idx.getType(); break; } return ndbout; diff --git a/ndb/test/src/NDBT_Test.cpp b/ndb/test/src/NDBT_Test.cpp index 4ff94bcf296..367223f8c98 100644 --- a/ndb/test/src/NDBT_Test.cpp +++ b/ndb/test/src/NDBT_Test.cpp @@ -484,7 +484,7 @@ void NDBT_TestCaseImpl1::startStepInThread(int stepNo, NDBT_Context* ctx){ NDBT_Step* pStep = steps[stepNo]; pStep->setContext(ctx); char buf[16]; - snprintf(buf, sizeof(buf), "step_%d", stepNo); + BaseString::snprintf(buf, sizeof(buf), "step_%d", stepNo); NdbThread* pThread = NdbThread_Create(runStep_C, (void**)pStep, 65535, @@ -704,7 +704,7 @@ void NDBT_TestCaseImpl1::printTestResult(){ res = "FAILED TO CREATE TABLE"; else if (tcr->getResult() == FAILED_TO_DISCOVER) res = "FAILED TO DISCOVER TABLE"; - snprintf(buf, 255," %-10s %-5s %-20s", tcr->getName(), res, tcr->getTimeStr()); + BaseString::snprintf(buf, 255," %-10s %-5s %-20s", tcr->getName(), res, tcr->getTimeStr()); ndbout << buf<<endl; } } @@ -1078,7 +1078,7 @@ const char* NDBT_TestSuite::getDate(){ tm_now = gmtime(&now); #endif - snprintf(theTime, 128, + BaseString::snprintf(theTime, 128, "%d-%.2d-%.2d %.2d:%.2d:%.2d", tm_now->tm_year + 1900, tm_now->tm_mon + 1, @@ -1150,6 +1150,20 @@ void NDBT_Step::print(){ } +void +NDBT_Context::sync_down(const char * key){ + Uint32 threads = getProperty(key, (unsigned)0); + if(threads){ + decProperty(key); + } +} + +void +NDBT_Context::sync_up_and_wait(const char * key, Uint32 value){ + setProperty(key, value); + getPropertyWait(key, (unsigned)0); +} + template class Vector<NDBT_TestCase*>; template class Vector<NDBT_TestCaseResult*>; template class Vector<NDBT_Step*>; diff --git a/ndb/test/src/NdbBackup.cpp b/ndb/test/src/NdbBackup.cpp index ad26dbeab16..1ce48d495a5 100644 --- a/ndb/test/src/NdbBackup.cpp +++ b/ndb/test/src/NdbBackup.cpp @@ -143,7 +143,7 @@ NdbBackup::execRestore(bool _restore_data, * Copy backup files to local dir */ - snprintf(buf, buf_len, + BaseString::snprintf(buf, buf_len, "scp %s:%s/BACKUP/BACKUP-%d/BACKUP-%d*.%d.* .", host, path, _backup_id, @@ -155,7 +155,7 @@ NdbBackup::execRestore(bool _restore_data, ndbout << "scp res: " << res << endl; - snprintf(buf, 255, "%sndb_restore -c \"host=%s\" -n %d -b %d %s %s .", + BaseString::snprintf(buf, 255, "%sndb_restore -c \"host=%s\" -n %d -b %d %s %s .", #if 1 "", #else diff --git a/ndb/test/src/NdbGrep.cpp b/ndb/test/src/NdbGrep.cpp index 8b7442b0e77..6c0c9cabfcb 100644 --- a/ndb/test/src/NdbGrep.cpp +++ b/ndb/test/src/NdbGrep.cpp @@ -60,10 +60,10 @@ NdbGrep::verify(NDBT_Context * ctx){ return -1; char cheat_table[255]; - snprintf(cheat_table, 255, "TEST_DB/def/%s",ctx->getTab()->getName()); + BaseString::snprintf(cheat_table, 255, "TEST_DB/def/%s",ctx->getTab()->getName()); char buf[255]; - snprintf(buf, 255, "testGrepVerify -c \"nodeid=%d;host=%s\" -t %s -r %d", + BaseString::snprintf(buf, 255, "testGrepVerify -c \"nodeid=%d;host=%s\" -t %s -r %d", 4, //cheat. Hardcoded nodeid.... ctx->getRemoteMgm(), cheat_table, diff --git a/ndb/test/src/UtilTransactions.cpp b/ndb/test/src/UtilTransactions.cpp index 506356dd140..c0e6effd244 100644 --- a/ndb/test/src/UtilTransactions.cpp +++ b/ndb/test/src/UtilTransactions.cpp @@ -383,11 +383,20 @@ UtilTransactions::clearTable3(Ndb* pNdb, pOp = pTrans->getNdbScanOperation(tab.getName()); if (pOp == NULL) { + err = pTrans->getNdbError(); + if(err.status == NdbError::TemporaryError){ + ERR(err); + pNdb->closeTransaction(pTrans); + NdbSleep_MilliSleep(50); + par = 1; + goto restart; + } goto failed; } NdbResultSet * rs = pOp->readTuplesExclusive(par); if( rs == 0 ) { + err = pTrans->getNdbError(); goto failed; } @@ -647,8 +656,16 @@ UtilTransactions::scanReadRecords(Ndb* pNdb, pOp = pTrans->getNdbScanOperation(tab.getName()); if (pOp == NULL) { - ERR(pTrans->getNdbError()); + const NdbError err = pNdb->getNdbError(); pNdb->closeTransaction(pTrans); + + if (err.status == NdbError::TemporaryError){ + ERR(err); + NdbSleep_MilliSleep(50); + retryAttempt++; + continue; + } + ERR(err); return NDBT_FAILED; } @@ -854,11 +871,12 @@ UtilTransactions::verifyIndex(Ndb* pNdb, ndbout << " Index " << indexName << " does not exist!" << endl; return NDBT_FAILED; } - + switch (pIndex->getType()){ case NdbDictionary::Index::UniqueHashIndex: + return verifyUniqueIndex(pNdb, pIndex, parallelism, transactional); case NdbDictionary::Index::OrderedIndex: - return verifyUniqueIndex(pNdb, indexName, parallelism, transactional); + return verifyOrderedIndex(pNdb, pIndex, parallelism, transactional); break; default: ndbout << "Unknown index type" << endl; @@ -870,7 +888,7 @@ UtilTransactions::verifyIndex(Ndb* pNdb, int UtilTransactions::verifyUniqueIndex(Ndb* pNdb, - const char* indexName, + const NdbDictionary::Index * pIndex, int parallelism, bool transactional){ @@ -882,7 +900,7 @@ UtilTransactions::verifyUniqueIndex(Ndb* pNdb, */ if (scanAndCompareUniqueIndex(pNdb, - indexName, + pIndex, parallelism, transactional) != NDBT_OK){ return NDBT_FAILED; @@ -896,7 +914,7 @@ UtilTransactions::verifyUniqueIndex(Ndb* pNdb, int UtilTransactions::scanAndCompareUniqueIndex(Ndb* pNdb, - const char * indexName, + const NdbDictionary::Index* pIndex, int parallelism, bool transactional){ @@ -933,8 +951,15 @@ UtilTransactions::scanAndCompareUniqueIndex(Ndb* pNdb, pOp = pTrans->getNdbScanOperation(tab.getName()); if (pOp == NULL) { - ERR(pTrans->getNdbError()); + const NdbError err = pNdb->getNdbError(); pNdb->closeTransaction(pTrans); + ERR(err); + + if (err.status == NdbError::TemporaryError){ + NdbSleep_MilliSleep(50); + retryAttempt++; + continue; + } return NDBT_FAILED; } @@ -996,7 +1021,7 @@ UtilTransactions::scanAndCompareUniqueIndex(Ndb* pNdb, if (readRowFromTableAndIndex(pNdb, pTrans, - indexName, + pIndex, row) != NDBT_OK){ pNdb->closeTransaction(pTrans); return NDBT_FAILED; @@ -1027,15 +1052,9 @@ UtilTransactions::scanAndCompareUniqueIndex(Ndb* pNdb, int UtilTransactions::readRowFromTableAndIndex(Ndb* pNdb, NdbConnection* scanTrans, - const char * indexName, + const NdbDictionary::Index* pIndex, NDBT_ResultRow& row ){ - const NdbDictionary::Index* pIndex - = pNdb->getDictionary()->getIndex(indexName, tab.getName()); - if (pIndex == 0){ - ndbout << " Index " << indexName << " does not exist!" << endl; - return NDBT_FAILED; - } NdbDictionary::Index::Type indexType= pIndex->getType(); int retryAttempt = 0; @@ -1050,7 +1069,7 @@ UtilTransactions::readRowFromTableAndIndex(Ndb* pNdb, // Allocate place to store the result NDBT_ResultRow tabRow(tab); NDBT_ResultRow indexRow(tab); - + const char * indexName = pIndex->getName(); while (true){ if(retryAttempt) @@ -1281,3 +1300,239 @@ close_all: return return_code; } + +int +UtilTransactions::verifyOrderedIndex(Ndb* pNdb, + const NdbDictionary::Index* pIndex, + int parallelism, + bool transactional){ + + int retryAttempt = 0; + const int retryMax = 100; + int check; + NdbConnection *pTrans; + NdbScanOperation *pOp; + NdbIndexScanOperation * iop = 0; + NdbResultSet* cursor= 0; + + NDBT_ResultRow scanRow(tab); + NDBT_ResultRow pkRow(tab); + NDBT_ResultRow indexRow(tab); + const char * indexName = pIndex->getName(); + + int res; + parallelism = 1; + + while (true){ + + if (retryAttempt >= retryMax){ + g_info << "ERROR: has retried this operation " << retryAttempt + << " times, failing!" << endl; + return NDBT_FAILED; + } + + pTrans = pNdb->startTransaction(); + if (pTrans == NULL) { + const NdbError err = pNdb->getNdbError(); + + if (err.status == NdbError::TemporaryError){ + ERR(err); + NdbSleep_MilliSleep(50); + retryAttempt++; + continue; + } + ERR(err); + return NDBT_FAILED; + } + + pOp = pTrans->getNdbScanOperation(tab.getName()); + if (pOp == NULL) { + ERR(pTrans->getNdbError()); + pNdb->closeTransaction(pTrans); + return NDBT_FAILED; + } + + NdbResultSet* + rs = pOp->readTuples(NdbScanOperation::LM_Read, 0, parallelism); + + if( rs == 0 ) { + ERR(pTrans->getNdbError()); + pNdb->closeTransaction(pTrans); + return NDBT_FAILED; + } + + check = pOp->interpret_exit_ok(); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + pNdb->closeTransaction(pTrans); + return NDBT_FAILED; + } + + if(get_values(pOp, scanRow)) + { + abort(); + } + + check = pTrans->execute(NoCommit); + if( check == -1 ) { + const NdbError err = pTrans->getNdbError(); + + if (err.status == NdbError::TemporaryError){ + ERR(err); + pNdb->closeTransaction(pTrans); + NdbSleep_MilliSleep(50); + retryAttempt++; + continue; + } + ERR(err); + pNdb->closeTransaction(pTrans); + return NDBT_FAILED; + } + + int eof; + int rows = 0; + while(check == 0 && (eof = rs->nextResult()) == 0){ + rows++; + + bool null_found= false; + for(int a = 0; a<(int)pIndex->getNoOfColumns(); a++){ + const NdbDictionary::Column * col = pIndex->getColumn(a); + if (scanRow.attributeStore(col->getName())->isNULL()) + { + null_found= true; + break; + } + } + + // Do pk lookup + NdbOperation * pk = pTrans->getNdbOperation(tab.getName()); + if(!pk || pk->readTuple()) + goto error; + if(equal(&tab, pk, scanRow) || get_values(pk, pkRow)) + goto error; + + if(!null_found) + { + if(!iop && (iop= pTrans->getNdbIndexScanOperation(indexName, + tab.getName()))) + { + cursor= iop->readTuples(NdbScanOperation::LM_CommittedRead, + parallelism); + iop->interpret_exit_ok(); + if(!cursor || get_values(iop, indexRow)) + goto error; + } + else if(!iop || iop->reset_bounds()) + { + goto error; + } + + if(equal(pIndex, iop, scanRow)) + goto error; + } + + check = pTrans->execute(NoCommit); + if(check) + goto error; + + if(scanRow.c_str() != pkRow.c_str()){ + g_err << "Error when comapring records" << endl; + g_err << " scanRow: \n" << scanRow.c_str().c_str() << endl; + g_err << " pkRow: \n" << pkRow.c_str().c_str() << endl; + pNdb->closeTransaction(pTrans); + return NDBT_FAILED; + } + + if(!null_found) + { + + if((res= cursor->nextResult()) != 0){ + g_err << "Failed to find row using index: " << res << endl; + ERR(pTrans->getNdbError()); + pNdb->closeTransaction(pTrans); + return NDBT_FAILED; + } + + if(scanRow.c_str() != indexRow.c_str()){ + g_err << "Error when comapring records" << endl; + g_err << " scanRow: \n" << scanRow.c_str().c_str() << endl; + g_err << " indexRow: \n" << indexRow.c_str().c_str() << endl; + pNdb->closeTransaction(pTrans); + return NDBT_FAILED; + } + + if(cursor->nextResult() == 0){ + g_err << "Found extra row!!" << endl; + g_err << " indexRow: \n" << indexRow.c_str().c_str() << endl; + pNdb->closeTransaction(pTrans); + return NDBT_FAILED; + } + } + } + + if (eof == -1 || check == -1) { + error: + const NdbError err = pTrans->getNdbError(); + + if (err.status == NdbError::TemporaryError){ + ERR(err); + iop = 0; + pNdb->closeTransaction(pTrans); + NdbSleep_MilliSleep(50); + retryAttempt++; + rows--; + continue; + } + ERR(err); + pNdb->closeTransaction(pTrans); + return NDBT_FAILED; + } + + pNdb->closeTransaction(pTrans); + + return NDBT_OK; + } + return NDBT_FAILED; +} + +int +UtilTransactions::get_values(NdbOperation* op, NDBT_ResultRow& dst) +{ + for (int a = 0; a < tab.getNoOfColumns(); a++){ + NdbRecAttr*& ref= dst.attributeStore(a); + if ((ref= op->getValue(a)) == 0) + { + return NDBT_FAILED; + } + } + return 0; +} + +int +UtilTransactions::equal(const NdbDictionary::Index* pIndex, + NdbOperation* op, const NDBT_ResultRow& src) +{ + for(Uint32 a = 0; a<pIndex->getNoOfColumns(); a++){ + const NdbDictionary::Column * col = pIndex->getColumn(a); + if(op->equal(col->getName(), + src.attributeStore(col->getName())->aRef()) != 0){ + return NDBT_FAILED; + } + } + return 0; +} + +int +UtilTransactions::equal(const NdbDictionary::Table* pTable, + NdbOperation* op, const NDBT_ResultRow& src) +{ + for(Uint32 a = 0; a<tab.getNoOfColumns(); a++){ + const NdbDictionary::Column* attr = tab.getColumn(a); + if (attr->getPrimaryKey() == true){ + if (op->equal(attr->getName(), src.attributeStore(a)->aRef()) != 0){ + return NDBT_FAILED; + } + } + } + return 0; +} diff --git a/ndb/test/tools/transproxy.cpp b/ndb/test/tools/transproxy.cpp index 90e216ec785..88267801172 100644 --- a/ndb/test/tools/transproxy.cpp +++ b/ndb/test/tools/transproxy.cpp @@ -32,7 +32,7 @@ fatal(char const* fmt, ...) va_list ap; char buf[200]; va_start(ap, fmt); - vsnprintf(buf, sizeof(buf), fmt, ap); + BaseString::vsnprintf(buf, sizeof(buf), fmt, ap); va_end(ap); ndbout << "FATAL: " << buf << endl; sleep(1); @@ -45,7 +45,7 @@ debug(char const* fmt, ...) va_list ap; char buf[200]; va_start(ap, fmt); - vsnprintf(buf, sizeof(buf), fmt, ap); + BaseString::vsnprintf(buf, sizeof(buf), fmt, ap); va_end(ap); ndbout << buf << endl; } diff --git a/ndb/tools/listTables.cpp b/ndb/tools/listTables.cpp index 4b24929ee4b..4fc5bcd7f21 100644 --- a/ndb/tools/listTables.cpp +++ b/ndb/tools/listTables.cpp @@ -38,7 +38,7 @@ fatal(char const* fmt, ...) va_list ap; char buf[500]; va_start(ap, fmt); - vsnprintf(buf, sizeof(buf), fmt, ap); + BaseString::vsnprintf(buf, sizeof(buf), fmt, ap); va_end(ap); ndbout << buf; if (ndb) @@ -54,7 +54,7 @@ fatal_dict(char const* fmt, ...) va_list ap; char buf[500]; va_start(ap, fmt); - vsnprintf(buf, sizeof(buf), fmt, ap); + BaseString::vsnprintf(buf, sizeof(buf), fmt, ap); va_end(ap); ndbout << buf; if (dic) diff --git a/ndb/tools/waiter.cpp b/ndb/tools/waiter.cpp index c27b46c9356..c01a3f9192e 100644 --- a/ndb/tools/waiter.cpp +++ b/ndb/tools/waiter.cpp @@ -15,8 +15,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include <ndb_global.h> #include <mgmapi.h> -#include <string.h> #include <NdbMain.h> #include <NdbOut.hpp> #include <NdbSleep.h> @@ -68,7 +68,7 @@ int main(int argc, const char** argv){ return NDBT_ProgramExit(NDBT_FAILED); } - for (int i = 0; i<lcfg.ids.size();i++) + for (unsigned i = 0; i<lcfg.ids.size();i++) { MgmtSrvrId * m = &lcfg.ids[i]; @@ -292,8 +292,8 @@ waitClusterStatus(const char* _addr, if (ndbNode->node_status < _status) allInState = false; else - g_info << "node_status(" << ndbNode->node_status - <<") != _status("<<_status<<")"<<endl; + g_info << "node_status(" << (unsigned)ndbNode->node_status + << ") != _status("<< (unsigned)_status << ")" <<endl; } else if (ndbNode->start_phase < _startphase) allInState = false; } else { |