19 #include "diskpage.hpp"
20 #include <signaldata/FsRef.hpp>
21 #include <signaldata/FsConf.hpp>
22 #include <signaldata/FsOpenReq.hpp>
23 #include <signaldata/FsCloseReq.hpp>
24 #include <signaldata/CreateFilegroupImpl.hpp>
25 #include <signaldata/DropFilegroupImpl.hpp>
26 #include <signaldata/FsReadWriteReq.hpp>
27 #include <signaldata/LCP.hpp>
28 #include <signaldata/SumaImpl.hpp>
29 #include <signaldata/LgmanContinueB.hpp>
30 #include <signaldata/GetTabInfo.hpp>
31 #include <signaldata/NodeFailRep.hpp>
32 #include <signaldata/DbinfoScan.hpp>
33 #include "dbtup/Dbtup.hpp"
35 #include <EventLogger.hpp>
38 #include <record_types.hpp>
54 #define DEBUG_UNDO_EXECUTION 0
55 #define DEBUG_SEARCH_LOG_HEAD 0
57 #define FREE_BUFFER_MARGIN (2 * File_formats::UNDO_PAGE_WORDS)
62 m_logfile_group_list(m_logfile_group_pool),
63 m_logfile_group_hash(m_logfile_group_pool),
64 m_client_mutex(
"lgman-client", 2, true)
66 BLOCK_CONSTRUCTOR(
Lgman);
69 addRecSignal(GSN_STTOR, &Lgman::execSTTOR);
70 addRecSignal(GSN_READ_CONFIG_REQ, &Lgman::execREAD_CONFIG_REQ);
71 addRecSignal(GSN_DUMP_STATE_ORD, &Lgman::execDUMP_STATE_ORD);
72 addRecSignal(GSN_DBINFO_SCANREQ, &Lgman::execDBINFO_SCANREQ);
73 addRecSignal(GSN_CONTINUEB, &Lgman::execCONTINUEB);
74 addRecSignal(GSN_NODE_FAILREP, &Lgman::execNODE_FAILREP);
76 addRecSignal(GSN_CREATE_FILE_IMPL_REQ, &Lgman::execCREATE_FILE_IMPL_REQ);
77 addRecSignal(GSN_CREATE_FILEGROUP_IMPL_REQ,
78 &Lgman::execCREATE_FILEGROUP_IMPL_REQ);
80 addRecSignal(GSN_DROP_FILE_IMPL_REQ, &Lgman::execDROP_FILE_IMPL_REQ);
81 addRecSignal(GSN_DROP_FILEGROUP_IMPL_REQ,
82 &Lgman::execDROP_FILEGROUP_IMPL_REQ);
84 addRecSignal(GSN_FSWRITEREQ, &Lgman::execFSWRITEREQ);
85 addRecSignal(GSN_FSWRITEREF, &Lgman::execFSWRITEREF,
true);
86 addRecSignal(GSN_FSWRITECONF, &Lgman::execFSWRITECONF);
88 addRecSignal(GSN_FSOPENREF, &Lgman::execFSOPENREF,
true);
89 addRecSignal(GSN_FSOPENCONF, &Lgman::execFSOPENCONF);
91 addRecSignal(GSN_FSCLOSECONF, &Lgman::execFSCLOSECONF);
93 addRecSignal(GSN_FSREADREF, &Lgman::execFSREADREF,
true);
96 addRecSignal(GSN_LCP_FRAG_ORD, &Lgman::execLCP_FRAG_ORD);
97 addRecSignal(GSN_END_LCP_REQ, &Lgman::execEND_LCP_REQ);
99 addRecSignal(GSN_START_RECREQ, &Lgman::execSTART_RECREQ);
103 addRecSignal(GSN_GET_TABINFOREQ, &Lgman::execGET_TABINFOREQ);
106 m_logfile_group_hash.setSize(10);
110 int ret = m_client_mutex.create();
111 ndbrequire(ret == 0);
115 CallbackEntry& ce = m_callbackEntry[THE_NULL_CALLBACK];
116 ce.m_function = TheNULLCallback.m_callbackFunction;
120 CallbackEntry& ce = m_callbackEntry[ENDLCP_CALLBACK];
121 ce.m_function = safe_cast(&Lgman::endlcp_callback);
125 CallbackTable& ct = m_callbackTable;
126 ct.m_count = COUNT_CALLBACKS;
127 ct.m_entry = m_callbackEntry;
128 m_callbackTableAddr = &ct;
135 (void)m_client_mutex.destroy();
140 Lgman::client_lock(BlockNumber
block,
int line)
144 Uint32 bno = blockToMain(block);
145 Uint32 ino = blockToInstance(block);
147 D(
"try lock " << bno <<
"/" << ino << V(line));
148 int ret = m_client_mutex.lock();
149 ndbrequire(ret == 0);
150 D(
"got lock " << bno <<
"/" << ino << V(line));
155 Lgman::client_unlock(BlockNumber block,
int line)
159 Uint32 bno = blockToMain(block);
160 Uint32 ino = blockToInstance(block);
162 D(
"unlock " << bno <<
"/" << ino << V(line));
163 int ret = m_client_mutex.unlock();
164 ndbrequire(ret == 0);
168 BLOCK_FUNCTIONS(
Lgman)
177 Uint32 ref = req->senderRef;
178 Uint32 senderData = req->senderData;
181 m_ctx.m_config.getOwnConfigIterator();
186 m_log_waiter_pool.wo_pool_init(RT_LGMAN_LOG_WAITER, pc);
187 m_file_pool.init(RT_LGMAN_FILE, pc);
188 m_logfile_group_pool.init(RT_LGMAN_FILEGROUP, pc);
190 m_data_buffer_pool.setSize(40);
193 conf->senderRef = reference();
194 conf->senderData = senderData;
195 sendSignal(ref, GSN_READ_CONFIG_CONF, signal,
196 ReadConfigConf::SignalLength, JBB);
200 Lgman::execSTTOR(
Signal* signal)
203 Uint32 startPhase = signal->theData[1];
204 switch (startPhase) {
206 m_tup = globalData.getBlock(DBTUP);
207 ndbrequire(m_tup != 0);
214 Lgman::sendSTTORRY(
Signal* signal)
216 signal->theData[0] = 0;
217 signal->theData[3] = 1;
218 signal->theData[4] = 2;
219 signal->theData[5] = 3;
220 signal->theData[6] = 4;
221 signal->theData[7] = 5;
222 signal->theData[8] = 6;
223 signal->theData[9] = 255;
224 sendSignal(NDBCNTR_REF, GSN_STTORRY, signal, 10, JBB);
228 Lgman::execCONTINUEB(
Signal* signal){
231 Uint32
type= signal->theData[0];
232 Uint32 ptrI = signal->theData[1];
233 client_lock(number(), __LINE__);
235 case LgmanContinueB::FILTER_LOG:
238 case LgmanContinueB::CUT_LOG_TAIL:
242 m_logfile_group_pool.getPtr(ptr, ptrI);
243 cut_log_tail(signal, ptr);
246 case LgmanContinueB::FLUSH_LOG:
250 m_logfile_group_pool.getPtr(ptr, ptrI);
251 flush_log(signal, ptr, signal->theData[2]);
254 case LgmanContinueB::PROCESS_LOG_BUFFER_WAITERS:
258 m_logfile_group_pool.getPtr(ptr, ptrI);
259 process_log_buffer_waiters(signal, ptr);
262 case LgmanContinueB::FIND_LOG_HEAD:
268 m_logfile_group_pool.getPtr(ptr, ptrI);
269 find_log_head(signal, ptr);
274 init_run_undo_log(signal);
277 case LgmanContinueB::EXECUTE_UNDO_RECORD:
279 execute_undo_record(signal);
281 case LgmanContinueB::STOP_UNDO_LOG:
283 stop_run_undo_log(signal);
285 case LgmanContinueB::READ_UNDO_LOG:
289 m_logfile_group_pool.getPtr(ptr, ptrI);
290 read_undo_log(signal, ptr);
293 case LgmanContinueB::PROCESS_LOG_SYNC_WAITERS:
297 m_logfile_group_pool.getPtr(ptr, ptrI);
298 process_log_sync_waiters(signal, ptr);
301 case LgmanContinueB::FORCE_LOG_SYNC:
305 m_logfile_group_pool.getPtr(ptr, ptrI);
306 force_log_sync(signal, ptr, signal->theData[2], signal->theData[3]);
309 case LgmanContinueB::DROP_FILEGROUP:
313 m_logfile_group_pool.getPtr(ptr, ptrI);
314 if ((ptr.p->m_state & Logfile_group::LG_THREAD_MASK) ||
315 ptr.p->m_outstanding_fs > 0)
318 sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 100,
322 Uint32 ref = signal->theData[2];
323 Uint32 data = signal->theData[3];
324 drop_filegroup_drop_files(signal, ptr, ref, data);
328 client_unlock(number(), __LINE__);
332 Lgman::execNODE_FAILREP(
Signal* signal)
337 failed.
assign(NdbNodeBitmask::Size, rep->theNodes);
340 for(
unsigned i = 1;
i < MAX_NDB_NODES;
i++) {
344 Uint32 elementsCleaned = simBlockNodeFailure(signal,
i);
345 ndbassert(elementsCleaned == 0);
346 (void) elementsCleaned;
352 Lgman::execDUMP_STATE_ORD(
Signal* signal){
354 if (signal->theData[0] == 12001 || signal->theData[0] == 12002)
358 m_logfile_group_list.first(ptr);
362 "lfg %u state: %x fs: %u lsn "
363 " [ last: %llu s(req): %llu s:ed: %llu lcp: %llu ] "
365 ptr.p->m_logfile_group_id, ptr.p->m_state,
366 ptr.p->m_outstanding_fs,
367 ptr.p->m_last_lsn, ptr.p->m_last_sync_req_lsn,
368 ptr.p->m_last_synced_lsn, ptr.p->m_last_lcp_lsn,
369 !ptr.p->m_log_buffer_waiters.isEmpty(),
370 !ptr.p->m_log_sync_waiters.isEmpty());
371 if (signal->theData[0] == 12001)
372 infoEvent(
"%s", tmp);
376 " callback_buffer_words: %u"
377 " free_buffer_words: %u free_file_words: %llu",
378 ptr.p->m_callback_buffer_words,
379 ptr.p->m_free_buffer_words,
380 ptr.p->m_free_file_words);
381 if (signal->theData[0] == 12001)
382 infoEvent(
"%s", tmp);
384 if (!ptr.p->m_log_buffer_waiters.isEmpty())
387 Local_log_waiter_list
388 list(m_log_waiter_pool, ptr.p->m_log_buffer_waiters);
391 " head(waiters).sz: %u %u",
394 if (signal->theData[0] == 12001)
395 infoEvent(
"%s", tmp);
398 if (!ptr.p->m_log_sync_waiters.isEmpty())
401 Local_log_waiter_list
402 list(m_log_waiter_pool, ptr.p->m_log_sync_waiters);
405 " m_last_synced_lsn: %llu head(waiters %x).m_sync_lsn: %llu",
406 ptr.p->m_last_synced_lsn,
408 waiter.p->m_sync_lsn);
409 if (signal->theData[0] == 12001)
410 infoEvent(
"%s", tmp);
413 while(!waiter.isNull())
415 ndbout_c(
"ptr: %x %p lsn: %llu next: %x",
416 waiter.i, waiter.p, waiter.p->m_sync_lsn, waiter.p->nextList);
420 m_logfile_group_list.next(ptr);
423 if (signal->theData[0] == 12003)
427 for (m_logfile_group_list.first(ptr); !ptr.isNull();
428 m_logfile_group_list.next(ptr))
430 if (ptr.p->m_callback_buffer_words != 0)
439 ndbout_c(
"Detected logfile-group with non zero m_callback_buffer_words");
440 signal->theData[0] = 12002;
441 execDUMP_STATE_ORD(signal);
447 ndbout_c(
"Check for non zero m_callback_buffer_words OK!");
454 Lgman::execDBINFO_SCANREQ(
Signal *signal)
463 switch(req.tableId) {
464 case Ndbinfo::LOGSPACES_TABLEID:
467 Uint32 startBucket =
cursor->data[0];
468 Logfile_group_hash_iterator iter;
469 m_logfile_group_hash.next(startBucket, iter);
471 while (!iter.curr.isNull())
475 Uint32 currentBucket = iter.bucket;
478 Uint64 free = ptr.p->m_free_file_words*4;
481 Local_undofile_list list(m_file_pool, ptr.p->m_files);
483 for (list.first(filePtr); !filePtr.isNull(); list.next(filePtr))
486 total += (Uint64)filePtr.p->m_file_size *
487 (Uint64)File_formats::NDB_PAGE_SIZE;
493 row.write_uint32(getOwnNodeId());
495 row.write_uint32(ptr.p->m_logfile_group_id);
498 row.write_uint64(total);
499 row.write_uint64((total-free));
500 row.write_uint64(high);
501 ndbinfo_send_row(signal, req, row, rl);
504 if (m_logfile_group_hash.next(iter) ==
false)
509 else if (iter.bucket == currentBucket)
514 else if (rl.need_break(req))
517 ndbinfo_send_scan_break(signal, req, rl, iter.bucket);
524 case Ndbinfo::LOGBUFFERS_TABLEID:
527 Uint32 startBucket =
cursor->data[0];
528 Logfile_group_hash_iterator iter;
529 m_logfile_group_hash.next(startBucket, iter);
531 while (!iter.curr.isNull())
535 Uint32 currentBucket = iter.bucket;
538 Uint64 free = ptr.p->m_free_buffer_words*4;
539 Uint64 total = ptr.p->m_total_buffer_words*4;
543 row.write_uint32(getOwnNodeId());
545 row.write_uint32(ptr.p->m_logfile_group_id);
548 row.write_uint64(total);
549 row.write_uint64((total-free));
550 row.write_uint64(high);
551 ndbinfo_send_row(signal, req, row, rl);
554 if (m_logfile_group_hash.next(iter) ==
false)
559 else if (iter.bucket == currentBucket)
564 else if (rl.need_break(req))
567 ndbinfo_send_scan_break(signal, req, rl, iter.bucket);
578 ndbinfo_send_scan_conf(signal, req, rl);
582 Lgman::execCREATE_FILEGROUP_IMPL_REQ(
Signal* signal){
586 Uint32 senderRef = req->senderRef;
587 Uint32 senderData = req->senderData;
590 CreateFilegroupImplRef::ErrorCode err = CreateFilegroupImplRef::NoError;
592 if (m_logfile_group_hash.find(ptr, req->filegroup_id))
595 err = CreateFilegroupImplRef::FilegroupAlreadyExists;
599 if (!m_logfile_group_list.isEmpty())
602 err = CreateFilegroupImplRef::OneLogfileGroupLimit;
606 if (!m_logfile_group_pool.seize(ptr))
609 err = CreateFilegroupImplRef::OutOfFilegroupRecords;
613 new (ptr.p) Logfile_group(req);
615 if (!alloc_logbuffer_memory(ptr, req->logfile_group.buffer_size))
618 err= CreateFilegroupImplRef::OutOfLogBufferMemory;
619 m_logfile_group_pool.release(ptr);
623 m_logfile_group_hash.add(ptr);
624 m_logfile_group_list.add(ptr);
626 if ((getNodeState().getNodeRestartInProgress() &&
627 getNodeState().starting.restartType !=
628 NodeState::ST_INITIAL_NODE_RESTART)||
629 getNodeState().getSystemRestartInProgress())
631 ptr.p->m_state = Logfile_group::LG_STARTING;
636 conf->senderData = senderData;
637 conf->senderRef = reference();
638 sendSignal(senderRef, GSN_CREATE_FILEGROUP_IMPL_CONF, signal,
639 CreateFilegroupImplConf::SignalLength, JBB);
645 ref->senderData = senderData;
646 ref->senderRef = reference();
647 ref->errorCode = err;
648 sendSignal(senderRef, GSN_CREATE_FILEGROUP_IMPL_REF, signal,
649 CreateFilegroupImplRef::SignalLength, JBB);
653 Lgman::execDROP_FILEGROUP_IMPL_REQ(
Signal* signal)
657 Uint32 errorCode = 0;
662 if (!m_logfile_group_hash.find(ptr, req.filegroup_id))
664 errorCode = DropFilegroupImplRef::NoSuchFilegroup;
668 if (ptr.p->m_version != req.filegroup_version)
670 errorCode = DropFilegroupImplRef::InvalidFilegroupVersion;
674 switch(req.requestInfo){
675 case DropFilegroupImplReq::Prepare:
677 case DropFilegroupImplReq::Commit:
678 m_logfile_group_list.remove(ptr);
679 ptr.p->m_state |= Logfile_group::LG_DROPPING;
680 signal->theData[0] = LgmanContinueB::DROP_FILEGROUP;
681 signal->theData[1] = ptr.i;
682 signal->theData[2] = req.senderRef;
683 signal->theData[3] = req.senderData;
684 sendSignal(reference(), GSN_CONTINUEB, signal, 4, JBB);
686 case DropFilegroupImplReq::Abort:
697 ref->senderRef = reference();
698 ref->senderData = req.senderData;
699 ref->errorCode = errorCode;
700 sendSignal(req.senderRef, GSN_DROP_FILEGROUP_IMPL_REF, signal,
701 DropFilegroupImplRef::SignalLength, JBB);
707 conf->senderRef = reference();
708 conf->senderData = req.senderData;
709 sendSignal(req.senderRef, GSN_DROP_FILEGROUP_IMPL_CONF, signal,
710 DropFilegroupImplConf::SignalLength, JBB);
715 Lgman::drop_filegroup_drop_files(
Signal* signal,
717 Uint32 ref, Uint32 data)
720 ndbrequire(! (ptr.p->m_state & Logfile_group::LG_THREAD_MASK));
721 ndbrequire(ptr.p->m_outstanding_fs == 0);
723 Local_undofile_list list(m_file_pool, ptr.p->m_files);
726 if (list.first(file_ptr))
729 ndbrequire(! (file_ptr.p->m_state & Undofile::FS_OUTSTANDING));
730 file_ptr.p->m_create.m_senderRef = ref;
731 file_ptr.p->m_create.m_senderData = data;
732 create_file_abort(signal, ptr, file_ptr);
736 Local_undofile_list metalist(m_file_pool, ptr.p->m_meta_files);
737 if (metalist.first(file_ptr))
740 metalist.remove(file_ptr);
742 file_ptr.p->m_create.m_senderRef = ref;
743 file_ptr.p->m_create.m_senderData = data;
744 create_file_abort(signal, ptr, file_ptr);
748 free_logbuffer_memory(ptr);
749 m_logfile_group_hash.release(ptr);
751 conf->senderData = data;
752 conf->senderRef = reference();
753 sendSignal(ref, GSN_DROP_FILEGROUP_IMPL_CONF, signal,
754 DropFilegroupImplConf::SignalLength, JBB);
758 Lgman::execCREATE_FILE_IMPL_REQ(
Signal* signal)
763 Uint32 senderRef = req->senderRef;
764 Uint32 senderData = req->senderData;
765 Uint32 requestInfo = req->requestInfo;
768 CreateFileImplRef::ErrorCode err = CreateFileImplRef::NoError;
771 if (!m_logfile_group_hash.find(ptr, req->filegroup_id))
774 err = CreateFileImplRef::InvalidFilegroup;
778 if (ptr.p->m_version != req->filegroup_version)
781 err = CreateFileImplRef::InvalidFilegroupVersion;
787 case CreateFileImplReq::Commit:
790 ndbrequire(find_file_by_id(file_ptr, ptr.p->m_meta_files, req->file_id));
791 file_ptr.p->m_create.m_senderRef = req->senderRef;
792 file_ptr.p->m_create.m_senderData = req->senderData;
793 create_file_commit(signal, ptr, file_ptr);
796 case CreateFileImplReq::Abort:
798 Uint32 senderRef = req->senderRef;
799 Uint32 senderData = req->senderData;
800 if (find_file_by_id(file_ptr, ptr.p->m_meta_files, req->file_id))
803 file_ptr.p->m_create.m_senderRef = senderRef;
804 file_ptr.p->m_create.m_senderData = senderData;
805 create_file_abort(signal, ptr, file_ptr);
811 conf->senderData = senderData;
812 conf->senderRef = reference();
813 sendSignal(senderRef, GSN_CREATE_FILE_IMPL_CONF, signal,
814 CreateFileImplConf::SignalLength, JBB);
822 if (!m_file_pool.seize(file_ptr))
825 err = CreateFileImplRef::OutOfFileRecords;
829 if (!handle.m_cnt == 1)
834 if (ERROR_INSERTED(15000) ||
835 (
sizeof(
void*) == 4 && req->file_size_hi & 0xFFFFFFFF))
838 err = CreateFileImplRef::FileSizeTooLarge;
842 Uint64 sz = (Uint64(req->file_size_hi) << 32) + req->file_size_lo;
846 err = CreateFileImplRef::FileSizeTooSmall;
850 new (file_ptr.p) Undofile(req, ptr.i);
852 Local_undofile_list tmp(m_file_pool, ptr.p->m_meta_files);
855 open_file(signal, file_ptr, req->requestInfo, &handle);
859 releaseSections(handle);
861 ref->senderData = senderData;
862 ref->senderRef = reference();
863 ref->errorCode = err;
864 sendSignal(senderRef, GSN_CREATE_FILE_IMPL_REF, signal,
865 CreateFileImplRef::SignalLength, JBB);
874 req->userReference = reference();
875 req->userPointer = ptr.i;
877 memset(req->fileNumber, 0,
sizeof(req->fileNumber));
878 FsOpenReq::setVersion(req->fileNumber, 4);
879 FsOpenReq::v4_setBasePath(req->fileNumber, FsOpenReq::BP_DD_UF);
882 req->fileFlags |= FsOpenReq::OM_READWRITE;
883 req->fileFlags |= FsOpenReq::OM_DIRECT;
884 req->fileFlags |= FsOpenReq::OM_SYNC;
886 case CreateFileImplReq::Create:
887 req->fileFlags |= FsOpenReq::OM_CREATE_IF_NONE;
888 req->fileFlags |= FsOpenReq::OM_INIT;
889 ptr.p->m_state = Undofile::FS_CREATING;
891 case CreateFileImplReq::CreateForce:
892 req->fileFlags |= FsOpenReq::OM_CREATE;
893 req->fileFlags |= FsOpenReq::OM_INIT;
894 ptr.p->m_state = Undofile::FS_CREATING;
896 case CreateFileImplReq::Open:
897 req->fileFlags |= FsOpenReq::OM_CHECK_SIZE;
898 ptr.p->m_state = Undofile::FS_OPENING;
904 req->page_size = File_formats::NDB_PAGE_SIZE;
905 Uint64
size = (Uint64)ptr.p->m_file_size * (Uint64)File_formats::NDB_PAGE_SIZE;
906 req->file_size_hi = (Uint32)(size >> 32);
907 req->file_size_lo = (Uint32)(size & 0xFFFFFFFF);
909 sendSignal(NDBFS_REF, GSN_FSOPENREQ, signal, FsOpenReq::SignalLength, JBB,
914 Lgman::execFSWRITEREQ(
Signal* signal)
921 m_file_pool.getPtr(ptr, req->userPointer);
922 m_shared_page_pool.getPtr(page_ptr, req->data.pageData[0]);
924 if (req->varIndex == 0)
928 page->m_page_header.init(File_formats::FT_Undofile,
932 page->m_file_id = ptr.p->m_file_id;
933 page->m_logfile_group_id = ptr.p->m_create.m_logfile_group_id;
934 page->m_logfile_group_version = ptr.p->m_create.m_logfile_group_version;
935 page->m_undo_pages = ptr.p->m_file_size - 1;
941 page->m_page_header.m_page_lsn_hi = 0;
942 page->m_page_header.m_page_lsn_lo = 0;
943 page->m_page_header.m_page_type = File_formats::PT_Undopage;
944 page->m_words_used = 0;
949 Lgman::execFSOPENREF(
Signal* signal)
957 Uint32 errCode = ref->errorCode;
958 Uint32 osErrCode = ref->osErrorCode;
961 m_logfile_group_pool.getPtr(lg_ptr, ptr.p->m_logfile_group_ptr_i);
965 ref->senderData = ptr.p->m_create.m_senderData;
966 ref->senderRef = reference();
967 ref->errorCode = CreateFileImplRef::FileError;
968 ref->fsErrCode = errCode;
969 ref->osErrCode = osErrCode;
971 sendSignal(ptr.p->m_create.m_senderRef, GSN_CREATE_FILE_IMPL_REF, signal,
972 CreateFileImplRef::SignalLength, JBB);
975 Local_undofile_list meta(m_file_pool, lg_ptr.p->m_meta_files);
983 Lgman::execFSOPENCONF(
Signal* signal)
990 Uint32 fd = conf->filePointer;
991 m_file_pool.getPtr(ptr, conf->userPointer);
996 Uint32 senderRef = ptr.p->m_create.m_senderRef;
997 Uint32 senderData = ptr.p->m_create.m_senderData;
1000 conf->senderData = senderData;
1001 conf->senderRef = reference();
1002 sendSignal(senderRef, GSN_CREATE_FILE_IMPL_CONF, signal,
1003 CreateFileImplConf::SignalLength, JBB);
1009 Local_undofile_list::Head& head, Uint32
id)
1011 Local_undofile_list list(m_file_pool, head);
1012 for(list.first(ptr); !ptr.isNull(); list.next(ptr))
1013 if(ptr.p->m_file_id ==
id)
1019 Lgman::create_file_commit(
Signal* signal,
1023 Uint32 senderRef = ptr.p->m_create.m_senderRef;
1024 Uint32 senderData = ptr.p->m_create.m_senderData;
1027 if(ptr.p->m_state == Undofile::FS_CREATING &&
1028 (lg_ptr.p->m_state & Logfile_group::LG_ONLINE))
1031 Local_undofile_list free(m_file_pool, lg_ptr.p->m_files);
1032 Local_undofile_list meta(m_file_pool, lg_ptr.p->m_meta_files);
1033 first= free.isEmpty();
1041 m_file_pool.getPtr(curr, lg_ptr.p->m_file_pos[HEAD].m_ptr_i);
1043 free.insert(ptr, curr);
1047 ptr.p->m_state = Undofile::FS_ONLINE | Undofile::FS_EMPTY;
1055 ptr.p->m_state = Undofile::FS_ONLINE;
1056 lg_ptr.p->m_state |= Logfile_group::LG_FLUSH_THREAD;
1057 signal->theData[0] = LgmanContinueB::FLUSH_LOG;
1058 signal->theData[1] = lg_ptr.i;
1059 signal->theData[2] = 0;
1060 sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
1065 ptr.p->m_state = Undofile::FS_SORTING;
1068 ptr.p->m_online.m_lsn = 0;
1069 ptr.p->m_online.m_outstanding = 0;
1071 Uint64 add= ptr.p->m_file_size - 1;
1072 lg_ptr.p->m_free_file_words += add * File_formats::UNDO_PAGE_WORDS;
1078 Buffer_idx tmp= { ptr.i, 0 };
1079 lg_ptr.p->m_file_pos[HEAD] = lg_ptr.p->m_file_pos[TAIL] = tmp;
1084 lg_ptr.p->m_tail_pos[0] = tmp;
1085 lg_ptr.p->m_tail_pos[1] = tmp;
1086 lg_ptr.p->m_tail_pos[2] = tmp;
1087 lg_ptr.p->m_next_reply_ptr_i = ptr.i;
1090 validate_logfile_group(lg_ptr,
"create_file_commit");
1093 conf->senderData = senderData;
1094 conf->senderRef = reference();
1095 sendSignal(senderRef, GSN_CREATE_FILE_IMPL_CONF, signal,
1096 CreateFileImplConf::SignalLength, JBB);
1100 Lgman::create_file_abort(
Signal* signal,
1104 if (ptr.p->m_fd == RNIL)
1106 ((
FsConf*)signal->getDataPtr())->userPointer = ptr.i;
1107 execFSCLOSECONF(signal);
1112 req->filePointer = ptr.p->m_fd;
1113 req->userReference = reference();
1114 req->userPointer = ptr.i;
1116 FsCloseReq::setRemoveFileFlag(req->fileFlag,
true);
1118 sendSignal(NDBFS_REF, GSN_FSCLOSEREQ, signal,
1119 FsCloseReq::SignalLength, JBB);
1123 Lgman::execFSCLOSECONF(
Signal* signal)
1127 Uint32 ptrI = ((
FsConf*)signal->getDataPtr())->userPointer;
1128 m_file_pool.getPtr(ptr, ptrI);
1130 Uint32 senderRef = ptr.p->m_create.m_senderRef;
1131 Uint32 senderData = ptr.p->m_create.m_senderData;
1133 m_logfile_group_pool.getPtr(lg_ptr, ptr.p->m_logfile_group_ptr_i);
1135 if (lg_ptr.p->m_state & Logfile_group::LG_DROPPING)
1139 Local_undofile_list list(m_file_pool, lg_ptr.p->m_files);
1142 drop_filegroup_drop_files(signal, lg_ptr, senderRef, senderData);
1147 Local_undofile_list list(m_file_pool, lg_ptr.p->m_meta_files);
1151 conf->senderData = senderData;
1152 conf->senderRef = reference();
1153 sendSignal(senderRef, GSN_CREATE_FILE_IMPL_CONF, signal,
1154 CreateFileImplConf::SignalLength, JBB);
1159 Lgman::execDROP_FILE_IMPL_REQ(
Signal* signal)
1170 m_logfile_group_id = req->filegroup_id;
1171 m_version = req->filegroup_version;
1172 m_state = LG_ONLINE;
1173 m_outstanding_fs = 0;
1174 m_next_reply_ptr_i = RNIL;
1177 m_last_synced_lsn = 0;
1178 m_last_sync_req_lsn = 0;
1179 m_max_sync_req_lsn = 0;
1180 m_last_read_lsn = 0;
1181 m_file_pos[0].m_ptr_i= m_file_pos[1].m_ptr_i = RNIL;
1183 m_free_file_words = 0;
1184 m_total_buffer_words = 0;
1185 m_free_buffer_words = 0;
1186 m_callback_buffer_words = 0;
1188 m_pos[CONSUMER].m_current_page.m_ptr_i = RNIL;
1189 m_pos[CONSUMER].m_current_pos.m_ptr_i = RNIL;
1190 m_pos[PRODUCER].m_current_page.m_ptr_i = RNIL;
1191 m_pos[PRODUCER].m_current_pos.m_ptr_i = RNIL;
1193 m_tail_pos[2].m_ptr_i= RNIL;
1194 m_tail_pos[2].m_idx= ~0;
1196 m_tail_pos[0] = m_tail_pos[1] = m_tail_pos[2];
1202 Uint32 pages= (((bytes + 3) >> 2) + File_formats::NDB_PAGE_SIZE_WORDS - 1)
1203 / File_formats::NDB_PAGE_SIZE_WORDS;
1204 Uint32 requested= pages;
1206 Page_map map(m_data_buffer_pool, ptr.p->m_buffer_pages);
1210 Uint32 cnt = pages > 64 ? 64 : pages;
1211 m_ctx.m_mm.alloc_pages(RG_DISK_OPERATIONS, &ptrI, &cnt, 1);
1215 range.m_ptr_i= ptrI;
1218 if (map.append((Uint32*)&range, 2) ==
false)
1225 m_ctx.m_mm.release_pages(RG_DISK_OPERATIONS,
1226 range.m_ptr_i, range.m_idx);
1229 pages -= range.m_idx;
1243 free_logbuffer_memory(ptr);
1247 #if defined VM_TRACE || defined ERROR_INSERT
1248 ndbout <<
"DD lgman: fg id:" << ptr.p->m_logfile_group_id <<
" undo buffer pages/bytes:" << (requested-pages) <<
"/" << (requested-pages)*File_formats::NDB_PAGE_SIZE << endl;
1251 init_logbuffer_pointers(ptr);
1258 Page_map map(m_data_buffer_pool, ptr.p->m_buffer_pages);
1259 Page_map::Iterator it;
1267 ndbrequire(map.next(it));
1270 ptr.p->m_pos[CONSUMER].m_current_page.m_ptr_i = 0;
1271 ptr.p->m_pos[CONSUMER].m_current_page.m_idx = range.m_idx - 1;
1272 ptr.p->m_pos[CONSUMER].m_current_pos.m_ptr_i = range.m_ptr_i;
1273 ptr.p->m_pos[CONSUMER].m_current_pos.m_idx = 0;
1275 ptr.p->m_pos[PRODUCER].m_current_page.m_ptr_i = 0;
1276 ptr.p->m_pos[PRODUCER].m_current_page.m_idx = range.m_idx - 1;
1277 ptr.p->m_pos[PRODUCER].m_current_pos.m_ptr_i = range.m_ptr_i;
1278 ptr.p->m_pos[PRODUCER].m_current_pos.m_idx = 0;
1280 Uint32 pages= range.m_idx;
1284 ndbrequire(map.next(it));
1286 pages += range.m_idx;
1289 ptr.p->m_total_buffer_words =
1290 ptr.p->m_free_buffer_words = pages * File_formats::UNDO_PAGE_WORDS;
1296 Buffer_idx head= ptr.p->m_file_pos[HEAD];
1297 Buffer_idx tail= ptr.p->m_file_pos[TAIL];
1299 if (head.m_ptr_i == tail.m_ptr_i && head.m_idx < tail.m_idx)
1301 pages += tail.m_idx - head.m_idx;
1306 m_file_pool.getPtr(file, head.m_ptr_i);
1307 Local_undofile_list list(m_file_pool, ptr.p->m_files);
1311 pages += (file.p->m_file_size - head.m_idx - 1);
1312 if(!list.next(file))
1315 }
while(file.i != tail.m_ptr_i);
1317 pages += tail.m_idx - head.m_idx;
1330 Page_map map(m_data_buffer_pool, ptr.p->m_buffer_pages);
1332 Page_map::Iterator it;
1337 ndbrequire(map.next(it));
1340 m_ctx.m_mm.release_pages(RG_DISK_OPERATIONS, range.m_ptr_i, range.m_idx);
1349 m_file_id = req->file_id;
1350 m_logfile_group_ptr_i= ptrI;
1352 Uint64 pages = req->file_size_hi;
1353 pages = (pages << 32) | req->file_size_lo;
1354 pages /= GLOBAL_PAGE_SIZE;
1355 m_file_size = Uint32(pages);
1356 #if defined VM_TRACE || defined ERROR_INSERT
1357 ndbout <<
"DD lgman: file id:" << m_file_id <<
" undofile pages/bytes:" << m_file_size <<
"/" << m_file_size*GLOBAL_PAGE_SIZE << endl;
1360 m_create.m_senderRef = req->senderRef;
1361 m_create.m_senderData = req->senderData;
1362 m_create.m_logfile_group_id = req->filegroup_id;
1366 Lgman* lgman, Uint32 logfile_group_id,
1369 Uint32 bno = block->number();
1370 Uint32 ino = block->instance();
1371 m_client_block=
block;
1372 m_block= numberToBlock(bno, ino);
1375 m_logfile_group_id= logfile_group_id;
1376 D(
"client ctor " << bno <<
"/" << ino);
1378 m_lgman->client_lock(m_block, 0);
1381 Logfile_client::~Logfile_client()
1384 Uint32 bno = blockToMain(m_block);
1385 Uint32 ino = blockToInstance(m_block);
1387 D(
"client dtor " << bno <<
"/" << ino);
1389 m_lgman->client_unlock(m_block, 0);
1397 if(m_lgman->m_logfile_group_list.first(ptr))
1399 if(ptr.p->m_last_synced_lsn >= lsn)
1408 list(m_lgman->m_log_waiter_pool, ptr.p->m_log_sync_waiters);
1410 empty= list.isEmpty();
1411 if(!list.seize(wait))
1414 wait.p->m_block= m_block;
1415 wait.p->m_sync_lsn=
lsn;
1416 memcpy(&wait.p->m_callback, &req->m_callback,
1419 ptr.p->m_max_sync_req_lsn = lsn > ptr.p->m_max_sync_req_lsn ?
1420 lsn : ptr.p->m_max_sync_req_lsn;
1423 if(ptr.p->m_last_sync_req_lsn < lsn &&
1424 ! (ptr.p->m_state & Lgman::Logfile_group::LG_FORCE_SYNC_THREAD))
1426 ptr.p->m_state |= Lgman::Logfile_group::LG_FORCE_SYNC_THREAD;
1427 signal->theData[0] = LgmanContinueB::FORCE_LOG_SYNC;
1428 signal->theData[1] = ptr.i;
1429 signal->theData[2] = (Uint32)(lsn >> 32);
1430 signal->theData[3] = (Uint32)(lsn & 0xFFFFFFFF);
1431 m_client_block->sendSignalWithDelay(m_lgman->reference(),
1432 GSN_CONTINUEB, signal, 10, 4);
1440 Lgman::force_log_sync(
Signal* signal,
1442 Uint32 lsn_hi, Uint32 lsn_lo)
1444 Local_log_waiter_list list(m_log_waiter_pool, ptr.p->m_log_sync_waiters);
1445 Uint64 force_lsn = lsn_hi; force_lsn <<= 32; force_lsn += lsn_lo;
1447 if(ptr.p->m_last_sync_req_lsn < force_lsn)
1452 Buffer_idx pos= ptr.p->m_pos[PRODUCER].m_current_pos;
1453 GlobalPage *page = m_shared_page_pool.getPtr(pos.m_ptr_i);
1455 Uint32 free= File_formats::UNDO_PAGE_WORDS - pos.m_idx;
1458 Uint64
lsn= ptr.p->m_last_lsn - 1;
1462 undo->m_page_header.m_page_lsn_lo = (Uint32)(lsn & 0xFFFFFFFF);
1463 undo->m_page_header.m_page_lsn_hi = (Uint32)(lsn >> 32);
1464 undo->m_words_used= File_formats::UNDO_PAGE_WORDS - free;
1469 ndbrequire(ptr.p->m_free_file_words >= free);
1470 ndbrequire(ptr.p->m_free_buffer_words > free);
1471 ptr.p->m_free_file_words -= free;
1472 ptr.p->m_free_buffer_words -= free;
1474 validate_logfile_group(ptr,
"force_log_sync");
1476 next_page(ptr.p, PRODUCER);
1477 ptr.p->m_pos[PRODUCER].m_current_pos.m_idx = 0;
1483 Uint64 max_req_lsn = ptr.p->m_max_sync_req_lsn;
1484 if(max_req_lsn > force_lsn &&
1485 max_req_lsn > ptr.p->m_last_sync_req_lsn)
1487 ndbrequire(ptr.p->m_state & Lgman::Logfile_group::LG_FORCE_SYNC_THREAD);
1488 signal->theData[0] = LgmanContinueB::FORCE_LOG_SYNC;
1489 signal->theData[1] = ptr.i;
1490 signal->theData[2] = (Uint32)(max_req_lsn >> 32);
1491 signal->theData[3] = (Uint32)(max_req_lsn & 0xFFFFFFFF);
1492 sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 10, 4);
1496 ptr.p->m_state &= ~(Uint32)Lgman::Logfile_group::LG_FORCE_SYNC_THREAD;
1503 Local_log_waiter_list
1504 list(m_log_waiter_pool, ptr.p->m_log_sync_waiters);
1511 bool removed=
false;
1514 Uint32 logfile_group_id = ptr.p->m_logfile_group_id;
1516 if(waiter.p->m_sync_lsn <= ptr.p->m_last_synced_lsn)
1519 Uint32 block = waiter.p->m_block;
1520 CallbackPtr & callback = waiter.p->m_callback;
1521 sendCallbackConf(signal, block, callback, logfile_group_id);
1523 list.releaseFirst(waiter);
1526 if(removed && !list.isEmpty())
1528 ptr.p->m_state |= Logfile_group::LG_SYNC_WAITERS_THREAD;
1529 signal->theData[0] = LgmanContinueB::PROCESS_LOG_SYNC_WAITERS;
1530 signal->theData[1] = ptr.i;
1531 sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
1535 ptr.p->m_state &= ~(Uint32)Logfile_group::LG_SYNC_WAITERS_THREAD;
1544 page=m_shared_page_pool.getPtr(ptr.p->m_pos[PRODUCER].m_current_pos.m_ptr_i);
1546 Uint32 total_free= ptr.p->m_free_buffer_words;
1547 assert(total_free >= sz);
1548 Uint32 pos= ptr.p->m_pos[PRODUCER].m_current_pos.m_idx;
1549 Uint32 free= File_formats::UNDO_PAGE_WORDS - pos;
1555 ndbrequire(total_free >= sz);
1556 ptr.p->m_free_buffer_words = total_free - sz;
1557 ptr.p->m_pos[PRODUCER].m_current_pos.m_idx = pos + sz;
1564 Uint64 lsn= ptr.p->m_last_lsn - 1;
1567 undo->m_page_header.m_page_lsn_lo = (Uint32)(lsn & 0xFFFFFFFF);
1568 undo->m_page_header.m_page_lsn_hi = (Uint32)(lsn >> 32);
1569 undo->m_words_used= File_formats::UNDO_PAGE_WORDS - free;
1574 ndbrequire(ptr.p->m_free_file_words >= free);
1575 ptr.p->m_free_file_words -= free;
1577 validate_logfile_group(ptr,
"get_log_buffer");
1580 assert(total_free >= free);
1582 page= m_shared_page_pool.getPtr(next_page(ptr.p, PRODUCER));
1587 Lgman::next_page(Logfile_group* ptrP, Uint32
i)
1589 Uint32 page_ptr_i= ptrP->m_pos[
i].m_current_pos.m_ptr_i;
1590 Uint32 left_in_range= ptrP->m_pos[
i].m_current_page.m_idx;
1591 if(left_in_range > 0)
1593 ptrP->m_pos[
i].m_current_page.m_idx = left_in_range - 1;
1594 ptrP->m_pos[
i].m_current_pos.m_ptr_i = page_ptr_i + 1;
1595 return page_ptr_i + 1;
1600 Uint32 pos= (ptrP->m_pos[
i].m_current_page.m_ptr_i + 2) % map.getSize();
1602 map.position(it, pos);
1609 tmp[0] = *it.data; map.next(it);
1612 ptrP->m_pos[
i].m_current_page.m_ptr_i = pos;
1613 ptrP->m_pos[
i].m_current_page.m_idx = range.m_idx - 1;
1614 ptrP->m_pos[
i].m_current_pos.m_ptr_i = range.m_ptr_i;
1616 return range.m_ptr_i;
1626 key.m_logfile_group_id= m_logfile_group_id;
1628 if(m_lgman->m_logfile_group_hash.find(ptr, key))
1630 Uint32 callback_buffer = ptr.p->m_callback_buffer_words;
1631 Uint32 free_buffer = ptr.p->m_free_buffer_words;
1632 if (free_buffer >= (sz + callback_buffer + FREE_BUFFER_MARGIN) &&
1633 ptr.p->m_log_buffer_waiters.isEmpty())
1635 ptr.p->m_callback_buffer_words = callback_buffer + sz;
1643 list(m_lgman->m_log_waiter_pool, ptr.p->m_log_buffer_waiters);
1645 empty= list.isEmpty();
1646 if(!list.seize(wait))
1652 wait.p->m_block= m_block;
1665 << pos.m_ptr_i <<
" "
1666 << pos.m_idx <<
" ]";
1674 << pos.m_current_page.m_ptr_i <<
" "
1675 << pos.m_current_page.m_idx <<
") ("
1676 << pos.m_current_pos.m_ptr_i <<
" "
1677 << pos.m_current_pos.m_idx <<
") ]";
1684 Logfile_group::Position consumer= ptr.p->m_pos[CONSUMER];
1685 Logfile_group::Position producer= ptr.p->m_pos[PRODUCER];
1689 if (consumer.m_current_page == producer.m_current_page)
1692 Buffer_idx pos = producer.m_current_pos;
1697 ndbout_c(
"force: %d ptr.p->m_file_pos[HEAD].m_ptr_i= %x",
1698 force, ptr.p->m_file_pos[HEAD].m_ptr_i);
1699 ndbout_c(
"consumer.m_current_page: %d %d producer.m_current_page: %d %d",
1700 consumer.m_current_page.m_ptr_i, consumer.m_current_page.m_idx,
1701 producer.m_current_page.m_ptr_i, producer.m_current_page.m_idx);
1704 if (! (ptr.p->m_state & Logfile_group::LG_DROPPING))
1708 if (ptr.p->m_log_buffer_waiters.isEmpty() || pos.m_idx == 0)
1713 else if (ptr.p->m_free_buffer_words < FREE_BUFFER_MARGIN)
1719 if (force < 2 || ptr.p->m_outstanding_fs)
1722 signal->theData[0] = LgmanContinueB::FLUSH_LOG;
1723 signal->theData[1] = ptr.i;
1724 signal->theData[2] = force + 1;
1725 sendSignalWithDelay(reference(), GSN_CONTINUEB, signal,
1726 force ? 10 : 100, 3);
1732 GlobalPage *page = m_shared_page_pool.getPtr(pos.m_ptr_i);
1734 Uint32 free= File_formats::UNDO_PAGE_WORDS - pos.m_idx;
1736 ndbout_c(
"force flush %d %d outstanding: %u isEmpty(): %u",
1737 pos.m_idx, ptr.p->m_free_buffer_words,
1738 ptr.p->m_outstanding_fs,
1739 ptr.p->m_log_buffer_waiters.isEmpty());
1741 ndbrequire(pos.m_idx);
1742 Uint64 lsn= ptr.p->m_last_lsn - 1;
1746 undo->m_page_header.m_page_lsn_lo = (Uint32)(lsn & 0xFFFFFFFF);
1747 undo->m_page_header.m_page_lsn_hi = (Uint32)(lsn >> 32);
1748 undo->m_words_used= File_formats::UNDO_PAGE_WORDS - free;
1753 ndbrequire(ptr.p->m_free_file_words >= free);
1754 ndbrequire(ptr.p->m_free_buffer_words > free);
1755 ptr.p->m_free_file_words -= free;
1756 ptr.p->m_free_buffer_words -= free;
1758 validate_logfile_group(ptr,
"force_log_flush");
1760 next_page(ptr.p, PRODUCER);
1761 ptr.p->m_pos[PRODUCER].m_current_pos.m_idx = 0;
1762 producer = ptr.p->m_pos[PRODUCER];
1769 ptr.p->m_state &= ~(Uint32)Logfile_group::LG_FLUSH_THREAD;
1776 while(!(consumer.m_current_page == producer.m_current_page) && !full)
1779 validate_logfile_group(ptr,
"before flush log");
1782 Uint32 page= consumer.m_current_pos.m_ptr_i;
1783 if(consumer.m_current_page.m_ptr_i == producer.m_current_page.m_ptr_i)
1790 if(producer.m_current_pos.m_ptr_i > page)
1796 Uint32 tmp= producer.m_current_pos.m_ptr_i -
page;
1797 cnt= write_log_pages(signal, ptr, page, tmp);
1800 consumer.m_current_pos.m_ptr_i += cnt;
1801 consumer.m_current_page.m_idx -= cnt;
1809 Uint32 tmp= consumer.m_current_page.m_idx + 1;
1810 cnt= write_log_pages(signal, ptr, page, tmp);
1820 ptr.p->m_pos[CONSUMER].m_current_page.m_idx= 0;
1821 next_page(ptr.p, CONSUMER);
1822 consumer = ptr.p->m_pos[CONSUMER];
1831 consumer.m_current_page.m_idx -= cnt;
1832 consumer.m_current_pos.m_ptr_i += cnt;
1838 Uint32 tmp= consumer.m_current_page.m_idx + 1;
1839 cnt= write_log_pages(signal, ptr, page, tmp);
1849 ptr.p->m_pos[CONSUMER].m_current_page.m_idx= 0;
1850 next_page(ptr.p, CONSUMER);
1851 consumer = ptr.p->m_pos[CONSUMER];
1860 consumer.m_current_page.m_idx -= cnt;
1861 consumer.m_current_pos.m_ptr_i += cnt;
1867 validate_logfile_group(ptr,
" after flush_log");
1870 ptr.p->m_pos[CONSUMER]= consumer;
1872 if (! (ptr.p->m_state & Logfile_group::LG_DROPPING))
1874 signal->theData[0] = LgmanContinueB::FLUSH_LOG;
1875 signal->theData[1] = ptr.i;
1876 signal->theData[2] = 0;
1877 sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
1881 ptr.p->m_state &= ~(Uint32)Logfile_group::LG_FLUSH_THREAD;
1888 Uint32 free_buffer= ptr.p->m_free_buffer_words;
1889 Uint32 callback_buffer = ptr.p->m_callback_buffer_words;
1890 Local_log_waiter_list
1891 list(m_log_waiter_pool, ptr.p->m_log_buffer_waiters);
1896 ptr.p->m_state &= ~(Uint32)Logfile_group::LG_WAITERS_THREAD;
1900 bool removed=
false;
1903 Uint32 sz = waiter.p->m_size;
1904 Uint32 logfile_group_id = ptr.p->m_logfile_group_id;
1905 if (sz + callback_buffer + FREE_BUFFER_MARGIN < free_buffer)
1909 Uint32 block = waiter.p->m_block;
1910 CallbackPtr & callback = waiter.p->m_callback;
1911 ptr.p->m_callback_buffer_words += sz;
1912 sendCallbackConf(signal, block, callback, logfile_group_id);
1914 list.releaseFirst(waiter);
1917 if (removed && !list.isEmpty())
1920 ptr.p->m_state |= Logfile_group::LG_WAITERS_THREAD;
1921 signal->theData[0] = LgmanContinueB::PROCESS_LOG_BUFFER_WAITERS;
1922 signal->theData[1] = ptr.i;
1923 sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
1928 ptr.p->m_state &= ~(Uint32)Logfile_group::LG_WAITERS_THREAD;
1932 #define REALLY_SLOW_FS 0
1936 Uint32 pageId, Uint32 in_pages)
1940 Buffer_idx head= ptr.p->m_file_pos[HEAD];
1941 Buffer_idx tail= ptr.p->m_file_pos[TAIL];
1942 m_file_pool.getPtr(filePtr, head.m_ptr_i);
1944 if(filePtr.p->m_online.m_outstanding > 0)
1950 Uint32 sz= filePtr.p->m_file_size - 1;
1951 Uint32 max, pages= in_pages;
1953 if(!(head.m_ptr_i == tail.m_ptr_i && head.m_idx < tail.m_idx))
1955 max= sz - head.m_idx;
1959 max= tail.m_idx - head.m_idx;
1963 req->filePointer = filePtr.p->m_fd;
1964 req->userReference = reference();
1965 req->userPointer = filePtr.i;
1966 req->varIndex = 1+head.m_idx;
1967 req->numberOfPages = pages;
1968 req->data.pageData[0] = pageId;
1969 req->operationFlag = 0;
1970 FsReadWriteReq::setFormatFlag(req->operationFlag,
1971 FsReadWriteReq::fsFormatSharedPage);
1978 ptr.p->m_file_pos[HEAD] = head;
1981 sendSignalWithDelay(NDBFS_REF, GSN_FSWRITEREQ, signal, REALLY_SLOW_FS,
1982 FsReadWriteReq::FixedLength + 1);
1984 sendSignal(NDBFS_REF, GSN_FSWRITEREQ, signal,
1985 FsReadWriteReq::FixedLength + 1, JBA);
1987 ptr.p->m_outstanding_fs++;
1988 filePtr.p->m_online.m_outstanding = max;
1989 filePtr.p->m_state |= Undofile::FS_OUTSTANDING;
1992 m_shared_page_pool.getPtr(pageId + max - 1);
1994 lsn += page->m_page_header.m_page_lsn_hi; lsn <<= 32;
1995 lsn += page->m_page_header.m_page_lsn_lo;
1997 filePtr.p->m_online.m_lsn =
lsn;
1998 ptr.p->m_last_sync_req_lsn =
lsn;
2003 req->numberOfPages = max;
2004 FsReadWriteReq::setSyncFlag(req->operationFlag, 1);
2007 sendSignalWithDelay(NDBFS_REF, GSN_FSWRITEREQ, signal, REALLY_SLOW_FS,
2008 FsReadWriteReq::FixedLength + 1);
2010 sendSignal(NDBFS_REF, GSN_FSWRITEREQ, signal,
2011 FsReadWriteReq::FixedLength + 1, JBA);
2013 ptr.p->m_outstanding_fs++;
2014 filePtr.p->m_online.m_outstanding = max;
2015 filePtr.p->m_state |= Undofile::FS_OUTSTANDING;
2018 m_shared_page_pool.getPtr(pageId + max - 1);
2020 lsn += page->m_page_header.m_page_lsn_hi; lsn <<= 32;
2021 lsn += page->m_page_header.m_page_lsn_lo;
2023 filePtr.p->m_online.m_lsn =
lsn;
2024 ptr.p->m_last_sync_req_lsn =
lsn;
2027 Local_undofile_list files(m_file_pool, ptr.p->m_files);
2028 if(!files.next(next))
2033 ndbout_c(
"changing file from %d to %d", filePtr.i, next.i);
2034 filePtr.p->m_state |= Undofile::FS_MOVE_NEXT;
2035 next.p->m_state &= ~(Uint32)Undofile::FS_EMPTY;
2038 head.m_ptr_i= next.i;
2039 ptr.p->m_file_pos[HEAD] = head;
2041 max += write_log_pages(signal, ptr, pageId + max, pages - max);
2049 Lgman::execFSWRITEREF(
Signal* signal)
2052 SimulatedBlock::execFSWRITEREF(signal);
2057 Lgman::execFSWRITECONF(
Signal* signal)
2060 client_lock(number(), __LINE__);
2063 m_file_pool.getPtr(ptr, conf->userPointer);
2065 ndbrequire(ptr.p->m_state & Undofile::FS_OUTSTANDING);
2066 ptr.p->m_state &= ~(Uint32)Undofile::FS_OUTSTANDING;
2069 m_logfile_group_pool.getPtr(lg_ptr, ptr.p->m_logfile_group_ptr_i);
2071 Uint32 cnt= lg_ptr.p->m_outstanding_fs;
2074 if(lg_ptr.p->m_next_reply_ptr_i == ptr.i)
2079 Local_undofile_list files(m_file_pool, lg_ptr.p->m_files);
2080 while(cnt && ! (ptr.p->m_state & Undofile::FS_OUTSTANDING))
2082 Uint32 state= ptr.p->m_state;
2083 Uint32 pages= ptr.p->m_online.m_outstanding;
2085 ptr.p->m_online.m_outstanding= 0;
2086 ptr.p->m_state &= ~(Uint32)Undofile::FS_MOVE_NEXT;
2090 lsn = ptr.p->m_online.m_lsn;
2092 if((state & Undofile::FS_MOVE_NEXT) && !files.next(ptr))
2098 lg_ptr.p->m_outstanding_fs = cnt;
2099 lg_ptr.p->m_free_buffer_words += (tot * File_formats::UNDO_PAGE_WORDS);
2100 lg_ptr.p->m_next_reply_ptr_i = ptr.i;
2101 lg_ptr.p->m_last_synced_lsn =
lsn;
2103 if(! (lg_ptr.p->m_state & Logfile_group::LG_SYNC_WAITERS_THREAD))
2105 process_log_sync_waiters(signal, lg_ptr);
2108 if(! (lg_ptr.p->m_state & Logfile_group::LG_WAITERS_THREAD))
2110 process_log_buffer_waiters(signal, lg_ptr);
2115 ndbout_c(
"miss matched writes");
2117 client_unlock(number(), __LINE__);
2123 Lgman::execLCP_FRAG_ORD(
Signal* signal)
2126 client_lock(number(), __LINE__);
2127 exec_lcp_frag_ord(signal,
this);
2128 client_unlock(number(), __LINE__);
2137 Uint32 lcp_id= ord->lcpId;
2138 Uint32 frag_id = ord->fragmentId;
2139 Uint32 table_id = ord->tableId;
2142 m_logfile_group_list.first(ptr);
2144 Uint32
entry= lcp_id == m_latest_lcp ?
2145 File_formats::Undofile::UNDO_LCP : File_formats::Undofile::UNDO_LCP_FIRST;
2146 if(!ptr.isNull() && ! (ptr.p->m_state & Logfile_group::LG_CUT_LOG_THREAD))
2149 ptr.p->m_state |= Logfile_group::LG_CUT_LOG_THREAD;
2150 signal->theData[0] = LgmanContinueB::CUT_LOG_TAIL;
2151 signal->theData[1] = ptr.i;
2152 client_block->sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
2155 if(!ptr.isNull() && ptr.p->m_last_lsn)
2159 undo[1] = (table_id << 16) | frag_id;
2162 Uint64 last_lsn= m_last_lsn;
2164 if(ptr.p->m_last_lsn == last_lsn
2166 && ((rand() % 100) > 50)
2170 undo[2] |= File_formats::Undofile::UNDO_NEXT_LSN << 16;
2171 Uint32 *dst= get_log_buffer(ptr,
sizeof(undo) >> 2);
2172 memcpy(dst, undo,
sizeof(undo));
2173 ndbrequire(ptr.p->m_free_file_words >= (
sizeof(undo) >> 2));
2174 ptr.p->m_free_file_words -= (
sizeof(undo) >> 2);
2178 Uint32 *dst= get_log_buffer(ptr, (
sizeof(undo) >> 2) + 2);
2179 * dst++ = (Uint32)(last_lsn >> 32);
2180 * dst++ = (Uint32)(last_lsn & 0xFFFFFFFF);
2181 memcpy(dst, undo,
sizeof(undo));
2182 ndbrequire(ptr.p->m_free_file_words >= (
sizeof(undo) >> 2));
2183 ptr.p->m_free_file_words -= ((
sizeof(undo) >> 2) + 2);
2185 ptr.p->m_last_lcp_lsn = last_lsn;
2186 m_last_lsn = ptr.p->m_last_lsn = last_lsn + 1;
2188 validate_logfile_group(ptr,
"execLCP_FRAG_ORD");
2191 while(!ptr.isNull())
2193 if (ptr.p->m_last_lsn)
2198 if(m_latest_lcp != lcp_id)
2200 ptr.p->m_tail_pos[0] = ptr.p->m_tail_pos[1];
2201 ptr.p->m_tail_pos[1] = ptr.p->m_tail_pos[2];
2202 ptr.p->m_tail_pos[2] = ptr.p->m_file_pos[HEAD];
2207 (
"execLCP_FRAG_ORD (%d %d) (%d %d) (%d %d) free pages: %ld",
2208 ptr.p->m_tail_pos[0].m_ptr_i, ptr.p->m_tail_pos[0].m_idx,
2209 ptr.p->m_tail_pos[1].m_ptr_i, ptr.p->m_tail_pos[1].m_idx,
2210 ptr.p->m_tail_pos[2].m_ptr_i, ptr.p->m_tail_pos[2].m_idx,
2211 (
long) (ptr.p->m_free_file_words / File_formats::UNDO_PAGE_WORDS));
2213 m_logfile_group_list.next(ptr);
2216 m_latest_lcp = lcp_id;
2220 Lgman::execEND_LCP_REQ(
Signal* signal)
2223 ndbrequire(m_latest_lcp == req->backupId);
2224 m_end_lcp_senderdata = req->senderData;
2227 m_logfile_group_list.first(ptr);
2229 while(!ptr.isNull())
2231 Uint64 lcp_lsn = ptr.p->m_last_lcp_lsn;
2232 if(ptr.p->m_last_synced_lsn < lcp_lsn)
2235 if(signal->getSendersBlockRef() != reference())
2237 D(
"Logfile_client - execEND_LCP_REQ");
2240 req.m_callback.m_callbackData = ptr.i;
2241 req.m_callback.m_callbackIndex = ENDLCP_CALLBACK;
2242 ndbrequire(tmp.sync_lsn(signal, lcp_lsn, &req, 0) == 0);
2247 ptr.p->m_last_lcp_lsn = 0;
2249 m_logfile_group_list.next(ptr);
2258 conf->senderData = m_end_lcp_senderdata;
2259 conf->senderRef = reference();
2260 sendSignal(DBLQH_REF, GSN_END_LCP_CONF,
2261 signal, EndLcpConf::SignalLength, JBB);
2265 Lgman::endlcp_callback(
Signal* signal, Uint32 ptr, Uint32 res)
2268 req->backupId = m_latest_lcp;
2269 req->senderData = m_end_lcp_senderdata;
2270 execEND_LCP_REQ(signal);
2277 if (likely(ptr.p->m_last_lsn))
2279 Buffer_idx tmp= ptr.p->m_tail_pos[0];
2280 Buffer_idx tail= ptr.p->m_file_pos[TAIL];
2283 m_file_pool.getPtr(filePtr, tail.m_ptr_i);
2288 if(tmp.m_ptr_i == tail.m_ptr_i && tail.m_idx < tmp.m_idx)
2290 free= tmp.m_idx - tail.m_idx;
2291 ptr.p->m_free_file_words += free * File_formats::UNDO_PAGE_WORDS;
2292 ptr.p->m_file_pos[TAIL] = tmp;
2296 free= filePtr.p->m_file_size - tail.m_idx - 1;
2297 ptr.p->m_free_file_words += free * File_formats::UNDO_PAGE_WORDS;
2300 Local_undofile_list files(m_file_pool, ptr.p->m_files);
2301 while(files.next(next) && (next.p->m_state & Undofile::FS_EMPTY))
2302 ndbrequire(next.i != filePtr.i);
2307 while((next.p->m_state & Undofile::FS_EMPTY) && files.next(next))
2308 ndbrequire(next.i != filePtr.i);
2312 tmp.m_ptr_i= next.i;
2313 ptr.p->m_file_pos[TAIL] = tmp;
2318 validate_logfile_group(ptr,
"cut log");
2323 ptr.p->m_state &= ~(Uint32)Logfile_group::LG_CUT_LOG_THREAD;
2324 m_logfile_group_list.next(ptr);
2327 if(!done || !ptr.isNull())
2329 ptr.p->m_state |= Logfile_group::LG_CUT_LOG_THREAD;
2330 signal->theData[0] = LgmanContinueB::CUT_LOG_TAIL;
2331 signal->theData[1] = ptr.i;
2332 sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
2342 m_logfile_group_list.first(ptr);
2349 signal->theData[0] = LgmanContinueB::FILTER_LOG;
2350 while(!ptr.isNull())
2352 signal->theData[1] = ptr.i;
2353 sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
2354 m_logfile_group_list.next(ptr);
2359 Lgman::alloc_log_space(Uint32 ref, Uint32 words)
2364 key.m_logfile_group_id= ref;
2366 if(m_logfile_group_hash.find(ptr, key) &&
2367 ptr.p->m_free_file_words >= (words + (4 * File_formats::UNDO_PAGE_WORDS)))
2369 ptr.p->m_free_file_words -= words;
2370 validate_logfile_group(ptr,
"alloc_log_space");
2383 Lgman::free_log_space(Uint32 ref, Uint32 words)
2387 key.m_logfile_group_id= ref;
2389 if(m_logfile_group_hash.find(ptr, key))
2391 ptr.p->m_free_file_words += (words + 2);
2392 validate_logfile_group(ptr,
"free_log_space");
2400 Logfile_client::add_entry(
const Change* src, Uint32 cnt)
2403 for(i= 0; i<cnt; i++)
2409 Uint64 last_lsn= m_lgman->m_last_lsn;
2412 key.m_logfile_group_id= m_logfile_group_id;
2414 if(m_lgman->m_logfile_group_hash.find(ptr, key))
2416 Uint32 callback_buffer = ptr.p->m_callback_buffer_words;
2417 Uint64 last_lsn_filegroup= ptr.p->m_last_lsn;
2418 if(last_lsn_filegroup == last_lsn
2420 && ((rand() % 100) > 50)
2424 dst= m_lgman->get_log_buffer(ptr, tot);
2425 for(i= 0; i<cnt; i++)
2427 memcpy(dst, src[i].ptr, 4*src[i].len);
2430 * (dst - 1) |= File_formats::Undofile::UNDO_NEXT_LSN << 16;
2431 ptr.p->m_free_file_words += 2;
2432 m_lgman->validate_logfile_group(ptr);
2436 dst= m_lgman->get_log_buffer(ptr, tot + 2);
2437 * dst++ = (Uint32)(last_lsn >> 32);
2438 * dst++ = (Uint32)(last_lsn & 0xFFFFFFFF);
2439 for(i= 0; i<cnt; i++)
2441 memcpy(dst, src[i].ptr, 4*src[i].len);
2451 if (unlikely(! (tot <= callback_buffer)))
2455 ptr.p->m_callback_buffer_words = callback_buffer - tot;
2458 m_lgman->m_last_lsn = ptr.p->m_last_lsn = last_lsn + 1;
2465 Lgman::execSTART_RECREQ(
Signal* signal)
2467 m_latest_lcp = signal->theData[0];
2470 m_logfile_group_list.first(ptr);
2474 infoEvent(
"Applying undo to LCP: %d", m_latest_lcp);
2475 ndbout_c(
"Applying undo to LCP: %d", m_latest_lcp);
2476 find_log_head(signal, ptr);
2480 signal->theData[0] = reference();
2481 sendSignal(DBLQH_REF, GSN_START_RECCONF, signal, 1, JBB);
2487 ndbrequire(ptr.p->m_state &
2488 (Logfile_group::LG_STARTING | Logfile_group::LG_SORTING));
2490 if(ptr.p->m_meta_files.isEmpty() && ptr.p->m_files.isEmpty())
2496 ptr.p->m_state &= ~(Uint32)Logfile_group::LG_STARTING;
2497 ptr.p->m_state |= Logfile_group::LG_ONLINE;
2498 m_logfile_group_list.next(ptr);
2499 signal->theData[0] = LgmanContinueB::FIND_LOG_HEAD;
2500 signal->theData[1] = ptr.i;
2501 sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
2505 ptr.p->m_state = Logfile_group::LG_SORTING;
2510 Local_undofile_list files(m_file_pool, ptr.p->m_meta_files);
2512 files.first(file_ptr);
2514 if(!file_ptr.isNull())
2519 Uint32 page_id = ptr.p->m_pos[CONSUMER].m_current_pos.m_ptr_i;
2520 file_ptr.p->m_online.m_outstanding= page_id;
2523 req->filePointer = file_ptr.p->m_fd;
2524 req->userReference = reference();
2525 req->userPointer = file_ptr.i;
2527 req->numberOfPages = 1;
2528 req->data.pageData[0] = page_id;
2529 req->operationFlag = 0;
2530 FsReadWriteReq::setFormatFlag(req->operationFlag,
2531 FsReadWriteReq::fsFormatSharedPage);
2533 sendSignal(NDBFS_REF, GSN_FSREADREQ, signal,
2534 FsReadWriteReq::FixedLength + 1, JBA);
2536 ptr.p->m_outstanding_fs++;
2537 file_ptr.p->m_state |= Undofile::FS_OUTSTANDING;
2546 ndbrequire(!ptr.p->m_files.isEmpty());
2547 Local_undofile_list read_files(m_file_pool, ptr.p->m_files);
2548 read_files.last(file_ptr);
2554 ptr.p->m_state = Logfile_group::LG_SEARCHING;
2555 file_ptr.p->m_state = Undofile::FS_SEARCHING;
2556 ptr.p->m_file_pos[TAIL].m_idx = 1;
2557 ptr.p->m_file_pos[HEAD].m_idx = file_ptr.p->m_file_size;
2558 ptr.p->m_file_pos[HEAD].m_ptr_i = ((file_ptr.p->m_file_size - 1) >> 1) + 1;
2560 Uint32 page_id = ptr.p->m_pos[CONSUMER].m_current_pos.m_ptr_i;
2561 file_ptr.p->m_online.m_outstanding= page_id;
2564 req->filePointer = file_ptr.p->m_fd;
2565 req->userReference = reference();
2566 req->userPointer = file_ptr.i;
2567 req->varIndex = ptr.p->m_file_pos[HEAD].m_ptr_i;
2568 req->numberOfPages = 1;
2569 req->data.pageData[0] = page_id;
2570 req->operationFlag = 0;
2571 FsReadWriteReq::setFormatFlag(req->operationFlag,
2572 FsReadWriteReq::fsFormatSharedPage);
2574 sendSignal(NDBFS_REF, GSN_FSREADREQ, signal,
2575 FsReadWriteReq::FixedLength + 1, JBA);
2577 ptr.p->m_outstanding_fs++;
2578 file_ptr.p->m_state |= Undofile::FS_OUTSTANDING;
2587 client_lock(number(), __LINE__);
2593 m_file_pool.getPtr(ptr, conf->userPointer);
2594 m_logfile_group_pool.getPtr(lg_ptr, ptr.p->m_logfile_group_ptr_i);
2596 ndbrequire(ptr.p->m_state & Undofile::FS_OUTSTANDING);
2597 ptr.p->m_state &= ~(Uint32)Undofile::FS_OUTSTANDING;
2599 Uint32 cnt= lg_ptr.p->m_outstanding_fs;
2602 if((ptr.p->m_state & Undofile::FS_EXECUTING)== Undofile::FS_EXECUTING)
2606 if(lg_ptr.p->m_next_reply_ptr_i == ptr.i)
2610 while(cnt && ! (ptr.p->m_state & Undofile::FS_OUTSTANDING))
2612 Uint32 state= ptr.p->m_state;
2613 Uint32 pages= ptr.p->m_online.m_outstanding;
2615 ptr.p->m_online.m_outstanding= 0;
2616 ptr.p->m_state &= ~(Uint32)Undofile::FS_MOVE_NEXT;
2620 if((state & Undofile::FS_MOVE_NEXT) && !files.
prev(ptr))
2624 lg_ptr.p->m_outstanding_fs = cnt;
2625 lg_ptr.p->m_pos[PRODUCER].m_current_pos.m_idx += tot;
2626 lg_ptr.p->m_next_reply_ptr_i = ptr.i;
2628 client_unlock(number(), __LINE__);
2632 lg_ptr.p->m_outstanding_fs = cnt - 1;
2635 m_shared_page_pool.getPtr(page_ptr, ptr.p->m_online.m_outstanding);
2636 ptr.p->m_online.m_outstanding= 0;
2642 lsn += page->m_page_header.m_page_lsn_hi; lsn <<= 32;
2643 lsn += page->m_page_header.m_page_lsn_lo;
2645 switch(ptr.p->m_state){
2646 case Undofile::FS_SORTING:
2649 case Undofile::FS_SEARCHING:
2651 find_log_head_in_file(signal, lg_ptr, ptr, lsn);
2652 client_unlock(number(), __LINE__);
2655 case Undofile::FS_EXECUTING:
2656 case Undofile::FS_CREATING:
2657 case Undofile::FS_DROPPING:
2658 case Undofile::FS_ONLINE:
2659 case Undofile::FS_OPENING:
2660 case Undofile::FS_EMPTY:
2668 ptr.p->m_state = Undofile::FS_EXECUTING;
2669 ptr.p->m_online.m_lsn =
lsn;
2681 while(!loop.isNull() && loop.p->m_online.m_lsn <=
lsn)
2700 find_log_head(signal, lg_ptr);
2701 client_unlock(number(), __LINE__);
2705 Lgman::execFSREADREF(
Signal* signal)
2708 SimulatedBlock::execFSREADREF(signal);
2713 Lgman::find_log_head_in_file(
Signal* signal,
2720 Uint32 curr= ptr.p->m_file_pos[HEAD].m_ptr_i;
2721 Uint32 head= ptr.p->m_file_pos[HEAD].m_idx;
2722 Uint32 tail= ptr.p->m_file_pos[TAIL].m_idx;
2724 ndbrequire(head > tail);
2725 Uint32 diff = head - tail;
2727 if(DEBUG_SEARCH_LOG_HEAD)
2728 printf(
"tail: %d(%lld) head: %d last: %d(%lld) -> ",
2729 tail, file_ptr.p->m_online.m_lsn,
2730 head, curr, last_lsn);
2731 if(last_lsn > file_ptr.p->m_online.m_lsn)
2733 if(DEBUG_SEARCH_LOG_HEAD)
2734 printf(
"moving tail ");
2736 file_ptr.p->m_online.m_lsn = last_lsn;
2737 ptr.p->m_file_pos[TAIL].m_idx = tail = curr;
2741 if(DEBUG_SEARCH_LOG_HEAD)
2742 printf(
"moving head ");
2744 ptr.p->m_file_pos[HEAD].m_idx = head = curr;
2750 ptr.p->m_file_pos[HEAD].m_ptr_i = curr = ((head + tail) >> 1);
2752 if(DEBUG_SEARCH_LOG_HEAD)
2753 ndbout_c(
"-> new search tail: %d(%lld) head: %d -> %d",
2754 tail, file_ptr.p->m_online.m_lsn,
2757 Uint32 page_id = ptr.p->m_pos[CONSUMER].m_current_pos.m_ptr_i;
2758 file_ptr.p->m_online.m_outstanding= page_id;
2761 req->filePointer = file_ptr.p->m_fd;
2762 req->userReference = reference();
2763 req->userPointer = file_ptr.i;
2764 req->varIndex = curr;
2765 req->numberOfPages = 1;
2766 req->data.pageData[0] = page_id;
2767 req->operationFlag = 0;
2768 FsReadWriteReq::setFormatFlag(req->operationFlag,
2769 FsReadWriteReq::fsFormatSharedPage);
2771 sendSignal(NDBFS_REF, GSN_FSREADREQ, signal,
2772 FsReadWriteReq::FixedLength + 1, JBA);
2774 ptr.p->m_outstanding_fs++;
2775 file_ptr.p->m_state |= Undofile::FS_OUTSTANDING;
2779 ndbrequire(diff == 1);
2780 if(DEBUG_SEARCH_LOG_HEAD)
2781 ndbout_c(
"-> found last page: %d", tail);
2784 file_ptr.p->m_state = Undofile::FS_EXECUTING;
2785 ptr.p->m_last_lsn = file_ptr.p->m_online.m_lsn;
2786 ptr.p->m_last_read_lsn = file_ptr.p->m_online.m_lsn;
2787 ptr.p->m_last_synced_lsn = file_ptr.p->m_online.m_lsn;
2788 m_last_lsn = file_ptr.p->m_online.m_lsn;
2793 ptr.p->m_file_pos[HEAD].m_ptr_i = file_ptr.i;
2794 ptr.p->m_file_pos[HEAD].m_idx = tail;
2796 ptr.p->m_file_pos[TAIL].m_ptr_i = file_ptr.i;
2797 ptr.p->m_file_pos[TAIL].m_idx = tail - 1;
2798 ptr.p->m_next_reply_ptr_i = file_ptr.i;
2801 Local_undofile_list files(m_file_pool, ptr.p->m_files);
2809 if(!files.prev(prev))
2813 ptr.p->m_file_pos[TAIL].m_ptr_i = prev.i;
2814 ptr.p->m_file_pos[TAIL].m_idx = prev.p->m_file_size - 1;
2815 ptr.p->m_next_reply_ptr_i = prev.i;
2819 infoEvent(
"Undo head - %s page: %d lsn: %lld",
2820 fs->get_filename(file_ptr.p->m_fd),
2821 tail, file_ptr.p->m_online.m_lsn);
2822 g_eventLogger->
info(
"Undo head - %s page: %d lsn: %lld",
2823 fs->get_filename(file_ptr.p->m_fd),
2824 tail, file_ptr.p->m_online.m_lsn);
2826 for(files.prev(file_ptr); !file_ptr.isNull(); files.prev(file_ptr))
2828 infoEvent(
" - next - %s(%lld)",
2829 fs->get_filename(file_ptr.p->m_fd),
2830 file_ptr.p->m_online.m_lsn);
2832 g_eventLogger->
info(
" - next - %s(%lld)",
2833 fs->get_filename(file_ptr.p->m_fd),
2834 file_ptr.p->m_online.m_lsn);
2841 m_logfile_group_list.next(ptr);
2842 signal->theData[0] = LgmanContinueB::FIND_LOG_HEAD;
2843 signal->theData[1] = ptr.i;
2844 sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
2848 Lgman::init_run_undo_log(
Signal* signal)
2854 Logfile_group_list& list= m_logfile_group_list;
2855 Logfile_group_list tmp(m_logfile_group_pool);
2857 bool found_any =
false;
2860 while(!group.isNull())
2866 if (ptr.p->m_state & Logfile_group::LG_ONLINE)
2882 ptr.p->m_free_buffer_words -= File_formats::UNDO_PAGE_WORDS;
2883 ptr.p->m_pos[CONSUMER].m_current_page.m_idx = 0;
2884 ptr.p->m_pos[PRODUCER].m_current_page.m_idx = 0;
2886 Uint32 page = ptr.p->m_pos[CONSUMER].m_current_pos.m_ptr_i;
2890 ptr.p->m_pos[CONSUMER].m_current_pos.m_idx = pageP->m_words_used;
2891 ptr.p->m_pos[PRODUCER].m_current_pos.m_idx = 1;
2892 ptr.p->m_last_read_lsn++;
2898 signal->theData[0] = LgmanContinueB::READ_UNDO_LOG;
2899 signal->theData[1] = ptr.i;
2900 sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
2906 for(tmp.first(pos); !pos.isNull(); tmp.next(pos))
2907 if(ptr.p->m_last_read_lsn >= pos.p->m_last_read_lsn)
2913 tmp.insert(ptr, pos);
2916 Logfile_group::LG_EXEC_THREAD | Logfile_group::LG_READ_THREAD;
2920 if (found_any ==
false)
2926 signal->theData[0] = reference();
2927 sendSignal(DBLQH_REF, GSN_START_RECCONF, signal, 1, JBB);
2931 execute_undo_record(signal);
2937 Uint32 cnt, free= ptr.p->m_free_buffer_words;
2939 if(! (ptr.p->m_state & Logfile_group::LG_EXEC_THREAD))
2945 ptr.p->m_state &= ~(Uint32)Logfile_group::LG_READ_THREAD;
2946 stop_run_undo_log(signal);
2950 if(free <= File_formats::UNDO_PAGE_WORDS)
2952 signal->theData[0] = LgmanContinueB::READ_UNDO_LOG;
2953 signal->theData[1] = ptr.i;
2954 sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 100, 2);
2958 Logfile_group::Position producer= ptr.p->m_pos[PRODUCER];
2959 Logfile_group::Position consumer= ptr.p->m_pos[CONSUMER];
2961 if(producer.m_current_page.m_idx == 0)
2967 Page_map map(m_data_buffer_pool, ptr.p->m_buffer_pages);
2968 Uint32 sz = map.getSize();
2969 Uint32 pos= (producer.m_current_page.m_ptr_i + sz - 2) % sz;
2970 map.position(it, pos);
2975 _tmp[0] = *it.data; map.next(it); _tmp[1] = *it.data;
2976 producer.m_current_page.m_ptr_i = pos;
2977 producer.m_current_page.m_idx = range.m_idx;
2978 producer.m_current_pos.m_ptr_i = range.m_ptr_i + range.m_idx;
2981 if(producer.m_current_page.m_ptr_i == consumer.m_current_page.m_ptr_i &&
2982 producer.m_current_pos.m_ptr_i > consumer.m_current_pos.m_ptr_i)
2985 producer.m_current_pos.m_ptr_i - consumer.m_current_pos.m_ptr_i - 1;
2986 ndbrequire(free >= max * File_formats::UNDO_PAGE_WORDS);
2987 cnt= read_undo_pages(signal, ptr, producer.m_current_pos.m_ptr_i, max);
2988 ndbrequire(cnt <= max);
2989 producer.m_current_pos.m_ptr_i -= cnt;
2990 producer.m_current_page.m_idx -= cnt;
2994 Uint32 max= producer.m_current_page.m_idx;
2995 ndbrequire(free >= max * File_formats::UNDO_PAGE_WORDS);
2996 cnt= read_undo_pages(signal, ptr, producer.m_current_pos.m_ptr_i, max);
2997 ndbrequire(cnt <= max);
2998 producer.m_current_pos.m_ptr_i -= cnt;
2999 producer.m_current_page.m_idx -= cnt;
3002 ndbrequire(free >= cnt * File_formats::UNDO_PAGE_WORDS);
3003 free -= (cnt * File_formats::UNDO_PAGE_WORDS);
3004 ptr.p->m_free_buffer_words = free;
3005 ptr.p->m_pos[PRODUCER] = producer;
3007 signal->theData[0] = LgmanContinueB::READ_UNDO_LOG;
3008 signal->theData[1] = ptr.i;
3010 if(free > File_formats::UNDO_PAGE_WORDS)
3011 sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
3013 sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 100, 2);
3018 Uint32 pageId, Uint32 pages)
3022 Buffer_idx tail= ptr.p->m_file_pos[TAIL];
3023 m_file_pool.getPtr(filePtr, tail.m_ptr_i);
3025 if(filePtr.p->m_online.m_outstanding > 0)
3031 Uint32 max= tail.m_idx;
3034 req->filePointer = filePtr.p->m_fd;
3035 req->userReference = reference();
3036 req->userPointer = filePtr.i;
3037 req->operationFlag = 0;
3038 FsReadWriteReq::setFormatFlag(req->operationFlag,
3039 FsReadWriteReq::fsFormatSharedPage);
3045 tail.m_idx -= pages;
3047 req->varIndex = 1 + tail.m_idx;
3048 req->numberOfPages = pages;
3049 req->data.pageData[0] = pageId - pages;
3050 ptr.p->m_file_pos[TAIL] = tail;
3052 if(DEBUG_UNDO_EXECUTION)
3053 ndbout_c(
"a reading from file: %d page(%d-%d) into (%d-%d)",
3054 ptr.i, 1 + tail.m_idx, 1+tail.m_idx+pages-1,
3055 pageId - pages, pageId - 1);
3057 sendSignal(NDBFS_REF, GSN_FSREADREQ, signal,
3058 FsReadWriteReq::FixedLength + 1, JBA);
3060 ptr.p->m_outstanding_fs++;
3061 filePtr.p->m_state |= Undofile::FS_OUTSTANDING;
3062 filePtr.p->m_online.m_outstanding = pages;
3069 ndbrequire(tail.m_idx - max == 0);
3071 req->numberOfPages = max;
3072 req->data.pageData[0] = pageId - max;
3074 if(DEBUG_UNDO_EXECUTION)
3075 ndbout_c(
"b reading from file: %d page(%d-%d) into (%d-%d)",
3077 pageId - max, pageId - 1);
3079 sendSignal(NDBFS_REF, GSN_FSREADREQ, signal,
3080 FsReadWriteReq::FixedLength + 1, JBA);
3082 ptr.p->m_outstanding_fs++;
3083 filePtr.p->m_online.m_outstanding = max;
3084 filePtr.p->m_state |= Undofile::FS_OUTSTANDING | Undofile::FS_MOVE_NEXT;
3088 Local_undofile_list files(m_file_pool, ptr.p->m_files);
3089 if(!files.prev(prev))
3095 if(DEBUG_UNDO_EXECUTION)
3096 ndbout_c(
"changing file from %d to %d", filePtr.i, prev.i);
3098 tail.m_idx= prev.p->m_file_size - 1;
3099 tail.m_ptr_i= prev.i;
3100 ptr.p->m_file_pos[TAIL] = tail;
3101 if(max < pages && filePtr.i != prev.i)
3102 max += read_undo_pages(signal, ptr, pageId - max, pages - max);
3110 Lgman::execute_undo_record(
Signal* signal)
3114 if((ptr = get_next_undo_record(&lsn)))
3116 Uint32 len= (* ptr) & 0xFFFF;
3117 Uint32 type= (* ptr) >> 16;
3118 Uint32 mask= type & ~(Uint32)File_formats::Undofile::UNDO_NEXT_LSN;
3120 case File_formats::Undofile::UNDO_END:
3121 stop_run_undo_log(signal);
3123 case File_formats::Undofile::UNDO_LCP:
3124 case File_formats::Undofile::UNDO_LCP_FIRST:
3126 Uint32 lcp = * (ptr - len + 1);
3127 if(m_latest_lcp && lcp > m_latest_lcp)
3131 const Uint32 * base = ptr - len + 1;
3132 Uint32 lcp = base[0];
3133 Uint32 tableId = base[1] >> 16;
3134 Uint32 fragId = base[1] & 0xFFFF;
3136 ndbout_c(
"NOT! ignoring lcp: %u tab: %u frag: %u",
3137 lcp, tableId, fragId);
3141 if(m_latest_lcp == 0 ||
3142 lcp < m_latest_lcp ||
3143 (lcp == m_latest_lcp &&
3144 mask == File_formats::Undofile::UNDO_LCP_FIRST))
3146 stop_run_undo_log(signal);
3151 case File_formats::Undofile::UNDO_TUP_ALLOC:
3152 case File_formats::Undofile::UNDO_TUP_UPDATE:
3153 case File_formats::Undofile::UNDO_TUP_FREE:
3154 case File_formats::Undofile::UNDO_TUP_CREATE:
3155 case File_formats::Undofile::UNDO_TUP_DROP:
3156 case File_formats::Undofile::UNDO_TUP_ALLOC_EXTENT:
3157 case File_formats::Undofile::UNDO_TUP_FREE_EXTENT:
3160 tup.disk_restart_undo(signal, lsn, mask, ptr - len + 1, len);
3168 signal->theData[0] = LgmanContinueB::EXECUTE_UNDO_RECORD;
3169 sendSignal(LGMAN_REF, GSN_CONTINUEB, signal, 1, JBB);
3175 Lgman::get_next_undo_record(Uint64 * this_lsn)
3178 m_logfile_group_list.first(ptr);
3180 Logfile_group::Position consumer= ptr.p->m_pos[CONSUMER];
3181 Logfile_group::Position producer= ptr.p->m_pos[PRODUCER];
3182 if(producer.m_current_pos.m_idx < 2)
3191 Uint32 pos = consumer.m_current_pos.m_idx;
3192 Uint32 page = consumer.m_current_pos.m_ptr_i;
3195 m_shared_page_pool.getPtr(page);
3202 pageP->m_data[0] = (File_formats::Undofile::UNDO_END << 16) | 1 ;
3203 pageP->m_page_header.m_page_lsn_hi = 0;
3204 pageP->m_page_header.m_page_lsn_lo = 0;
3205 pos= consumer.m_current_pos.m_idx= pageP->m_words_used = 1;
3207 return pageP->m_data;
3210 Uint32 *
record= pageP->m_data + pos - 1;
3211 Uint32 len= (* record) & 0xFFFF;
3213 Uint32 *prev= record - len;
3217 if(((* record) >> 16) & File_formats::Undofile::UNDO_NEXT_LSN)
3219 lsn = ptr.p->m_last_read_lsn - 1;
3220 ndbrequire((Int64)lsn >= 0);
3224 ndbrequire(pos >= 3);
3225 lsn += * (prev - 1); lsn <<= 32;
3226 lsn += * (prev - 0);
3228 ndbrequire((Int64)lsn >= 0);
3232 ndbrequire(pos >= len);
3239 ndbrequire(producer.m_current_pos.m_idx);
3240 ptr.p->m_pos[PRODUCER].m_current_pos.m_idx --;
3242 if(consumer.m_current_page.m_idx)
3244 consumer.m_current_page.m_idx--;
3245 consumer.m_current_pos.m_ptr_i --;
3251 Page_map map(m_data_buffer_pool, ptr.p->m_buffer_pages);
3252 Uint32 sz = map.getSize();
3253 Uint32 tmp = (consumer.m_current_page.m_ptr_i + sz - 2) % sz;
3255 map.position(it, tmp);
3261 _tmp[0] = *it.data; map.next(it); _tmp[1] = *it.data;
3263 consumer.m_current_page.m_idx = range.m_idx - 1;
3264 consumer.m_current_page.m_ptr_i = tmp;
3266 consumer.m_current_pos.m_ptr_i = range.m_ptr_i + range.m_idx - 1;
3269 if(DEBUG_UNDO_EXECUTION)
3270 ndbout_c(
"reading from %d", consumer.m_current_pos.m_ptr_i);
3273 m_shared_page_pool.getPtr(consumer.m_current_pos.m_ptr_i);
3275 pos= consumer.m_current_pos.m_idx= pageP->m_words_used;
3278 tmp += pageP->m_page_header.m_page_lsn_hi; tmp <<= 32;
3279 tmp += pageP->m_page_header.m_page_lsn_lo;
3281 prev = pageP->m_data + pos - 1;
3283 if(((* prev) >> 16) & File_formats::Undofile::UNDO_NEXT_LSN)
3285 ndbrequire(lsn + 1 == ptr.p->m_last_read_lsn);
3288 ptr.p->m_pos[CONSUMER] = consumer;
3289 ptr.p->m_free_buffer_words += File_formats::UNDO_PAGE_WORDS;
3293 ptr.p->m_pos[CONSUMER].m_current_pos.m_idx -= len;
3296 * this_lsn = ptr.p->m_last_read_lsn =
lsn;
3302 if(m_logfile_group_list.next(sort))
3304 while(!sort.isNull() && sort.p->m_last_read_lsn >
lsn)
3305 m_logfile_group_list.next(sort);
3307 if(sort.i != ptr.p->nextList)
3309 m_logfile_group_list.remove(ptr);
3311 m_logfile_group_list.add(ptr);
3313 m_logfile_group_list.insert(ptr, sort);
3320 Lgman::stop_run_undo_log(
Signal* signal)
3322 bool running =
false, outstanding =
false;
3324 m_logfile_group_list.first(ptr);
3325 while(!ptr.isNull())
3330 ptr.p->m_state &= ~(Uint32)Logfile_group::LG_EXEC_THREAD;
3332 if(ptr.p->m_state & Logfile_group::LG_READ_THREAD)
3339 else if(ptr.p->m_outstanding_fs)
3343 else if(ptr.p->m_state != Logfile_group::LG_ONLINE)
3348 ndbrequire(ptr.p->m_state == 0);
3349 ptr.p->m_state = Logfile_group::LG_ONLINE;
3350 Buffer_idx tail= ptr.p->m_file_pos[TAIL];
3351 Uint32 pages= ptr.p->m_pos[PRODUCER].m_current_pos.m_idx;
3356 m_file_pool.getPtr(file, tail.m_ptr_i);
3357 Uint32 page= tail.m_idx;
3358 Uint32 size= file.p->m_file_size;
3359 ndbrequire(size >= page);
3360 Uint32 diff= size -
page;
3365 Local_undofile_list files(m_file_pool, ptr.p->m_files);
3366 if(!files.next(file))
3369 tail.m_ptr_i= file.i;
3373 tail.m_idx += pages;
3377 ptr.p->m_tail_pos[0] = tail;
3378 ptr.p->m_tail_pos[1] = tail;
3379 ptr.p->m_tail_pos[2] = tail;
3380 ptr.p->m_file_pos[TAIL] = tail;
3382 init_logbuffer_pointers(ptr);
3385 Buffer_idx head= ptr.p->m_file_pos[HEAD];
3387 m_file_pool.getPtr(file, head.m_ptr_i);
3388 if (head.m_idx == file.p->m_file_size - 1)
3390 Local_undofile_list files(m_file_pool, ptr.p->m_files);
3391 if(!files.next(file))
3397 head.m_ptr_i = file.i;
3398 ptr.p->m_file_pos[HEAD] = head;
3402 client_lock(number(), __LINE__);
3403 ptr.p->m_free_file_words = (Uint64)File_formats::UNDO_PAGE_WORDS *
3404 (Uint64)compute_free_file_pages(ptr);
3405 client_unlock(number(), __LINE__);
3406 ptr.p->m_next_reply_ptr_i = ptr.p->m_file_pos[HEAD].m_ptr_i;
3408 ptr.p->m_state |= Logfile_group::LG_FLUSH_THREAD;
3409 signal->theData[0] = LgmanContinueB::FLUSH_LOG;
3410 signal->theData[1] = ptr.i;
3411 signal->theData[2] = 0;
3412 sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
3418 m_file_pool.getPtr(tf, tail.m_ptr_i);
3419 m_file_pool.getPtr(hf, ptr.p->m_file_pos[HEAD].m_ptr_i);
3420 infoEvent(
"Logfile group: %d ", ptr.p->m_logfile_group_id);
3421 g_eventLogger->
info(
"Logfile group: %d ", ptr.p->m_logfile_group_id);
3422 infoEvent(
" head: %s page: %d",
3423 fs->get_filename(hf.p->m_fd),
3424 ptr.p->m_file_pos[HEAD].m_idx);
3425 g_eventLogger->
info(
" head: %s page: %d",
3426 fs->get_filename(hf.p->m_fd),
3427 ptr.p->m_file_pos[HEAD].m_idx);
3428 infoEvent(
" tail: %s page: %d",
3429 fs->get_filename(tf.p->m_fd), tail.m_idx);
3430 g_eventLogger->
info(
" tail: %s page: %d",
3431 fs->get_filename(tf.p->m_fd), tail.m_idx);
3435 m_logfile_group_list.next(ptr);
3447 signal->theData[0] = LgmanContinueB::STOP_UNDO_LOG;
3448 sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 100, 1);
3452 infoEvent(
"Flushing page cache after undo completion");
3453 g_eventLogger->
info(
"Flushing page cache after undo completion");
3459 ord->lcpId = m_latest_lcp;
3460 sendSignal(PGMAN_REF, GSN_LCP_FRAG_ORD, signal,
3461 LcpFragOrd::SignalLength, JBB);
3464 req->senderData = 0;
3465 req->senderRef = reference();
3466 req->backupId = m_latest_lcp;
3467 sendSignal(PGMAN_REF, GSN_END_LCP_REQ, signal,
3468 EndLcpReq::SignalLength, JBB);
3476 tup.disk_restart_undo(signal, 0, File_formats::Undofile::UNDO_END, 0, 0);
3486 undo[0] = m_latest_lcp;
3487 undo[1] = (0 << 16) | 0;
3488 undo[2] = (File_formats::Undofile::UNDO_LCP_FIRST << 16 )
3489 | (
sizeof(undo) >> 2);
3492 ndbrequire(m_logfile_group_list.first(ptr));
3494 Uint64 last_lsn= m_last_lsn;
3495 if(ptr.p->m_last_lsn == last_lsn
3497 && ((rand() % 100) > 50)
3501 undo[2] |= File_formats::Undofile::UNDO_NEXT_LSN << 16;
3502 Uint32 *dst= get_log_buffer(ptr,
sizeof(undo) >> 2);
3503 memcpy(dst, undo,
sizeof(undo));
3504 ndbrequire(ptr.p->m_free_file_words >= (
sizeof(undo) >> 2));
3505 ptr.p->m_free_file_words -= (
sizeof(undo) >> 2);
3509 Uint32 *dst= get_log_buffer(ptr, (
sizeof(undo) >> 2) + 2);
3510 * dst++ = (Uint32)(last_lsn >> 32);
3511 * dst++ = (Uint32)(last_lsn & 0xFFFFFFFF);
3512 memcpy(dst, undo,
sizeof(undo));
3513 ndbrequire(ptr.p->m_free_file_words >= ((
sizeof(undo) >> 2) + 2));
3514 ptr.p->m_free_file_words -= ((
sizeof(undo) >> 2) + 2);
3516 m_last_lsn = ptr.p->m_last_lsn = last_lsn + 1;
3518 ptr.p->m_last_synced_lsn = last_lsn;
3519 while(m_logfile_group_list.next(ptr))
3520 ptr.p->m_last_synced_lsn = last_lsn;
3522 infoEvent(
"Flushing complete");
3523 g_eventLogger->
info(
"Flushing complete");
3525 signal->theData[0] = reference();
3526 sendSignal(DBLQH_REF, GSN_START_RECCONF, signal, 1, JBB);
3535 if (ptr.p->m_file_pos[HEAD].m_ptr_i == RNIL)
3538 Uint32 pages = compute_free_file_pages(ptr);
3540 Uint32 group_pages =
3541 ((ptr.p->m_free_file_words + File_formats::UNDO_PAGE_WORDS - 1)/ File_formats::UNDO_PAGE_WORDS) ;
3542 Uint32 last = ptr.p->m_free_file_words % File_formats::UNDO_PAGE_WORDS;
3544 if(! (pages >= group_pages))
3546 ndbout << heading <<
" Tail: " << ptr.p->m_file_pos[TAIL]
3547 <<
" Head: " << ptr.p->m_file_pos[HEAD]
3548 <<
" free: " << group_pages <<
"(" << last <<
")"
3549 <<
" found: " << pages;
3550 for(Uint32 i = 0; i<3; i++)
3552 ndbout <<
" - " << ptr.p->m_tail_pos[
i];
3556 ndbrequire(pages >= group_pages);
3562 void Lgman::execGET_TABINFOREQ(
Signal* signal)
3566 if(!assembleFragments(signal))
3573 const Uint32 reqType = req->requestType & (~GetTabInfoReq::LongSignalConf);
3574 BlockReference retRef= req->senderRef;
3575 Uint32 senderData= req->senderData;
3576 Uint32 tableId= req->tableId;
3578 if(reqType == GetTabInfoReq::RequestByName)
3582 releaseSections(handle);
3584 sendGET_TABINFOREF(signal, req, GetTabInfoRef::NoFetchByName);
3589 key.m_logfile_group_id= tableId;
3591 m_logfile_group_hash.find(ptr, key);
3593 if(ptr.p->m_logfile_group_id != tableId)
3597 sendGET_TABINFOREF(signal, req, GetTabInfoRef::InvalidTableId);
3604 conf->senderData= senderData;
3605 conf->tableId= tableId;
3606 conf->freeWordsHi= (Uint32)(ptr.p->m_free_file_words >> 32);
3607 conf->freeWordsLo= (Uint32)(ptr.p->m_free_file_words & 0xFFFFFFFF);
3609 conf->senderRef= reference();
3610 sendSignal(retRef, GSN_GET_TABINFO_CONF, signal,
3611 GetTabInfoConf::SignalLength, JBB);
3616 GetTabInfoRef::ErrorCode errorCode)
3623 BlockReference retRef = req->senderRef;
3624 ref->errorCode = errorCode;
3626 sendSignal(retRef, GSN_GET_TABINFOREF, signal, signal->
length(), JBB);