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,