18 #include "restore.hpp"
19 #include <signaldata/FsRef.hpp>
20 #include <signaldata/FsConf.hpp>
21 #include <signaldata/FsOpenReq.hpp>
22 #include <signaldata/FsCloseReq.hpp>
23 #include <signaldata/FsReadWriteReq.hpp>
24 #include <signaldata/RestoreImpl.hpp>
25 #include <signaldata/DictTabInfo.hpp>
26 #include <signaldata/KeyInfo.hpp>
27 #include <signaldata/AttrInfo.hpp>
28 #include <signaldata/LqhKey.hpp>
29 #include <AttributeHeader.hpp>
30 #include <md5_hash.hpp>
31 #include <dblqh/Dblqh.hpp>
32 #include <dbtup/Dbtup.hpp>
33 #include <KeyDescriptor.hpp>
35 #define PAGES LCP_RESTORE_BUFFER
39 m_file_list(m_file_pool),
40 m_file_hash(m_file_pool)
45 addRecSignal(GSN_STTOR, &Restore::execSTTOR);
46 addRecSignal(GSN_DUMP_STATE_ORD, &Restore::execDUMP_STATE_ORD);
47 addRecSignal(GSN_CONTINUEB, &Restore::execCONTINUEB);
48 addRecSignal(GSN_READ_CONFIG_REQ, &Restore::execREAD_CONFIG_REQ,
true);
50 addRecSignal(GSN_RESTORE_LCP_REQ, &Restore::execRESTORE_LCP_REQ);
52 addRecSignal(GSN_FSOPENREF, &Restore::execFSOPENREF,
true);
54 addRecSignal(GSN_FSREADREF, &Restore::execFSREADREF,
true);
55 addRecSignal(GSN_FSREADCONF, &Restore::execFSREADCONF);
56 addRecSignal(GSN_FSCLOSEREF, &Restore::execFSCLOSEREF,
true);
57 addRecSignal(GSN_FSCLOSECONF, &Restore::execFSCLOSECONF);
59 addRecSignal(GSN_LQHKEYREF, &Restore::execLQHKEYREF);
60 addRecSignal(GSN_LQHKEYCONF, &Restore::execLQHKEYCONF);
62 ndbrequire(
sizeof(Column) == 8);
76 c_lqh = (
Dblqh*)globalData.getBlock(DBLQH, instance());
77 c_tup = (
Dbtup*)globalData.getBlock(DBTUP, instance());
78 ndbrequire(c_lqh != 0 && c_tup != 0);
85 Restore::execREAD_CONFIG_REQ(
Signal* signal)
89 Uint32 ref = req->senderRef;
90 Uint32 senderData = req->senderData;
91 ndbrequire(req->noOfParameters == 0);
94 m_ctx.m_config.getOwnConfigIterator();
98 Uint32 noBackups = 0, noTables = 0, noAttribs = 0;
99 ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_DB_DISCLESS, &m_diskless));
100 ndb_mgm_get_int_parameter(p, CFG_DB_PARALLEL_BACKUPS, &noBackups);
102 ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_DICT_TABLE, &noTables));
103 ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_DB_NO_ATTRIBUTES, &noAttribs));
107 c_backupPool.setSize(noBackups);
108 c_backupFilePool.setSize(3 * noBackups);
109 c_tablePool.setSize(noBackups * noTables);
110 c_attributePool.setSize(noBackups * noAttribs);
111 c_triggerPool.setSize(noBackups * 3 * noTables);
114 c_fragmentPool.setSize(noBackups * NO_OF_FRAG_PER_NODE * noTables);
117 ndb_mgm_get_int_parameter(p, CFG_DB_BACKUP_MEM, &szMem);
118 Uint32 noPages = (szMem +
sizeof(Page32) - 1) /
sizeof(Page32);
121 c_pagePool.setSize(noPages + NO_OF_PAGES_META_FILE + 2);
123 Uint32 szDataBuf = (2 * 1024 * 1024);
124 Uint32 szLogBuf = (2 * 1024 * 1024);
125 Uint32 szWrite = 32768;
126 ndb_mgm_get_int_parameter(p, CFG_DB_BACKUP_DATA_BUFFER_MEM, &szDataBuf);
127 ndb_mgm_get_int_parameter(p, CFG_DB_BACKUP_LOG_BUFFER_MEM, &szLogBuf);
128 ndb_mgm_get_int_parameter(p, CFG_DB_BACKUP_WRITE_SIZE, &szWrite);
130 c_defaults.m_logBufferSize = szLogBuf;
131 c_defaults.m_dataBufferSize = szDataBuf;
132 c_defaults.m_minWriteSize = szWrite;
133 c_defaults.m_maxWriteSize = szWrite;
136 ArrayList<Table> tables(c_tablePool);
138 while(tables.seize(ptr)){
139 new (ptr.p) Table(c_attributePool, c_fragmentPool);
145 ArrayList<BackupFile> ops(c_backupFilePool);
147 while(ops.seize(ptr)){
154 ArrayList<BackupRecord> recs(c_backupPool);
156 while(recs.seize(ptr)){
157 new (ptr.p) BackupRecord(*
this, c_pagePool, c_tablePool,
158 c_backupFilePool, c_triggerPool);
166 ndbrequire(c_pagePool.seizeId(p, 0));
167 c_startOfPages = (Uint32 *)p.p;
168 c_pagePool.release(p);
171 bat[0].WA = c_startOfPages;
172 bat[0].nrr = c_pagePool.getSize()*
sizeof(Page32)/
sizeof(Uint32);
175 m_file_pool.setSize(1);
176 Uint32 cnt = 2*MAX_ATTRIBUTES_IN_TABLE;
178 cnt += List::getSegmentSize()-1;
179 cnt /= List::getSegmentSize();
181 m_databuffer_pool.setSize(cnt);
184 conf->senderRef = reference();
185 conf->senderData = senderData;
186 sendSignal(ref, GSN_READ_CONFIG_CONF, signal,
187 ReadConfigConf::SignalLength, JBB);
191 Restore::sendSTTORRY(
Signal* signal){
192 signal->theData[0] = 0;
193 signal->theData[3] = 1;
194 signal->theData[4] = 3;
195 signal->theData[5] = 255;
196 BlockReference cntrRef = !isNdbMtLqh() ? NDBCNTR_REF : RESTORE_REF;
197 sendSignal(cntrRef, GSN_STTORRY, signal, 6, JBB);
201 Restore::execCONTINUEB(
Signal* signal){
204 switch(signal->theData[0]){
205 case RestoreContinueB::RESTORE_NEXT:
208 m_file_pool.getPtr(file_ptr, signal->theData[1]);
209 restore_next(signal, file_ptr);
212 case RestoreContinueB::READ_FILE:
215 m_file_pool.getPtr(file_ptr, signal->theData[1]);
216 read_file(signal, file_ptr);
225 Restore::execDUMP_STATE_ORD(
Signal* signal){
230 Restore::execRESTORE_LCP_REQ(
Signal* signal){
235 Uint32 senderRef= req->senderRef;
236 Uint32 senderData= req->senderData;
240 if(!m_file_list.seize(file_ptr))
242 err= RestoreLcpRef::NoFileRecord;
246 if((err= init_file(req, file_ptr)))
251 open_file(signal, file_ptr);
256 ref->senderData= senderData;
257 ref->senderRef= reference();
258 ref->errorCode = err;
259 sendSignal(senderRef, GSN_RESTORE_LCP_REF, signal,
260 RestoreLcpRef::SignalLength, JBB);
264 Restore::init_file(
const RestoreLcpReq* req, FilePtr file_ptr)
266 new (file_ptr.p) File();
267 file_ptr.p->m_sender_ref = req->senderRef;
268 file_ptr.p->m_sender_data = req->senderData;
270 file_ptr.p->m_fd = RNIL;
271 file_ptr.p->m_file_type = BackupFormat::LCP_FILE;
272 file_ptr.p->m_status = File::FIRST_READ;
274 file_ptr.p->m_lcp_no = req->lcpNo;
275 file_ptr.p->m_table_id = req->tableId;
276 file_ptr.p->m_fragment_id = req->fragmentId;
277 file_ptr.p->m_table_version = RNIL;
279 file_ptr.p->m_bytes_left = 0;
280 file_ptr.p->m_current_page_ptr_i = RNIL;
281 file_ptr.p->m_current_page_pos = 0;
282 file_ptr.p->m_current_page_index = 0;
283 file_ptr.p->m_current_file_page = 0;
284 file_ptr.p->m_outstanding_reads = 0;
285 file_ptr.p->m_outstanding_operations = 0;
286 file_ptr.p->m_rows_restored = 0;
290 ndbassert(columns.isEmpty());
293 ndbassert(pages.isEmpty());
296 Uint32 buf_size= PAGES*GLOBAL_PAGE_SIZE;
297 Uint32 page_count= (buf_size+GLOBAL_PAGE_SIZE-1)/GLOBAL_PAGE_SIZE;
298 if(!pages.seize(page_count))
300 return RestoreLcpRef::OutOfDataBuffer;
304 for(pages.first(it); !it.isNull(); pages.next(it))
310 for(pages.first(it); !it.isNull(); pages.next(it))
313 if(!m_global_page_pool.
seize(page_ptr))
315 err= RestoreLcpRef::OutOfReadBufferPages;
318 * it.data = page_ptr.i;
323 for(pages.first(it); !it.isNull(); pages.next(it))
325 if(* it.data == RNIL)
327 m_global_page_pool.
release(* it.data);
333 file_ptr.p->m_current_page_ptr_i = *it.data;
345 for(pages.first(it); !it.isNull(); pages.next(it))
347 if(* it.data == RNIL)
349 m_global_page_pool.
release(* it.data);
352 ndbout_c(
"RESTORE table: %d %lld rows applied",
353 file_ptr.p->m_table_id,
354 file_ptr.p->m_rows_restored);
358 m_file_list.release(file_ptr);
362 Restore::open_file(
Signal* signal, FilePtr file_ptr)
364 signal->theData[0] = NDB_LE_StartReadLCP;
365 signal->theData[1] = file_ptr.p->m_table_id;
366 signal->theData[2] = file_ptr.p->m_fragment_id;
367 sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 3, JBB);
370 req->userReference = reference();
371 req->fileFlags = FsOpenReq::OM_READONLY | FsOpenReq::OM_GZ;
372 req->userPointer = file_ptr.i;
374 FsOpenReq::setVersion(req->fileNumber, 5);
375 FsOpenReq::setSuffix(req->fileNumber, FsOpenReq::S_DATA);
376 FsOpenReq::v5_setLcpNo(req->fileNumber, file_ptr.p->m_lcp_no);
377 FsOpenReq::v5_setTableId(req->fileNumber, file_ptr.p->m_table_id);
378 FsOpenReq::v5_setFragmentId(req->fileNumber, file_ptr.p->m_fragment_id);
379 sendSignal(NDBFS_REF, GSN_FSOPENREQ, signal, FsOpenReq::SignalLength, JBA);
383 Restore::execFSOPENREF(
Signal* signal)
390 Uint32 errCode= ref->errorCode;
391 Uint32 osError= ref->osErrorCode;
394 rep->senderData= file_ptr.p->m_sender_data;
395 rep->errorCode = errCode;
396 rep->extra[0] = osError;
397 sendSignal(file_ptr.p->m_sender_ref,
398 GSN_RESTORE_LCP_REF, signal, RestoreLcpRef::SignalLength+1, JBB);
409 m_file_pool.getPtr(file_ptr, conf->userPointer);
411 file_ptr.p->m_fd = conf->filePointer;
417 file_ptr.p->m_status |= File::FILE_THREAD_RUNNING;
418 signal->theData[0] = RestoreContinueB::READ_FILE;
419 signal->theData[1] = file_ptr.i;
420 sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
422 file_ptr.p->m_status |= File::RESTORE_THREAD_RUNNING;
423 signal->theData[0] = RestoreContinueB::RESTORE_NEXT;
424 signal->theData[1] = file_ptr.i;
425 sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
429 Restore::restore_next(
Signal* signal, FilePtr file_ptr)
431 Uint32 *data, len= 0;
432 Uint32 status = file_ptr.p->m_status;
433 Uint32 page_count = file_ptr.p->m_pages.getSize();
436 Uint32 left= file_ptr.p->m_bytes_left;
445 m_global_page_pool.
getPtr(page_ptr, file_ptr.p->m_current_page_ptr_i);
448 Uint32 pos= file_ptr.p->m_current_page_pos;
449 if(status & File::READING_RECORDS)
454 len= ntohl(* (page_ptr.p->data + pos)) + 1;
461 if(pos + 1 == GLOBAL_PAGE_SIZE_WORDS)
469 Uint32 next_page = file_ptr.p->m_current_page_index + 1;
470 pages.position(it, next_page % page_count);
471 m_global_page_pool.
getPtr(next_page_ptr, * it.data);
472 len= ntohl(* next_page_ptr.p->data);
476 len= ntohl(* (page_ptr.p->data + pos + 1));
480 if(file_ptr.p->m_status & File::FIRST_READ)
483 file_ptr.p->m_status &= ~(Uint32)File::FIRST_READ;
491 ndbout_c(
"records: %d len: %x left: %d",
492 status & File::READING_RECORDS, 4*len, left);
494 if (unlikely((status & File:: FILE_THREAD_RUNNING) == 0))
496 crash_during_restore(file_ptr, __LINE__, 0);
506 if(pos + len >= GLOBAL_PAGE_SIZE_WORDS)
511 if(next_page_ptr.p == 0)
514 Uint32 next_page = file_ptr.p->m_current_page_index + 1;
515 pages.position(it, next_page % page_count);
516 m_global_page_pool.
getPtr(next_page_ptr, * it.data);
518 file_ptr.p->m_current_page_ptr_i = next_page_ptr.i;
519 file_ptr.p->m_current_page_pos = (pos + len) - GLOBAL_PAGE_SIZE_WORDS;
520 file_ptr.p->m_current_page_index =
521 (file_ptr.p->m_current_page_index + 1) % page_count;
523 Uint32 first = (GLOBAL_PAGE_SIZE_WORDS - pos);
525 memmove(page_ptr.p, page_ptr.p->data+pos, 4 * first);
526 memcpy(page_ptr.p->data+first, next_page_ptr.p, 4 * (len - first));
527 data= page_ptr.p->data;
531 file_ptr.p->m_current_page_pos = pos + len;
532 data= page_ptr.p->data+pos;
535 file_ptr.p->m_bytes_left -= 4*len;
537 if(status & File::READING_RECORDS)
541 file_ptr.p->m_status = status & ~(Uint32)File::READING_RECORDS;
545 parse_record(signal, file_ptr, data, len);
550 switch(ntohl(* data)){
551 case BackupFormat::FILE_HEADER:
552 parse_file_header(signal, file_ptr, data-3, len+3);
554 case BackupFormat::FRAGMENT_HEADER:
555 file_ptr.p->m_status = status | File::READING_RECORDS;
556 parse_fragment_header(signal, file_ptr, data, len);
558 case BackupFormat::FRAGMENT_FOOTER:
559 parse_fragment_footer(signal, file_ptr, data, len);
561 case BackupFormat::TABLE_LIST:
562 parse_table_list(signal, file_ptr, data, len);
564 case BackupFormat::TABLE_DESCRIPTION:
565 parse_table_description(signal, file_ptr, data, len);
567 case BackupFormat::GCP_ENTRY:
568 parse_gcp_entry(signal, file_ptr, data, len);
570 case BackupFormat::EMPTY_ENTRY:
574 if (check_file_version(signal, ntohl(* (data+2))) == 0)
579 parse_error(signal, file_ptr, __LINE__, ntohl(* data));
584 if(file_ptr.p->m_bytes_left == 0 && status & File::FILE_EOF)
586 file_ptr.p->m_status &= ~(Uint32)File::RESTORE_THREAD_RUNNING;
590 close_file(signal, file_ptr);
594 signal->theData[0] = RestoreContinueB::RESTORE_NEXT;
595 signal->theData[1] = file_ptr.i;
598 sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
600 sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 100, 2);
604 Restore::read_file(
Signal* signal, FilePtr file_ptr)
606 Uint32 left= file_ptr.p->m_bytes_left;
607 Uint32 page_count = file_ptr.p->m_pages.getSize();
608 Uint32 free= GLOBAL_PAGE_SIZE * page_count - left;
609 Uint32 read_count= free/GLOBAL_PAGE_SIZE;
611 if(read_count <= file_ptr.p->m_outstanding_reads)
613 signal->theData[0] = RestoreContinueB::READ_FILE;
614 signal->theData[1] = file_ptr.i;
615 sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
619 read_count -= file_ptr.p->m_outstanding_reads;
620 Uint32 curr_page= file_ptr.p->m_current_page_index;
624 req->filePointer = file_ptr.p->m_fd;
625 req->userReference = reference();
626 req->userPointer = file_ptr.i;
627 req->numberOfPages = 1;
628 req->operationFlag = 0;
629 FsReadWriteReq::setFormatFlag(req->operationFlag,
630 FsReadWriteReq::fsFormatGlobalPage);
631 FsReadWriteReq::setPartialReadFlag(req->operationFlag, 1);
633 Uint32 start= (curr_page + page_count - read_count) % page_count;
636 pages.position(it, start);
639 file_ptr.p->m_outstanding_reads++;
640 req->varIndex = file_ptr.p->m_current_file_page++;
641 req->data.pageData[0] = *it.data;
642 sendSignal(NDBFS_REF, GSN_FSREADREQ, signal,
643 FsReadWriteReq::FixedLength + 1, JBB);
646 if(start == page_count)
649 pages.position(it, start);
655 }
while(start != curr_page);
659 Restore::execFSREADREF(
Signal * signal)
662 SimulatedBlock::execFSREADREF(signal);
667 Restore::execFSREADCONF(
Signal * signal)
672 m_file_pool.getPtr(file_ptr, conf->userPointer);
674 file_ptr.p->m_bytes_left += conf->bytes_read;
676 ndbassert(file_ptr.p->m_outstanding_reads);
677 file_ptr.p->m_outstanding_reads--;
679 if(file_ptr.p->m_outstanding_reads == 0)
681 ndbassert(conf->bytes_read <= GLOBAL_PAGE_SIZE);
682 if(conf->bytes_read == GLOBAL_PAGE_SIZE)
684 read_file(signal, file_ptr);
688 file_ptr.p->m_status |= File::FILE_EOF;
689 file_ptr.p->m_status &= ~(Uint32)File::FILE_THREAD_RUNNING;
695 Restore::close_file(
Signal* signal, FilePtr file_ptr)
698 req->filePointer = file_ptr.p->m_fd;
699 req->userPointer = file_ptr.i;
700 req->userReference = reference();
702 sendSignal(NDBFS_REF, GSN_FSCLOSEREQ, signal, FsCloseReq::SignalLength, JBA);
706 Restore::execFSCLOSEREF(
Signal * signal)
709 SimulatedBlock::execFSCLOSEREF(signal);
714 Restore::execFSCLOSECONF(
Signal * signal)
719 m_file_pool.getPtr(file_ptr, conf->userPointer);
721 file_ptr.p->m_fd = RNIL;
723 if(file_ptr.p->m_outstanding_operations == 0)
726 restore_lcp_conf(signal, file_ptr);
732 Restore::parse_file_header(
Signal* signal,
734 const Uint32* data, Uint32 len)
738 if(memcmp(fh->Magic,
"NDBBCKUP", 8) != 0)
740 parse_error(signal, file_ptr, __LINE__, *data);
744 file_ptr.p->m_lcp_version = ntohl(fh->BackupVersion);
745 if (check_file_version(signal, ntohl(fh->BackupVersion)))
747 parse_error(signal, file_ptr, __LINE__, ntohl(fh->NdbVersion));
750 ndbassert(ntohl(fh->SectionType) == BackupFormat::FILE_HEADER);
752 if(ntohl(fh->SectionLength) != len-3)
754 parse_error(signal, file_ptr, __LINE__, ntohl(fh->SectionLength));
758 if(ntohl(fh->FileType) != BackupFormat::LCP_FILE)
760 parse_error(signal, file_ptr, __LINE__, ntohl(fh->FileType));
764 if(fh->ByteOrder != 0x12345678)
766 parse_error(signal, file_ptr, __LINE__, fh->ByteOrder);
772 Restore::parse_table_list(
Signal* signal, FilePtr file_ptr,
773 const Uint32 *data, Uint32 len)
778 if(ntohl(fh->TableIds[0]) != file_ptr.p->m_table_id)
780 parse_error(signal, file_ptr, __LINE__, ntohl(fh->TableIds[0]));
786 Restore::parse_table_description(
Signal* signal, FilePtr file_ptr,
787 const Uint32 *data, Uint32 len)
789 bool lcp = file_ptr.p->is_lcp();
801 stat = SimpleProperties::unpack(it, &tmpTab,
802 DictTabInfo::TableMapping,
803 DictTabInfo::TableMappingSize,
805 ndbrequire(stat == SimpleProperties::Break);
807 if(tmpTab.TableId != file_ptr.p->m_table_id)
809 parse_error(signal, file_ptr, __LINE__, tmpTab.TableId);
814 Uint32 colstore[
sizeof(Column)/
sizeof(Uint32)];
816 for(Uint32
i = 0;
i<tmpTab.NoOfAttributes;
i++) {
819 stat = SimpleProperties::unpack(it, &tmp,
820 DictTabInfo::AttributeMapping,
821 DictTabInfo::AttributeMappingSize,
824 ndbrequire(stat == SimpleProperties::Break);
827 const Uint32 arr = tmp.AttributeArraySize;
828 const Uint32 sz = 1 << tmp.AttributeSize;
829 const Uint32 sz32 = (sz * arr + 31) >> 5;
830 const bool varsize = tmp.AttributeArrayType != NDB_ARRAYTYPE_FIXED;
832 c.m_id = tmp.AttributeId;
834 c.m_flags = (tmp.AttributeKeyFlag ? Column::COL_KEY : 0);
835 c.m_flags |= (tmp.AttributeStorageType == NDB_STORAGETYPE_DISK ?
836 Column::COL_DISK : 0);
838 if(lcp && (c.m_flags & Column::COL_DISK))
848 if(!tmp.AttributeNullableFlag && !varsize)
853 c.m_flags |= (varsize ? Column::COL_VAR : 0);
854 c.m_flags |= (tmp.AttributeNullableFlag ? Column::COL_NULL : 0);
857 memcpy(colstore, &c,
sizeof(Column));
858 if(!columns.append(colstore,
sizeof(Column)/
sizeof(Uint32)))
860 parse_error(signal, file_ptr, __LINE__,
i);
869 c.m_id = AttributeHeader::DISK_REF;
872 memcpy(colstore, &c,
sizeof(Column));
873 if(!columns.append(colstore,
sizeof(Column)/
sizeof(Uint32)))
875 parse_error(signal, file_ptr, __LINE__, 0);
881 c.m_id = AttributeHeader::ROWID;
884 memcpy(colstore, &c,
sizeof(Column));
885 if(!columns.append(colstore,
sizeof(Column)/
sizeof(Uint32)))
887 parse_error(signal, file_ptr, __LINE__, 0);
892 if (tmpTab.RowGCIFlag)
894 c.m_id = AttributeHeader::ROW_GCI;
897 memcpy(colstore, &c,
sizeof(Column));
898 if(!columns.append(colstore,
sizeof(Column)/
sizeof(Uint32)))
900 parse_error(signal, file_ptr, __LINE__, 0);
906 file_ptr.p->m_table_version = tmpTab.TableVersion;
910 Restore::parse_fragment_header(
Signal* signal, FilePtr file_ptr,
911 const Uint32 *data, Uint32 len)
915 if(ntohl(fh->TableId) != file_ptr.p->m_table_id)
917 parse_error(signal, file_ptr, __LINE__, ntohl(fh->TableId));
921 if(ntohl(fh->ChecksumType) != 0)
923 parse_error(signal, file_ptr, __LINE__, ntohl(fh->SectionLength));
927 file_ptr.p->m_fragment_id = ntohl(fh->FragmentNo);
929 if(file_ptr.p->is_lcp())
934 c_tup->start_restore_lcp(file_ptr.p->m_table_id,
935 file_ptr.p->m_fragment_id);
940 Restore::parse_record(
Signal* signal, FilePtr file_ptr,
941 const Uint32 *data, Uint32 len)
946 Uint32 *
const key_start = signal->getDataPtrSend()+24;
947 Uint32 *
const attr_start = key_start + MAX_KEY_SIZE_IN_WORDS;
950 const Uint32*
const dataStart = data;
959 Uint32 tableId = file_ptr.p->m_table_id;
960 const KeyDescriptor* desc = g_key_descriptor_pool.getPtr(tableId);
962 if (likely(file_ptr.p->m_lcp_version >= NDBD_RAW_LCP))
965 rowid_val.m_page_no = data[0];
966 rowid_val.m_page_idx = data[1];
967 keyLen = c_tup->read_lcp_keys(tableId, data+2, len - 3, key_start);
970 memcpy(attr_start + 1, data + 2, 4 * (len - 3));
971 attrLen = 1 + len - 3;
975 Uint32 *keyData = key_start;
976 Uint32 *attrData = attr_start;
979 Uint32 _align[
sizeof(Column)/
sizeof(Uint32)];
985 _align[0] = *it.data; ndbrequire(columns.next(it));
986 _align[1] = *it.data; columns.next(it);
988 if (c.m_id == AttributeHeader::ROWID)
990 rowid_val.m_page_no = data[0];
991 rowid_val.m_page_idx = data[1];
997 if (c.m_id == AttributeHeader::ROW_GCI)
999 memcpy(&gci_val, data, 8);
1005 if (! (c.m_flags & (Column::COL_VAR | Column::COL_NULL)))
1007 ndbrequire(data < dataStart + len);
1009 if(c.m_flags & Column::COL_KEY)
1011 memcpy(keyData, data, 4*c.m_size);
1012 keyData += c.m_size;
1016 memcpy(attrData, data, 4*c.m_size);
1017 attrData += c.m_size;
1021 if(c.m_flags & Column::COL_DISK)
1026 while (data + 2 < dataStart + len) {
1027 Uint32 sz= ntohl(*data); data++;
1028 Uint32
id= ntohl(*data); data++;
1030 ndbrequire(columns.position(it, 2 *
id));
1032 _align[0] = *it.data; ndbrequire(columns.next(it));
1033 _align[1] = *it.data;
1035 Uint32 sz32 = (sz + 3) >> 2;
1036 ndbassert(c.m_flags & (Column::COL_VAR | Column::COL_NULL));
1037 if (c.m_flags & Column::COL_KEY)
1039 memcpy(keyData, data, 4 * sz32);
1044 memcpy(attrData, data, sz);
1050 ndbrequire(data == dataStart + len - 1);
1052 ndbrequire(disk ==
false);
1053 ndbrequire(rowid ==
true);
1054 keyLen = Uint32(keyData - key_start);
1055 attrLen = Uint32(attrData - attr_start);
1056 if (desc->noOfKeyAttr != desc->noOfVarKeys)
1058 reorder_key(desc, key_start, keyLen);
1065 if (g_key_descriptor_pool.getPtr(tableId)->hasCharAttr)
1066 hashValue = calulate_hash(tableId, key_start);
1068 hashValue = md5_hash((Uint64*)key_start, keyLen);
1071 LqhKeyReq::setAttrLen(tmp, attrLen);
1075 LqhKeyReq::setKeyLen(tmp, keyLen);
1076 LqhKeyReq::setLastReplicaNo(tmp, 0);
1080 LqhKeyReq::setApplicationAddressFlag(tmp, 0);
1081 LqhKeyReq::setDirtyFlag(tmp, 1);
1082 LqhKeyReq::setSimpleFlag(tmp, 1);
1083 LqhKeyReq::setOperation(tmp, ZINSERT);
1084 LqhKeyReq::setSameClientAndTcFlag(tmp, 0);
1085 LqhKeyReq::setAIInLqhKeyReq(tmp, 0);
1086 LqhKeyReq::setNoDiskFlag(tmp, disk ? 0 : 1);
1087 LqhKeyReq::setRowidFlag(tmp, 1);
1088 LqhKeyReq::setGCIFlag(tmp, gci);
1089 req->clientConnectPtr = file_ptr.i;
1090 req->hashValue = hashValue;
1091 req->requestInfo = tmp;
1092 req->tcBlockref = reference();
1093 req->savePointId = 0;
1094 req->tableSchemaVersion = file_ptr.p->m_table_id +
1095 (file_ptr.p->m_table_version << 16);
1096 req->fragmentData = file_ptr.p->m_fragment_id;
1100 memcpy(req->variableData, key_start, 16);
1101 Uint32 pos = keyLen > 4 ? 4 : keyLen;
1102 req->variableData[pos++] = rowid_val.m_page_no;
1103 req->variableData[pos++] = rowid_val.m_page_idx;
1105 req->variableData[pos++] = (Uint32)gci_val;
1106 file_ptr.p->m_outstanding_operations++;
1108 LqhKeyReq::FixedSignalLength+pos);
1112 c_lqh->receive_keyinfo(signal,
1117 c_lqh->receive_attrinfo(signal, attr_start, attrLen);
1122 Uint32 *data, Uint32 len)
1126 Uint32 Tmp[MAX_KEY_SIZE_IN_WORDS];
1127 for(i = 0; i<desc->noOfKeyAttr; i++)
1129 Uint32 attr = desc->keyAttr[
i].attributeDescriptor;
1130 switch(AttributeDescriptor::getArrayType(attr)){
1131 case NDB_ARRAYTYPE_FIXED:
1132 var += AttributeDescriptor::getSizeInWords(attr);
1138 for(i = 0; i<desc->noOfKeyAttr; i++)
1141 Uint32 attr = desc->keyAttr[
i].attributeDescriptor;
1142 switch(AttributeDescriptor::getArrayType(attr)){
1143 case NDB_ARRAYTYPE_FIXED:
1144 sz = AttributeDescriptor::getSizeInWords(attr);
1145 memcpy(dst, src, 4 * sz);
1148 case NDB_ARRAYTYPE_SHORT_VAR:
1149 sz = (1 + ((Uint8*)var)[0] + 3) >> 2;
1150 memcpy(dst, var, 4 * sz);
1153 case NDB_ARRAYTYPE_MEDIUM_VAR:
1154 sz = (2 + ((Uint8*)var)[0] + 256*((Uint8*)var)[1] + 3) >> 2;
1155 memcpy(dst, var, 4 * sz);
1164 ndbassert((Uint32) (dst - Tmp) == len);
1165 memcpy(data, Tmp, 4*len);
1169 Restore::calulate_hash(Uint32 tableId,
const Uint32 *src)
1172 Uint64 Tmp[(MAX_KEY_SIZE_IN_WORDS*MAX_XFRM_MULTIPLY) >> 1];
1173 Uint32 keyPartLen[MAX_ATTRIBUTES_IN_INDEX];
1174 Uint32 keyLen =
xfrm_key(tableId, src, (Uint32*)Tmp,
sizeof(Tmp) >> 2,
1178 return md5_hash(Tmp, keyLen);
1182 Restore::execLQHKEYREF(
Signal* signal)
1186 m_file_pool.getPtr(file_ptr, ref->connectPtr);
1188 crash_during_restore(file_ptr, __LINE__, ref->errorCode);
1193 Restore::crash_during_restore(FilePtr file_ptr, Uint32 line, Uint32 errCode)
1197 file_ptr.p->m_lcp_no,
1198 file_ptr.p->m_table_id,
1199 file_ptr.p->m_fragment_id);
1204 "Error %d (line: %u) during restore of %s",
1205 errCode, line, name);
1210 "Error (line %u) during restore of %s",
1213 progError(__LINE__, NDBD_EXIT_INVALID_LCP_FILE, buf);
1217 Restore::execLQHKEYCONF(
Signal* signal)
1221 m_file_pool.getPtr(file_ptr, conf->opPtr);
1223 ndbassert(file_ptr.p->m_outstanding_operations);
1224 file_ptr.p->m_outstanding_operations--;
1225 file_ptr.p->m_rows_restored++;
1226 if(file_ptr.p->m_outstanding_operations == 0 && file_ptr.p->m_fd == RNIL)
1229 restore_lcp_conf(signal, file_ptr);
1235 Restore::restore_lcp_conf(
Signal* signal, FilePtr file_ptr)
1238 rep->senderData= file_ptr.p->m_sender_data;
1239 if(file_ptr.p->is_lcp())
1246 c_tup->complete_restore_lcp(signal,
1247 file_ptr.p->m_sender_ref,
1248 file_ptr.p->m_sender_data,
1249 file_ptr.p->m_table_id,
1250 file_ptr.p->m_fragment_id);
1254 sendSignal(file_ptr.p->m_sender_ref,
1255 GSN_RESTORE_LCP_CONF, signal,
1256 RestoreLcpConf::SignalLength, JBB);
1259 signal->theData[0] = NDB_LE_ReadLCPComplete;
1260 signal->theData[1] = file_ptr.p->m_table_id;
1261 signal->theData[2] = file_ptr.p->m_fragment_id;
1262 signal->theData[3] = Uint32(file_ptr.p->m_rows_restored >> 32);
1263 signal->theData[4] = Uint32(file_ptr.p->m_rows_restored);
1264 sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 5, JBB);
1270 Restore::parse_fragment_footer(
Signal* signal, FilePtr file_ptr,
1271 const Uint32 *data, Uint32 len)
1275 if(ntohl(fh->TableId) != file_ptr.p->m_table_id)
1277 parse_error(signal, file_ptr, __LINE__, ntohl(fh->TableId));
1281 if(ntohl(fh->Checksum) != 0)
1283 parse_error(signal, file_ptr, __LINE__, ntohl(fh->SectionLength));
1289 Restore::parse_gcp_entry(
Signal* signal, FilePtr file_ptr,
1290 const Uint32 *data, Uint32 len)
1296 Restore::parse_error(
Signal* signal,
1297 FilePtr file_ptr, Uint32 line, Uint32
extra)
1299 char buf[255], name[100];
1301 file_ptr.p->m_lcp_no,
1302 file_ptr.p->m_table_id,
1303 file_ptr.p->m_fragment_id);
1306 "Parse error in file: %s, extra: %d",
1309 progError(line, NDBD_EXIT_INVALID_LCP_FILE, buf);
1316 ndbout <<
"[ Col: id: " << col.m_id
1317 <<
" size: " << col.m_size
1318 <<
" key: " << (Uint32)(col.m_flags & Restore::Column::COL_KEY)
1319 <<
" variable: " << (Uint32)(col.m_flags & Restore::Column::COL_VAR)
1320 <<
" null: " << (Uint32)(col.m_flags & Restore::Column::COL_NULL)
1321 <<
" disk: " << (Uint32)(col.m_flags & Restore::Column::COL_DISK)
1328 Restore::check_file_version(
Signal* signal, Uint32 file_version)
1330 if (file_version < MAKE_VERSION(5,1,6))
1334 ndbGetVersionString(file_version, 0, 0, verbuf,
sizeof(verbuf));
1336 "Unsupported version of LCP files found on disk, "
1337 " found: %s", verbuf);
1340 NDBD_EXIT_SR_RESTARTCONFLICT,