20 #include "diskpage.hpp"
21 #include <signaldata/FsRef.hpp>
22 #include <signaldata/FsConf.hpp>
23 #include <signaldata/FsOpenReq.hpp>
24 #include <signaldata/FsCloseReq.hpp>
25 #include <signaldata/CreateFilegroupImpl.hpp>
26 #include <signaldata/DropFilegroupImpl.hpp>
27 #include <signaldata/FsReadWriteReq.hpp>
28 #include <signaldata/Extent.hpp>
29 #include <signaldata/DumpStateOrd.hpp>
30 #include <signaldata/TsmanContinueB.hpp>
31 #include <signaldata/GetTabInfo.hpp>
32 #include <signaldata/NodeFailRep.hpp>
33 #include <dbtup/Dbtup.hpp>
37 #define COMMITTED_MASK ((1 << 0) | (1 << 1))
38 #define UNCOMMITTED_MASK ((1 << 2) | (1 << 3))
39 #define UNCOMMITTED_SHIFT 2
45 m_file_hash(m_file_pool),
46 m_tablespace_list(m_tablespace_pool),
47 m_tablespace_hash(m_tablespace_pool),
51 m_client_mutex(
"tsman-client", 2, true)
53 BLOCK_CONSTRUCTOR(
Tsman);
55 Uint32 SZ = File_formats::Datafile::EXTENT_HEADER_BITMASK_BITS_PER_PAGE;
56 ndbrequire((COMMITTED_MASK & UNCOMMITTED_MASK) == 0);
57 ndbrequire((COMMITTED_MASK | UNCOMMITTED_MASK) == ((1 << SZ) - 1));
60 addRecSignal(GSN_STTOR, &Tsman::execSTTOR);
61 addRecSignal(GSN_READ_CONFIG_REQ, &Tsman::execREAD_CONFIG_REQ);
63 addRecSignal(GSN_CONTINUEB, &Tsman::execCONTINUEB);
64 addRecSignal(GSN_NODE_FAILREP, &Tsman::execNODE_FAILREP);
66 addRecSignal(GSN_CREATE_FILE_IMPL_REQ, &Tsman::execCREATE_FILE_IMPL_REQ);
67 addRecSignal(GSN_CREATE_FILEGROUP_IMPL_REQ, &Tsman::execCREATE_FILEGROUP_IMPL_REQ);
69 addRecSignal(GSN_DROP_FILE_IMPL_REQ, &Tsman::execDROP_FILE_IMPL_REQ);
70 addRecSignal(GSN_DROP_FILEGROUP_IMPL_REQ, &Tsman::execDROP_FILEGROUP_IMPL_REQ);
74 addRecSignal(GSN_FSOPENREF, &Tsman::execFSOPENREF,
true);
78 addRecSignal(GSN_FSCLOSECONF, &Tsman::execFSCLOSECONF);
84 addRecSignal(GSN_START_RECREQ, &Tsman::execSTART_RECREQ);
86 addRecSignal(GSN_LCP_FRAG_ORD, &Tsman::execLCP_FRAG_ORD);
89 addRecSignal(GSN_GET_TABINFOREQ, &Tsman::execGET_TABINFOREQ);
91 m_tablespace_hash.setSize(10);
92 m_file_hash.setSize(10);
93 m_lcp_ongoing =
false;
97 int ret = m_client_mutex.create();
105 (void)m_client_mutex.destroy();
110 Tsman::client_lock(BlockNumber
block,
int line)
114 Uint32 bno = blockToMain(block);
115 Uint32 ino = blockToInstance(block);
117 D(
"try lock " << bno <<
"/" << ino << V(line));
118 int ret = m_client_mutex.lock();
119 ndbrequire(ret == 0);
120 D(
"got lock " << bno <<
"/" << ino << V(line));
125 Tsman::client_unlock(BlockNumber block,
int line)
129 Uint32 bno = blockToMain(block);
130 Uint32 ino = blockToInstance(block);
132 D(
"unlock " << bno <<
"/" << ino << V(line));
133 int ret = m_client_mutex.unlock();
134 ndbrequire(ret == 0);
138 BLOCK_FUNCTIONS(
Tsman)
147 Uint32 ref = req->senderRef;
148 Uint32 senderData = req->senderData;
151 m_ctx.m_config.getOwnConfigIterator();
157 m_file_pool.init(RT_TSMAN_FILE, pc);
158 m_tablespace_pool.init(RT_TSMAN_FILEGROUP, pc);
161 conf->senderRef = reference();
162 conf->senderData = senderData;
163 sendSignal(ref, GSN_READ_CONFIG_CONF, signal,
164 ReadConfigConf::SignalLength, JBB);
168 Tsman::execSTTOR(
Signal* signal)
171 Uint32 startPhase = signal->theData[1];
172 switch (startPhase) {
174 m_pgman = globalData.getBlock(PGMAN);
175 m_lgman = (
Lgman*)globalData.getBlock(LGMAN);
176 m_tup = globalData.getBlock(DBTUP);
177 ndbrequire(m_pgman != 0 && m_lgman != 0 && m_tup != 0);
184 Tsman::sendSTTORRY(
Signal* signal){
185 signal->theData[0] = 0;
186 signal->theData[3] = 1;
187 signal->theData[4] = 3;
188 signal->theData[5] = 255;
189 sendSignal(NDBCNTR_REF, GSN_STTORRY, signal, 6, JBB);
193 Tsman::execCONTINUEB(
Signal* signal){
195 Uint32
type = signal->theData[0];
196 Uint32 ptrI = signal->theData[1];
197 client_lock(number(), __LINE__);
199 case TsmanContinueB::SCAN_TABLESPACE_EXTENT_HEADERS:
200 scan_tablespace(signal, ptrI);
202 case TsmanContinueB::SCAN_DATAFILE_EXTENT_HEADERS:
203 scan_datafile(signal, ptrI, signal->theData[2]);
205 case TsmanContinueB::END_LCP:
206 end_lcp(signal, ptrI, signal->theData[2], signal->theData[3]);
208 case TsmanContinueB::RELEASE_EXTENT_PAGES:
211 m_file_pool.getPtr(ptr, ptrI);
212 release_extent_pages(signal, ptr);
215 case TsmanContinueB::LOAD_EXTENT_PAGES:
218 m_file_pool.getPtr(ptr, ptrI);
219 load_extent_pages(signal, ptr);
226 client_unlock(number(), __LINE__);
230 Tsman::execNODE_FAILREP(
Signal* signal)
235 failed.
assign(NdbNodeBitmask::Size, rep->theNodes);
238 for(
unsigned i = 1;
i < MAX_NDB_NODES;
i++) {
243 ndbassert(elementsCleaned == 0);
244 (void) elementsCleaned;
267 if(signal->theData[0] == DumpStateOrd::DumpTsman + 0)
269 Uint32
id = signal->theData[1];
272 req->request.tablespace_id =
id;
273 req->request.table_id = 0;
274 req->request.fragment_id = 0;
275 execALLOC_EXTENT_REQ(signal);
277 if(req->reply.errorCode == 0){
279 ndbout_c(
"page: %d %d count: %d",
280 req->reply.page_id.m_file_no,
281 req->reply.page_id.m_page_no,
282 req->reply.page_count);
284 ndbout_c(
"Error: %d", req->reply.errorCode);
288 if(signal->theData[0] == DumpStateOrd::DumpTsman + 1)
290 Uint32
id = signal->theData[1];
291 Uint32
file= signal->theData[2];
292 Uint32
page= signal->theData[3];
293 Uint32 bits= signal->theData[4];
296 req->request.tablespace_id =
id;
297 req->request.table_id = 0;
298 req->request.fragment_id = 0;
299 req->key.m_page_no= page;
300 req->key.m_file_no= file;
302 execALLOC_PAGE_REQ(signal);
304 if(req->reply.errorCode == 0){
306 ndbout_c(
"page: %d %d bits: %d",
311 ndbout_c(
"Error: %d", req->reply.errorCode);
316 if(signal->theData[0] == DumpStateOrd::DumpTsman + 2)
318 Uint32
id = signal->theData[1];
320 for(
size_t i = 0;
i<1000;
i++)
327 Uint32 sz = chunks.size();
328 switch((rand() * sz) % 2){
333 req->request.tablespace_id =
id;
334 req->request.table_id = 0;
335 req->request.fragment_id = 0;
336 execALLOC_EXTENT_REQ(signal);
337 if(req->reply.errorCode == 0){
339 c.start_page = req->reply.page_id;
340 c.page_count = req->reply.page_count;
342 ndbout_c(
"execALLOC_EXTENT_REQ - OK - [ %d %d ] count: %d(%d)",
343 c.start_page.m_file_no,
344 c.start_page.m_page_no,
349 chunks.back().bitmask.fill(words, zero);
351 ndbout_c(
"execALLOC_EXTENT_REQ - OK - [ %d %d ] count: %d",
352 chunks.back().start_page.m_file_no,
353 chunks.back().start_page.m_page_no,
354 chunks.back().page_count);
356 ndbout_c(
"Error: %d", req->reply.errorCode);
362 Uint32 chunk = rand() % sz;
363 Uint32 count = chunks[chunk].page_count;
364 Uint32
page = rand() % count;
365 ndbout_c(
"case 1 - %d %d %d", chunk, count, page);
369 (chunks[chunk].bitmask.getBase());
370 Uint32 curr_bits = header->get_free_bits(page);
371 Uint32 new_bits = curr_bits ^ rand();
372 Local_key key = chunks[chunk].start_page;
373 key.m_page_no +=
page;
374 ndbrequire(update_page_free_bits(signal, &key, new_bits) == 0);
381 if(signal->theData[0] == DumpStateOrd::DumpTsman + 3)
384 req->requestType= GetTabInfoReq::RequestById;
385 req->tableId= signal->theData[1];
387 execGET_TABINFOREQ(signal);
394 Tsman::execCREATE_FILEGROUP_IMPL_REQ(
Signal* signal){
398 Uint32 senderRef = req->senderRef;
399 Uint32 senderData = req->senderData;
402 CreateFilegroupImplRef::ErrorCode err = CreateFilegroupImplRef::NoError;
404 if (m_tablespace_hash.find(ptr, req->filegroup_id))
407 err = CreateFilegroupImplRef::FilegroupAlreadyExists;
411 if (!m_tablespace_pool.seize(ptr))
414 err = CreateFilegroupImplRef::OutOfFilegroupRecords;
418 new (ptr.p) Tablespace(
this, req);
419 m_tablespace_hash.add(ptr);
420 m_tablespace_list.add(ptr);
422 ptr.p->m_state = Tablespace::TS_ONLINE;
426 conf->senderData = senderData;
427 conf->senderRef = reference();
428 sendSignal(senderRef, GSN_CREATE_FILEGROUP_IMPL_CONF, signal,
429 CreateFilegroupImplConf::SignalLength, JBB);
434 ref->senderData = senderData;
435 ref->senderRef = reference();
436 ref->errorCode = err;
437 sendSignal(senderRef, GSN_CREATE_FILEGROUP_IMPL_REF, signal,
438 CreateFilegroupImplRef::SignalLength, JBB);
444 out <<
"table: " << obj.m_table
445 <<
" fragment: " << obj.m_fragment_id <<
" ";
446 for(Uint32
i = 0;
i<32;
i++)
456 Tsman::execDROP_FILEGROUP_IMPL_REQ(
Signal* signal){
459 Uint32 errorCode = 0;
464 if (!m_tablespace_hash.find(ptr, req.filegroup_id))
466 errorCode = DropFilegroupImplRef::NoSuchFilegroup;
470 if (ptr.p->m_version != req.filegroup_version)
472 errorCode = DropFilegroupImplRef::InvalidFilegroupVersion;
476 if (! (ptr.p->m_meta_files.isEmpty() && ptr.p->m_free_files.isEmpty() &&
477 ptr.p->m_full_files.isEmpty()))
479 errorCode = DropFilegroupImplRef::FilegroupInUse;
483 switch(req.requestInfo){
484 case DropFilegroupImplReq::Prepare:
485 ptr.p->m_state = Tablespace::TS_DROPPING;
487 case DropFilegroupImplReq::Commit:
488 if (ptr.p->m_ref_count)
491 sendSignalWithDelay(reference(), GSN_DROP_FILEGROUP_REQ, signal,
492 100, signal->getLength());
495 m_tablespace_list.remove(ptr);
496 m_tablespace_hash.release(ptr);
498 case DropFilegroupImplReq::Abort:
499 ptr.p->m_state = Tablespace::TS_ONLINE;
510 ref->senderRef = reference();
511 ref->senderData = req.senderData;
512 ref->errorCode = errorCode;
513 sendSignal(req.senderRef, GSN_DROP_FILEGROUP_IMPL_REF, signal,
514 DropFilegroupImplRef::SignalLength, JBB);
520 conf->senderRef = reference();
521 conf->senderData = req.senderData;
522 sendSignal(req.senderRef, GSN_DROP_FILEGROUP_IMPL_CONF, signal,
523 DropFilegroupImplConf::SignalLength, JBB);
529 Datafile_list::Head& head,
532 Local_datafile_list list(m_file_pool, head);
533 for(list.first(ptr); !ptr.isNull(); list.next(ptr))
534 if(ptr.p->m_file_id ==
id)
540 Tsman::execCREATE_FILE_IMPL_REQ(
Signal* signal){
542 client_lock(number(), __LINE__);
545 Uint32 senderRef = req->senderRef;
546 Uint32 senderData = req->senderData;
549 CreateFileImplRef::ErrorCode err = CreateFileImplRef::NoError;
552 if (!m_tablespace_hash.find(ptr, req->filegroup_id))
555 err = CreateFileImplRef::InvalidFilegroup;
559 if (ptr.p->m_version != req->filegroup_version)
562 err = CreateFileImplRef::InvalidFilegroupVersion;
566 if (ptr.p->m_state != Tablespace::TS_ONLINE)
569 err = CreateFileImplRef::FilegroupNotOnline;
574 switch(req->requestInfo){
575 case CreateFileImplReq::Commit:
577 ndbrequire(find_file_by_id(file_ptr, ptr.p->m_meta_files, req->file_id));
578 file_ptr.p->m_create.m_senderRef = req->senderRef;
579 file_ptr.p->m_create.m_senderData = req->senderData;
580 file_ptr.p->m_create.m_requestInfo = req->requestInfo;
583 pgman.map_file_no(signal, file_ptr.p->m_file_no, file_ptr.p->m_fd);
584 file_ptr.p->m_create.m_loading_extent_page = 1;
585 load_extent_pages(signal, file_ptr);
586 client_unlock(number(), __LINE__);
589 case CreateFileImplReq::Abort:
591 Uint32 senderRef = req->senderRef;
592 Uint32 senderData = req->senderData;
593 if(find_file_by_id(file_ptr, ptr.p->m_meta_files, req->file_id))
595 file_ptr.p->m_create.m_senderRef = senderRef;
596 file_ptr.p->m_create.m_senderData = senderData;
597 file_ptr.p->m_create.m_requestInfo = req->requestInfo;
598 create_file_abort(signal, file_ptr);
599 client_unlock(number(), __LINE__);
605 conf->senderData = senderData;
606 conf->senderRef = reference();
607 sendSignal(senderRef, GSN_CREATE_FILE_IMPL_CONF, signal,
608 CreateFileImplConf::SignalLength, JBB);
609 client_unlock(number(), __LINE__);
618 if (!handle.m_cnt == 1)
623 if (!m_file_pool.seize(file_ptr))
626 err = CreateFileImplRef::OutOfFileRecords;
630 if(ERROR_INSERTED(16000) ||
631 (
sizeof(
void*) == 4 && req->file_size_hi & 0xFFFFFFFF))
634 releaseSections(handle);
637 ref->senderData = senderData;
638 ref->senderRef = reference();
639 ref->errorCode = CreateFileImplRef::FileSizeTooLarge;
640 sendSignal(senderRef, GSN_CREATE_FILE_IMPL_REF, signal,
641 CreateFileImplRef::SignalLength, JBB);
642 client_unlock(number(), __LINE__);
646 new (file_ptr.p) Datafile(req);
647 Local_datafile_list tmp(m_file_pool, ptr.p->m_meta_files);
650 file_ptr.p->m_state = Datafile::FS_CREATING;
651 file_ptr.p->m_tablespace_ptr_i = ptr.i;
652 file_ptr.p->m_extent_size = ptr.p->m_extent_size;
654 err = (CreateFileImplRef::ErrorCode)open_file(signal, ptr, file_ptr, req,
658 client_unlock(number(), __LINE__);
662 releaseSections(handle);
664 ref->senderData = senderData;
665 ref->senderRef = reference();
666 ref->errorCode = err;
667 sendSignal(senderRef, GSN_CREATE_FILE_IMPL_REF, signal,
668 CreateFileImplRef::SignalLength, JBB);
669 client_unlock(number(), __LINE__);
672 static inline Uint64 DIV(Uint64 a, Uint64 b){
return (a + b - 1) / b;}
677 Uint32
page = ptr.p->m_create.m_extent_pages;
681 preq.m_page.m_file_no = ptr.p->m_file_no;
682 preq.m_page.m_page_no =
page;
684 preq.m_callback.m_callbackData = ptr.i;
685 preq.m_callback.m_callbackFunction =
686 safe_cast(&Tsman::release_extent_pages_callback);
689 int flags = Page_cache_client::UNLOCK_PAGE;
691 if((page_id = pgman.get_page(signal, preq, flags)) > 0)
693 execute(signal, preq.m_callback, page_id);
698 create_file_abort(signal, ptr);
702 Tsman::release_extent_pages_callback(
Signal* signal,
707 m_file_pool.getPtr(ptr, ptrI);
709 key.m_file_no = ptr.p->m_file_no;
710 key.m_page_no = ptr.p->m_create.m_extent_pages;
712 ndbrequire(pgman.drop_page(key, page_id));
713 ptr.p->m_create.m_extent_pages--;
715 signal->theData[0] = TsmanContinueB::RELEASE_EXTENT_PAGES;
716 signal->theData[1] = ptr.i;
718 sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
724 if (ptr.p->m_fd == RNIL)
726 ((
FsConf*)signal->getDataPtr())->userPointer = ptr.i;
727 execFSCLOSECONF(signal);
732 req->filePointer = ptr.p->m_fd;
733 req->userReference = reference();
734 req->userPointer = ptr.i;
736 FsCloseReq::setRemoveFileFlag(req->fileFlag,
true);
738 sendSignal(NDBFS_REF, GSN_FSCLOSEREQ, signal,
739 FsCloseReq::SignalLength, JBB);
743 Tsman::execFSCLOSECONF(
Signal* signal)
747 Uint32 ptrI = ((
FsConf*)signal->getDataPtr())->userPointer;
748 m_file_pool.getPtr(ptr, ptrI);
750 Uint32 senderRef = ptr.p->m_create.m_senderRef;
751 Uint32 senderData = ptr.p->m_create.m_senderData;
753 if (ptr.p->m_state == Datafile::FS_CREATING)
755 if (ptr.p->m_file_no != RNIL)
759 pgman.free_data_file(signal, ptr.p->m_file_no);
763 conf->senderData = senderData;
764 conf->senderRef = reference();
765 sendSignal(senderRef, GSN_CREATE_FILE_IMPL_CONF, signal,
766 CreateFileImplConf::SignalLength, JBB);
768 else if(ptr.p->m_state == Datafile::FS_DROPPING)
770 m_file_hash.remove(ptr);
772 pgman.free_data_file(signal, ptr.p->m_file_no, ptr.p->m_fd);
774 conf->senderData = senderData;
775 conf->senderRef = reference();
776 sendSignal(senderRef, GSN_DROP_FILE_IMPL_CONF, signal,
777 DropFileImplConf::SignalLength, JBB);
786 m_tablespace_pool.getPtr(lg_ptr, ptr.p->m_tablespace_ptr_i);
787 Local_datafile_list list(m_file_pool, lg_ptr.p->m_meta_files);
793 Tsman::open_file(
Signal* signal,
799 Uint32 requestInfo = org->requestInfo;
800 Uint32 hi = org->file_size_hi;
801 Uint32 lo = org->file_size_lo;
803 if(requestInfo == CreateFileImplReq::Create ||
804 requestInfo == CreateFileImplReq::CreateForce){
807 Uint32 file_no = pgman.create_data_file(signal);
810 return CreateFileImplRef::OutOfFileRecords;
812 ptr.p->m_file_no = file_no;
816 req->userReference = reference();
817 req->userPointer = ptr.i;
819 memset(req->fileNumber, 0,
sizeof(req->fileNumber));
820 FsOpenReq::setVersion(req->fileNumber, 4);
821 FsOpenReq::v4_setBasePath(req->fileNumber, FsOpenReq::BP_DD_DF);
824 req->fileFlags |= FsOpenReq::OM_READWRITE;
825 req->fileFlags |= FsOpenReq::OM_DIRECT;
826 req->fileFlags |= FsOpenReq::OM_THREAD_POOL;
828 case CreateFileImplReq::Create:
829 req->fileFlags |= FsOpenReq::OM_CREATE_IF_NONE;
830 req->fileFlags |= FsOpenReq::OM_INIT;
832 case CreateFileImplReq::CreateForce:
833 req->fileFlags |= FsOpenReq::OM_CREATE;
834 req->fileFlags |= FsOpenReq::OM_INIT;
836 case CreateFileImplReq::Open:
837 req->fileFlags |= FsOpenReq::OM_CHECK_SIZE;
843 req->page_size = File_formats::NDB_PAGE_SIZE;
844 req->file_size_hi = hi;
845 req->file_size_lo = lo;
847 Uint64 pages = (Uint64(hi) << 32 | lo) / File_formats::NDB_PAGE_SIZE;
848 Uint32 extent_size = ts_ptr.p->m_extent_size;
849 Uint64 extents = (pages + extent_size - 1) / extent_size;
850 extents = extents ? extents : 1;
851 Uint64 data_pages = extents * extent_size;
854 ndbrequire(eh_words < File_formats::Datafile::EXTENT_PAGE_WORDS);
855 Uint32 extents_per_page = File_formats::Datafile::EXTENT_PAGE_WORDS/eh_words;
856 Uint64 extent_pages = (extents + extents_per_page - 1) / extents_per_page;
859 ptr.p->m_create.m_extent_pages = Uint32(extent_pages);
860 ptr.p->m_create.m_data_pages = Uint32(data_pages);
865 pages = 1 + extent_pages + data_pages;
866 Uint64 bytes = pages * File_formats::NDB_PAGE_SIZE;
867 hi = (Uint32)(bytes >> 32);
868 lo = (Uint32)(bytes & 0xFFFFFFFF);
869 req->file_size_hi = hi;
870 req->file_size_lo = lo;
871 #if defined VM_TRACE || defined ERROR_INSERT
872 ndbout <<
"DD tsman: file id:" << ptr.p->m_file_id <<
" datafile pages/bytes:" << data_pages <<
"/" << data_pages*File_formats::NDB_PAGE_SIZE <<
" extent pages:" << extent_pages << endl;
875 sendSignal(NDBFS_REF, GSN_FSOPENREQ, signal, FsOpenReq::SignalLength, JBB,
892 m_file_pool.getPtr(ptr, req->userPointer);
893 m_shared_page_pool.getPtr(page_ptr, req->data.pageData[0]);
894 memset(page_ptr.p, 0, File_formats::NDB_PAGE_SIZE);
896 Uint32 page_no = req->varIndex;
897 Uint32
size = ptr.p->m_extent_size;
898 Uint32 extent_pages = ptr.p->m_create.m_extent_pages;
899 Uint32 datapages = ptr.p->m_create.m_data_pages;
902 Uint32 per_page = File_formats::Datafile::EXTENT_PAGE_WORDS / header_words;
903 Uint32 extents = datapages/
size;
909 m_tablespace_hash.getPtr(lg_ptr, ptr.p->m_tablespace_ptr_i);
913 page->m_page_header.init(File_formats::FT_Datafile,
917 page->m_file_no = ptr.p->m_file_no;
918 page->m_file_id = ptr.p->m_file_id;
919 page->m_tablespace_id = lg_ptr.p->m_tablespace_id;
920 page->m_tablespace_version = lg_ptr.p->m_version;
921 page->m_data_pages = extents *
size;
922 page->m_extent_pages = extent_pages;
923 page->m_extent_size =
size;
924 page->m_extent_count = extents;
925 page->m_extent_headers_per_page = per_page;
926 page->m_extent_header_words = header_words;
927 page->m_extent_header_bits_per_page =
928 File_formats::Datafile::EXTENT_HEADER_BITMASK_BITS_PER_PAGE;
930 else if ((page_no-1) < extent_pages)
934 Uint32 curr_extent = page_no*per_page;
938 page->m_page_header.m_page_lsn_hi = 0;
939 page->m_page_header.m_page_lsn_lo = 0;
940 page->m_page_header.m_page_type = File_formats::PT_Unallocated;
942 for(Uint32
i = 0;
i<per_page;
i++)
945 memset(head, 0, 4*header_words);
946 head->m_table = RNIL;
947 head->m_next_free_extent = ++curr_extent;
949 if (page_no == extent_pages)
951 Uint32 last = extents - ((extent_pages - 1) * per_page);
952 page->get_header(last - 1, size)->m_next_free_extent = RNIL;
960 page->m_page_header.m_page_lsn_hi = 0;
961 page->m_page_header.m_page_lsn_lo = 0;
966 Tsman::create_file_ref(
Signal* signal,
969 Uint32 error, Uint32 fsError, Uint32 osError)
972 ref->senderData = ptr.p->m_create.m_senderData;
973 ref->senderRef = reference();
974 ref->errorCode = (CreateFileImplRef::ErrorCode)error;
975 ref->fsErrCode = fsError;
976 ref->osErrCode = osError;
977 sendSignal(ptr.p->m_create.m_senderRef, GSN_CREATE_FILE_IMPL_REF, signal,
978 CreateFileImplRef::SignalLength, JBB);
980 Local_datafile_list meta(m_file_pool, lg_ptr.p->m_meta_files);
985 Tsman::execFSOPENREF(
Signal* signal)
993 Uint32 errCode = ref->errorCode;
994 Uint32 osErrCode = ref->osErrorCode;
997 m_tablespace_hash.getPtr(lg_ptr, ptr.p->m_tablespace_ptr_i);
999 create_file_ref(signal, lg_ptr, ptr,
1000 CreateFileImplRef::FileError, errCode, osErrCode);
1011 m_file_pool.getPtr(ptr, conf->userPointer);
1012 m_tablespace_hash.getPtr(lg_ptr, ptr.p->m_tablespace_ptr_i);
1014 Uint32 fd = ptr.p->m_fd = conf->filePointer;
1016 switch(ptr.p->m_create.m_requestInfo){
1017 case CreateFileImplReq::Create:
1018 case CreateFileImplReq::CreateForce:
1023 conf->senderData = ptr.p->m_create.m_senderData;
1024 conf->senderRef = reference();
1025 sendSignal(ptr.p->m_create.m_senderRef, GSN_CREATE_FILE_IMPL_CONF, signal,
1026 CreateFileImplConf::SignalLength, JBB);
1029 case CreateFileImplReq::Open:
1037 if(m_global_page_pool.seize(page_ptr) ==
false)
1040 create_file_ref(signal, lg_ptr, ptr,
1041 CreateFileImplRef::OutOfMemory, 0, 0);
1045 ptr.p->m_create.m_page_ptr_i = page_ptr.i;
1048 req->filePointer = fd;
1049 req->userReference = reference();
1050 req->userPointer = ptr.i;
1052 req->numberOfPages = 1;
1053 req->operationFlag = 0;
1054 FsReadWriteReq::setFormatFlag(req->operationFlag,
1055 FsReadWriteReq::fsFormatGlobalPage);
1056 req->data.pageData[0] = page_ptr.i;
1057 sendSignal(NDBFS_REF, GSN_FSREADREQ, signal,
1058 FsReadWriteReq::FixedLength + 1, JBB);
1075 m_file_pool.getPtr(ptr, conf->userPointer);
1076 m_tablespace_hash.getPtr(lg_ptr, ptr.p->m_tablespace_ptr_i);
1079 m_global_page_pool.getPtr(page_ptr, ptr.p->m_create.m_page_ptr_i);
1084 CreateFileImplRef::ErrorCode err = CreateFileImplRef::NoError;
1089 err = CreateFileImplRef::InvalidFileMetadata;
1090 fsError = page->m_page_header.validate(File_formats::FT_Datafile,
1098 if(page->m_file_id != ptr.p->m_file_id)
1102 if(page->m_tablespace_id != lg_ptr.p->m_tablespace_id)
1106 if(page->m_tablespace_version != lg_ptr.p->m_version)
1110 if(page->m_data_pages != ptr.p->m_create.m_data_pages)
1114 if(page->m_extent_pages != ptr.p->m_create.m_extent_pages)
1118 if(page->m_extent_size != ptr.p->m_extent_size)
1122 if(page->m_extent_header_bits_per_page !=
1123 File_formats::Datafile::EXTENT_HEADER_BITMASK_BITS_PER_PAGE)
1129 if(page->m_extent_header_words != eh_words)
1133 Uint32 per_page = File_formats::Datafile::EXTENT_PAGE_WORDS/eh_words;
1134 if(page->m_extent_headers_per_page != per_page)
1138 Uint32 extents = page->m_data_pages / ptr.p->m_extent_size;
1139 if(page->m_extent_count != extents)
1143 ptr.p->m_file_no = page->m_file_no;
1154 m_global_page_pool.release(page_ptr);
1157 conf->senderData = ptr.p->m_create.m_senderData;
1158 conf->senderRef = reference();
1159 sendSignal(ptr.p->m_create.m_senderRef, GSN_CREATE_FILE_IMPL_CONF, signal,
1160 CreateFileImplConf::SignalLength, JBB);
1164 m_global_page_pool.release(page_ptr);
1165 create_file_ref(signal, lg_ptr, ptr, err, fsError, osError);
1169 Tsman::execFSREADREF(
Signal* signal)
1177 m_tablespace_hash.find(lg_ptr, ptr.p->m_tablespace_ptr_i);
1179 m_global_page_pool.release(ptr.p->m_create.m_page_ptr_i);
1180 create_file_ref(signal, lg_ptr, ptr, CreateFileImplRef::FileReadError,
1181 ref->errorCode, ref->osErrorCode);
1191 preq.m_page.m_file_no = ptr.p->m_file_no;
1192 preq.m_page.m_page_no = ptr.p->m_create.m_loading_extent_page;
1194 preq.m_callback.m_callbackData = ptr.i;
1195 preq.m_callback.m_callbackFunction =
1196 safe_cast(&Tsman::load_extent_page_callback);
1199 int flags = Page_cache_client::LOCK_PAGE;
1201 if((page_id = pgman.get_page(signal, preq, flags)) > 0)
1203 load_extent_page_callback(signal, ptr.i, (Uint32)page_id);
1213 Tsman::load_extent_page_callback(
Signal* signal,
1215 Uint32 real_page_ptr_i)
1219 m_file_pool.getPtr(ptr, callback);
1221 if(++ptr.p->m_create.m_loading_extent_page <= ptr.p->m_create.m_extent_pages)
1223 signal->theData[0] = TsmanContinueB::LOAD_EXTENT_PAGES;
1224 signal->theData[1] = ptr.i;
1225 sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
1229 Uint32 senderRef = ptr.p->m_create.m_senderRef;
1230 Uint32 senderData = ptr.p->m_create.m_senderData;
1231 Uint32 extent_pages = ptr.p->m_create.m_extent_pages;
1232 Uint32 data_pages = ptr.p->m_create.m_data_pages;
1233 ndbassert(ptr.p->m_create.m_requestInfo == CreateFileImplReq::Commit);
1236 Uint32 per_page = File_formats::Datafile::EXTENT_PAGE_WORDS/eh;
1238 ptr.p->m_state = Datafile::FS_ONLINE;
1239 ptr.p->m_online.m_offset_data_pages = 1 + extent_pages;
1240 ptr.p->m_online.m_first_free_extent = per_page;
1241 ptr.p->m_online.m_lcp_free_extent_head = RNIL;
1242 ptr.p->m_online.m_lcp_free_extent_tail = RNIL;
1243 ptr.p->m_online.m_data_pages = data_pages;
1244 ptr.p->m_online.m_used_extent_cnt = 0;
1245 ptr.p->m_online.m_extent_headers_per_extent_page = per_page;
1248 m_tablespace_pool.getPtr(ts_ptr, ptr.p->m_tablespace_ptr_i);
1251 getNodeState().starting.restartType == NodeState::ST_INITIAL_START) ||
1253 getNodeState().starting.restartType == NodeState::ST_INITIAL_NODE_RESTART))
1255 Local_datafile_list free(m_file_pool, ts_ptr.p->m_free_files);
1256 Local_datafile_list meta(m_file_pool, ts_ptr.p->m_meta_files);
1260 m_file_hash.add(ptr);
1263 conf->senderData = senderData;
1264 conf->senderRef = reference();
1265 sendSignal(senderRef, GSN_CREATE_FILE_IMPL_CONF, signal,
1266 CreateFileImplConf::SignalLength, JBB);
1270 Tsman::execSTART_RECREQ(
Signal* signal)
1273 m_tablespace_list.first(lg_ptr);
1275 signal->theData[0] = TsmanContinueB::SCAN_TABLESPACE_EXTENT_HEADERS;
1276 signal->theData[1] = lg_ptr.i;
1277 sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
1281 Tsman::scan_tablespace(
Signal* signal, Uint32 ptrI)
1286 signal->theData[0] = reference();
1287 sendSignal(DBLQH_REF, GSN_START_RECCONF, signal, 1, JBB);
1291 m_tablespace_pool.getPtr(lg_ptr, ptrI);
1295 Local_datafile_list meta(m_file_pool, lg_ptr.p->m_meta_files);
1296 meta.first(file_ptr);
1299 scan_datafile(signal, lg_ptr.i, file_ptr.i);
1303 Tsman::scan_datafile(
Signal* signal, Uint32 ptrI, Uint32 filePtrI)
1307 m_tablespace_pool.getPtr(lg_ptr, ptrI);
1308 if(filePtrI == RNIL)
1310 m_tablespace_list.next(lg_ptr);
1311 signal->theData[0] = TsmanContinueB::SCAN_TABLESPACE_EXTENT_HEADERS;
1312 signal->theData[1] = lg_ptr.i;
1313 sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
1317 m_file_pool.getPtr(file_ptr, filePtrI);
1318 scan_extent_headers(signal, file_ptr);
1326 m_tablespace_pool.getPtr(lg_ptr, ptr.p->m_tablespace_ptr_i);
1328 Uint32 firstFree= RNIL;
1329 Uint32
size = ptr.p->m_extent_size;
1330 Uint32 per_page = ptr.p->m_online.m_extent_headers_per_extent_page;
1331 Uint32 pages= ptr.p->m_online.m_offset_data_pages - 1;
1332 Uint32 datapages= ptr.p->m_online.m_data_pages;
1333 for(Uint32
i = 0;
i < pages;
i++)
1335 Uint32 page_no = pages -
i;
1337 preq.m_page.m_page_no = page_no;
1338 preq.m_page.m_file_no = ptr.p->m_file_no;
1340 int flags = Page_cache_client::DIRTY_REQ;
1342 int real_page_id = pgman.get_page(signal, preq, flags);
1343 ndbrequire(real_page_id > 0);
1344 D(
"scan_extent_headers" << V(pages) << V(page_no) << V(real_page_id));
1349 Uint32 extents= per_page;
1350 if(page_no == pages)
1356 Uint32 total_extents = datapages /
size;
1357 extents= total_extents - (pages - 1)*per_page;
1359 for(Uint32 j = 0; j<extents; j++)
1361 Uint32 extent_no = extents - j - 1;
1363 page->get_header(extent_no, size);
1364 if (header->m_table == RNIL)
1366 D(
"extent free" << V(j));
1367 header->m_next_free_extent = firstFree;
1368 firstFree = page_no * per_page + extent_no;
1372 Uint32 tableId= header->m_table;
1373 Uint32 fragmentId= header->m_fragment_id;
1376 key.m_file_no = ptr.p->m_file_no;
1378 pages + 1 + size * (page_no * per_page + extent_no - per_page);
1379 key.m_page_idx = page_no * per_page + extent_no;
1380 if(!tup.disk_restart_alloc_extent(tableId, fragmentId, &key, size))
1382 ptr.p->m_online.m_used_extent_cnt++;
1383 for(Uint32 i = 0; i<
size; i++, key.m_page_no++)
1385 Uint32 bits= header->get_free_bits(i) & COMMITTED_MASK;
1386 header->update_free_bits(i, bits | (bits << UNCOMMITTED_SHIFT));
1387 tup.disk_restart_page_bits(tableId, fragmentId, &key, bits);
1389 D(
"extent used" << V(j) << V(tableId) << V(fragmentId) << V(key));
1393 header->m_table = RNIL;
1394 header->m_next_free_extent = firstFree;
1395 firstFree = page_no * per_page + extent_no;
1396 D(
"extent free" << V(j) << V(tableId) << V(fragmentId) << V(key));
1401 ptr.p->m_online.m_first_free_extent= firstFree;
1403 Local_datafile_list meta(m_file_pool, lg_ptr.p->m_meta_files);
1406 if(firstFree != RNIL)
1408 Local_datafile_list free(m_file_pool, lg_ptr.p->m_free_files);
1414 Local_datafile_list full(m_file_pool, lg_ptr.p->m_full_files);
1419 signal->theData[0] = TsmanContinueB::SCAN_DATAFILE_EXTENT_HEADERS;
1420 signal->theData[1] = lg_ptr.i;
1421 signal->theData[2] = next.i;
1422 sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
1426 Tsman::execDROP_FILE_IMPL_REQ(
Signal* signal)
1429 client_lock(number(), __LINE__);
1434 Uint32 errorCode = 0;
1437 if (!m_tablespace_hash.find(fg_ptr, req.filegroup_id))
1439 errorCode = DropFileImplRef::InvalidFilegroup;
1443 if (fg_ptr.p->m_version != req.filegroup_version)
1445 errorCode = DropFileImplRef::InvalidFilegroupVersion;
1449 switch(req.requestInfo){
1450 case DropFileImplReq::Prepare:{
1451 if (find_file_by_id(file_ptr, fg_ptr.p->m_full_files, req.file_id))
1454 Local_datafile_list full(m_file_pool, fg_ptr.p->m_full_files);
1455 full.remove(file_ptr);
1457 else if(find_file_by_id(file_ptr, fg_ptr.p->m_free_files, req.file_id))
1460 Local_datafile_list free(m_file_pool, fg_ptr.p->m_free_files);
1461 free.remove(file_ptr);
1463 else if(find_file_by_id(file_ptr, fg_ptr.p->m_meta_files, req.file_id))
1466 Local_datafile_list meta(m_file_pool, fg_ptr.p->m_meta_files);
1467 meta.remove(file_ptr);
1471 errorCode = DropFileImplRef::NoSuchFile;
1475 Local_datafile_list meta(m_file_pool, fg_ptr.p->m_meta_files);
1478 if (file_ptr.p->m_online.m_used_extent_cnt ||
1479 file_ptr.p->m_state != Datafile::FS_ONLINE)
1481 errorCode = DropFileImplRef::FileInUse;
1485 file_ptr.p->m_state = Datafile::FS_DROPPING;
1488 case DropFileImplReq::Commit:
1489 ndbrequire(find_file_by_id(file_ptr, fg_ptr.p->m_meta_files, req.file_id));
1490 if (file_ptr.p->m_ref_count)
1493 sendSignalWithDelay(reference(), GSN_DROP_FILE_REQ, signal,
1494 100, signal->getLength());
1498 file_ptr.p->m_create.m_extent_pages =
1499 file_ptr.p->m_online.m_offset_data_pages - 1;
1500 file_ptr.p->m_create.m_senderRef = req.senderRef;
1501 file_ptr.p->m_create.m_senderData = req.senderData;
1502 release_extent_pages(signal, file_ptr);
1503 client_unlock(number(), __LINE__);
1505 case DropFileImplReq::Abort:{
1506 ndbrequire(find_file_by_id(file_ptr, fg_ptr.p->m_meta_files, req.file_id));
1507 file_ptr.p->m_state = Datafile::FS_ONLINE;
1508 Local_datafile_list meta(m_file_pool, fg_ptr.p->m_meta_files);
1509 meta.remove(file_ptr);
1510 if (file_ptr.p->m_online.m_first_free_extent != RNIL)
1512 Local_datafile_list free(m_file_pool, fg_ptr.p->m_free_files);
1517 Local_datafile_list full(m_file_pool, fg_ptr.p->m_full_files);
1528 ref->senderRef = reference();
1529 ref->senderData = req.senderData;
1530 ref->errorCode = errorCode;
1531 sendSignal(req.senderRef, GSN_DROP_FILE_IMPL_REF, signal,
1532 DropFileImplRef::SignalLength, JBB);
1537 conf->senderRef = reference();
1538 conf->senderData = req.senderData;
1539 sendSignal(req.senderRef, GSN_DROP_FILE_IMPL_CONF, signal,
1540 DropFileImplConf::SignalLength, JBB);
1542 client_unlock(number(), __LINE__);
1548 m_logfile_group_id = req->tablespace.logfile_group_id;
1549 m_tablespace_id = req->filegroup_id;
1550 m_version = req->filegroup_version;
1553 m_extent_size = (Uint32)DIV(req->tablespace.extent_size, File_formats::NDB_PAGE_SIZE);
1554 #if defined VM_TRACE || defined ERROR_INSERT
1555 ndbout <<
"DD tsman: ts id:" << m_tablespace_id <<
" extent pages/bytes:" << m_extent_size <<
"/" << m_extent_size*File_formats::NDB_PAGE_SIZE << endl;
1561 m_file_id = req->file_id;
1565 m_online.m_first_free_extent = RNIL;
1568 m_create.m_senderRef = req->senderRef;
1569 m_create.m_senderData = req->senderData;
1570 m_create.m_requestInfo = req->requestInfo;
1580 AllocExtentReq::ErrorCode err;
1582 ndbrequire(m_tablespace_hash.find(ts_ptr, req.request.tablespace_id));
1585 if (tmp.first(file_ptr))
1587 Uint32 size = file_ptr.p->m_extent_size;
1588 Uint32 extent = file_ptr.p->m_online.m_first_free_extent;
1589 Uint32 data_off = file_ptr.p->m_online.m_offset_data_pages;
1591 Uint32 per_page = File_formats::Datafile::EXTENT_PAGE_WORDS/eh_words;
1592 Uint32 page_no = extent / per_page;
1593 Uint32 extent_no = extent % per_page;
1596 preq.m_page.m_page_no = page_no;
1597 preq.m_page.m_file_no = file_ptr.p->m_file_no;
1602 int flags = Page_cache_client::DIRTY_REQ;
1605 if ((real_page_id = pgman.
get_page(signal, preq, flags)) > 0)
1612 page->get_header(extent_no, size);
1614 ndbrequire(header->m_table == RNIL);
1615 Uint32 next_free = header->m_next_free_extent;
1620 memset(header, 0, 4*eh_words);
1621 header->m_table = req.request.table_id;
1622 header->m_fragment_id = req.request.fragment_id;
1627 file_ptr.p->m_online.m_used_extent_cnt++;
1628 file_ptr.p->m_online.m_first_free_extent = next_free;
1629 if (next_free == RNIL)
1633 tmp.remove(file_ptr);
1640 ndbassert(extent >= per_page);
1641 preq.m_page.m_page_no = data_off + size * (extent - per_page);
1642 preq.m_page.m_page_idx = extent;
1645 rep->reply.errorCode = 0;
1646 rep->reply.page_id = preq.m_page;
1647 rep->reply.page_count =
size;
1653 err = AllocExtentReq::UnmappedExtentPageIsNotImplemented;
1659 err = AllocExtentReq::NoExtentAvailable;
1661 if (tmp.isEmpty() && full_tmp.isEmpty())
1664 err = AllocExtentReq::NoDatafile;
1672 rep->reply.errorCode = err;
1682 FreeExtentReq::ErrorCode err = (FreeExtentReq::ErrorCode)0;
1685 file_key.m_file_no = req.request.key.m_file_no;
1686 ndbrequire(m_file_hash.find(file_ptr, file_key));
1688 struct req val = lookup_extent(req.request.key.m_page_no, file_ptr.p);
1690 (req.request.key.m_page_no - val.m_extent_pages) / val.m_extent_size +
1691 file_ptr.p->m_online.m_extent_headers_per_extent_page;
1694 preq.m_page.m_page_no = val.m_extent_page_no;
1695 preq.m_page.m_file_no = req.request.key.m_file_no;
1697 ndbout <<
"Free extent: " << req.request.key << endl;
1702 int flags = Page_cache_client::DIRTY_REQ;
1705 if ((real_page_id = pgman.get_page(signal, preq, flags)) > 0)
1712 page->get_header(val.m_extent_no, val.m_extent_size);
1714 ndbrequire(header->m_table == req.request.table_id);
1715 header->m_table = RNIL;
1717 file_ptr.p->m_online.m_used_extent_cnt--;
1721 header->m_next_free_extent= file_ptr.p->m_online.m_lcp_free_extent_head;
1722 if(file_ptr.p->m_online.m_lcp_free_extent_head == RNIL)
1723 file_ptr.p->m_online.m_lcp_free_extent_tail= extent;
1724 file_ptr.p->m_online.m_lcp_free_extent_head= extent;
1729 header->m_next_free_extent = file_ptr.p->m_online.m_first_free_extent;
1730 if (file_ptr.p->m_online.m_first_free_extent == RNIL)
1736 m_tablespace_pool.getPtr(ptr, file_ptr.p->m_tablespace_ptr_i);
1742 file_ptr.p->m_online.m_first_free_extent = extent;
1748 err = FreeExtentReq::UnmappedExtentPageIsNotImplemented;
1755 rep->reply.errorCode = err;
1760 Tsman::update_page_free_bits(
Signal* signal,
1762 unsigned committed_bits)
1774 file_key.m_file_no = key->m_file_no;
1775 ndbrequire(m_file_hash.find(file_ptr, file_key));
1777 struct req val = lookup_extent(key->m_page_no, file_ptr.p);
1780 preq.m_page.m_page_no = val.m_extent_page_no;
1781 preq.m_page.m_file_no = key->m_file_no;
1786 int flags = Page_cache_client::COMMIT_REQ;
1789 if ((real_page_id = pgman.get_page(signal, preq, flags)) > 0)
1796 page->get_header(val.m_extent_no, val.m_extent_size);
1798 if (header->m_table == RNIL)
1800 ndbout <<
"update page free bits page: " << *key
1801 <<
" " << *header << endl;
1806 ndbout <<
"update page free bits page(" << committed_bits <<
") "
1807 << *key <<
" " << *header << endl;
1810 ndbrequire(header->m_table != RNIL);
1812 Uint32 page_no_in_extent = calc_page_no_in_extent(key->m_page_no, &val);
1817 ndbassert((committed_bits & ~(COMMITTED_MASK)) == 0);
1818 Uint32 src = header->get_free_bits(page_no_in_extent) & UNCOMMITTED_MASK;
1819 header->update_free_bits(page_no_in_extent, src | committed_bits);
1821 pgman.update_lsn(preq.m_page, 0);
1826 return AllocExtentReq::UnmappedExtentPageIsNotImplemented;
1831 unsigned* uncommitted,
1832 unsigned* committed)
1838 file_key.m_file_no = key->m_file_no;
1839 ndbrequire(m_file_hash.find(file_ptr, file_key));
1841 struct req val = lookup_extent(key->m_page_no, file_ptr.p);
1844 preq.m_page.m_page_no = val.m_extent_page_no;
1845 preq.m_page.m_file_no = key->m_file_no;
1853 if ((real_page_id = pgman.get_page(signal, preq, flags)) > 0)
1860 page->get_header(val.m_extent_no, val.m_extent_size);
1862 ndbrequire(header->m_table != RNIL);
1864 Uint32 page_no_in_extent = calc_page_no_in_extent(key->m_page_no, &val);
1865 Uint32 bits = header->get_free_bits(page_no_in_extent);
1866 *uncommitted = (bits & UNCOMMITTED_MASK) >> UNCOMMITTED_SHIFT;
1867 *committed = (bits & COMMITTED_MASK);
1871 return AllocExtentReq::UnmappedExtentPageIsNotImplemented;
1875 Tsman::unmap_page(
Signal* signal,
Local_key *key, Uint32 uncommitted_bits)
1887 file_key.m_file_no = key->m_file_no;
1888 ndbrequire(m_file_hash.find(file_ptr, file_key));
1890 struct req val = lookup_extent(key->m_page_no, file_ptr.p);
1893 preq.m_page.m_page_no = val.m_extent_page_no;
1894 preq.m_page.m_file_no = key->m_file_no;
1902 if ((real_page_id = pgman.get_page(signal, preq, flags)) > 0)
1909 page->get_header(val.m_extent_no, val.m_extent_size);
1911 if (header->m_table == RNIL)
1913 ndbout <<
"trying to unmap page: " << *key
1914 <<
" " << *header << endl;
1916 ndbrequire(header->m_table != RNIL);
1918 Uint32 page_no_in_extent = calc_page_no_in_extent(key->m_page_no, &val);
1923 ndbassert(((uncommitted_bits << UNCOMMITTED_SHIFT) & ~UNCOMMITTED_MASK) == 0);
1924 Uint32 src = header->get_free_bits(page_no_in_extent) & COMMITTED_MASK;
1925 header->update_free_bits(page_no_in_extent,
1926 src | (uncommitted_bits << UNCOMMITTED_SHIFT));
1929 return AllocExtentReq::UnmappedExtentPageIsNotImplemented;
1933 Tsman::restart_undo_page_free_bits(
Signal* signal,
1949 file_key.m_file_no = key->m_file_no;
1950 ndbrequire(m_file_hash.find(file_ptr, file_key));
1952 struct req val = lookup_extent(key->m_page_no, file_ptr.p);
1955 preq.m_page.m_page_no = val.m_extent_page_no;
1956 preq.m_page.m_file_no = key->m_file_no;
1961 int flags = Page_cache_client::DIRTY_REQ;
1964 if ((real_page_id = pgman.get_page(signal, preq, flags)) > 0)
1971 page->get_header(val.m_extent_no, val.m_extent_size);
1973 if (header->m_table == RNIL)
1976 ndbout_c(
"tsman: apply undo - skip table == RNIL");
1980 Uint32 page_no_in_extent = calc_page_no_in_extent(key->m_page_no, &val);
1981 Uint32 src = header->get_free_bits(page_no_in_extent);
1983 if (! (header->m_table == tableId && header->m_fragment_id == fragId))
1985 ndbout_c(
"%u %u != %u %u",
1986 header->m_table, header->m_fragment_id,
1990 ndbrequire(header->m_table == tableId);
1991 ndbrequire(header->m_fragment_id == fragId);
1998 ndbout <<
"tsman: apply "
1999 << *key <<
" " << (src & COMMITTED_MASK)
2000 <<
" -> " << bits << endl;
2003 ndbassert((bits & ~(COMMITTED_MASK)) == 0);
2004 header->update_free_bits(page_no_in_extent,
2005 bits | (bits << UNCOMMITTED_SHIFT));
2010 return AllocExtentReq::UnmappedExtentPageIsNotImplemented;
2020 AllocPageReq::ErrorCode
2021 err= AllocPageReq::UnmappedExtentPageIsNotImplemented;
2031 file_key.m_file_no = req.key.m_file_no;
2032 ndbrequire(m_file_hash.find(file_ptr, file_key));
2034 struct req val = lookup_extent(req.key.m_page_no, file_ptr.p);
2035 Uint32 page_no_in_extent = calc_page_no_in_extent(req.key.m_page_no, &val);
2038 preq.m_page.m_page_no = val.m_extent_page_no;
2039 preq.m_page.m_file_no = req.key.m_file_no;
2041 Uint32 SZ= File_formats::Datafile::EXTENT_HEADER_BITMASK_BITS_PER_PAGE;
2046 int flags = Page_cache_client::DIRTY_REQ;
2052 if ((real_page_id = pgman.
get_page(signal, preq, flags)) > 0)
2058 header= page->get_header(val.m_extent_no, val.m_extent_size);
2060 ndbrequire(header->m_table == req.request.table_id);
2062 Uint32
word = header->get_free_word_offset(page_no_in_extent);
2063 Uint32 shift = SZ * (page_no_in_extent & 7);
2072 Uint32 reqbits = req.bits << UNCOMMITTED_SHIFT;
2077 Uint32 *src= header->m_page_bitmask +
word;
2078 for(page_no= page_no_in_extent; page_no<val.m_extent_size; page_no++)
2080 src_bits= (* src >> shift) & ((1 << SZ) - 1);
2081 if((src_bits & UNCOMMITTED_MASK) <= reqbits)
2086 src = src + (shift >> 5);
2091 src= header->m_page_bitmask;
2092 for(page_no= 0; page_no<page_no_in_extent; page_no++)
2094 src_bits= (* src >> shift) & ((1 << SZ) - 1);
2095 if((src_bits & UNCOMMITTED_MASK) <= reqbits)
2100 src = src + (shift >> 5);
2105 printf(
"req.bits: %d bits: ", req.bits);
2106 for(Uint32 i = 0; i<
size; i++)
2108 printf(
"%x", header->get_free_bits(i));
2112 err= AllocPageReq::NoPageFree;
2115 rep->reply.errorCode = err;
2119 header->update_free_bits(page_no, src_bits | UNCOMMITTED_MASK);
2120 rep->bits= (src_bits & UNCOMMITTED_MASK) >> UNCOMMITTED_SHIFT;
2121 rep->key.m_page_no = req.key.m_page_no + page_no - page_no_in_extent;
2122 rep->reply.errorCode= 0;
2127 Tsman::execLCP_FRAG_ORD(
Signal* signal)
2130 ndbrequire(!m_lcp_ongoing);
2131 m_lcp_ongoing =
true;
2138 ndbrequire(m_lcp_ongoing);
2139 m_lcp_ongoing =
false;
2145 if (m_tablespace_list.first(ptr))
2148 ptr.p->m_ref_count ++;
2149 signal->theData[0] = TsmanContinueB::END_LCP;
2150 signal->theData[1] = ptr.i;
2151 signal->theData[2] = 0;
2152 signal->theData[3] = RNIL;
2153 sendSignal(reference(), GSN_CONTINUEB, signal, 4, JBB);
2161 m_tablespace_list.getPtr(ptr, ptrI);
2162 ndbrequire(ptr.p->m_ref_count);
2163 ptr.p->m_ref_count--;
2167 Uint32 nextFile = RNIL;
2175 if(!tmp.
first(file))
2184 ndbrequire(file.p->m_ref_count);
2185 file.p->m_ref_count--;
2194 if(!tmp.
first(file))
2197 if(m_tablespace_list.next(ptr))
2205 ndbrequire(file.p->m_ref_count);
2206 file.p->m_ref_count--;
2214 nextFile = file.p->nextList;
2219 if(file.p->m_online.m_lcp_free_extent_head != RNIL)
2221 ndbout_c(
"moving extents (%d %d) to real free list %d",
2222 file.p->m_online.m_lcp_free_extent_head,
2223 file.p->m_online.m_lcp_free_extent_tail,
2224 file.p->m_online.m_first_free_extent);
2226 if(file.p->m_online.m_first_free_extent == RNIL)
2228 ndbrequire(list == 1);
2229 file.p->m_online.m_first_free_extent =
2230 file.p->m_online.m_lcp_free_extent_head;
2231 file.p->m_online.m_lcp_free_extent_head = RNIL;
2232 file.p->m_online.m_lcp_free_extent_tail = RNIL;
2241 Uint32 extent = file.p->m_online.m_lcp_free_extent_tail;
2242 Uint32 size = ptr.p->m_extent_size;
2244 Uint32 per_page = File_formats::Datafile::EXTENT_PAGE_WORDS/eh_words;
2246 Uint32 page_no = extent / per_page;
2247 Uint32 extent_no = extent % per_page;
2250 preq.m_page.m_page_no = page_no;
2251 preq.m_page.m_file_no = file.p->m_file_no;
2253 int flags = Page_cache_client::DIRTY_REQ;
2256 ndbrequire((real_page_id = pgman.
get_page(signal, preq, flags)) > 0);
2263 page->get_header(extent_no, size);
2265 header->m_next_free_extent = file.p->m_online.m_first_free_extent;
2266 file.p->m_online.m_first_free_extent =
2267 file.p->m_online.m_lcp_free_extent_head;
2269 file.p->m_online.m_lcp_free_extent_head = RNIL;
2270 file.p->m_online.m_lcp_free_extent_tail = RNIL;
2286 m_tablespace_list.next(ptr);
2292 ndbrequire(ptr.i != RNIL);
2293 m_file_pool.getPtr(file);
2294 file.p->m_ref_count++;
2300 ptr.p->m_ref_count++;
2302 signal->theData[0] = TsmanContinueB::END_LCP;
2303 signal->theData[1] = ptr.i;
2304 signal->theData[2] = list;
2305 signal->theData[3] = file.i;
2306 sendSignal(reference(), GSN_CONTINUEB, signal, 4, JBB);
2314 if(m_tsman->m_tablespace_hash.find(ts_ptr, m_tablespace_id))
2316 Uint32 logfile_group_id = ts_ptr.p->m_logfile_group_id;
2318 D(
"Logfile_client - get_tablespace_info");
2319 Logfile_client lgman(m_tsman, m_tsman->m_lgman, logfile_group_id,
false);
2320 rep->tablespace.extent_size = ts_ptr.p->m_extent_size;
2321 rep->tablespace.logfile_group_id = lgman.m_logfile_group_id;
2327 void Tsman::execGET_TABINFOREQ(
Signal* signal)
2338 Uint32 tableId= req->tableId;
2339 const Uint32 reqType = req->requestType & (~GetTabInfoReq::LongSignalConf);
2340 BlockReference retRef= req->senderRef;
2341 Uint32 senderData= req->senderData;
2343 if(reqType == GetTabInfoReq::RequestByName)
2347 releaseSections(handle);
2349 sendGET_TABINFOREF(signal, req, GetTabInfoRef::NoFetchByName);
2353 Datafile_hash::Iterator iter;
2354 if (!m_file_hash.first(iter))
2360 while(iter.curr.p->m_file_id != tableId && m_file_hash.next(iter))
2363 if(iter.curr.p->m_file_id != tableId)
2365 sendGET_TABINFOREF(signal, req, GetTabInfoRef::InvalidTableId);
2373 Uint32 total_free_extents = file_ptr.p->m_online.m_data_pages;
2374 total_free_extents /= file_ptr.p->m_extent_size;
2375 total_free_extents -= file_ptr.p->m_online.m_used_extent_cnt;
2379 conf->senderData= senderData;
2380 conf->tableId= tableId;
2381 conf->freeExtents= total_free_extents;
2383 conf->senderRef= reference();
2384 sendSignal(retRef, GSN_GET_TABINFO_CONF, signal,
2385 GetTabInfoConf::SignalLength, JBB);
2390 GetTabInfoRef::ErrorCode errorCode)
2397 BlockReference retRef = req->senderRef;
2398 ref->errorCode = errorCode;
2400 sendSignal(retRef, GSN_GET_TABINFOREF, signal, signal->
length(), JBB);