diff options
Diffstat (limited to 'storage/ndb/src')
28 files changed, 763 insertions, 247 deletions
diff --git a/storage/ndb/src/kernel/blocks/ERROR_codes.txt b/storage/ndb/src/kernel/blocks/ERROR_codes.txt index 56b5b8e4bc8..83aa1183772 100644 --- a/storage/ndb/src/kernel/blocks/ERROR_codes.txt +++ b/storage/ndb/src/kernel/blocks/ERROR_codes.txt @@ -8,7 +8,7 @@ Next DBDICT 6007 Next DBDIH 7178 Next DBTC 8039 Next CMVMI 9000 -Next BACKUP 10036 +Next BACKUP 10038 Next DBUTIL 11002 Next DBTUX 12008 Next SUMA 13001 @@ -425,6 +425,9 @@ Backup Stuff: 10034: define backup reply error 10035: Fail to allocate buffers +10036: Halt backup for table >= 2 +10037: Resume backup (from 10036) + 11001: Send UTIL_SEQUENCE_REF (in master) 5028: Crash when receiving LQHKEYREQ (in non-master) diff --git a/storage/ndb/src/kernel/blocks/backup/Backup.cpp b/storage/ndb/src/kernel/blocks/backup/Backup.cpp index 79970ce9723..aae64b4bb6c 100644 --- a/storage/ndb/src/kernel/blocks/backup/Backup.cpp +++ b/storage/ndb/src/kernel/blocks/backup/Backup.cpp @@ -355,6 +355,25 @@ Backup::execCONTINUEB(Signal* signal) GetTabInfoReq::SignalLength, JBB); return; } + case BackupContinueB::ZDELAY_SCAN_NEXT: + if (ERROR_INSERTED(10036)) + { + jam(); + sendSignalWithDelay(BACKUP_REF, GSN_CONTINUEB, signal, 300, + signal->getLength()); + return; + } + else + { + jam(); + CLEAR_ERROR_INSERT_VALUE; + ndbout_c("Resuming backup"); + memmove(signal->theData, signal->theData + 1, + 4*ScanFragNextReq::SignalLength); + sendSignal(DBLQH_REF, GSN_SCAN_NEXTREQ, signal, + ScanFragNextReq::SignalLength, JBB); + return ; + } default: ndbrequire(0); }//switch @@ -3924,6 +3943,22 @@ Backup::checkScan(Signal* signal, BackupFilePtr filePtr) req->transId2 = (BACKUP << 20) + (getOwnNodeId() << 8); req->batch_size_rows= 16; req->batch_size_bytes= 0; + + if (ERROR_INSERTED(10036) && + filePtr.p->tableId >= 2 && + filePtr.p->operation.noOfRecords > 0) + { + ndbout_c("halting backup for table %d fragment: %d after %d records", + filePtr.p->tableId, + filePtr.p->fragmentNo, + filePtr.p->operation.noOfRecords); + memmove(signal->theData+1, signal->theData, + 4*ScanFragNextReq::SignalLength); + signal->theData[0] = BackupContinueB::ZDELAY_SCAN_NEXT; + sendSignalWithDelay(BACKUP_REF, GSN_CONTINUEB, signal, + 300, 1+ScanFragNextReq::SignalLength); + return; + } if(ERROR_INSERTED(10032)) sendSignalWithDelay(DBLQH_REF, GSN_SCAN_NEXTREQ, signal, 100, ScanFragNextReq::SignalLength); diff --git a/storage/ndb/src/kernel/blocks/dbacc/Dbacc.hpp b/storage/ndb/src/kernel/blocks/dbacc/Dbacc.hpp index 6474bb5b1a3..6337e252c0b 100644 --- a/storage/ndb/src/kernel/blocks/dbacc/Dbacc.hpp +++ b/storage/ndb/src/kernel/blocks/dbacc/Dbacc.hpp @@ -1099,6 +1099,7 @@ private: }; Uint32 c_errorInsert3000_TableId; + Uint32 c_memusage_report_frequency; }; #endif diff --git a/storage/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp b/storage/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp index e83c06dc38f..bf2fa5b7584 100644 --- a/storage/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp +++ b/storage/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp @@ -111,6 +111,7 @@ void Dbacc::execCONTINUEB(Signal* signal) } case ZREPORT_MEMORY_USAGE:{ jam(); + Uint32 cnt = signal->theData[1]; static int c_currentMemUsed = 0; int now = cpagesize ? (cnoOfAllocatedPages * 100)/cpagesize : 0; const int thresholds[] = { 99, 90, 80, 0}; @@ -124,14 +125,22 @@ void Dbacc::execCONTINUEB(Signal* signal) } } - if(now != c_currentMemUsed){ - reportMemoryUsage(signal, now > c_currentMemUsed ? 1 : -1); + if(now != c_currentMemUsed || + (c_memusage_report_frequency && cnt + 1 == c_memusage_report_frequency)) + { + reportMemoryUsage(signal, + now > c_currentMemUsed ? 1 : + now < c_currentMemUsed ? -1 : 0); + cnt = 0; + c_currentMemUsed = now; + } + else + { + cnt ++; } - - c_currentMemUsed = now; - signal->theData[0] = ZREPORT_MEMORY_USAGE; - sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 2000, 1); + signal->theData[1] = cnt; + sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 1000, 2); return; } @@ -198,7 +207,8 @@ void Dbacc::execNDB_STTOR(Signal* signal) csystemRestart = ZFALSE; signal->theData[0] = ZREPORT_MEMORY_USAGE; - sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 2000, 1); + signal->theData[1] = 0; + sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 1000, 2); break; default: jam(); @@ -352,6 +362,10 @@ void Dbacc::execREAD_CONFIG_REQ(Signal* signal) initRecords(); ndbrestart1Lab(signal); + c_memusage_report_frequency = 0; + ndb_mgm_get_int_parameter(p, CFG_DB_MEMREPORT_FREQUENCY, + &c_memusage_report_frequency); + tdata0 = 0; initialiseRecordsLab(signal, ref, senderData); return; diff --git a/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp b/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp index 87d9b7e631f..5f00f62da87 100644 --- a/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp +++ b/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp @@ -478,7 +478,7 @@ Dbdict::packTableIntoPages(SimpleProperties::Writer & w, CreateFragmentationReq::SignalLength); ndbrequire(signal->theData[0] == 0); Uint16 *data = (Uint16*)&signal->theData[25]; - Uint32 count = 2 + data[0] * data[1]; + Uint32 count = 2 + (1 + data[0]) * data[1]; w.add(DictTabInfo::ReplicaDataLen, 2*count); for (Uint32 i = 0; i < count; i++) data[i] = htons(data[i]); diff --git a/storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp b/storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp index a407280cf3d..af8f86b0d84 100644 --- a/storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp +++ b/storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp @@ -6727,7 +6727,7 @@ void Dbdih::execCREATE_FRAGMENTATION_REQ(Signal * signal) FragmentstorePtr fragPtr; ReplicaRecordPtr replicaPtr; getFragstore(primTabPtr.p, fragNo, fragPtr); - fragments[count++] = c_nextLogPart++; + fragments[count++] = fragPtr.p->m_log_part_id; fragments[count++] = fragPtr.p->preferredPrimary; for (replicaPtr.i = fragPtr.p->storedReplicas; replicaPtr.i != RNIL; diff --git a/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp b/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp index 35b78c1fb15..0be59fdf96b 100644 --- a/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp +++ b/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp @@ -11275,7 +11275,7 @@ void Dblqh::execLCP_PREPARE_REF(Signal* signal) /** * First fragment mean that last LCP is complete :-) */ - EXECUTE_DIRECT(TSMAN, GSN_END_LCP_REQ, signal, signal->length()); + EXECUTE_DIRECT(TSMAN, GSN_LCP_FRAG_ORD, signal, signal->length()); jamEntry(); } @@ -11326,7 +11326,7 @@ void Dblqh::execLCP_PREPARE_CONF(Signal* signal) /** * First fragment mean that last LCP is complete :-) */ - EXECUTE_DIRECT(TSMAN, GSN_END_LCP_REQ, signal, signal->length()); + EXECUTE_DIRECT(TSMAN, GSN_LCP_FRAG_ORD, signal, signal->length()); jamEntry(); } @@ -11610,6 +11610,9 @@ void Dblqh::completeLcpRoundLab(Signal* signal, Uint32 lcpId) sendSignal(LGMAN_REF, GSN_END_LCP_REQ, signal, EndLcpReq::SignalLength, JBB); + EXECUTE_DIRECT(TSMAN, GSN_END_LCP_REQ, signal, EndLcpReq::SignalLength); + jamEntry(); + lcpPtr.i = 0; ptrAss(lcpPtr, lcpRecord); lcpPtr.p->m_outstanding = 3; diff --git a/storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp b/storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp index 8a9242e9748..44f7954f00d 100644 --- a/storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp +++ b/storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp @@ -5057,7 +5057,7 @@ void Dbtc::execLQHKEYREF(Signal* signal) ptrAss(tcConnectptr, tcConnectRecord); TcConnectRecord * const regTcPtr = tcConnectptr.p; if (regTcPtr->tcConnectstate == OS_OPERATING) { - apiConnectptr.i = regTcPtr->apiConnect; + Uint32 save = apiConnectptr.i = regTcPtr->apiConnect; ptrCheckGuard(apiConnectptr, capiConnectFilesize, apiConnectRecord); ApiConnectRecord * const regApiPtr = apiConnectptr.p; compare_transid1 = regApiPtr->transid[0] ^ lqhKeyRef->transId1; @@ -5181,7 +5181,7 @@ void Dbtc::execLQHKEYREF(Signal* signal) regApiPtr->lqhkeyreqrec--; // Compensate for extra during read tcKeyRef->connectPtr = indexOp; EXECUTE_DIRECT(DBTC, GSN_TCKEYREF, signal, TcKeyRef::SignalLength); - apiConnectptr.i = regTcPtr->apiConnect; + apiConnectptr.i = save; apiConnectptr.p = regApiPtr; } else { jam(); @@ -5206,6 +5206,8 @@ void Dbtc::execLQHKEYREF(Signal* signal) jam(); sendtckeyconf(signal, 1); regApiPtr->apiConnectstate = CS_CONNECTED; + regApiPtr->m_transaction_nodes.clear(); + setApiConTimer(apiConnectptr.i, 0,__LINE__); } return; } else if (regApiPtr->tckeyrec > 0 || regApiPtr->m_exec_flag) { @@ -11863,17 +11865,6 @@ void Dbtc::execTCKEYREF(Signal* signal) case(IOS_INDEX_ACCESS_WAIT_FOR_TRANSID_AI): case(IOS_INDEX_ACCESS_WAIT_FOR_TCKEYCONF): { jam(); - // If we fail index access for a non-read operation during commit - // we abort transaction - if (commitFlg == 1) { - jam(); - releaseIndexOperation(regApiPtr, indexOp); - apiConnectptr.i = indexOp->connectionIndex; - ptrCheckGuard(apiConnectptr, capiConnectFilesize, apiConnectRecord); - terrorCode = tcKeyRef->errorCode; - abortErrorLab(signal); - break; - } /** * Increase count as it will be decreased below... * (and the code is written to handle failing lookup on "real" table diff --git a/storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp b/storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp index 0ce7a2a03c2..408925e4103 100644 --- a/storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp +++ b/storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp @@ -624,7 +624,8 @@ struct Fragrecord { DLList<ScanOp>::Head m_scanList; - bool m_undo_complete; + enum { UC_LCP = 1, UC_CREATE = 2 }; + Uint32 m_undo_complete; Uint32 m_tablespace_id; Uint32 m_logfile_group_id; Disk_alloc_info m_disk_alloc_info; @@ -988,6 +989,9 @@ ArrayPool<TupTriggerData> c_triggerPool; ,UNDO_UPDATE = File_formats::Undofile::UNDO_TUP_UPDATE ,UNDO_FREE = File_formats::Undofile::UNDO_TUP_FREE ,UNDO_CREATE = File_formats::Undofile::UNDO_TUP_CREATE + ,UNDO_DROP = File_formats::Undofile::UNDO_TUP_DROP + ,UNDO_ALLOC_EXTENT = File_formats::Undofile::UNDO_TUP_ALLOC_EXTENT + ,UNDO_FREE_EXTENT = File_formats::Undofile::UNDO_TUP_FREE_EXTENT }; struct Alloc @@ -1020,6 +1024,30 @@ ArrayPool<TupTriggerData> c_triggerPool; Uint32 m_table; Uint32 m_type_length; // 16 bit type, 16 bit length }; + + struct Drop + { + Uint32 m_table; + Uint32 m_type_length; // 16 bit type, 16 bit length + }; + + struct AllocExtent + { + Uint32 m_table; + Uint32 m_fragment; + Uint32 m_page_no; + Uint32 m_file_no; + Uint32 m_type_length; + }; + + struct FreeExtent + { + Uint32 m_table; + Uint32 m_fragment; + Uint32 m_page_no; + Uint32 m_file_no; + Uint32 m_type_length; + }; }; Extent_info_pool c_extent_pool; @@ -1419,7 +1447,7 @@ public: int nr_delete(Signal*, Uint32, Uint32 fragPtr, const Local_key*, Uint32 gci); void nr_delete_page_callback(Signal*, Uint32 op, Uint32 page); - void nr_delete_logbuffer_callback(Signal*, Uint32 op, Uint32 page); + void nr_delete_log_buffer_callback(Signal*, Uint32 op, Uint32 page); private: BLOCK_DEFINES(Dbtup); @@ -2344,9 +2372,10 @@ private: Uint32 fragId); - void releaseFragment(Signal* signal, Uint32 tableId); + void releaseFragment(Signal* signal, Uint32 tableId, Uint32); void drop_fragment_free_var_pages(Signal*); - void drop_fragment_free_exent(Signal*, TablerecPtr, FragrecordPtr, Uint32); + void drop_fragment_free_extent(Signal*, TablerecPtr, FragrecordPtr, Uint32); + void drop_fragment_free_extent_log_buffer_callback(Signal*, Uint32, Uint32); void drop_fragment_unmap_pages(Signal*, TablerecPtr, FragrecordPtr, Uint32); void drop_fragment_unmap_page_callback(Signal* signal, Uint32, Uint32); @@ -2570,6 +2599,7 @@ private: // Trigger variables Uint32 c_maxTriggersPerTable; + Uint32 c_memusage_report_frequency; Uint32 c_errorInsert4000TableId; Uint32 c_min_list_size[MAX_FREE_LIST + 1]; @@ -2629,6 +2659,9 @@ private: void disk_page_commit_callback(Signal*, Uint32 opPtrI, Uint32 page_id); void disk_page_log_buffer_callback(Signal*, Uint32 opPtrI, Uint32); + + void disk_page_alloc_extent_log_buffer_callback(Signal*, Uint32, Uint32); + void disk_page_free_extent_log_buffer_callback(Signal*, Uint32, Uint32); Uint64 disk_page_undo_alloc(Page*, const Local_key*, Uint32 sz, Uint32 gci, Uint32 logfile_group_id); @@ -2644,6 +2677,9 @@ private: void undo_createtable_callback(Signal* signal, Uint32 opPtrI, Uint32 unused); void undo_createtable_logsync_callback(Signal* signal, Uint32, Uint32); + void drop_table_log_buffer_callback(Signal*, Uint32, Uint32); + void drop_table_logsync_callback(Signal*, Uint32, Uint32); + void disk_page_set_dirty(Ptr<Page>); void restart_setup_page(Disk_alloc_info&, Ptr<Page>); void update_extent_pos(Disk_alloc_info&, Ptr<Extent_info>); @@ -2677,7 +2713,7 @@ public: private: void disk_restart_undo_next(Signal*); - void disk_restart_undo_lcp(Uint32, Uint32); + void disk_restart_undo_lcp(Uint32, Uint32, Uint32 flag); void disk_restart_undo_callback(Signal* signal, Uint32, Uint32); void disk_restart_undo_alloc(Apply_undo*); void disk_restart_undo_update(Apply_undo*); diff --git a/storage/ndb/src/kernel/blocks/dbtup/DbtupCommit.cpp b/storage/ndb/src/kernel/blocks/dbtup/DbtupCommit.cpp index 9c70cb7f0f8..1f703599cf5 100644 --- a/storage/ndb/src/kernel/blocks/dbtup/DbtupCommit.cpp +++ b/storage/ndb/src/kernel/blocks/dbtup/DbtupCommit.cpp @@ -151,10 +151,10 @@ void Dbtup::initOpConnection(Operationrec* regOperPtr) static inline bool -operator>=(const Local_key& key1, const Local_key& key2) +operator>(const Local_key& key1, const Local_key& key2) { return key1.m_page_no > key2.m_page_no || - (key1.m_page_no == key2.m_page_no && key1.m_page_idx >= key2.m_page_idx); + (key1.m_page_no == key2.m_page_no && key1.m_page_idx > key2.m_page_idx); } void @@ -175,8 +175,11 @@ Dbtup::dealloc_tuple(Signal* signal, { Local_key disk; memcpy(&disk, ptr->get_disk_ref_ptr(regTabPtr), sizeof(disk)); + PagePtr tmpptr; + tmpptr.i = m_pgman.m_ptr.i; + tmpptr.p = reinterpret_cast<Page*>(m_pgman.m_ptr.p); disk_page_free(signal, regTabPtr, regFragPtr, - &disk, *(PagePtr*)&m_pgman.m_ptr, gci); + &disk, tmpptr, gci); } if (! (bits & Tuple_header::LCP_SKIP) && lcpScan_ptr_i != RNIL) @@ -186,7 +189,7 @@ Dbtup::dealloc_tuple(Signal* signal, Local_key rowid = regOperPtr->m_tuple_location; Local_key scanpos = scanOp.p->m_scanPos.m_key; rowid.m_page_no = page->frag_page_id; - if (rowid >= scanpos) + if (rowid > scanpos) { extra_bits = Tuple_header::LCP_KEEP; // Note REMOVE FREE ptr->m_operation_ptr_i = lcp_keep_list; @@ -214,6 +217,7 @@ Dbtup::commit_operation(Signal* signal, { ndbassert(regOperPtr->op_struct.op_type != ZDELETE); + Uint32 lcpScan_ptr_i= regFragPtr->m_lcp_scan_op; Uint32 save= tuple_ptr->m_operation_ptr_i; Uint32 bits= tuple_ptr->m_header_bits; @@ -263,7 +267,6 @@ Dbtup::commit_operation(Signal* signal, Local_key key; memcpy(&key, copy->get_disk_ref_ptr(regTabPtr), sizeof(Local_key)); Uint32 logfile_group_id= regFragPtr->m_logfile_group_id; - Uint32 lcpScan_ptr_i= regFragPtr->m_lcp_scan_op; PagePtr diskPagePtr = *(PagePtr*)&m_pgman.m_ptr; ndbassert(diskPagePtr.p->m_page_no == key.m_page_no); @@ -272,19 +275,6 @@ Dbtup::commit_operation(Signal* signal, if(copy_bits & Tuple_header::DISK_ALLOC) { disk_page_alloc(signal, regTabPtr, regFragPtr, &key, diskPagePtr, gci); - - if(lcpScan_ptr_i != RNIL) - { - ScanOpPtr scanOp; - c_scanOpPool.getPtr(scanOp, lcpScan_ptr_i); - Local_key rowid = regOperPtr->m_tuple_location; - Local_key scanpos = scanOp.p->m_scanPos.m_key; - rowid.m_page_no = pagePtr.p->frag_page_id; - if(rowid >= scanpos) - { - copy_bits |= Tuple_header::LCP_SKIP; - } - } } if(regTabPtr->m_attributes[DD].m_no_of_varsize == 0) @@ -311,6 +301,18 @@ Dbtup::commit_operation(Signal* signal, copy_bits |= Tuple_header::DISK_PART; } + if(lcpScan_ptr_i != RNIL && (bits & Tuple_header::ALLOC)) + { + ScanOpPtr scanOp; + c_scanOpPool.getPtr(scanOp, lcpScan_ptr_i); + Local_key rowid = regOperPtr->m_tuple_location; + Local_key scanpos = scanOp.p->m_scanPos.m_key; + rowid.m_page_no = pagePtr.p->frag_page_id; + if(rowid > scanpos) + { + copy_bits |= Tuple_header::LCP_SKIP; + } + } Uint32 clear= Tuple_header::ALLOC | Tuple_header::FREE | @@ -356,7 +358,12 @@ Dbtup::disk_page_commit_callback(Signal* signal, regOperPtr.p->m_commit_disk_callback_page= page_id; m_global_page_pool.getPtr(m_pgman.m_ptr, page_id); - disk_page_set_dirty(*(Ptr<Page>*)&m_pgman.m_ptr); + { + PagePtr tmp; + tmp.i = m_pgman.m_ptr.i; + tmp.p = reinterpret_cast<Page*>(m_pgman.m_ptr.p); + disk_page_set_dirty(tmp); + } execTUP_COMMITREQ(signal); if(signal->theData[0] == 0) @@ -543,7 +550,14 @@ void Dbtup::execTUP_COMMITREQ(Signal* signal) break; } get_page = true; - disk_page_set_dirty(*(Ptr<Page>*)&m_pgman.m_ptr); + + { + PagePtr tmpptr; + tmpptr.i = m_pgman.m_ptr.i; + tmpptr.p = reinterpret_cast<Page*>(m_pgman.m_ptr.p); + disk_page_set_dirty(tmpptr); + } + regOperPtr.p->m_commit_disk_callback_page= res; regOperPtr.p->op_struct.m_load_diskpage_on_commit= 0; } diff --git a/storage/ndb/src/kernel/blocks/dbtup/DbtupDiskAlloc.cpp b/storage/ndb/src/kernel/blocks/dbtup/DbtupDiskAlloc.cpp index 7959606b7f4..0342f2c9e0c 100644 --- a/storage/ndb/src/kernel/blocks/dbtup/DbtupDiskAlloc.cpp +++ b/storage/ndb/src/kernel/blocks/dbtup/DbtupDiskAlloc.cpp @@ -68,6 +68,26 @@ operator<<(NdbOut& out, const Ptr<Dbtup::Extent_info> & ptr) return out; } +#if NOT_YET_FREE_EXTENT +static +inline +bool +check_free(const Dbtup::Extent_info* extP) +{ + Uint32 res = 0; + for (Uint32 i = 1; i<MAX_FREE_LIST; i++) + res += extP->m_free_page_count[i]; + return res; +} +#error "Code for deallocting extents when they get empty" +#error "This code is not yet complete" +#endif + +#if NOT_YET_UNDO_ALLOC_EXTENT +#error "This is needed for deallocting extents when they get empty" +#error "This code is not complete yet" +#endif + void Dbtup::dump_disk_alloc(Dbtup::Disk_alloc_info & alloc) { @@ -444,23 +464,71 @@ Dbtup::disk_page_prealloc(Signal* signal, /** * We need to alloc an extent */ +#if NOT_YET_UNDO_ALLOC_EXTENT + Uint32 logfile_group_id = fragPtr.p->m_logfile_group_id; + + err = c_lgman->alloc_log_space(logfile_group_id, + sizeof(Disk_undo::AllocExtent)>>2); + if(unlikely(err)) + { + return -err; + } +#endif + if (!c_extent_pool.seize(ext)) { + jam(); //XXX err= 2; +#if NOT_YET_UNDO_ALLOC_EXTENT + c_lgman->free_log_space(logfile_group_id, + sizeof(Disk_undo::AllocExtent)>>2); +#endif c_page_request_pool.release(req); ndbout_c("no free extent info"); return -err; } - + if ((err= tsman.alloc_extent(&ext.p->m_key)) < 0) { + jam(); +#if NOT_YET_UNDO_ALLOC_EXTENT + c_lgman->free_log_space(logfile_group_id, + sizeof(Disk_undo::AllocExtent)>>2); +#endif c_extent_pool.release(ext); c_page_request_pool.release(req); return err; } int pages= err; +#if NOT_YET_UNDO_ALLOC_EXTENT + { + /** + * Do something here + */ + { + Callback cb; + cb.m_callbackData= ext.i; + cb.m_callbackFunction = + safe_cast(&Dbtup::disk_page_alloc_extent_log_buffer_callback); + Uint32 sz= sizeof(Disk_undo::AllocExtent)>>2; + + Logfile_client lgman(this, c_lgman, logfile_group_id); + int res= lgman.get_log_buffer(signal, sz, &cb); + switch(res){ + case 0: + break; + case -1: + ndbrequire("NOT YET IMPLEMENTED" == 0); + break; + default: + execute(signal, cb, res); + } + } + } +#endif + ndbout << "allocated " << pages << " pages: " << ext.p->m_key << endl; ext.p->m_first_page_no = ext.p->m_key.m_page_no; bzero(ext.p->m_free_page_count, sizeof(ext.p->m_free_page_count)); @@ -1016,6 +1084,12 @@ Dbtup::disk_page_free(Signal *signal, extentPtr.p->m_free_space += sz; update_extent_pos(alloc, extentPtr); +#if NOT_YET_FREE_EXTENT + if (check_free(extentPtr.p) == 0) + { + ndbout_c("free: extent is free"); + } +#endif } void @@ -1118,14 +1192,56 @@ Dbtup::disk_page_abort_prealloc_callback_1(Signal* signal, extentPtr.p->m_free_space += sz; update_extent_pos(alloc, extentPtr); +#if NOT_YET_FREE_EXTENT + if (check_free(extentPtr.p) == 0) + { + ndbout_c("abort: extent is free"); + } +#endif +} + +#if NOT_YET_UNDO_ALLOC_EXTENT +void +Dbtup::disk_page_alloc_extent_log_buffer_callback(Signal* signal, + Uint32 extentPtrI, + Uint32 unused) +{ + Ptr<Extent_info> extentPtr; + c_extent_pool.getPtr(extentPtr, extentPtrI); + + Local_key key = extentPtr.p->m_key; + Tablespace_client2 tsman(signal, c_tsman, &key); + + Ptr<Tablerec> tabPtr; + tabPtr.i= tsman.m_table_id; + ptrCheckGuard(tabPtr, cnoOfTablerec, tablerec); + + Ptr<Fragrecord> fragPtr; + getFragmentrec(fragPtr, tsman.m_fragment_id, tabPtr.p); + + Logfile_client lgman(this, c_lgman, fragPtr.p->m_logfile_group_id); + + Disk_undo::AllocExtent alloc; + alloc.m_table = tabPtr.i; + alloc.m_fragment = tsman.m_fragment_id; + alloc.m_page_no = key.m_page_no; + alloc.m_file_no = key.m_file_no; + alloc.m_type_length = (Disk_undo::UNDO_ALLOC_EXTENT<<16)|(sizeof(alloc)>> 2); + + Logfile_client::Change c[1] = {{ &alloc, sizeof(alloc) >> 2 } }; + + Uint64 lsn= lgman.add_entry(c, 1); + + tsman.update_lsn(&key, lsn); } +#endif Uint64 Dbtup::disk_page_undo_alloc(Page* page, const Local_key* key, Uint32 sz, Uint32 gci, Uint32 logfile_group_id) { - Logfile_client lsman(this, c_lgman, logfile_group_id); - + Logfile_client lgman(this, c_lgman, logfile_group_id); + Disk_undo::Alloc alloc; alloc.m_type_length= (Disk_undo::UNDO_ALLOC << 16) | (sizeof(alloc) >> 2); alloc.m_page_no = key->m_page_no; @@ -1133,7 +1249,7 @@ Dbtup::disk_page_undo_alloc(Page* page, const Local_key* key, Logfile_client::Change c[1] = {{ &alloc, sizeof(alloc) >> 2 } }; - Uint64 lsn= lsman.add_entry(c, 1); + Uint64 lsn= lgman.add_entry(c, 1); m_pgman.update_lsn(* key, lsn); return lsn; @@ -1144,7 +1260,7 @@ Dbtup::disk_page_undo_update(Page* page, const Local_key* key, const Uint32* src, Uint32 sz, Uint32 gci, Uint32 logfile_group_id) { - Logfile_client lsman(this, c_lgman, logfile_group_id); + Logfile_client lgman(this, c_lgman, logfile_group_id); Disk_undo::Update update; update.m_page_no = key->m_page_no; @@ -1162,7 +1278,7 @@ Dbtup::disk_page_undo_update(Page* page, const Local_key* key, ndbassert(4*(3 + sz + 1) == (sizeof(update) + 4*sz - 4)); - Uint64 lsn= lsman.add_entry(c, 3); + Uint64 lsn= lgman.add_entry(c, 3); m_pgman.update_lsn(* key, lsn); return lsn; @@ -1173,7 +1289,7 @@ Dbtup::disk_page_undo_free(Page* page, const Local_key* key, const Uint32* src, Uint32 sz, Uint32 gci, Uint32 logfile_group_id) { - Logfile_client lsman(this, c_lgman, logfile_group_id); + Logfile_client lgman(this, c_lgman, logfile_group_id); Disk_undo::Free free; free.m_page_no = key->m_page_no; @@ -1191,7 +1307,7 @@ Dbtup::disk_page_undo_free(Page* page, const Local_key* key, ndbassert(4*(3 + sz + 1) == (sizeof(free) + 4*sz - 4)); - Uint64 lsn= lsman.add_entry(c, 3); + Uint64 lsn= lgman.add_entry(c, 3); m_pgman.update_lsn(* key, lsn); return lsn; @@ -1221,7 +1337,7 @@ Dbtup::disk_restart_undo(Signal* signal, Uint64 lsn, ndbrequire(len == 3); Uint32 tableId = ptr[1] >> 16; Uint32 fragId = ptr[1] & 0xFFFF; - disk_restart_undo_lcp(tableId, fragId); + disk_restart_undo_lcp(tableId, fragId, Fragrecord::UC_LCP); disk_restart_undo_next(signal); return; } @@ -1260,10 +1376,20 @@ Dbtup::disk_restart_undo(Signal* signal, Uint64 lsn, ptrCheckGuard(tabPtr, cnoOfTablerec, tablerec); for(Uint32 i = 0; i<MAX_FRAG_PER_NODE; i++) if (tabPtr.p->fragrec[i] != RNIL) - disk_restart_undo_lcp(tabPtr.i, tabPtr.p->fragid[i]); + disk_restart_undo_lcp(tabPtr.i, tabPtr.p->fragid[i], + Fragrecord::UC_CREATE); disk_restart_undo_next(signal); return; } + case File_formats::Undofile::UNDO_TUP_DROP: + jam(); + case File_formats::Undofile::UNDO_TUP_ALLOC_EXTENT: + jam(); + case File_formats::Undofile::UNDO_TUP_FREE_EXTENT: + jam(); + disk_restart_undo_next(signal); + return; + case File_formats::Undofile::UNDO_END: f_undo_done = true; return; @@ -1297,7 +1423,7 @@ Dbtup::disk_restart_undo_next(Signal* signal) } void -Dbtup::disk_restart_undo_lcp(Uint32 tableId, Uint32 fragId) +Dbtup::disk_restart_undo_lcp(Uint32 tableId, Uint32 fragId, Uint32 flag) { Ptr<Tablerec> tabPtr; tabPtr.i= tableId; @@ -1309,7 +1435,7 @@ Dbtup::disk_restart_undo_lcp(Uint32 tableId, Uint32 fragId) getFragmentrec(fragPtr, fragId, tabPtr.p); if (!fragPtr.isNull()) { - fragPtr.p->m_undo_complete = true; + fragPtr.p->m_undo_complete |= flag; } } } @@ -1518,6 +1644,12 @@ Dbtup::disk_restart_alloc_extent(Uint32 tableId, Uint32 fragId, if (tabPtr.p->tableStatus == DEFINED) { getFragmentrec(fragPtr, fragId, tabPtr.p); + if (fragPtr.p->m_undo_complete & Fragrecord::UC_CREATE) + { + jam(); + return -1; + } + if (!fragPtr.isNull()) { Disk_alloc_info& alloc= fragPtr.p->m_disk_alloc_info; diff --git a/storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp b/storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp index ef52f8a87e5..52981e7fc83 100644 --- a/storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp +++ b/storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp @@ -3125,7 +3125,7 @@ Dbtup::nr_delete(Signal* signal, Uint32 senderData, disk_page_set_dirty(disk_page); preq.m_callback.m_callbackFunction = - safe_cast(&Dbtup::nr_delete_logbuffer_callback); + safe_cast(&Dbtup::nr_delete_log_buffer_callback); Logfile_client lgman(this, c_lgman, fragPtr.p->m_logfile_group_id); res= lgman.get_log_buffer(signal, sz, &preq.m_callback); switch(res){ @@ -3178,7 +3178,7 @@ Dbtup::nr_delete_page_callback(Signal* signal, Callback cb; cb.m_callbackData = userpointer; cb.m_callbackFunction = - safe_cast(&Dbtup::nr_delete_logbuffer_callback); + safe_cast(&Dbtup::nr_delete_log_buffer_callback); Logfile_client lgman(this, c_lgman, fragPtr.p->m_logfile_group_id); int res= lgman.get_log_buffer(signal, sz, &cb); switch(res){ @@ -3198,7 +3198,7 @@ Dbtup::nr_delete_page_callback(Signal* signal, } void -Dbtup::nr_delete_logbuffer_callback(Signal* signal, +Dbtup::nr_delete_log_buffer_callback(Signal* signal, Uint32 userpointer, Uint32 unused) { diff --git a/storage/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp b/storage/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp index 2b3093ed205..3e9469c4edf 100644 --- a/storage/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp +++ b/storage/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp @@ -163,11 +163,12 @@ void Dbtup::execCONTINUEB(Signal* signal) break; case ZREL_FRAG: ljam(); - releaseFragment(signal, dataPtr); + releaseFragment(signal, dataPtr, signal->theData[2]); break; case ZREPORT_MEMORY_USAGE:{ ljam(); static int c_currentMemUsed = 0; + Uint32 cnt = signal->theData[1]; Uint32 tmp = c_page_pool.getSize(); int now = tmp ? (cnoOfAllocatedPages * 100)/tmp : 0; const int thresholds[] = { 100, 90, 80, 0 }; @@ -181,12 +182,22 @@ void Dbtup::execCONTINUEB(Signal* signal) } } - if(now != c_currentMemUsed){ - reportMemoryUsage(signal, now > c_currentMemUsed ? 1 : -1); + if(now != c_currentMemUsed || + (c_memusage_report_frequency && cnt + 1 == c_memusage_report_frequency)) + { + reportMemoryUsage(signal, + now > c_currentMemUsed ? 1 : + now < c_currentMemUsed ? -1 : 0); + cnt = 0; c_currentMemUsed = now; + } + else + { + cnt++; } signal->theData[0] = ZREPORT_MEMORY_USAGE; - sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 2000, 1); + signal->theData[1] = cnt; + sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 1000, 2); return; } case ZBUILD_INDEX: @@ -211,7 +222,7 @@ void Dbtup::execCONTINUEB(Signal* signal) fragPtr.i= signal->theData[2]; ptrCheckGuard(tabPtr, cnoOfTablerec, tablerec); ptrCheckGuard(fragPtr, cnoOfFragrec, fragrecord); - drop_fragment_free_exent(signal, tabPtr, fragPtr, signal->theData[3]); + drop_fragment_free_extent(signal, tabPtr, fragPtr, signal->theData[3]); return; } case ZUNMAP_PAGES: @@ -336,6 +347,10 @@ void Dbtup::execREAD_CONFIG_REQ(Signal* signal) clastBitMask = 1; clastBitMask = clastBitMask << 31; + c_memusage_report_frequency = 0; + ndb_mgm_get_int_parameter(p, CFG_DB_MEMREPORT_FREQUENCY, + &c_memusage_report_frequency); + initialiseRecordsLab(signal, 0, ref, senderData); }//Dbtup::execSIZEALT_REP() @@ -501,7 +516,8 @@ void Dbtup::execNDB_STTOR(Signal* signal) /* RESTART. */ /*****************************************/ signal->theData[0] = ZREPORT_MEMORY_USAGE; - sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 2000, 1); + signal->theData[1] = 0; + sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 1000, 1); break; default: ljam(); diff --git a/storage/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp b/storage/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp index 41b00b0a04b..b5010205880 100644 --- a/storage/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp +++ b/storage/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp @@ -308,6 +308,7 @@ void Dbtup::execTUP_ADD_ATTRREQ(Signal* signal) if(lastAttr) { + jam(); /** * Init Disk_alloc_info */ @@ -319,6 +320,11 @@ void Dbtup::execTUP_ADD_ATTRREQ(Signal* signal) ndbrequire(tsman.get_tablespace_info(&rep) == 0); regFragPtr.p->m_logfile_group_id= rep.tablespace.logfile_group_id; } + else + { + jam(); + regFragPtr.p->m_logfile_group_id = RNIL; + } new (®FragPtr.p->m_disk_alloc_info) Disk_alloc_info(regTabPtr.p, rep.tablespace.extent_size); releaseFragoperrec(fragOperPtr); @@ -563,7 +569,12 @@ void Dbtup::execTUP_ADD_ATTRREQ(Signal* signal) regFragPtr.p->m_tablespace_id); ndbrequire(tsman.get_tablespace_info(&rep) == 0); regFragPtr.p->m_logfile_group_id= rep.tablespace.logfile_group_id; - } + } + else + { + jam(); + regFragPtr.p->m_logfile_group_id = RNIL; + } new (®FragPtr.p->m_disk_alloc_info) Disk_alloc_info(regTabPtr.p, rep.tablespace.extent_size); @@ -596,7 +607,7 @@ void Dbtup::execTUP_ADD_ATTRREQ(Signal* signal) ndbrequire("NOT YET IMPLEMENTED" == 0); break; } - execute(signal, cb, 0); + execute(signal, cb, regFragPtr.p->m_logfile_group_id); return; } } @@ -873,7 +884,8 @@ Dbtup::execDROP_TAB_REQ(Signal* signal) signal->theData[0]= ZREL_FRAG; signal->theData[1]= tabPtr.i; - sendSignal(cownref, GSN_CONTINUEB, signal, 2, JBB); + signal->theData[2]= RNIL; + sendSignal(cownref, GSN_CONTINUEB, signal, 3, JBB); } void Dbtup::releaseTabDescr(Tablerec* const regTabPtr) @@ -901,7 +913,8 @@ void Dbtup::releaseTabDescr(Tablerec* const regTabPtr) } } -void Dbtup::releaseFragment(Signal* signal, Uint32 tableId) +void Dbtup::releaseFragment(Signal* signal, Uint32 tableId, + Uint32 logfile_group_id) { TablerecPtr tabPtr; tabPtr.i= tableId; @@ -928,16 +941,35 @@ void Dbtup::releaseFragment(Signal* signal, Uint32 tableId) sendSignal(cownref, GSN_CONTINUEB, signal, 4, JBB); return; } + +#if NOT_YET_UNDO_DROP_TABLE +#error "This code is complete, but I prefer not to enable it until I need it" + if (logfile_group_id != RNIL) + { + Callback cb; + cb.m_callbackData= tabPtr.i; + cb.m_callbackFunction = + safe_cast(&Dbtup::drop_table_log_buffer_callback); + Uint32 sz= sizeof(Disk_undo::Drop) >> 2; + int r0 = c_lgman->alloc_log_space(logfile_group_id, sz); + + Logfile_client lgman(this, c_lgman, logfile_group_id); + int res= lgman.get_log_buffer(signal, sz, &cb); + switch(res){ + case 0: + ljam(); + return; + case -1: + ndbrequire("NOT YET IMPLEMENTED" == 0); + break; + default: + execute(signal, cb, logfile_group_id); + return; + } + } +#endif - DropTabConf * const dropConf= (DropTabConf *)signal->getDataPtrSend(); - dropConf->senderRef= reference(); - dropConf->senderData= tabPtr.p->m_dropTable.tabUserPtr; - dropConf->tableId= tabPtr.i; - sendSignal(tabPtr.p->m_dropTable.tabUserRef, GSN_DROP_TAB_CONF, - signal, DropTabConf::SignalLength, JBB); - - releaseTabDescr(tabPtr.p); - initTab(tabPtr.p); + drop_table_logsync_callback(signal, tabPtr.i, RNIL); } void @@ -964,7 +996,7 @@ Dbtup::drop_fragment_unmap_pages(Signal *signal, alloc_info.m_curr_extent_info_ptr_i= RNIL; } - drop_fragment_free_exent(signal, tabPtr, fragPtr, 0); + drop_fragment_free_extent(signal, tabPtr, fragPtr, 0); return; } @@ -997,7 +1029,7 @@ Dbtup::drop_fragment_unmap_pages(Signal *signal, } return; } - drop_fragment_free_exent(signal, tabPtr, fragPtr, 0); + drop_fragment_free_extent(signal, tabPtr, fragPtr, 0); } void @@ -1030,10 +1062,10 @@ Dbtup::drop_fragment_unmap_page_callback(Signal* signal, } void -Dbtup::drop_fragment_free_exent(Signal *signal, - TablerecPtr tabPtr, - FragrecordPtr fragPtr, - Uint32 pos) +Dbtup::drop_fragment_free_extent(Signal *signal, + TablerecPtr tabPtr, + FragrecordPtr fragPtr, + Uint32 pos) { if (tabPtr.p->m_no_of_disk_attributes) { @@ -1043,25 +1075,32 @@ Dbtup::drop_fragment_free_exent(Signal *signal, if(!alloc_info.m_free_extents[pos].isEmpty()) { jam(); - Local_extent_info_list - list(c_extent_pool, alloc_info.m_free_extents[pos]); - Ptr<Extent_info> ext_ptr; - list.first(ext_ptr); + Callback cb; + cb.m_callbackData= fragPtr.i; + cb.m_callbackFunction = + safe_cast(&Dbtup::drop_fragment_free_extent_log_buffer_callback); +#if NOT_YET_UNDO_FREE_EXTENT + Uint32 sz= sizeof(Disk_undo::FreeExtent) >> 2; + int r0 = c_lgman->alloc_log_space(fragPtr.p->m_logfile_group_id, sz); - Tablespace_client tsman(signal, c_tsman, tabPtr.i, - fragPtr.p->fragmentId, - fragPtr.p->m_tablespace_id); + Logfile_client lgman(this, c_lgman, fragPtr.p->m_logfile_group_id); - tsman.free_extent(&ext_ptr.p->m_key); - c_extent_hash.remove(ext_ptr); - list.release(ext_ptr); - - signal->theData[0] = ZFREE_EXTENT; - signal->theData[1] = tabPtr.i; - signal->theData[2] = fragPtr.i; - signal->theData[3] = pos; - sendSignal(cownref, GSN_CONTINUEB, signal, 4, JBB); + int res= lgman.get_log_buffer(signal, sz, &cb); + switch(res){ + case 0: + ljam(); + return; + case -1: + ndbrequire("NOT YET IMPLEMENTED" == 0); + break; + default: + execute(signal, cb, fragPtr.p->m_logfile_group_id); + return; + } +#else + execute(signal, cb, fragPtr.p->m_logfile_group_id); return; +#endif } } @@ -1081,6 +1120,123 @@ Dbtup::drop_fragment_free_exent(Signal *signal, } void +Dbtup::drop_table_log_buffer_callback(Signal* signal, Uint32 tablePtrI, + Uint32 logfile_group_id) +{ + TablerecPtr tabPtr; + tabPtr.i = tablePtrI; + ptrCheckGuard(tabPtr, cnoOfTablerec, tablerec); + + ndbrequire(tabPtr.p->m_no_of_disk_attributes); + + Disk_undo::Drop drop; + drop.m_table = tabPtr.i; + drop.m_type_length = + (Disk_undo::UNDO_DROP << 16) | (sizeof(drop) >> 2); + Logfile_client lgman(this, c_lgman, logfile_group_id); + + Logfile_client::Change c[1] = {{ &drop, sizeof(drop) >> 2 } }; + Uint64 lsn = lgman.add_entry(c, 1); + + Logfile_client::Request req; + req.m_callback.m_callbackData= tablePtrI; + req.m_callback.m_callbackFunction = + safe_cast(&Dbtup::drop_table_logsync_callback); + + int ret = lgman.sync_lsn(signal, lsn, &req, 0); + switch(ret){ + case 0: + return; + default: + ndbout_c("ret: %d", ret); + ndbrequire(false); + } +} + +void +Dbtup::drop_table_logsync_callback(Signal* signal, + Uint32 tabPtrI, + Uint32 logfile_group_id) +{ + TablerecPtr tabPtr; + tabPtr.i = tabPtrI; + ptrCheckGuard(tabPtr, cnoOfTablerec, tablerec); + + DropTabConf * const dropConf= (DropTabConf *)signal->getDataPtrSend(); + dropConf->senderRef= reference(); + dropConf->senderData= tabPtr.p->m_dropTable.tabUserPtr; + dropConf->tableId= tabPtr.i; + sendSignal(tabPtr.p->m_dropTable.tabUserRef, GSN_DROP_TAB_CONF, + signal, DropTabConf::SignalLength, JBB); + + releaseTabDescr(tabPtr.p); + initTab(tabPtr.p); +} + +void +Dbtup::drop_fragment_free_extent_log_buffer_callback(Signal* signal, + Uint32 fragPtrI, + Uint32 unused) +{ + FragrecordPtr fragPtr; + fragPtr.i = fragPtrI; + ptrCheckGuard(fragPtr, cnoOfFragrec, fragrecord); + + TablerecPtr tabPtr; + tabPtr.i = fragPtr.p->fragTableId; + ptrCheckGuard(tabPtr, cnoOfTablerec, tablerec); + + ndbrequire(tabPtr.p->m_no_of_disk_attributes); + Disk_alloc_info& alloc_info= fragPtr.p->m_disk_alloc_info; + + for(Uint32 pos = 0; pos<EXTENT_SEARCH_MATRIX_SIZE; pos++) + { + if(!alloc_info.m_free_extents[pos].isEmpty()) + { + jam(); + Local_extent_info_list + list(c_extent_pool, alloc_info.m_free_extents[pos]); + Ptr<Extent_info> ext_ptr; + list.first(ext_ptr); + +#if NOT_YET_UNDO_FREE_EXTENT +#error "This code is complete" +#error "but not needed until we do dealloc of empty extents" + Disk_undo::FreeExtent free; + free.m_table = tabPtr.i; + free.m_fragment = fragPtr.p->fragmentId; + free.m_file_no = ext_ptr.p->m_key.m_file_no; + free.m_page_no = ext_ptr.p->m_key.m_page_no; + free.m_type_length = + (Disk_undo::UNDO_FREE_EXTENT << 16) | (sizeof(free) >> 2); + Logfile_client lgman(this, c_lgman, fragPtr.p->m_logfile_group_id); + + Logfile_client::Change c[1] = {{ &free, sizeof(free) >> 2 } }; + Uint64 lsn = lgman.add_entry(c, 1); +#else + Uint64 lsn = 0; +#endif + + Tablespace_client tsman(signal, c_tsman, tabPtr.i, + fragPtr.p->fragmentId, + fragPtr.p->m_tablespace_id); + + tsman.free_extent(&ext_ptr.p->m_key, lsn); + c_extent_hash.remove(ext_ptr); + list.release(ext_ptr); + + signal->theData[0] = ZFREE_EXTENT; + signal->theData[1] = tabPtr.i; + signal->theData[2] = fragPtr.i; + signal->theData[3] = pos; + sendSignal(cownref, GSN_CONTINUEB, signal, 4, JBB); + return; + } + } + ndbrequire(false); +} + +void Dbtup::drop_fragment_free_var_pages(Signal* signal) { ljam(); @@ -1111,7 +1267,7 @@ Dbtup::drop_fragment_free_var_pages(Signal* signal) sendSignal(cownref, GSN_CONTINUEB, signal, 3, JBB); return; } - + Uint32 logfile_group_id = fragPtr.p->m_logfile_group_id ; releaseFragPages(fragPtr.p); Uint32 i; for(i= 0; i<MAX_FRAG_PER_NODE; i++) @@ -1125,7 +1281,8 @@ Dbtup::drop_fragment_free_var_pages(Signal* signal) signal->theData[0]= ZREL_FRAG; signal->theData[1]= tabPtr.i; - sendSignal(cownref, GSN_CONTINUEB, signal, 2, JBB); + signal->theData[2]= logfile_group_id; + sendSignal(cownref, GSN_CONTINUEB, signal, 3, JBB); return; } diff --git a/storage/ndb/src/kernel/blocks/dbtup/DbtupRoutines.cpp b/storage/ndb/src/kernel/blocks/dbtup/DbtupRoutines.cpp index b0f585e5a67..c8546209f94 100644 --- a/storage/ndb/src/kernel/blocks/dbtup/DbtupRoutines.cpp +++ b/storage/ndb/src/kernel/blocks/dbtup/DbtupRoutines.cpp @@ -784,6 +784,7 @@ int Dbtup::updateAttributes(KeyReqStruct *req_struct, memcpy(req_struct->m_tuple_ptr->get_disk_ref_ptr(regTabPtr), inBuffer+inBufIndex+1, sz << 2); inBufIndex += 1 + sz; + req_struct->in_buf_index = inBufIndex; } else { diff --git a/storage/ndb/src/kernel/blocks/dbtup/DbtupScan.cpp b/storage/ndb/src/kernel/blocks/dbtup/DbtupScan.cpp index 7c734c99d2c..653a24ba6a1 100644 --- a/storage/ndb/src/kernel/blocks/dbtup/DbtupScan.cpp +++ b/storage/ndb/src/kernel/blocks/dbtup/DbtupScan.cpp @@ -53,8 +53,7 @@ Dbtup::execACC_SCANREQ(Signal* signal) // flags Uint32 bits = 0; - if (!AccScanReq::getLcpScanFlag(req->requestInfo) || - tablePtr.p->m_no_of_disk_attributes == 0) + if (!AccScanReq::getLcpScanFlag(req->requestInfo)) { // seize from pool and link to per-fragment list LocalDLList<ScanOp> list(c_scanOpPool, frag.m_scanList); @@ -1051,24 +1050,21 @@ Dbtup::execLCP_FRAG_ORD(Signal* signal) tablePtr.i = req->tableId; ptrCheckGuard(tablePtr, cnoOfTablerec, tablerec); - if(tablePtr.p->m_no_of_disk_attributes) - { - jam(); - FragrecordPtr fragPtr; - Uint32 fragId = req->fragmentId; - fragPtr.i = RNIL; - getFragmentrec(fragPtr, fragId, tablePtr.p); - ndbrequire(fragPtr.i != RNIL); - Fragrecord& frag = *fragPtr.p; - - ndbrequire(frag.m_lcp_scan_op == RNIL && c_lcp_scan_op != RNIL); - frag.m_lcp_scan_op = c_lcp_scan_op; - ScanOpPtr scanPtr; - c_scanOpPool.getPtr(scanPtr, frag.m_lcp_scan_op); - ndbrequire(scanPtr.p->m_fragPtrI == RNIL); - scanPtr.p->m_fragPtrI = fragPtr.i; - - scanFirst(signal, scanPtr); - scanPtr.p->m_state = ScanOp::First; - } + jam(); + FragrecordPtr fragPtr; + Uint32 fragId = req->fragmentId; + fragPtr.i = RNIL; + getFragmentrec(fragPtr, fragId, tablePtr.p); + ndbrequire(fragPtr.i != RNIL); + Fragrecord& frag = *fragPtr.p; + + ndbrequire(frag.m_lcp_scan_op == RNIL && c_lcp_scan_op != RNIL); + frag.m_lcp_scan_op = c_lcp_scan_op; + ScanOpPtr scanPtr; + c_scanOpPool.getPtr(scanPtr, frag.m_lcp_scan_op); + ndbrequire(scanPtr.p->m_fragPtrI == RNIL); + scanPtr.p->m_fragPtrI = fragPtr.i; + + scanFirst(signal, scanPtr); + scanPtr.p->m_state = ScanOp::First; } diff --git a/storage/ndb/src/kernel/blocks/diskpage.hpp b/storage/ndb/src/kernel/blocks/diskpage.hpp index 044597be1cf..c75f2a0c070 100644 --- a/storage/ndb/src/kernel/blocks/diskpage.hpp +++ b/storage/ndb/src/kernel/blocks/diskpage.hpp @@ -154,7 +154,10 @@ struct File_formats ,UNDO_TUP_UPDATE = 4 ,UNDO_TUP_FREE = 5 ,UNDO_TUP_CREATE = 6 - + ,UNDO_TUP_DROP = 7 + ,UNDO_TUP_ALLOC_EXTENT = 8 + ,UNDO_TUP_FREE_EXTENT = 9 + ,UNDO_END = 0x7FFF ,UNDO_NEXT_LSN = 0x8000 }; diff --git a/storage/ndb/src/kernel/blocks/lgman.cpp b/storage/ndb/src/kernel/blocks/lgman.cpp index dff41ab8bca..17a4c4a4a83 100644 --- a/storage/ndb/src/kernel/blocks/lgman.cpp +++ b/storage/ndb/src/kernel/blocks/lgman.cpp @@ -1160,14 +1160,15 @@ Lgman::process_log_sync_waiters(Signal* signal, Ptr<Logfile_group> ptr) bool removed= false; Ptr<Log_waiter> waiter; list.first(waiter); + Uint32 logfile_group_id = ptr.p->m_logfile_group_id; if(waiter.p->m_sync_lsn <= ptr.p->m_last_synced_lsn) { removed= true; Uint32 block = waiter.p->m_block; SimulatedBlock* b = globalData.getBlock(block); - b->execute(signal, waiter.p->m_callback, 0); - + b->execute(signal, waiter.p->m_callback, logfile_group_id); + list.releaseFirst(waiter); } @@ -1522,12 +1523,13 @@ Lgman::process_log_buffer_waiters(Signal* signal, Ptr<Logfile_group> ptr) bool removed= false; Ptr<Log_waiter> waiter; list.first(waiter); + Uint32 logfile_group_id = ptr.p->m_logfile_group_id; if(waiter.p->m_size + 2*File_formats::UNDO_PAGE_WORDS < free_buffer) { removed= true; Uint32 block = waiter.p->m_block; SimulatedBlock* b = globalData.getBlock(block); - b->execute(signal, waiter.p->m_callback, 0); + b->execute(signal, waiter.p->m_callback, logfile_group_id); list.releaseFirst(waiter); } @@ -2061,6 +2063,7 @@ Lgman::execSTART_RECREQ(Signal* signal) if(ptr.i != RNIL) { infoEvent("Applying undo to LCP: %d", m_latest_lcp); + ndbout_c("Applying undo to LCP: %d", m_latest_lcp); find_log_head(signal, ptr); return; } @@ -2680,13 +2683,14 @@ Lgman::execute_undo_record(Signal* signal) case File_formats::Undofile::UNDO_LCP_FIRST: { Uint32 lcp = * (ptr - len + 1); - if(lcp > m_latest_lcp) + if(m_latest_lcp && lcp > m_latest_lcp) { // Just ignore break; } - if(lcp < m_latest_lcp || + if(m_latest_lcp == 0 || + lcp < m_latest_lcp || (lcp == m_latest_lcp && mask == File_formats::Undofile::UNDO_LCP_FIRST)) { @@ -2699,6 +2703,9 @@ Lgman::execute_undo_record(Signal* signal) case File_formats::Undofile::UNDO_TUP_UPDATE: case File_formats::Undofile::UNDO_TUP_FREE: case File_formats::Undofile::UNDO_TUP_CREATE: + case File_formats::Undofile::UNDO_TUP_DROP: + case File_formats::Undofile::UNDO_TUP_ALLOC_EXTENT: + case File_formats::Undofile::UNDO_TUP_FREE_EXTENT: tup->disk_restart_undo(signal, lsn, mask, ptr - len + 1, len); return; default: diff --git a/storage/ndb/src/kernel/blocks/print_file.cpp b/storage/ndb/src/kernel/blocks/print_file.cpp index 14b83cccaee..696658ef8de 100644 --- a/storage/ndb/src/kernel/blocks/print_file.cpp +++ b/storage/ndb/src/kernel/blocks/print_file.cpp @@ -304,6 +304,8 @@ print_undo_page(int count, void* ptr, Uint32 sz){ case File_formats::Undofile::UNDO_LCP: printf("[ %lld LCP %d tab: %d frag: %d ]", lsn, src[0], src[1] >> 16, src[1] & 0xFFFF); + if(g_verbosity <= 3) + printf("\n"); break; case File_formats::Undofile::UNDO_TUP_ALLOC: if(g_verbosity > 3) @@ -340,6 +342,48 @@ print_undo_page(int count, void* ptr, Uint32 sz){ req->m_gci); } break; + case File_formats::Undofile::UNDO_TUP_CREATE: + { + Dbtup::Disk_undo::Create *req = (Dbtup::Disk_undo::Create*)src; + printf("[ %lld Create %d ]", lsn, req->m_table); + if(g_verbosity <= 3) + printf("\n"); + break; + } + case File_formats::Undofile::UNDO_TUP_DROP: + { + Dbtup::Disk_undo::Drop *req = (Dbtup::Disk_undo::Drop*)src; + printf("[ %lld Drop %d ]", lsn, req->m_table); + if(g_verbosity <= 3) + printf("\n"); + break; + } + case File_formats::Undofile::UNDO_TUP_ALLOC_EXTENT: + { + Dbtup::Disk_undo::AllocExtent *req = (Dbtup::Disk_undo::AllocExtent*)src; + printf("[ %lld AllocExtent tab: %d frag: %d file: %d page: %d ]", + lsn, + req->m_table, + req->m_fragment, + req->m_file_no, + req->m_page_no); + if(g_verbosity <= 3) + printf("\n"); + break; + } + case File_formats::Undofile::UNDO_TUP_FREE_EXTENT: + { + Dbtup::Disk_undo::FreeExtent *req = (Dbtup::Disk_undo::FreeExtent*)src; + printf("[ %lld FreeExtent tab: %d frag: %d file: %d page: %d ]", + lsn, + req->m_table, + req->m_fragment, + req->m_file_no, + req->m_page_no); + if(g_verbosity <= 3) + printf("\n"); + break; + } default: ndbout_c("[ Unknown type %d len: %d, pos: %d ]", type, len, pos); if(!(len && type)) @@ -361,11 +405,11 @@ print_undo_page(int count, void* ptr, Uint32 sz){ } } } - + if(count == g_uf_zero.m_undo_pages + 1) { } - + return 0; } diff --git a/storage/ndb/src/kernel/blocks/tsman.cpp b/storage/ndb/src/kernel/blocks/tsman.cpp index 89725ca309e..48a8d470ccc 100644 --- a/storage/ndb/src/kernel/blocks/tsman.cpp +++ b/storage/ndb/src/kernel/blocks/tsman.cpp @@ -79,12 +79,14 @@ Tsman::Tsman(Block_context& ctx, addRecSignal(GSN_START_RECREQ, &Tsman::execSTART_RECREQ); + addRecSignal(GSN_LCP_FRAG_ORD, &Tsman::execLCP_FRAG_ORD); addRecSignal(GSN_END_LCP_REQ, &Tsman::execEND_LCP_REQ); addRecSignal(GSN_GET_TABINFOREQ, &Tsman::execGET_TABINFOREQ); m_tablespace_hash.setSize(10); m_file_hash.setSize(10); + m_lcp_ongoing = false; } Tsman::~Tsman() @@ -1101,6 +1103,7 @@ Tsman::load_extent_page_callback(Signal* signal, ptr.p->m_online.m_lcp_free_extent_tail = RNIL; ptr.p->m_online.m_data_pages = data_pages; ptr.p->m_online.m_used_extent_cnt = 0; + ptr.p->m_online.m_extent_headers_per_extent_page = per_page; Ptr<Tablespace> ts_ptr; m_tablespace_pool.getPtr(ts_ptr, ptr.p->m_tablespace_ptr_i); @@ -1182,9 +1185,8 @@ Tsman::scan_extent_headers(Signal* signal, Ptr<Datafile> ptr) m_tablespace_pool.getPtr(lg_ptr, ptr.p->m_tablespace_ptr_i); Uint32 firstFree= RNIL; - Uint32 size = lg_ptr.p->m_extent_size; - Uint32 eh_words = File_formats::Datafile::extent_header_words(size); - Uint32 per_page = File_formats::Datafile::EXTENT_PAGE_WORDS/eh_words; + Uint32 size = ptr.p->m_extent_size; + Uint32 per_page = ptr.p->m_online.m_extent_headers_per_extent_page; Uint32 SZ= File_formats::Datafile::EXTENT_HEADER_BITMASK_BITS_PER_PAGE; Uint32 pages= ptr.p->m_online.m_offset_data_pages - 1; Uint32 datapages= ptr.p->m_online.m_data_pages; @@ -1410,23 +1412,21 @@ Tsman::execALLOC_EXTENT_REQ(Signal* signal) AllocExtentReq::ErrorCode err; ndbrequire(m_tablespace_hash.find(ts_ptr, req.request.tablespace_id)); - Uint32 size = ts_ptr.p->m_extent_size; Local_datafile_list tmp(m_file_pool, ts_ptr.p->m_free_files); if (tmp.first(file_ptr)) { - Uint32 eh_words = File_formats::Datafile::extent_header_words(size); - Uint32 per_page = File_formats::Datafile::EXTENT_PAGE_WORDS/eh_words; - + Uint32 size = file_ptr.p->m_extent_size; Uint32 extent = file_ptr.p->m_online.m_first_free_extent; Uint32 data_off = file_ptr.p->m_online.m_offset_data_pages; + Uint32 eh_words = File_formats::Datafile::extent_header_words(size); + Uint32 per_page = File_formats::Datafile::EXTENT_PAGE_WORDS/eh_words; Uint32 page_no = extent / per_page; Uint32 extent_no = extent % per_page; Page_cache_client::Request preq; preq.m_page.m_page_no = page_no; preq.m_page.m_file_no = file_ptr.p->m_file_no; - preq.m_page.m_page_idx = extent; /** * Handling of unmapped extent header pages is not implemented @@ -1470,6 +1470,7 @@ Tsman::execALLOC_EXTENT_REQ(Signal* signal) */ ndbassert(extent >= per_page); preq.m_page.m_page_no = data_off + size * (extent - /* zero */ per_page); + preq.m_page.m_page_idx = extent; // extent_no AllocExtentReq* rep = (AllocExtentReq*)signal->getDataPtr(); rep->reply.errorCode = 0; @@ -1501,28 +1502,21 @@ void Tsman::execFREE_EXTENT_REQ(Signal* signal) { jamEntry(); - Ptr<Tablespace> ts_ptr; Ptr<Datafile> file_ptr; FreeExtentReq req = *(FreeExtentReq*)signal->getDataPtr(); FreeExtentReq::ErrorCode err = (FreeExtentReq::ErrorCode)0; - ndbrequire(m_tablespace_hash.find(ts_ptr, req.request.tablespace_id)); Datafile file_key; file_key.m_file_no = req.request.key.m_file_no; ndbrequire(m_file_hash.find(file_ptr, file_key)); - Uint32 size = ts_ptr.p->m_extent_size; - - Uint32 eh_words = File_formats::Datafile::extent_header_words(size); - Uint32 per_page = File_formats::Datafile::EXTENT_PAGE_WORDS/eh_words; - Uint32 data_off = file_ptr.p->m_online.m_offset_data_pages; - Uint32 extent = (req.request.key.m_page_no - data_off) / size + per_page; - - Uint32 page_no = extent / per_page; - Uint32 extent_no = extent % per_page; + struct req val = lookup_extent(req.request.key.m_page_no, file_ptr.p); + Uint32 extent = + (req.request.key.m_page_no - val.m_extent_pages) / val.m_extent_size + + file_ptr.p->m_online.m_extent_headers_per_extent_page; Page_cache_client::Request preq; - preq.m_page.m_page_no = page_no; + preq.m_page.m_page_no = val.m_extent_page_no; preq.m_page.m_file_no = req.request.key.m_file_no; ndbout << "Free extent: " << req.request.key << endl; @@ -1539,16 +1533,38 @@ Tsman::execFREE_EXTENT_REQ(Signal* signal) File_formats::Datafile::Extent_page* page = (File_formats::Datafile::Extent_page*)ptr_p; File_formats::Datafile::Extent_header* header = - page->get_header(extent_no, size); + page->get_header(val.m_extent_no, val.m_extent_size); ndbrequire(header->m_table == req.request.table_id); header->m_table = RNIL; - header->m_next_free_extent= file_ptr.p->m_online.m_lcp_free_extent_head; - if(file_ptr.p->m_online.m_lcp_free_extent_head == RNIL) - file_ptr.p->m_online.m_lcp_free_extent_tail= extent; - file_ptr.p->m_online.m_lcp_free_extent_head= extent; file_ptr.p->m_online.m_used_extent_cnt--; + if (m_lcp_ongoing) + { + jam(); + header->m_next_free_extent= file_ptr.p->m_online.m_lcp_free_extent_head; + if(file_ptr.p->m_online.m_lcp_free_extent_head == RNIL) + file_ptr.p->m_online.m_lcp_free_extent_tail= extent; + file_ptr.p->m_online.m_lcp_free_extent_head= extent; + } + else + { + jam(); + header->m_next_free_extent = file_ptr.p->m_online.m_first_free_extent; + if (file_ptr.p->m_online.m_first_free_extent == RNIL) + { + /** + * Move from full to free + */ + Ptr<Tablespace> ptr; + m_tablespace_pool.getPtr(ptr, file_ptr.p->m_tablespace_ptr_i); + Local_datafile_list free(m_file_pool, ptr.p->m_free_files); + Local_datafile_list full(m_file_pool, ptr.p->m_full_files); + full.remove(file_ptr); + free.add(file_ptr); + } + file_ptr.p->m_online.m_first_free_extent = extent; + } } else { @@ -1583,18 +1599,10 @@ Tsman::update_page_free_bits(Signal* signal, file_key.m_file_no = key->m_file_no; ndbrequire(m_file_hash.find(file_ptr, file_key)); - Uint32 size = file_ptr.p->m_extent_size; - Uint32 data_off = file_ptr.p->m_online.m_offset_data_pages; - Uint32 eh_words = File_formats::Datafile::extent_header_words(size); - Uint32 per_page = File_formats::Datafile::EXTENT_PAGE_WORDS/eh_words; - Uint32 SZ= File_formats::Datafile::EXTENT_HEADER_BITMASK_BITS_PER_PAGE; - - Uint32 extent = (key->m_page_no - data_off) / size + per_page; - Uint32 page_no = extent / per_page; - Uint32 extent_no = extent % per_page; + struct req val = lookup_extent(key->m_page_no, file_ptr.p); Page_cache_client::Request preq; - preq.m_page.m_page_no = page_no; + preq.m_page.m_page_no = val.m_extent_page_no; preq.m_page.m_file_no = key->m_file_no; /** @@ -1609,12 +1617,12 @@ Tsman::update_page_free_bits(Signal* signal, File_formats::Datafile::Extent_page* page = (File_formats::Datafile::Extent_page*)ptr_p; File_formats::Datafile::Extent_header* header = - page->get_header(extent_no, size); + page->get_header(val.m_extent_no, val.m_extent_size); ndbrequire(header->m_table != RNIL); - Uint32 page_no_in_extent = (key->m_page_no - data_off) % size; - + Uint32 page_no_in_extent = calc_page_no_in_extent(key->m_page_no, &val); + /** * Toggle word */ @@ -1637,26 +1645,15 @@ Tsman::get_page_free_bits(Signal* signal, Local_key *key, { jamEntry(); - /** - * XXX make into subroutine - */ Ptr<Datafile> file_ptr; Datafile file_key; file_key.m_file_no = key->m_file_no; ndbrequire(m_file_hash.find(file_ptr, file_key)); - - Uint32 size = file_ptr.p->m_extent_size; - Uint32 data_off = file_ptr.p->m_online.m_offset_data_pages; - Uint32 eh_words = File_formats::Datafile::extent_header_words(size); - Uint32 per_page = File_formats::Datafile::EXTENT_PAGE_WORDS/eh_words; - Uint32 SZ= File_formats::Datafile::EXTENT_HEADER_BITMASK_BITS_PER_PAGE; - Uint32 extent = (key->m_page_no - data_off) / size + per_page; - Uint32 page_no = extent / per_page; - Uint32 extent_no = extent % per_page; + struct req val = lookup_extent(key->m_page_no, file_ptr.p); Page_cache_client::Request preq; - preq.m_page.m_page_no = page_no; + preq.m_page.m_page_no = val.m_extent_page_no; preq.m_page.m_file_no = key->m_file_no; /** @@ -1671,11 +1668,11 @@ Tsman::get_page_free_bits(Signal* signal, Local_key *key, File_formats::Datafile::Extent_page* page = (File_formats::Datafile::Extent_page*)ptr_p; File_formats::Datafile::Extent_header* header = - page->get_header(extent_no, size); + page->get_header(val.m_extent_no, val.m_extent_size); ndbrequire(header->m_table != RNIL); - Uint32 page_no_in_extent = (key->m_page_no - data_off) % size; + Uint32 page_no_in_extent = calc_page_no_in_extent(key->m_page_no, &val); Uint32 bits = header->get_free_bits(page_no_in_extent); *uncommitted = (bits & UNCOMMITTED_MASK) >> UNCOMMITTED_SHIFT; *committed = (bits & COMMITTED_MASK); @@ -1700,19 +1697,11 @@ Tsman::unmap_page(Signal* signal, Local_key *key, Uint32 uncommitted_bits) Datafile file_key; file_key.m_file_no = key->m_file_no; ndbrequire(m_file_hash.find(file_ptr, file_key)); - - Uint32 size = file_ptr.p->m_extent_size; - Uint32 data_off = file_ptr.p->m_online.m_offset_data_pages; - Uint32 eh_words = File_formats::Datafile::extent_header_words(size); - Uint32 per_page = File_formats::Datafile::EXTENT_PAGE_WORDS/eh_words; - Uint32 SZ= File_formats::Datafile::EXTENT_HEADER_BITMASK_BITS_PER_PAGE; - - Uint32 extent = (key->m_page_no - data_off) / size + per_page; - Uint32 page_no = extent / per_page; - Uint32 extent_no = extent % per_page; + + struct req val = lookup_extent(key->m_page_no, file_ptr.p); Page_cache_client::Request preq; - preq.m_page.m_page_no = page_no; + preq.m_page.m_page_no = val.m_extent_page_no; preq.m_page.m_file_no = key->m_file_no; /** @@ -1727,12 +1716,12 @@ Tsman::unmap_page(Signal* signal, Local_key *key, Uint32 uncommitted_bits) File_formats::Datafile::Extent_page* page = (File_formats::Datafile::Extent_page*)ptr_p; File_formats::Datafile::Extent_header* header = - page->get_header(extent_no, size); + page->get_header(val.m_extent_no, val.m_extent_size); ndbrequire(header->m_table != RNIL); - Uint32 page_no_in_extent = (key->m_page_no - data_off) % size; - + Uint32 page_no_in_extent = calc_page_no_in_extent(key->m_page_no, &val); + /** * Toggle word */ @@ -1767,18 +1756,10 @@ Tsman::restart_undo_page_free_bits(Signal* signal, file_key.m_file_no = key->m_file_no; ndbrequire(m_file_hash.find(file_ptr, file_key)); - Uint32 size = file_ptr.p->m_extent_size; - Uint32 data_off = file_ptr.p->m_online.m_offset_data_pages; - Uint32 eh_words = File_formats::Datafile::extent_header_words(size); - Uint32 per_page = File_formats::Datafile::EXTENT_PAGE_WORDS/eh_words; - Uint32 SZ= File_formats::Datafile::EXTENT_HEADER_BITMASK_BITS_PER_PAGE; - - Uint32 extent = (key->m_page_no - data_off) / size + per_page; - Uint32 page_no = extent / per_page; - Uint32 extent_no = extent % per_page; - + struct req val = lookup_extent(key->m_page_no, file_ptr.p); + Page_cache_client::Request preq; - preq.m_page.m_page_no = page_no; + preq.m_page.m_page_no = val.m_extent_page_no; preq.m_page.m_file_no = key->m_file_no; /** @@ -1793,7 +1774,7 @@ Tsman::restart_undo_page_free_bits(Signal* signal, File_formats::Datafile::Extent_page* page = (File_formats::Datafile::Extent_page*)ptr_p; File_formats::Datafile::Extent_header* header = - page->get_header(extent_no, size); + page->get_header(val.m_extent_no, val.m_extent_size); Uint64 lsn = 0; lsn += page->m_page_header.m_page_lsn_hi; lsn <<= 32; @@ -1816,7 +1797,7 @@ Tsman::restart_undo_page_free_bits(Signal* signal, return 0; } - Uint32 page_no_in_extent = (key->m_page_no - data_off) % size; + Uint32 page_no_in_extent = calc_page_no_in_extent(key->m_page_no, &val); Uint32 src = header->get_free_bits(page_no_in_extent); ndbrequire(header->m_table == tableId); @@ -1862,17 +1843,11 @@ Tsman::execALLOC_PAGE_REQ(Signal* signal) Datafile file_key; file_key.m_file_no = req.key.m_file_no; ndbrequire(m_file_hash.find(file_ptr, file_key)); - - Uint32 size = file_ptr.p->m_extent_size; - Uint32 data_off = file_ptr.p->m_online.m_offset_data_pages; - Uint32 eh_words = File_formats::Datafile::extent_header_words(size); - Uint32 per_page = File_formats::Datafile::EXTENT_PAGE_WORDS/eh_words; - - Uint32 extent = (req.key.m_page_no - data_off) / size; - Uint32 extent_no = extent % per_page; + + struct req val = lookup_extent(req.key.m_page_no, file_ptr.p); Page_cache_client::Request preq; - preq.m_page.m_page_no = 1 /* zero */ + extent / per_page; + preq.m_page.m_page_no = val.m_extent_page_no; preq.m_page.m_file_no = req.key.m_file_no; Uint32 SZ= File_formats::Datafile::EXTENT_HEADER_BITMASK_BITS_PER_PAGE; @@ -1891,11 +1866,11 @@ Tsman::execALLOC_PAGE_REQ(Signal* signal) File_formats::Datafile::Extent_page* page = (File_formats::Datafile::Extent_page*)ptr_p; - header= page->get_header(extent_no, size); + header= page->get_header(val.m_extent_no, val.m_extent_size); ndbrequire(header->m_table == req.request.table_id); - Uint32 page_no_in_extent = (req.key.m_page_no - data_off) % size; + Uint32 page_no_in_extent = calc_page_no_in_extent(req.key.m_page_no, &val); Uint32 word = header->get_free_word_offset(page_no_in_extent); Uint32 shift = SZ * (page_no_in_extent & 7); @@ -1912,7 +1887,7 @@ Tsman::execALLOC_PAGE_REQ(Signal* signal) * Search */ Uint32 *src= header->m_page_bitmask + word; - for(page_no= page_no_in_extent; page_no<size; page_no++) + for(page_no= page_no_in_extent; page_no<val.m_extent_size; page_no++) { src_bits= (* src >> shift) & ((1 << SZ) - 1); if((src_bits & UNCOMMITTED_MASK) <= reqbits) @@ -1955,15 +1930,26 @@ Tsman::execALLOC_PAGE_REQ(Signal* signal) found: header->update_free_bits(page_no, src_bits | UNCOMMITTED_MASK); rep->bits= (src_bits & UNCOMMITTED_MASK) >> UNCOMMITTED_SHIFT; - rep->key.m_page_no= data_off + extent * size + page_no; + rep->key.m_page_no= + val.m_extent_pages + val.m_extent_no * val.m_extent_size + page_no; rep->reply.errorCode= 0; return; } void +Tsman::execLCP_FRAG_ORD(Signal* signal) +{ + jamEntry(); + ndbrequire(!m_lcp_ongoing); + m_lcp_ongoing = true; +} + +void Tsman::execEND_LCP_REQ(Signal* signal) { jamEntry(); + ndbrequire(m_lcp_ongoing); + m_lcp_ongoing = false; /** * Move extents from "lcp" free list to real free list diff --git a/storage/ndb/src/kernel/blocks/tsman.hpp b/storage/ndb/src/kernel/blocks/tsman.hpp index 7c92dfcb068..018d648de07 100644 --- a/storage/ndb/src/kernel/blocks/tsman.hpp +++ b/storage/ndb/src/kernel/blocks/tsman.hpp @@ -63,6 +63,7 @@ protected: void execALLOC_PAGE_REQ(Signal* signal); + void execLCP_FRAG_ORD(Signal*); void execEND_LCP_REQ(Signal*); void end_lcp(Signal*, Uint32 tablespace, Uint32 list, Uint32 file); @@ -108,6 +109,7 @@ public: Uint32 m_offset_data_pages; // 1(zero) + extent header pages Uint32 m_data_pages; Uint32 m_used_extent_cnt; + Uint32 m_extent_headers_per_extent_page; } m_online; struct { Uint32 m_senderData; @@ -196,6 +198,7 @@ private: Datafile_pool m_file_pool; Tablespace_pool m_tablespace_pool; + bool m_lcp_ongoing; Datafile_hash m_file_hash; Tablespace_list m_tablespace_list; Tablespace_hash m_tablespace_hash; @@ -226,15 +229,52 @@ private: void release_extent_pages(Signal* signal, Ptr<Datafile> ptr); void release_extent_pages_callback(Signal*, Uint32, Uint32); + + struct req + { + Uint32 m_extent_pages; + Uint32 m_extent_size; + Uint32 m_extent_no; // on extent page + Uint32 m_extent_page_no; + }; + + struct req lookup_extent(Uint32 page_no, const Datafile*) const; + Uint32 calc_page_no_in_extent(Uint32 page_no, const struct req* val) const; }; +inline +Tsman::req +Tsman::lookup_extent(Uint32 page_no, const Datafile * filePtrP) const +{ + struct req val; + val.m_extent_size = filePtrP->m_extent_size; + val.m_extent_pages = filePtrP->m_online.m_offset_data_pages; + Uint32 per_page = filePtrP->m_online.m_extent_headers_per_extent_page; + + Uint32 extent = + (page_no - val.m_extent_pages) / val.m_extent_size + per_page; + + val.m_extent_page_no = extent / per_page; + val.m_extent_no = extent % per_page; + return val; +} + +inline +Uint32 +Tsman::calc_page_no_in_extent(Uint32 page_no, const Tsman::req* val) const +{ + return (page_no - val->m_extent_pages) % val->m_extent_size; +} + class Tablespace_client { +public: Tsman * m_tsman; Signal* m_signal; Uint32 m_table_id; Uint32 m_fragment_id; Uint32 m_tablespace_id; + public: Tablespace_client(Signal* signal, Tsman* tsman, Uint32 table, Uint32 fragment, Uint32 tablespaceId) { @@ -244,6 +284,8 @@ public: m_fragment_id= fragment; m_tablespace_id= tablespaceId; } + + Tablespace_client(Signal* signal, Tsman* tsman, Local_key* key); /** * Return >0 if success, no of pages in extent, sets key @@ -274,7 +316,7 @@ public: /** * Free extent */ - int free_extent(Local_key* key); + int free_extent(Local_key* key, Uint64 lsn); /** * Update page free bits @@ -307,6 +349,11 @@ public: * <0 - on error */ int get_tablespace_info(CreateFilegroupImplReq* rep); + + /** + * Update lsn of page corresponing to key + */ + int update_lsn(Local_key* key, Uint64 lsn); }; #include <signaldata/Extent.hpp> @@ -351,12 +398,14 @@ Tablespace_client::alloc_page_from_extent(Local_key* key, Uint32 bits) inline int -Tablespace_client::free_extent(Local_key* key) +Tablespace_client::free_extent(Local_key* key, Uint64 lsn) { FreeExtentReq* req = (FreeExtentReq*)m_signal->theData; req->request.key = *key; req->request.table_id = m_table_id; req->request.tablespace_id = m_tablespace_id; + req->request.lsn_hi = (Uint32)(lsn >> 32); + req->request.lsn_lo = (Uint32)(lsn & 0xFFFFFFFF); m_tsman->execFREE_EXTENT_REQ(m_signal); if(req->reply.errorCode == 0){ @@ -407,5 +456,4 @@ Tablespace_client::restart_undo_page_free_bits(Local_key* key, page_lsn); } - #endif diff --git a/storage/ndb/src/mgmsrv/ConfigInfo.cpp b/storage/ndb/src/mgmsrv/ConfigInfo.cpp index 0a5700cd5b2..c61288e5b7c 100644 --- a/storage/ndb/src/mgmsrv/ConfigInfo.cpp +++ b/storage/ndb/src/mgmsrv/ConfigInfo.cpp @@ -1288,6 +1288,18 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = { "0", "0", STR_VALUE(MAX_INT_RNIL) }, + + { + CFG_DB_MEMREPORT_FREQUENCY, + "MemReportFrequency", + DB_TOKEN, + "Frequency of mem reports in seconds, 0 = only when passing %-limits", + ConfigInfo::CI_USED, + false, + ConfigInfo::CI_INT, + "0", + "0", + STR_VALUE(MAX_INT_RNIL) }, /*************************************************************************** * API diff --git a/storage/ndb/src/mgmsrv/MgmtSrvr.cpp b/storage/ndb/src/mgmsrv/MgmtSrvr.cpp index 0a849f6e00e..29cf869d7bf 100644 --- a/storage/ndb/src/mgmsrv/MgmtSrvr.cpp +++ b/storage/ndb/src/mgmsrv/MgmtSrvr.cpp @@ -1921,7 +1921,7 @@ MgmtSrvr::handleStatus(NodeId nodeId, bool alive, bool nfComplete) m_started_nodes.push_back(nodeId); rep->setEventType(NDB_LE_Connected); } else { - rep->setEventType(NDB_LE_Connected); + rep->setEventType(NDB_LE_Disconnected); if(nfComplete) { DBUG_VOID_RETURN; diff --git a/storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp b/storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp index cbf2b1f5525..ba2329888d2 100644 --- a/storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp +++ b/storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp @@ -2190,9 +2190,14 @@ NdbDictInterface::parseTableInfo(NdbTableImpl ** ret, impl->m_replicaCount = replicaCount; impl->m_fragmentCount = fragCount; DBUG_PRINT("info", ("replicaCount=%x , fragCount=%x",replicaCount,fragCount)); - for(i = 0; i < (Uint32) (fragCount*replicaCount); i++) + Uint32 pos = 2; + for(i = 0; i < (Uint32) fragCount;i++) { - impl->m_fragments.push_back(ntohs(tableDesc->ReplicaData[i+2])); + pos++; // skip logpart + for (Uint32 j = 0; j<(Uint32)replicaCount; j++) + { + impl->m_fragments.push_back(ntohs(tableDesc->ReplicaData[pos++])); + } } Uint32 topBit = (1 << 31); @@ -2296,7 +2301,7 @@ NdbDictionaryImpl::createTable(NdbTableImpl &t) } // blob tables - use "t2" to get values set by kernel - if (t2->m_noOfBlobs != 0 && createBlobTables(*t2) != 0) { + if (t2->m_noOfBlobs != 0 && createBlobTables(t, *t2) != 0) { int save_code = m_error.code; (void)dropTableGlobal(*t2); m_error.code = save_code; @@ -2310,7 +2315,7 @@ NdbDictionaryImpl::createTable(NdbTableImpl &t) } int -NdbDictionaryImpl::createBlobTables(NdbTableImpl &t) +NdbDictionaryImpl::createBlobTables(NdbTableImpl& orig, NdbTableImpl &t) { DBUG_ENTER("NdbDictionaryImpl::createBlobTables"); for (unsigned i = 0; i < t.m_columns.size(); i++) { @@ -2319,6 +2324,10 @@ NdbDictionaryImpl::createBlobTables(NdbTableImpl &t) continue; NdbTableImpl bt; NdbBlob::getBlobTable(bt, &t, &c); + NdbDictionary::Column::StorageType + d = NdbDictionary::Column::StorageTypeDisk; + if (orig.m_columns[i]->getStorageType() == d) + bt.getColumn("DATA")->setStorageType(d); if (createTable(bt) != 0) { DBUG_RETURN(-1); } diff --git a/storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp b/storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp index c6f6e431fba..26d7c13f968 100644 --- a/storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp +++ b/storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp @@ -581,7 +581,7 @@ public: bool setTransporter(class TransporterFacade * tf); int createTable(NdbTableImpl &t); - int createBlobTables(NdbTableImpl& t); + int createBlobTables(NdbTableImpl& org, NdbTableImpl& created); int alterTable(NdbTableImpl &t); int dropTable(const char * name); int dropTable(NdbTableImpl &); diff --git a/storage/ndb/src/ndbapi/NdbTransaction.cpp b/storage/ndb/src/ndbapi/NdbTransaction.cpp index 7d7040a6b74..5e3738823d3 100644 --- a/storage/ndb/src/ndbapi/NdbTransaction.cpp +++ b/storage/ndb/src/ndbapi/NdbTransaction.cpp @@ -476,6 +476,7 @@ NdbTransaction::executeNoBlobs(ExecType aTypeOfExec, * This timeout situation can occur if NDB crashes. */ ndbout << "This timeout should never occur, execute(..)" << endl; + theError.code = 4012; setOperationErrorCodeAbort(4012); // Error code for "Cluster Failure" DBUG_RETURN(-1); }//if @@ -1978,6 +1979,14 @@ NdbTransaction::receiveTCINDXCONF(const TcIndxConf * indxConf, } } else if ((tNoComp >= tNoSent) && (theLastExecOpInList->theCommitIndicator == 1)){ + + if (m_abortOption == AO_IgnoreError && theError.code != 0){ + /** + * There's always a TCKEYCONF when using IgnoreError + */ + return -1; + } + /**********************************************************************/ // We sent the transaction with Commit flag set and received a CONF with // no Commit flag set. This is clearly an anomaly. diff --git a/storage/ndb/src/ndbapi/Ndbif.cpp b/storage/ndb/src/ndbapi/Ndbif.cpp index cd7e779d188..fba40659ec7 100644 --- a/storage/ndb/src/ndbapi/Ndbif.cpp +++ b/storage/ndb/src/ndbapi/Ndbif.cpp @@ -1088,6 +1088,7 @@ Ndb::check_send_timeout() //abort(); #endif a_con->theReleaseOnClose = true; + a_con->theError.code = 4012; a_con->setOperationErrorCodeAbort(4012); a_con->theCommitStatus = NdbTransaction::NeedAbort; a_con->theCompletionStatus = NdbTransaction::CompletedFailure; @@ -1275,9 +1276,9 @@ Ndb::waitCompletedTransactions(int aMilliSecondsToWait, NDB_TICKS currTime = NdbTick_CurrentMillisecond(); NDB_TICKS maxTime = currTime + (NDB_TICKS)waitTime; theMinNoOfEventsToWakeUp = noOfEventsToWaitFor; + const int maxsleep = aMilliSecondsToWait > 10 ? 10 : aMilliSecondsToWait; do { - if (waitTime < 1000) waitTime = 1000; - poll_guard->wait_for_input(waitTime); + poll_guard->wait_for_input(maxsleep); if (theNoOfCompletedTransactions >= (Uint32)noOfEventsToWaitFor) { break; }//if diff --git a/storage/ndb/src/ndbapi/TransporterFacade.cpp b/storage/ndb/src/ndbapi/TransporterFacade.cpp index 6e30e15a325..24bf6dbbc6a 100644 --- a/storage/ndb/src/ndbapi/TransporterFacade.cpp +++ b/storage/ndb/src/ndbapi/TransporterFacade.cpp @@ -1384,15 +1384,13 @@ int PollGuard::wait_for_input_in_loop(int wait_time, bool forceSend) m_tp->forceSend(m_block_no); else m_tp->checkForceSend(m_block_no); - if (wait_time == -1) //Means wait forever - response_time= WAITFOR_RESPONSE_TIMEOUT; - else - response_time= wait_time; + NDB_TICKS curr_time = NdbTick_CurrentMillisecond(); NDB_TICKS max_time = curr_time + (NDB_TICKS)wait_time; + const int maxsleep = (wait_time == -1 || wait_time > 10) ? 10 : wait_time; do { - wait_for_input(response_time); + wait_for_input(maxsleep); Uint32 state= m_waiter->get_state(); if (state == NO_WAIT) { |