diff options
author | unknown <tsmith@sita.local> | 2007-07-09 10:33:33 -0600 |
---|---|---|
committer | unknown <tsmith@sita.local> | 2007-07-09 10:33:33 -0600 |
commit | 7350d52ce65f789b8ef8f0a54b4effb65f2316ad (patch) | |
tree | b7447a78c3e772d16b16c1b4f3b56adb47887205 /storage | |
parent | 407209c163564d5321e9cfab60d622c665ea51d9 (diff) | |
parent | 1d599ea1cff1c501ef4d5ba5deedfd2af44a78e0 (diff) | |
download | mariadb-git-7350d52ce65f789b8ef8f0a54b4effb65f2316ad.tar.gz |
Merge tsmith@bk-internal.mysql.com:/home/bk/mysql-5.1-maint
into sita.local:/Users/tsmith/m/bk/maint/51
mysql-test/suite/rpl/r/rpl_row_tabledefs_2myisam.result:
Auto merged
mysql-test/suite/rpl/r/rpl_row_tabledefs_3innodb.result:
Auto merged
Diffstat (limited to 'storage')
-rw-r--r-- | storage/ndb/include/ndbapi/Ndb.hpp | 34 | ||||
-rw-r--r-- | storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp | 24 | ||||
-rw-r--r-- | storage/ndb/src/kernel/blocks/lgman.cpp | 17 | ||||
-rw-r--r-- | storage/ndb/src/kernel/blocks/lgman.hpp | 3 | ||||
-rw-r--r-- | storage/ndb/src/ndbapi/Ndb.cpp | 176 | ||||
-rw-r--r-- | storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp | 2 |
6 files changed, 240 insertions, 16 deletions
diff --git a/storage/ndb/include/ndbapi/Ndb.hpp b/storage/ndb/include/ndbapi/Ndb.hpp index a6a3df92ddb..4d0219d1a3c 100644 --- a/storage/ndb/include/ndbapi/Ndb.hpp +++ b/storage/ndb/include/ndbapi/Ndb.hpp @@ -1281,6 +1281,16 @@ public: */ /** + * Structure for passing in pointers to startTransaction + * + */ + struct Key_part_ptr + { + const void * ptr; + unsigned len; + }; + + /** * Start a transaction * * @note When the transaction is completed it must be closed using @@ -1301,6 +1311,30 @@ public: Uint32 keyLen = 0); /** + * Compute hash value given table/keys + * + * @param hashvalueptr - OUT, is set to hashvalue if return value is 0 + * @param table Pointer to table object + * @param keyData Null-terminated array of pointers to keyParts that is + * part of distribution key. + * Length of resp. keyPart will be read from + * metadata and checked against passed value + * @param xfrmbuf Pointer to temporary buffer that will be used + * to calculate hashvalue + * @param xfrmbuflen Lengh of buffer + * + * @note if xfrmbuf is null (default) malloc/free will be made + * if xfrmbuf is not null but length is too short, method will fail + * + * @return 0 - ok - hashvalueptr is set + * else - fail, return error code + */ + static int computeHash(Uint32* hashvalueptr, + const NdbDictionary::Table*, + const struct Key_part_ptr * keyData, + void* xfrmbuf = 0, Uint32 xfrmbuflen = 0); + + /** * Close a transaction. * * @note should be called after the transaction has completed, irrespective diff --git a/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp b/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp index e47fcf34471..efb88bfccd2 100644 --- a/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp +++ b/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp @@ -11795,7 +11795,7 @@ void Dblqh::sendLCP_COMPLETE_REP(Signal* signal, Uint32 lcpId) sendEMPTY_LCP_CONF(signal, true); } - if (getNodeState().getNodeRestartInProgress()) + if (getNodeState().getNodeRestartInProgress() && cstartRecReq != 3) { jam(); ndbrequire(cstartRecReq == 2); @@ -14215,15 +14215,6 @@ void Dblqh::execSTART_RECREQ(Signal* signal) * WE ALSO NEED TO SET CNEWEST_GCI TO ENSURE THAT LOG RECORDS ARE EXECUTED * WITH A PROPER GCI. *------------------------------------------------------------------------ */ - if(cstartType == NodeState::ST_INITIAL_NODE_RESTART){ - jam(); - cstartRecReq = 2; - StartRecConf * conf = (StartRecConf*)signal->getDataPtrSend(); - conf->startingNodeId = getOwnNodeId(); - sendSignal(cmasterDihBlockref, GSN_START_RECCONF, signal, - StartRecConf::SignalLength, JBB); - return; - }//if if (c_lcp_restoring_fragments.isEmpty()) { @@ -14276,6 +14267,19 @@ void Dblqh::execSTART_RECCONF(Signal* signal) jam(); csrExecUndoLogState = EULS_COMPLETED; + + if(cstartType == NodeState::ST_INITIAL_NODE_RESTART) + { + jam(); + cstartRecReq = 2; + + StartRecConf * conf = (StartRecConf*)signal->getDataPtrSend(); + conf->startingNodeId = getOwnNodeId(); + sendSignal(cmasterDihBlockref, GSN_START_RECCONF, signal, + StartRecConf::SignalLength, JBB); + return; + } + c_lcp_complete_fragments.first(fragptr); build_acc(signal, fragptr.i); return; diff --git a/storage/ndb/src/kernel/blocks/lgman.cpp b/storage/ndb/src/kernel/blocks/lgman.cpp index 25cdac89737..23738717580 100644 --- a/storage/ndb/src/kernel/blocks/lgman.cpp +++ b/storage/ndb/src/kernel/blocks/lgman.cpp @@ -346,6 +346,12 @@ Lgman::execCREATE_FILEGROUP_REQ(Signal* signal){ m_logfile_group_hash.add(ptr); m_logfile_group_list.add(ptr); + + if (getNodeState().getNodeRestartInProgress() || + getNodeState().getSystemRestartInProgress()) + { + ptr.p->m_state = Logfile_group::LG_STARTING; + } CreateFilegroupImplConf* conf= (CreateFilegroupImplConf*)signal->getDataPtr(); @@ -370,8 +376,6 @@ Lgman::execDROP_FILEGROUP_REQ(Signal* signal) { jamEntry(); - jamEntry(); - Uint32 errorCode = 0; DropFilegroupImplReq req = *(DropFilegroupImplReq*)signal->getDataPtr(); do @@ -717,7 +721,8 @@ Lgman::create_file_commit(Signal* signal, Uint32 senderData = ptr.p->m_create.m_senderData; bool first= false; - if(ptr.p->m_state == Undofile::FS_CREATING) + if(ptr.p->m_state == Undofile::FS_CREATING && + (lg_ptr.p->m_state & Logfile_group::LG_ONLINE)) { jam(); Local_undofile_list free(m_file_pool, lg_ptr.p->m_files); @@ -2082,13 +2087,17 @@ Lgman::execSTART_RECREQ(Signal* signal) void Lgman::find_log_head(Signal* signal, Ptr<Logfile_group> ptr) { + ndbrequire(ptr.p->m_state & + (Logfile_group::LG_STARTING | Logfile_group::LG_SORTING)); + if(ptr.p->m_meta_files.isEmpty() && ptr.p->m_files.isEmpty()) { jam(); /** * Logfile_group wo/ any files */ - + ptr.p->m_state &= ~(Uint32)Logfile_group::LG_STARTING; + ptr.p->m_state |= Logfile_group::LG_ONLINE; m_logfile_group_list.next(ptr); signal->theData[0] = LgmanContinueB::FIND_LOG_HEAD; signal->theData[1] = ptr.i; diff --git a/storage/ndb/src/kernel/blocks/lgman.hpp b/storage/ndb/src/kernel/blocks/lgman.hpp index b26c3219088..d2706818144 100644 --- a/storage/ndb/src/kernel/blocks/lgman.hpp +++ b/storage/ndb/src/kernel/blocks/lgman.hpp @@ -175,13 +175,14 @@ public: ,LG_SORTING = 0x002 // Sorting files ,LG_SEARCHING = 0x004 // Searching in last file ,LG_EXEC_THREAD = 0x008 // Execute thread is running - ,LG_READ_THREAD = 0x010 // Read thread is running + ,LG_READ_THREAD = 0x010 // Read thread is running ,LG_FORCE_SYNC_THREAD = 0x020 ,LG_SYNC_WAITERS_THREAD = 0x040 ,LG_CUT_LOG_THREAD = 0x080 ,LG_WAITERS_THREAD = 0x100 ,LG_FLUSH_THREAD = 0x200 ,LG_DROPPING = 0x400 + ,LG_STARTING = 0x800 }; static const Uint32 LG_THREAD_MASK = Logfile_group::LG_FORCE_SYNC_THREAD | diff --git a/storage/ndb/src/ndbapi/Ndb.cpp b/storage/ndb/src/ndbapi/Ndb.cpp index 9b8e4e86d30..bbeeed3ae70 100644 --- a/storage/ndb/src/ndbapi/Ndb.cpp +++ b/storage/ndb/src/ndbapi/Ndb.cpp @@ -37,6 +37,7 @@ Name: Ndb.cpp #include "API.hpp" #include <NdbEnv.h> #include <BaseString.hpp> +#include <NdbSqlUtil.hpp> /**************************************************************************** void connect(); @@ -304,6 +305,181 @@ Return Value: Returns a pointer to a connection object. Return NULL otherwise. Remark: Start transaction. Synchronous. *****************************************************************************/ +int +Ndb::computeHash(Uint32 *retval, + const NdbDictionary::Table *table, + const struct Key_part_ptr * keyData, + void* buf, Uint32 bufLen) +{ + Uint32 j = 0; + Uint32 sumlen = 0; // Needed len + const NdbTableImpl* impl = &NdbTableImpl::getImpl(*table); + const NdbColumnImpl* const * cols = impl->m_columns.getBase(); + Uint32 len; + NdbTransaction* trans; + char* pos; + + Uint32 colcnt = impl->m_columns.size(); + Uint32 parts = impl->m_noOfDistributionKeys; + if (parts == 0) + { + parts = impl->m_noOfKeys; + } + + for (Uint32 i = 0; i<parts; i++) + { + if (unlikely(keyData[i].ptr == 0)) + goto enullptr; + } + + if (unlikely(keyData[parts].ptr != 0)) + goto emissingnullptr; + + const NdbColumnImpl* partcols[NDB_MAX_NO_OF_ATTRIBUTES_IN_KEY]; + for (Uint32 i = 0; i<colcnt && j < parts; i++) + { + if (cols[i]->m_distributionKey) + { + // wl3717_todo + // char allowed now as dist key so this case should be tested + partcols[j++] = cols[i]; + } + } + + for (Uint32 i = 0; i<parts; i++) + { + Uint32 lb, len; + if (unlikely(!NdbSqlUtil::get_var_length(partcols[i]->m_type, + keyData[i].ptr, + keyData[i].len, + lb, len))) + goto emalformedkey; + + if (unlikely(keyData[i].len < (lb + len))) + goto elentosmall; + + Uint32 maxlen = (partcols[i]->m_attrSize * partcols[i]->m_arraySize); + + if (unlikely(lb == 0 && keyData[i].len != maxlen)) + goto emalformedkey; + + if (partcols[i]->m_cs) + { + Uint32 xmul = partcols[i]->m_cs->strxfrm_multiply; + xmul = xmul ? xmul : 1; + len = xmul * (maxlen - lb); + } + + len = (lb + len + 3) & ~(Uint32)3; + sumlen += len; + + } + + if (buf) + { + UintPtr org = UintPtr(buf); + UintPtr use = (org + 7) & ~(UintPtr)7; + + buf = (void*)use; + bufLen -= (use - org); + + if (unlikely(sumlen > bufLen)) + goto ebuftosmall; + } + else + { + buf = malloc(sumlen); + if (unlikely(buf == 0)) + goto enomem; + bufLen = 0; + assert((UintPtr(buf) & 7) == 0); + } + + pos = (char*)buf; + for (Uint32 i = 0; i<parts; i++) + { + Uint32 lb, len; + NdbSqlUtil::get_var_length(partcols[i]->m_type, + keyData[i].ptr, keyData[i].len, lb, len); + CHARSET_INFO* cs; + if ((cs = partcols[i]->m_cs)) + { + Uint32 xmul = cs->strxfrm_multiply; + if (xmul == 0) + xmul = 1; + /* + * Varchar end-spaces are ignored in comparisons. To get same hash + * we blank-pad to maximum length via strnxfrm. + */ + Uint32 maxlen = (partcols[i]->m_attrSize * partcols[i]->m_arraySize); + Uint32 dstLen = xmul * (maxlen - lb); + int n = NdbSqlUtil::strnxfrm_bug7284(cs, + (unsigned char*)pos, + dstLen, + ((unsigned char*)keyData[i].ptr)+lb, + len); + + if (unlikely(n == -1)) + goto emalformedstring; + + while ((n & 3) != 0) + { + pos[n++] = 0; + } + pos += n; + } + else + { + len += lb; + memcpy(pos, keyData[i].ptr, len); + while (len & 3) + { + * (pos + len++) = 0; + } + pos += len; + } + } + len = UintPtr(pos) - UintPtr(buf); + assert((len & 3) == 0); + + Uint32 values[4]; + md5_hash(values, (const Uint64*)buf, len >> 2); + + if (retval) + { + * retval = values[1]; + } + + if (bufLen == 0) + free(buf); + + return 0; + +enullptr: + return 4316; + +emissingnullptr: + return 4276; + +elentosmall: + return 4277; + +ebuftosmall: + return 4278; + +emalformedstring: + if (bufLen == 0) + free(buf); + + return 4279; + +emalformedkey: + return 4280; + +enomem: + return 4000; +} + NdbTransaction* Ndb::startTransaction(const NdbDictionary::Table *table, const char * keyData, Uint32 keyLen) diff --git a/storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp b/storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp index 673587b1ed7..aa9bd174471 100644 --- a/storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp +++ b/storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp @@ -391,7 +391,7 @@ struct NdbFileImpl : public NdbDictObjectImpl { NdbFileImpl(NdbDictionary::Object::Type t); Uint64 m_size; - Uint32 m_free; + Uint64 m_free; BaseString m_path; BaseString m_filegroup_name; Uint32 m_filegroup_id; |