00001 /* Copyright (C) 2003 MySQL AB 00002 00003 This program is free software; you can redistribute it and/or modify 00004 it under the terms of the GNU General Public License as published by 00005 the Free Software Foundation; either version 2 of the License, or 00006 (at your option) any later version. 00007 00008 This program is distributed in the hope that it will be useful, 00009 but WITHOUT ANY WARRANTY; without even the implied warranty of 00010 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00011 GNU General Public License for more details. 00012 00013 You should have received a copy of the GNU General Public License 00014 along with this program; if not, write to the Free Software 00015 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ 00016 00017 #include <ndb_global.h> 00018 #include <my_sys.h> 00019 00020 #define DBDICT_C 00021 #include "Dbdict.hpp" 00022 00023 #include <ndb_limits.h> 00024 #include <NdbOut.hpp> 00025 #include <Properties.hpp> 00026 #include <Configuration.hpp> 00027 #include <SectionReader.hpp> 00028 #include <SimpleProperties.hpp> 00029 #include <AttributeHeader.hpp> 00030 #include <KeyDescriptor.hpp> 00031 #include <signaldata/DictSchemaInfo.hpp> 00032 #include <signaldata/DictTabInfo.hpp> 00033 #include <signaldata/DropTabFile.hpp> 00034 00035 #include <signaldata/EventReport.hpp> 00036 #include <signaldata/FsCloseReq.hpp> 00037 #include <signaldata/FsConf.hpp> 00038 #include <signaldata/FsOpenReq.hpp> 00039 #include <signaldata/FsReadWriteReq.hpp> 00040 #include <signaldata/FsRef.hpp> 00041 #include <signaldata/GetTabInfo.hpp> 00042 #include <signaldata/GetTableId.hpp> 00043 #include <signaldata/HotSpareRep.hpp> 00044 #include <signaldata/NFCompleteRep.hpp> 00045 #include <signaldata/NodeFailRep.hpp> 00046 #include <signaldata/ReadNodesConf.hpp> 00047 #include <signaldata/RelTabMem.hpp> 00048 #include <signaldata/WaitGCP.hpp> 00049 #include <signaldata/ListTables.hpp> 00050 00051 #include <signaldata/CreateTrig.hpp> 00052 #include <signaldata/AlterTrig.hpp> 00053 #include <signaldata/DropTrig.hpp> 00054 #include <signaldata/CreateIndx.hpp> 00055 #include <signaldata/DropIndx.hpp> 00056 #include <signaldata/BuildIndx.hpp> 00057 00058 #include <signaldata/DropFilegroup.hpp> 00059 #include <signaldata/CreateFilegroup.hpp> 00060 #include <signaldata/CreateFilegroupImpl.hpp> 00061 00062 #include <signaldata/CreateEvnt.hpp> 00063 #include <signaldata/UtilPrepare.hpp> 00064 #include <signaldata/UtilExecute.hpp> 00065 #include <signaldata/UtilRelease.hpp> 00066 #include <signaldata/SumaImpl.hpp> 00067 00068 #include <signaldata/LqhFrag.hpp> 00069 00070 #include <signaldata/DiAddTab.hpp> 00071 #include <signaldata/DihStartTab.hpp> 00072 00073 #include <signaldata/DropTable.hpp> 00074 #include <signaldata/DropTab.hpp> 00075 #include <signaldata/PrepDropTab.hpp> 00076 00077 #include <signaldata/CreateTable.hpp> 00078 #include <signaldata/AlterTable.hpp> 00079 #include <signaldata/AlterTab.hpp> 00080 #include <signaldata/CreateFragmentation.hpp> 00081 #include <signaldata/CreateTab.hpp> 00082 #include <NdbSleep.h> 00083 #include <signaldata/ApiBroadcast.hpp> 00084 00085 #include <signaldata/DropObj.hpp> 00086 #include <signaldata/CreateObj.hpp> 00087 #include <SLList.hpp> 00088 00089 #define ZNOT_FOUND 626 00090 #define ZALREADYEXIST 630 00091 00092 //#define EVENT_PH2_DEBUG 00093 //#define EVENT_PH3_DEBUG 00094 //#define EVENT_DEBUG 00095 00096 static const char EVENT_SYSTEM_TABLE_NAME[] = "sys/def/NDB$EVENTS_0"; 00097 00098 #define EVENT_TRACE \ 00099 // ndbout_c("Event debug trace: File: %s Line: %u", __FILE__, __LINE__) 00100 00101 #define DIV(x,y) (((x)+(y)-1)/(y)) 00102 #define WORDS2PAGES(x) DIV(x, (ZSIZE_OF_PAGES_IN_WORDS - ZPAGE_HEADER_SIZE)) 00103 #include <ndb_version.h> 00104 00105 static 00106 struct { 00107 Uint32 m_gsn_user_req; 00108 Uint32 m_gsn_req; 00109 Uint32 m_gsn_ref; 00110 Uint32 m_gsn_conf; 00111 void (Dbdict::* m_trans_commit_start)(Signal*, Dbdict::SchemaTransaction*); 00112 void (Dbdict::* m_trans_commit_complete)(Signal*,Dbdict::SchemaTransaction*); 00113 void (Dbdict::* m_trans_abort_start)(Signal*, Dbdict::SchemaTransaction*); 00114 void (Dbdict::* m_trans_abort_complete)(Signal*, Dbdict::SchemaTransaction*); 00115 00116 void (Dbdict::* m_prepare_start)(Signal*, Dbdict::SchemaOp*); 00117 void (Dbdict::* m_prepare_complete)(Signal*, Dbdict::SchemaOp*); 00118 void (Dbdict::* m_commit)(Signal*, Dbdict::SchemaOp*); 00119 void (Dbdict::* m_commit_start)(Signal*, Dbdict::SchemaOp*); 00120 void (Dbdict::* m_commit_complete)(Signal*, Dbdict::SchemaOp*); 00121 void (Dbdict::* m_abort)(Signal*, Dbdict::SchemaOp*); 00122 void (Dbdict::* m_abort_start)(Signal*, Dbdict::SchemaOp*); 00123 void (Dbdict::* m_abort_complete)(Signal*, Dbdict::SchemaOp*); 00124 00125 } f_dict_op[] = { 00129 { 00130 GSN_CREATE_FILEGROUP_REQ, 00131 GSN_CREATE_OBJ_REQ, GSN_CREATE_OBJ_REF, GSN_CREATE_OBJ_CONF, 00132 0, 0, 0, 0, 00133 &Dbdict::create_fg_prepare_start, &Dbdict::create_fg_prepare_complete, 00134 &Dbdict::createObj_commit, 00135 0, 0, 00136 &Dbdict::createObj_abort, 00137 &Dbdict::create_fg_abort_start, &Dbdict::create_fg_abort_complete, 00138 } 00139 00143 ,{ 00144 GSN_CREATE_FILE_REQ, 00145 GSN_CREATE_OBJ_REQ, GSN_CREATE_OBJ_REF, GSN_CREATE_OBJ_CONF, 00146 0, 0, 0, 0, 00147 &Dbdict::create_file_prepare_start, &Dbdict::create_file_prepare_complete, 00148 &Dbdict::createObj_commit, 00149 &Dbdict::create_file_commit_start, 0, 00150 &Dbdict::createObj_abort, 00151 &Dbdict::create_file_abort_start, &Dbdict::create_file_abort_complete, 00152 } 00153 00157 ,{ 00158 GSN_DROP_FILE_REQ, 00159 GSN_DROP_OBJ_REQ, GSN_DROP_OBJ_REF, GSN_DROP_OBJ_CONF, 00160 0, 0, 0, 0, 00161 &Dbdict::drop_file_prepare_start, 0, 00162 &Dbdict::dropObj_commit, 00163 &Dbdict::drop_file_commit_start, &Dbdict::drop_file_commit_complete, 00164 &Dbdict::dropObj_abort, 00165 &Dbdict::drop_file_abort_start, 0 00166 } 00167 00171 ,{ 00172 GSN_DROP_FILEGROUP_REQ, 00173 GSN_DROP_OBJ_REQ, GSN_DROP_OBJ_REF, GSN_DROP_OBJ_CONF, 00174 0, 0, 0, 0, 00175 &Dbdict::drop_fg_prepare_start, 0, 00176 &Dbdict::dropObj_commit, 00177 &Dbdict::drop_fg_commit_start, &Dbdict::drop_fg_commit_complete, 00178 &Dbdict::dropObj_abort, 00179 &Dbdict::drop_fg_abort_start, 0 00180 } 00181 00185 ,{ 00186 GSN_DROP_FILE_REQ, 00187 GSN_DROP_OBJ_REQ, GSN_DROP_OBJ_REF, GSN_DROP_OBJ_CONF, 00188 0, 0, 0, 0, 00189 &Dbdict::drop_undofile_prepare_start, 0, 00190 0, 00191 0, 0, 00192 0, 0 00193 } 00194 }; 00195 00196 Uint32 00197 alter_obj_inc_schema_version(Uint32 old) 00198 { 00199 return (old & 0x00FFFFFF) + ((old + 0x1000000) & 0xFF000000); 00200 } 00201 00202 static 00203 Uint32 00204 alter_obj_dec_schema_version(Uint32 old) 00205 { 00206 return (old & 0x00FFFFFF) + ((old - 0x1000000) & 0xFF000000); 00207 } 00208 00209 static 00210 Uint32 00211 create_obj_inc_schema_version(Uint32 old) 00212 { 00213 return (old + 0x00000001) & 0x00FFFFFF; 00214 } 00215 00216 /* **************************************************************** */ 00217 /* ---------------------------------------------------------------- */ 00218 /* MODULE: GENERAL MODULE -------------------------------- */ 00219 /* ---------------------------------------------------------------- */ 00220 /* */ 00221 /* This module contains general stuff. Mostly debug signals and */ 00222 /* general signals that go into a specific module after checking a */ 00223 /* state variable. Also general subroutines used by many. */ 00224 /* ---------------------------------------------------------------- */ 00225 /* **************************************************************** */ 00226 00227 /* ---------------------------------------------------------------- */ 00228 // This signal is used to dump states of various variables in the 00229 // block by command. 00230 /* ---------------------------------------------------------------- */ 00231 void 00232 Dbdict::execDUMP_STATE_ORD(Signal* signal) 00233 { 00234 jamEntry(); 00235 00236 #ifdef VM_TRACE 00237 if(signal->theData[0] == 1222){ 00238 const Uint32 tab = signal->theData[1]; 00239 PrepDropTabReq* req = (PrepDropTabReq*)signal->getDataPtr(); 00240 req->senderRef = reference(); 00241 req->senderData = 1222; 00242 req->tableId = tab; 00243 sendSignal(DBLQH_REF, GSN_PREP_DROP_TAB_REQ, signal, 00244 PrepDropTabReq::SignalLength, JBB); 00245 } 00246 00247 if(signal->theData[0] == 1223){ 00248 const Uint32 tab = signal->theData[1]; 00249 PrepDropTabReq* req = (PrepDropTabReq*)signal->getDataPtr(); 00250 req->senderRef = reference(); 00251 req->senderData = 1222; 00252 req->tableId = tab; 00253 sendSignal(DBTC_REF, GSN_PREP_DROP_TAB_REQ, signal, 00254 PrepDropTabReq::SignalLength, JBB); 00255 } 00256 00257 if(signal->theData[0] == 1224){ 00258 const Uint32 tab = signal->theData[1]; 00259 PrepDropTabReq* req = (PrepDropTabReq*)signal->getDataPtr(); 00260 req->senderRef = reference(); 00261 req->senderData = 1222; 00262 req->tableId = tab; 00263 sendSignal(DBDIH_REF, GSN_PREP_DROP_TAB_REQ, signal, 00264 PrepDropTabReq::SignalLength, JBB); 00265 } 00266 00267 if(signal->theData[0] == 1225){ 00268 const Uint32 tab = signal->theData[1]; 00269 const Uint32 ver = signal->theData[2]; 00270 TableRecordPtr tabRecPtr; 00271 c_tableRecordPool.getPtr(tabRecPtr, tab); 00272 DropTableReq * req = (DropTableReq*)signal->getDataPtr(); 00273 req->senderData = 1225; 00274 req->senderRef = numberToRef(1,1); 00275 req->tableId = tab; 00276 req->tableVersion = tabRecPtr.p->tableVersion + ver; 00277 sendSignal(DBDICT_REF, GSN_DROP_TABLE_REQ, signal, 00278 DropTableReq::SignalLength, JBB); 00279 } 00280 #endif 00281 #define MEMINFO(x, y) infoEvent(x ": %d %d", y.getSize(), y.getNoOfFree()) 00282 if(signal->theData[0] == 1226){ 00283 MEMINFO("c_obj_pool", c_obj_pool); 00284 MEMINFO("c_opRecordPool", c_opRecordPool); 00285 MEMINFO("c_rope_pool", c_rope_pool); 00286 } 00287 00288 if (signal->theData[0] == 1227) 00289 { 00290 DLHashTable<DictObject>::Iterator iter; 00291 bool ok = c_obj_hash.first(iter); 00292 for(; ok; ok = c_obj_hash.next(iter)) 00293 { 00294 Rope name(c_rope_pool, iter.curr.p->m_name); 00295 const Uint32 size = name.size(); 00296 char buf[1024]; 00297 name.copy(buf); 00298 ndbout_c("%s m_ref_count: %d", buf, iter.curr.p->m_ref_count); 00299 } 00300 } 00301 00302 return; 00303 }//Dbdict::execDUMP_STATE_ORD() 00304 00305 /* ---------------------------------------------------------------- */ 00306 /* ---------------------------------------------------------------- */ 00307 // CONTINUEB is used when a real-time break is needed for long 00308 // processes. 00309 /* ---------------------------------------------------------------- */ 00310 /* ---------------------------------------------------------------- */ 00311 void Dbdict::execCONTINUEB(Signal* signal) 00312 { 00313 jamEntry(); 00314 switch (signal->theData[0]) { 00315 case ZPACK_TABLE_INTO_PAGES : 00316 jam(); 00317 packTableIntoPages(signal); 00318 break; 00319 00320 case ZSEND_GET_TAB_RESPONSE : 00321 jam(); 00322 sendGetTabResponse(signal); 00323 break; 00324 00325 case ZDICT_LOCK_POLL: 00326 jam(); 00327 checkDictLockQueue(signal, true); 00328 break; 00329 00330 default : 00331 ndbrequire(false); 00332 break; 00333 }//switch 00334 return; 00335 }//execCONTINUEB() 00336 00337 /* ---------------------------------------------------------------- */ 00338 /* ---------------------------------------------------------------- */ 00339 // Routine to handle pack table into pages. 00340 /* ---------------------------------------------------------------- */ 00341 /* ---------------------------------------------------------------- */ 00342 00343 void Dbdict::packTableIntoPages(Signal* signal) 00344 { 00345 const Uint32 tableId= signal->theData[1]; 00346 const Uint32 type= signal->theData[2]; 00347 const Uint32 pageId= signal->theData[3]; 00348 00349 PageRecordPtr pagePtr; 00350 c_pageRecordArray.getPtr(pagePtr, pageId); 00351 00352 memset(&pagePtr.p->word[0], 0, 4 * ZPAGE_HEADER_SIZE); 00353 LinearWriter w(&pagePtr.p->word[ZPAGE_HEADER_SIZE], 00354 ZMAX_PAGES_OF_TABLE_DEFINITION * ZSIZE_OF_PAGES_IN_WORDS); 00355 w.first(); 00356 switch((DictTabInfo::TableType)type) { 00357 case DictTabInfo::SystemTable: 00358 case DictTabInfo::UserTable: 00359 case DictTabInfo::UniqueHashIndex: 00360 case DictTabInfo::HashIndex: 00361 case DictTabInfo::UniqueOrderedIndex: 00362 case DictTabInfo::OrderedIndex:{ 00363 jam(); 00364 TableRecordPtr tablePtr; 00365 c_tableRecordPool.getPtr(tablePtr, tableId); 00366 packTableIntoPages(w, tablePtr, signal); 00367 break; 00368 } 00369 case DictTabInfo::Tablespace: 00370 case DictTabInfo::LogfileGroup:{ 00371 FilegroupPtr fg_ptr; 00372 ndbrequire(c_filegroup_hash.find(fg_ptr, tableId)); 00373 const Uint32 free_hi= signal->theData[4]; 00374 const Uint32 free_lo= signal->theData[5]; 00375 packFilegroupIntoPages(w, fg_ptr, free_hi, free_lo); 00376 break; 00377 } 00378 case DictTabInfo::Datafile:{ 00379 FilePtr fg_ptr; 00380 ndbrequire(c_file_hash.find(fg_ptr, tableId)); 00381 const Uint32 free_extents= signal->theData[4]; 00382 packFileIntoPages(w, fg_ptr, free_extents); 00383 break; 00384 } 00385 case DictTabInfo::Undofile:{ 00386 FilePtr fg_ptr; 00387 ndbrequire(c_file_hash.find(fg_ptr, tableId)); 00388 packFileIntoPages(w, fg_ptr, 0); 00389 break; 00390 } 00391 case DictTabInfo::UndefTableType: 00392 case DictTabInfo::HashIndexTrigger: 00393 case DictTabInfo::SubscriptionTrigger: 00394 case DictTabInfo::ReadOnlyConstraint: 00395 case DictTabInfo::IndexTrigger: 00396 ndbrequire(false); 00397 } 00398 00399 Uint32 wordsOfTable = w.getWordsUsed(); 00400 Uint32 pagesUsed = WORDS2PAGES(wordsOfTable); 00401 pagePtr.p->word[ZPOS_CHECKSUM] = 00402 computeChecksum(&pagePtr.p->word[0], pagesUsed * ZSIZE_OF_PAGES_IN_WORDS); 00403 00404 switch (c_packTable.m_state) { 00405 case PackTable::PTS_IDLE: 00406 ndbrequire(false); 00407 break; 00408 case PackTable::PTS_GET_TAB: 00409 jam(); 00410 c_retrieveRecord.retrievedNoOfPages = pagesUsed; 00411 c_retrieveRecord.retrievedNoOfWords = wordsOfTable; 00412 sendGetTabResponse(signal); 00413 return; 00414 break; 00415 }//switch 00416 ndbrequire(false); 00417 return; 00418 }//packTableIntoPages() 00419 00420 void 00421 Dbdict::packTableIntoPages(SimpleProperties::Writer & w, 00422 TableRecordPtr tablePtr, 00423 Signal* signal){ 00424 00425 union { 00426 char tableName[MAX_TAB_NAME_SIZE]; 00427 char frmData[MAX_FRM_DATA_SIZE]; 00428 char rangeData[16*MAX_NDB_PARTITIONS]; 00429 char ngData[2*MAX_NDB_PARTITIONS]; 00430 char tsData[2*2*MAX_NDB_PARTITIONS]; 00431 char defaultValue[MAX_ATTR_DEFAULT_VALUE_SIZE]; 00432 char attributeName[MAX_ATTR_NAME_SIZE]; 00433 }; 00434 ConstRope r(c_rope_pool, tablePtr.p->tableName); 00435 r.copy(tableName); 00436 w.add(DictTabInfo::TableName, tableName); 00437 w.add(DictTabInfo::TableId, tablePtr.i); 00438 w.add(DictTabInfo::TableVersion, tablePtr.p->tableVersion); 00439 w.add(DictTabInfo::NoOfKeyAttr, tablePtr.p->noOfPrimkey); 00440 w.add(DictTabInfo::NoOfAttributes, tablePtr.p->noOfAttributes); 00441 w.add(DictTabInfo::NoOfNullable, tablePtr.p->noOfNullAttr); 00442 w.add(DictTabInfo::NoOfVariable, (Uint32)0); 00443 w.add(DictTabInfo::KeyLength, tablePtr.p->tupKeyLength); 00444 00445 w.add(DictTabInfo::TableLoggedFlag, 00446 !!(tablePtr.p->m_bits & TableRecord::TR_Logged)); 00447 w.add(DictTabInfo::RowGCIFlag, 00448 !!(tablePtr.p->m_bits & TableRecord::TR_RowGCI)); 00449 w.add(DictTabInfo::RowChecksumFlag, 00450 !!(tablePtr.p->m_bits & TableRecord::TR_RowChecksum)); 00451 00452 w.add(DictTabInfo::MinLoadFactor, tablePtr.p->minLoadFactor); 00453 w.add(DictTabInfo::MaxLoadFactor, tablePtr.p->maxLoadFactor); 00454 w.add(DictTabInfo::TableKValue, tablePtr.p->kValue); 00455 w.add(DictTabInfo::FragmentTypeVal, tablePtr.p->fragmentType); 00456 w.add(DictTabInfo::TableTypeVal, tablePtr.p->tableType); 00457 w.add(DictTabInfo::MaxRowsLow, tablePtr.p->maxRowsLow); 00458 w.add(DictTabInfo::MaxRowsHigh, tablePtr.p->maxRowsHigh); 00459 w.add(DictTabInfo::DefaultNoPartFlag, tablePtr.p->defaultNoPartFlag); 00460 w.add(DictTabInfo::LinearHashFlag, tablePtr.p->linearHashFlag); 00461 w.add(DictTabInfo::FragmentCount, tablePtr.p->fragmentCount); 00462 w.add(DictTabInfo::MinRowsLow, tablePtr.p->minRowsLow); 00463 w.add(DictTabInfo::MinRowsHigh, tablePtr.p->minRowsHigh); 00464 00465 if(signal) 00466 { 00467 /* Denna branch körs vid GET_TABINFOREQ */ 00468 00469 Uint32 * theData = signal->getDataPtrSend(); 00470 CreateFragmentationReq * const req = (CreateFragmentationReq*)theData; 00471 req->senderRef = 0; 00472 req->senderData = RNIL; 00473 req->fragmentationType = tablePtr.p->fragmentType; 00474 req->noOfFragments = 0; 00475 req->primaryTableId = tablePtr.i; 00476 EXECUTE_DIRECT(DBDIH, GSN_CREATE_FRAGMENTATION_REQ, signal, 00477 CreateFragmentationReq::SignalLength); 00478 ndbrequire(signal->theData[0] == 0); 00479 Uint16 *data = (Uint16*)&signal->theData[25]; 00480 Uint32 count = 2 + data[0] * data[1]; 00481 w.add(DictTabInfo::ReplicaDataLen, 2*count); 00482 for (Uint32 i = 0; i < count; i++) 00483 data[i] = htons(data[i]); 00484 w.add(DictTabInfo::ReplicaData, data, 2*count); 00485 } 00486 else 00487 { 00488 /* Denna del körs vid CREATE_TABLEREQ, ALTER_TABLEREQ */ 00489 ; 00490 } 00491 00492 if (tablePtr.p->primaryTableId != RNIL){ 00493 TableRecordPtr primTab; 00494 c_tableRecordPool.getPtr(primTab, tablePtr.p->primaryTableId); 00495 ConstRope r2(c_rope_pool, primTab.p->tableName); 00496 r2.copy(tableName); 00497 w.add(DictTabInfo::PrimaryTable, tableName); 00498 w.add(DictTabInfo::PrimaryTableId, tablePtr.p->primaryTableId); 00499 w.add(DictTabInfo::IndexState, tablePtr.p->indexState); 00500 w.add(DictTabInfo::InsertTriggerId, tablePtr.p->insertTriggerId); 00501 w.add(DictTabInfo::UpdateTriggerId, tablePtr.p->updateTriggerId); 00502 w.add(DictTabInfo::DeleteTriggerId, tablePtr.p->deleteTriggerId); 00503 w.add(DictTabInfo::CustomTriggerId, tablePtr.p->customTriggerId); 00504 } 00505 00506 ConstRope frm(c_rope_pool, tablePtr.p->frmData); 00507 frm.copy(frmData); 00508 w.add(DictTabInfo::FrmLen, frm.size()); 00509 w.add(DictTabInfo::FrmData, frmData, frm.size()); 00510 00511 { 00512 jam(); 00513 ConstRope ts(c_rope_pool, tablePtr.p->tsData); 00514 ts.copy(tsData); 00515 w.add(DictTabInfo::TablespaceDataLen, ts.size()); 00516 w.add(DictTabInfo::TablespaceData, tsData, ts.size()); 00517 00518 ConstRope ng(c_rope_pool, tablePtr.p->ngData); 00519 ng.copy(ngData); 00520 w.add(DictTabInfo::FragmentDataLen, ng.size()); 00521 w.add(DictTabInfo::FragmentData, ngData, ng.size()); 00522 00523 ConstRope range(c_rope_pool, tablePtr.p->rangeData); 00524 range.copy(rangeData); 00525 w.add(DictTabInfo::RangeListDataLen, range.size()); 00526 w.add(DictTabInfo::RangeListData, rangeData, range.size()); 00527 } 00528 00529 if(tablePtr.p->m_tablespace_id != RNIL) 00530 { 00531 w.add(DictTabInfo::TablespaceId, tablePtr.p->m_tablespace_id); 00532 FilegroupPtr tsPtr; 00533 ndbrequire(c_filegroup_hash.find(tsPtr, tablePtr.p->m_tablespace_id)); 00534 w.add(DictTabInfo::TablespaceVersion, tsPtr.p->m_version); 00535 } 00536 00537 AttributeRecordPtr attrPtr; 00538 LocalDLFifoList<AttributeRecord> list(c_attributeRecordPool, 00539 tablePtr.p->m_attributes); 00540 for(list.first(attrPtr); !attrPtr.isNull(); list.next(attrPtr)){ 00541 jam(); 00542 00543 ConstRope name(c_rope_pool, attrPtr.p->attributeName); 00544 name.copy(attributeName); 00545 00546 w.add(DictTabInfo::AttributeName, attributeName); 00547 w.add(DictTabInfo::AttributeId, attrPtr.p->attributeId); 00548 w.add(DictTabInfo::AttributeKeyFlag, attrPtr.p->tupleKey > 0); 00549 00550 const Uint32 desc = attrPtr.p->attributeDescriptor; 00551 const Uint32 attrType = AttributeDescriptor::getType(desc); 00552 const Uint32 attrSize = AttributeDescriptor::getSize(desc); 00553 const Uint32 arraySize = AttributeDescriptor::getArraySize(desc); 00554 const Uint32 arrayType = AttributeDescriptor::getArrayType(desc); 00555 const Uint32 nullable = AttributeDescriptor::getNullable(desc); 00556 const Uint32 DKey = AttributeDescriptor::getDKey(desc); 00557 const Uint32 disk= AttributeDescriptor::getDiskBased(desc); 00558 00559 00560 // AttributeType deprecated 00561 w.add(DictTabInfo::AttributeSize, attrSize); 00562 w.add(DictTabInfo::AttributeArraySize, arraySize); 00563 w.add(DictTabInfo::AttributeArrayType, arrayType); 00564 w.add(DictTabInfo::AttributeNullableFlag, nullable); 00565 w.add(DictTabInfo::AttributeDKey, DKey); 00566 w.add(DictTabInfo::AttributeExtType, attrType); 00567 w.add(DictTabInfo::AttributeExtPrecision, attrPtr.p->extPrecision); 00568 w.add(DictTabInfo::AttributeExtScale, attrPtr.p->extScale); 00569 w.add(DictTabInfo::AttributeExtLength, attrPtr.p->extLength); 00570 w.add(DictTabInfo::AttributeAutoIncrement, 00571 (Uint32)attrPtr.p->autoIncrement); 00572 00573 if(disk) 00574 w.add(DictTabInfo::AttributeStorageType, (Uint32)NDB_STORAGETYPE_DISK); 00575 else 00576 w.add(DictTabInfo::AttributeStorageType, (Uint32)NDB_STORAGETYPE_MEMORY); 00577 00578 ConstRope def(c_rope_pool, attrPtr.p->defaultValue); 00579 def.copy(defaultValue); 00580 w.add(DictTabInfo::AttributeDefaultValue, defaultValue); 00581 00582 w.add(DictTabInfo::AttributeEnd, 1); 00583 } 00584 00585 w.add(DictTabInfo::TableEnd, 1); 00586 } 00587 00588 void 00589 Dbdict::packFilegroupIntoPages(SimpleProperties::Writer & w, 00590 FilegroupPtr fg_ptr, 00591 const Uint32 undo_free_hi, 00592 const Uint32 undo_free_lo){ 00593 00594 DictFilegroupInfo::Filegroup fg; fg.init(); 00595 ConstRope r(c_rope_pool, fg_ptr.p->m_name); 00596 r.copy(fg.FilegroupName); 00597 00598 fg.FilegroupId = fg_ptr.p->key; 00599 fg.FilegroupType = fg_ptr.p->m_type; 00600 fg.FilegroupVersion = fg_ptr.p->m_version; 00601 00602 switch(fg.FilegroupType){ 00603 case DictTabInfo::Tablespace: 00604 //fg.TS_DataGrow = group.m_grow_spec; 00605 fg.TS_ExtentSize = fg_ptr.p->m_tablespace.m_extent_size; 00606 fg.TS_LogfileGroupId = fg_ptr.p->m_tablespace.m_default_logfile_group_id; 00607 FilegroupPtr lfg_ptr; 00608 ndbrequire(c_filegroup_hash.find(lfg_ptr, fg.TS_LogfileGroupId)); 00609 fg.TS_LogfileGroupVersion = lfg_ptr.p->m_version; 00610 break; 00611 case DictTabInfo::LogfileGroup: 00612 fg.LF_UndoBufferSize = fg_ptr.p->m_logfilegroup.m_undo_buffer_size; 00613 fg.LF_UndoFreeWordsHi= undo_free_hi; 00614 fg.LF_UndoFreeWordsLo= undo_free_lo; 00615 //fg.LF_UndoGrow = ; 00616 break; 00617 default: 00618 ndbrequire(false); 00619 } 00620 00621 SimpleProperties::UnpackStatus s; 00622 s = SimpleProperties::pack(w, 00623 &fg, 00624 DictFilegroupInfo::Mapping, 00625 DictFilegroupInfo::MappingSize, true); 00626 00627 ndbrequire(s == SimpleProperties::Eof); 00628 } 00629 00630 void 00631 Dbdict::packFileIntoPages(SimpleProperties::Writer & w, 00632 FilePtr f_ptr, const Uint32 free_extents){ 00633 00634 DictFilegroupInfo::File f; f.init(); 00635 ConstRope r(c_rope_pool, f_ptr.p->m_path); 00636 r.copy(f.FileName); 00637 00638 f.FileType = f_ptr.p->m_type; 00639 f.FilegroupId = f_ptr.p->m_filegroup_id;; //group.m_id; 00640 f.FileSizeHi = (f_ptr.p->m_file_size >> 32); 00641 f.FileSizeLo = (f_ptr.p->m_file_size & 0xFFFFFFFF); 00642 f.FileFreeExtents= free_extents; 00643 f.FileId = f_ptr.p->key; 00644 f.FileVersion = f_ptr.p->m_version; 00645 00646 FilegroupPtr lfg_ptr; 00647 ndbrequire(c_filegroup_hash.find(lfg_ptr, f.FilegroupId)); 00648 f.FilegroupVersion = lfg_ptr.p->m_version; 00649 00650 SimpleProperties::UnpackStatus s; 00651 s = SimpleProperties::pack(w, 00652 &f, 00653 DictFilegroupInfo::FileMapping, 00654 DictFilegroupInfo::FileMappingSize, true); 00655 00656 ndbrequire(s == SimpleProperties::Eof); 00657 } 00658 00659 /* ---------------------------------------------------------------- */ 00660 /* ---------------------------------------------------------------- */ 00661 // The routines to handle responses from file system. 00662 /* ---------------------------------------------------------------- */ 00663 /* ---------------------------------------------------------------- */ 00664 00665 /* ---------------------------------------------------------------- */ 00666 // A file was successfully closed. 00667 /* ---------------------------------------------------------------- */ 00668 void Dbdict::execFSCLOSECONF(Signal* signal) 00669 { 00670 FsConnectRecordPtr fsPtr; 00671 FsConf * const fsConf = (FsConf *)&signal->theData[0]; 00672 jamEntry(); 00673 c_fsConnectRecordPool.getPtr(fsPtr, fsConf->userPointer); 00674 switch (fsPtr.p->fsState) { 00675 case FsConnectRecord::CLOSE_WRITE_SCHEMA: 00676 jam(); 00677 closeWriteSchemaConf(signal, fsPtr); 00678 break; 00679 case FsConnectRecord::CLOSE_READ_SCHEMA: 00680 jam(); 00681 closeReadSchemaConf(signal, fsPtr); 00682 break; 00683 case FsConnectRecord::CLOSE_READ_TAB_FILE: 00684 jam(); 00685 closeReadTableConf(signal, fsPtr); 00686 break; 00687 case FsConnectRecord::CLOSE_WRITE_TAB_FILE: 00688 jam(); 00689 closeWriteTableConf(signal, fsPtr); 00690 break; 00691 case FsConnectRecord::OPEN_READ_SCHEMA2: 00692 openSchemaFile(signal, 1, fsPtr.i, false, false); 00693 break; 00694 default: 00695 jamLine((fsPtr.p->fsState & 0xFFF)); 00696 ndbrequire(false); 00697 break; 00698 }//switch 00699 }//execFSCLOSECONF() 00700 00701 00702 /* ---------------------------------------------------------------- */ 00703 // A file was successfully opened. 00704 /* ---------------------------------------------------------------- */ 00705 void Dbdict::execFSOPENCONF(Signal* signal) 00706 { 00707 FsConnectRecordPtr fsPtr; 00708 jamEntry(); 00709 FsConf * const fsConf = (FsConf *)&signal->theData[0]; 00710 c_fsConnectRecordPool.getPtr(fsPtr, fsConf->userPointer); 00711 00712 Uint32 filePointer = fsConf->filePointer; 00713 fsPtr.p->filePtr = filePointer; 00714 switch (fsPtr.p->fsState) { 00715 case FsConnectRecord::OPEN_WRITE_SCHEMA: 00716 jam(); 00717 fsPtr.p->fsState = FsConnectRecord::WRITE_SCHEMA; 00718 writeSchemaFile(signal, filePointer, fsPtr.i); 00719 break; 00720 case FsConnectRecord::OPEN_READ_SCHEMA1: 00721 jam(); 00722 fsPtr.p->fsState = FsConnectRecord::READ_SCHEMA1; 00723 readSchemaFile(signal, filePointer, fsPtr.i); 00724 break; 00725 case FsConnectRecord::OPEN_READ_SCHEMA2: 00726 jam(); 00727 fsPtr.p->fsState = FsConnectRecord::READ_SCHEMA2; 00728 readSchemaFile(signal, filePointer, fsPtr.i); 00729 break; 00730 case FsConnectRecord::OPEN_READ_TAB_FILE1: 00731 jam(); 00732 fsPtr.p->fsState = FsConnectRecord::READ_TAB_FILE1; 00733 readTableFile(signal, filePointer, fsPtr.i); 00734 break; 00735 case FsConnectRecord::OPEN_READ_TAB_FILE2: 00736 jam(); 00737 fsPtr.p->fsState = FsConnectRecord::READ_TAB_FILE2; 00738 readTableFile(signal, filePointer, fsPtr.i); 00739 break; 00740 case FsConnectRecord::OPEN_WRITE_TAB_FILE: 00741 jam(); 00742 fsPtr.p->fsState = FsConnectRecord::WRITE_TAB_FILE; 00743 writeTableFile(signal, filePointer, fsPtr.i); 00744 break; 00745 default: 00746 jamLine((fsPtr.p->fsState & 0xFFF)); 00747 ndbrequire(false); 00748 break; 00749 }//switch 00750 }//execFSOPENCONF() 00751 00752 /* ---------------------------------------------------------------- */ 00753 // An open file was refused. 00754 /* ---------------------------------------------------------------- */ 00755 void Dbdict::execFSOPENREF(Signal* signal) 00756 { 00757 jamEntry(); 00758 FsRef * const fsRef = (FsRef *)&signal->theData[0]; 00759 FsConnectRecordPtr fsPtr; 00760 c_fsConnectRecordPool.getPtr(fsPtr, fsRef->userPointer); 00761 switch (fsPtr.p->fsState) { 00762 case FsConnectRecord::OPEN_READ_SCHEMA1: 00763 jam(); 00764 openReadSchemaRef(signal, fsPtr); 00765 return; 00766 case FsConnectRecord::OPEN_READ_TAB_FILE1: 00767 jam(); 00768 openReadTableRef(signal, fsPtr); 00769 return; 00770 default: 00771 break; 00772 }//switch 00773 { 00774 char msg[100]; 00775 sprintf(msg, "File system open failed during FsConnectRecord state %d", (Uint32)fsPtr.p->fsState); 00776 fsRefError(signal,__LINE__,msg); 00777 } 00778 }//execFSOPENREF() 00779 00780 /* ---------------------------------------------------------------- */ 00781 // A file was successfully read. 00782 /* ---------------------------------------------------------------- */ 00783 void Dbdict::execFSREADCONF(Signal* signal) 00784 { 00785 jamEntry(); 00786 FsConf * const fsConf = (FsConf *)&signal->theData[0]; 00787 FsConnectRecordPtr fsPtr; 00788 c_fsConnectRecordPool.getPtr(fsPtr, fsConf->userPointer); 00789 switch (fsPtr.p->fsState) { 00790 case FsConnectRecord::READ_SCHEMA1: 00791 case FsConnectRecord::READ_SCHEMA2: 00792 readSchemaConf(signal ,fsPtr); 00793 break; 00794 case FsConnectRecord::READ_TAB_FILE1: 00795 case FsConnectRecord::READ_TAB_FILE2: 00796 jam(); 00797 readTableConf(signal ,fsPtr); 00798 break; 00799 default: 00800 jamLine((fsPtr.p->fsState & 0xFFF)); 00801 ndbrequire(false); 00802 break; 00803 }//switch 00804 }//execFSREADCONF() 00805 00806 /* ---------------------------------------------------------------- */ 00807 // A read file was refused. 00808 /* ---------------------------------------------------------------- */ 00809 void Dbdict::execFSREADREF(Signal* signal) 00810 { 00811 jamEntry(); 00812 FsRef * const fsRef = (FsRef *)&signal->theData[0]; 00813 FsConnectRecordPtr fsPtr; 00814 c_fsConnectRecordPool.getPtr(fsPtr, fsRef->userPointer); 00815 switch (fsPtr.p->fsState) { 00816 case FsConnectRecord::READ_SCHEMA1: 00817 jam(); 00818 readSchemaRef(signal, fsPtr); 00819 return; 00820 case FsConnectRecord::READ_TAB_FILE1: 00821 jam(); 00822 readTableRef(signal, fsPtr); 00823 return; 00824 default: 00825 break; 00826 }//switch 00827 { 00828 char msg[100]; 00829 sprintf(msg, "File system read failed during FsConnectRecord state %d", (Uint32)fsPtr.p->fsState); 00830 fsRefError(signal,__LINE__,msg); 00831 } 00832 }//execFSREADREF() 00833 00834 /* ---------------------------------------------------------------- */ 00835 // A file was successfully written. 00836 /* ---------------------------------------------------------------- */ 00837 void Dbdict::execFSWRITECONF(Signal* signal) 00838 { 00839 FsConf * const fsConf = (FsConf *)&signal->theData[0]; 00840 FsConnectRecordPtr fsPtr; 00841 jamEntry(); 00842 c_fsConnectRecordPool.getPtr(fsPtr, fsConf->userPointer); 00843 switch (fsPtr.p->fsState) { 00844 case FsConnectRecord::WRITE_TAB_FILE: 00845 writeTableConf(signal, fsPtr); 00846 break; 00847 case FsConnectRecord::WRITE_SCHEMA: 00848 jam(); 00849 writeSchemaConf(signal, fsPtr); 00850 break; 00851 default: 00852 jamLine((fsPtr.p->fsState & 0xFFF)); 00853 ndbrequire(false); 00854 break; 00855 }//switch 00856 }//execFSWRITECONF() 00857 00858 00859 /* ---------------------------------------------------------------- */ 00860 // Routines to handle Read/Write of Table Files 00861 /* ---------------------------------------------------------------- */ 00862 void 00863 Dbdict::writeTableFile(Signal* signal, Uint32 tableId, 00864 SegmentedSectionPtr tabInfoPtr, Callback* callback){ 00865 00866 ndbrequire(c_writeTableRecord.tableWriteState == WriteTableRecord::IDLE); 00867 00868 Uint32 pages = WORDS2PAGES(tabInfoPtr.sz); 00869 c_writeTableRecord.no_of_words = tabInfoPtr.sz; 00870 c_writeTableRecord.tableWriteState = WriteTableRecord::TWR_CALLBACK; 00871 c_writeTableRecord.m_callback = * callback; 00872 00873 c_writeTableRecord.pageId = 0; 00874 ndbrequire(pages == 1); 00875 00876 PageRecordPtr pageRecPtr; 00877 c_pageRecordArray.getPtr(pageRecPtr, c_writeTableRecord.pageId); 00878 copy(&pageRecPtr.p->word[ZPAGE_HEADER_SIZE], tabInfoPtr); 00879 00880 memset(&pageRecPtr.p->word[0], 0, 4 * ZPAGE_HEADER_SIZE); 00881 pageRecPtr.p->word[ZPOS_CHECKSUM] = 00882 computeChecksum(&pageRecPtr.p->word[0], 00883 pages * ZSIZE_OF_PAGES_IN_WORDS); 00884 00885 startWriteTableFile(signal, tableId); 00886 } 00887 00888 void Dbdict::startWriteTableFile(Signal* signal, Uint32 tableId) 00889 { 00890 FsConnectRecordPtr fsPtr; 00891 c_writeTableRecord.tableId = tableId; 00892 c_fsConnectRecordPool.getPtr(fsPtr, getFsConnRecord()); 00893 fsPtr.p->fsState = FsConnectRecord::OPEN_WRITE_TAB_FILE; 00894 openTableFile(signal, 0, fsPtr.i, tableId, true); 00895 c_writeTableRecord.noOfTableFilesHandled = 0; 00896 }//Dbdict::startWriteTableFile() 00897 00898 void Dbdict::openTableFile(Signal* signal, 00899 Uint32 fileNo, 00900 Uint32 fsConPtr, 00901 Uint32 tableId, 00902 bool writeFlag) 00903 { 00904 FsOpenReq * const fsOpenReq = (FsOpenReq *)&signal->theData[0]; 00905 00906 fsOpenReq->userReference = reference(); 00907 fsOpenReq->userPointer = fsConPtr; 00908 if (writeFlag) { 00909 jam(); 00910 fsOpenReq->fileFlags = 00911 FsOpenReq::OM_WRITEONLY | 00912 FsOpenReq::OM_TRUNCATE | 00913 FsOpenReq::OM_CREATE | 00914 FsOpenReq::OM_SYNC; 00915 } else { 00916 jam(); 00917 fsOpenReq->fileFlags = FsOpenReq::OM_READONLY; 00918 }//if 00919 fsOpenReq->fileNumber[3] = 0; // Initialise before byte changes 00920 FsOpenReq::setVersion(fsOpenReq->fileNumber, 1); 00921 FsOpenReq::setSuffix(fsOpenReq->fileNumber, FsOpenReq::S_TABLELIST); 00922 FsOpenReq::v1_setDisk(fsOpenReq->fileNumber, (fileNo + 1)); 00923 FsOpenReq::v1_setTable(fsOpenReq->fileNumber, tableId); 00924 FsOpenReq::v1_setFragment(fsOpenReq->fileNumber, (Uint32)-1); 00925 FsOpenReq::v1_setS(fsOpenReq->fileNumber, 0); 00926 FsOpenReq::v1_setP(fsOpenReq->fileNumber, 255); 00927 /* ---------------------------------------------------------------- */ 00928 // File name : D1/DBDICT/T0/S1.TableList 00929 // D1 means Disk 1 (set by fileNo + 1) 00930 // T0 means table id = 0 00931 // S1 means tableVersion 1 00932 // TableList indicates that this is a file for a table description. 00933 /* ---------------------------------------------------------------- */ 00934 sendSignal(NDBFS_REF, GSN_FSOPENREQ, signal, FsOpenReq::SignalLength, JBA); 00935 }//openTableFile() 00936 00937 void Dbdict::writeTableFile(Signal* signal, Uint32 filePtr, Uint32 fsConPtr) 00938 { 00939 FsReadWriteReq * const fsRWReq = (FsReadWriteReq *)&signal->theData[0]; 00940 00941 fsRWReq->filePointer = filePtr; 00942 fsRWReq->userReference = reference(); 00943 fsRWReq->userPointer = fsConPtr; 00944 fsRWReq->operationFlag = 0; // Initialise before bit changes 00945 FsReadWriteReq::setSyncFlag(fsRWReq->operationFlag, 1); 00946 FsReadWriteReq::setFormatFlag(fsRWReq->operationFlag, 00947 FsReadWriteReq::fsFormatArrayOfPages); 00948 fsRWReq->varIndex = ZBAT_TABLE_FILE; 00949 fsRWReq->numberOfPages = WORDS2PAGES(c_writeTableRecord.no_of_words); 00950 fsRWReq->data.arrayOfPages.varIndex = c_writeTableRecord.pageId; 00951 fsRWReq->data.arrayOfPages.fileOffset = 0; // Write to file page 0 00952 sendSignal(NDBFS_REF, GSN_FSWRITEREQ, signal, 8, JBA); 00953 }//writeTableFile() 00954 00955 void Dbdict::writeTableConf(Signal* signal, 00956 FsConnectRecordPtr fsPtr) 00957 { 00958 fsPtr.p->fsState = FsConnectRecord::CLOSE_WRITE_TAB_FILE; 00959 closeFile(signal, fsPtr.p->filePtr, fsPtr.i); 00960 return; 00961 }//Dbdict::writeTableConf() 00962 00963 void Dbdict::closeWriteTableConf(Signal* signal, 00964 FsConnectRecordPtr fsPtr) 00965 { 00966 c_writeTableRecord.noOfTableFilesHandled++; 00967 if (c_writeTableRecord.noOfTableFilesHandled < 2) { 00968 jam(); 00969 fsPtr.p->fsState = FsConnectRecord::OPEN_WRITE_TAB_FILE; 00970 openTableFile(signal, 1, fsPtr.i, c_writeTableRecord.tableId, true); 00971 return; 00972 } 00973 ndbrequire(c_writeTableRecord.noOfTableFilesHandled == 2); 00974 c_fsConnectRecordPool.release(fsPtr); 00975 WriteTableRecord::TableWriteState state = c_writeTableRecord.tableWriteState; 00976 c_writeTableRecord.tableWriteState = WriteTableRecord::IDLE; 00977 switch (state) { 00978 case WriteTableRecord::IDLE: 00979 case WriteTableRecord::WRITE_ADD_TABLE_MASTER : 00980 case WriteTableRecord::WRITE_ADD_TABLE_SLAVE : 00981 case WriteTableRecord::WRITE_RESTART_FROM_MASTER : 00982 case WriteTableRecord::WRITE_RESTART_FROM_OWN : 00983 ndbrequire(false); 00984 break; 00985 case WriteTableRecord::TWR_CALLBACK: 00986 jam(); 00987 execute(signal, c_writeTableRecord.m_callback, 0); 00988 return; 00989 } 00990 ndbrequire(false); 00991 }//Dbdict::closeWriteTableConf() 00992 00993 void Dbdict::startReadTableFile(Signal* signal, Uint32 tableId) 00994 { 00995 //globalSignalLoggers.log(number(), "startReadTableFile"); 00996 ndbrequire(!c_readTableRecord.inUse); 00997 00998 FsConnectRecordPtr fsPtr; 00999 c_fsConnectRecordPool.getPtr(fsPtr, getFsConnRecord()); 01000 c_readTableRecord.inUse = true; 01001 c_readTableRecord.tableId = tableId; 01002 fsPtr.p->fsState = FsConnectRecord::OPEN_READ_TAB_FILE1; 01003 openTableFile(signal, 0, fsPtr.i, tableId, false); 01004 }//Dbdict::startReadTableFile() 01005 01006 void Dbdict::openReadTableRef(Signal* signal, 01007 FsConnectRecordPtr fsPtr) 01008 { 01009 fsPtr.p->fsState = FsConnectRecord::OPEN_READ_TAB_FILE2; 01010 openTableFile(signal, 1, fsPtr.i, c_readTableRecord.tableId, false); 01011 return; 01012 }//Dbdict::openReadTableConf() 01013 01014 void Dbdict::readTableFile(Signal* signal, Uint32 filePtr, Uint32 fsConPtr) 01015 { 01016 FsReadWriteReq * const fsRWReq = (FsReadWriteReq *)&signal->theData[0]; 01017 01018 fsRWReq->filePointer = filePtr; 01019 fsRWReq->userReference = reference(); 01020 fsRWReq->userPointer = fsConPtr; 01021 fsRWReq->operationFlag = 0; // Initialise before bit changes 01022 FsReadWriteReq::setSyncFlag(fsRWReq->operationFlag, 0); 01023 FsReadWriteReq::setFormatFlag(fsRWReq->operationFlag, 01024 FsReadWriteReq::fsFormatArrayOfPages); 01025 fsRWReq->varIndex = ZBAT_TABLE_FILE; 01026 fsRWReq->numberOfPages = WORDS2PAGES(c_readTableRecord.no_of_words); 01027 fsRWReq->data.arrayOfPages.varIndex = c_readTableRecord.pageId; 01028 fsRWReq->data.arrayOfPages.fileOffset = 0; // Write to file page 0 01029 sendSignal(NDBFS_REF, GSN_FSREADREQ, signal, 8, JBA); 01030 }//readTableFile() 01031 01032 void Dbdict::readTableConf(Signal* signal, 01033 FsConnectRecordPtr fsPtr) 01034 { 01035 /* ---------------------------------------------------------------- */ 01036 // Verify the data read from disk 01037 /* ---------------------------------------------------------------- */ 01038 bool crashInd; 01039 if (fsPtr.p->fsState == FsConnectRecord::READ_TAB_FILE1) { 01040 jam(); 01041 crashInd = false; 01042 } else { 01043 jam(); 01044 crashInd = true; 01045 }//if 01046 01047 PageRecordPtr tmpPagePtr; 01048 c_pageRecordArray.getPtr(tmpPagePtr, c_readTableRecord.pageId); 01049 Uint32 sz = 01050 WORDS2PAGES(c_readTableRecord.no_of_words)*ZSIZE_OF_PAGES_IN_WORDS; 01051 Uint32 chk = computeChecksum((const Uint32*)tmpPagePtr.p, sz); 01052 01053 ndbrequire((chk == 0) || !crashInd); 01054 if(chk != 0){ 01055 jam(); 01056 ndbrequire(fsPtr.p->fsState == FsConnectRecord::READ_TAB_FILE1); 01057 readTableRef(signal, fsPtr); 01058 return; 01059 }//if 01060 01061 fsPtr.p->fsState = FsConnectRecord::CLOSE_READ_TAB_FILE; 01062 closeFile(signal, fsPtr.p->filePtr, fsPtr.i); 01063 return; 01064 }//Dbdict::readTableConf() 01065 01066 void Dbdict::readTableRef(Signal* signal, 01067 FsConnectRecordPtr fsPtr) 01068 { 01069 fsPtr.p->fsState = FsConnectRecord::OPEN_READ_TAB_FILE2; 01070 openTableFile(signal, 1, fsPtr.i, c_readTableRecord.tableId, false); 01071 return; 01072 }//Dbdict::readTableRef() 01073 01074 void Dbdict::closeReadTableConf(Signal* signal, 01075 FsConnectRecordPtr fsPtr) 01076 { 01077 c_fsConnectRecordPool.release(fsPtr); 01078 c_readTableRecord.inUse = false; 01079 01080 execute(signal, c_readTableRecord.m_callback, 0); 01081 return; 01082 }//Dbdict::closeReadTableConf() 01083 01084 /* ---------------------------------------------------------------- */ 01085 // Routines to handle Read/Write of Schema Files 01086 /* ---------------------------------------------------------------- */ 01087 void 01088 Dbdict::updateSchemaState(Signal* signal, Uint32 tableId, 01089 SchemaFile::TableEntry* te, Callback* callback){ 01090 01091 jam(); 01092 ndbrequire(tableId < c_tableRecordPool.getSize()); 01093 XSchemaFile * xsf = &c_schemaFile[c_schemaRecord.schemaPage != 0]; 01094 SchemaFile::TableEntry * tableEntry = getTableEntry(xsf, tableId); 01095 01096 SchemaFile::TableState newState = 01097 (SchemaFile::TableState)te->m_tableState; 01098 SchemaFile::TableState oldState = 01099 (SchemaFile::TableState)tableEntry->m_tableState; 01100 01101 Uint32 newVersion = te->m_tableVersion; 01102 Uint32 oldVersion = tableEntry->m_tableVersion; 01103 01104 bool ok = false; 01105 switch(newState){ 01106 case SchemaFile::ADD_STARTED: 01107 jam(); 01108 ok = true; 01109 ndbrequire(create_obj_inc_schema_version(oldVersion) == newVersion); 01110 ndbrequire(oldState == SchemaFile::INIT || 01111 oldState == SchemaFile::DROP_TABLE_COMMITTED); 01112 break; 01113 case SchemaFile::TABLE_ADD_COMMITTED: 01114 jam(); 01115 ok = true; 01116 ndbrequire(newVersion == oldVersion); 01117 ndbrequire(oldState == SchemaFile::ADD_STARTED || 01118 oldState == SchemaFile::DROP_TABLE_STARTED); 01119 break; 01120 case SchemaFile::ALTER_TABLE_COMMITTED: 01121 jam(); 01122 ok = true; 01123 ndbrequire(alter_obj_inc_schema_version(oldVersion) == newVersion); 01124 ndbrequire(oldState == SchemaFile::TABLE_ADD_COMMITTED || 01125 oldState == SchemaFile::ALTER_TABLE_COMMITTED); 01126 break; 01127 case SchemaFile::DROP_TABLE_STARTED: 01128 jam(); 01129 case SchemaFile::DROP_TABLE_COMMITTED: 01130 jam(); 01131 ok = true; 01132 break; 01133 case SchemaFile::INIT: 01134 jam(); 01135 ok = true; 01136 ndbrequire((oldState == SchemaFile::ADD_STARTED)); 01137 }//if 01138 ndbrequire(ok); 01139 01140 * tableEntry = * te; 01141 computeChecksum(xsf, tableId / NDB_SF_PAGE_ENTRIES); 01142 01143 ndbrequire(c_writeSchemaRecord.inUse == false); 01144 c_writeSchemaRecord.inUse = true; 01145 01146 c_writeSchemaRecord.pageId = c_schemaRecord.schemaPage; 01147 c_writeSchemaRecord.newFile = false; 01148 c_writeSchemaRecord.firstPage = tableId / NDB_SF_PAGE_ENTRIES; 01149 c_writeSchemaRecord.noOfPages = 1; 01150 c_writeSchemaRecord.m_callback = * callback; 01151 01152 startWriteSchemaFile(signal); 01153 } 01154 01155 void Dbdict::startWriteSchemaFile(Signal* signal) 01156 { 01157 FsConnectRecordPtr fsPtr; 01158 c_fsConnectRecordPool.getPtr(fsPtr, getFsConnRecord()); 01159 fsPtr.p->fsState = FsConnectRecord::OPEN_WRITE_SCHEMA; 01160 openSchemaFile(signal, 0, fsPtr.i, true, c_writeSchemaRecord.newFile); 01161 c_writeSchemaRecord.noOfSchemaFilesHandled = 0; 01162 }//Dbdict::startWriteSchemaFile() 01163 01164 void Dbdict::openSchemaFile(Signal* signal, 01165 Uint32 fileNo, 01166 Uint32 fsConPtr, 01167 bool writeFlag, 01168 bool newFile) 01169 { 01170 FsOpenReq * const fsOpenReq = (FsOpenReq *)&signal->theData[0]; 01171 fsOpenReq->userReference = reference(); 01172 fsOpenReq->userPointer = fsConPtr; 01173 if (writeFlag) { 01174 jam(); 01175 fsOpenReq->fileFlags = 01176 FsOpenReq::OM_WRITEONLY | 01177 FsOpenReq::OM_SYNC; 01178 if (newFile) 01179 fsOpenReq->fileFlags |= 01180 FsOpenReq::OM_TRUNCATE | 01181 FsOpenReq::OM_CREATE; 01182 } else { 01183 jam(); 01184 fsOpenReq->fileFlags = FsOpenReq::OM_READONLY; 01185 }//if 01186 fsOpenReq->fileNumber[3] = 0; // Initialise before byte changes 01187 FsOpenReq::setVersion(fsOpenReq->fileNumber, 1); 01188 FsOpenReq::setSuffix(fsOpenReq->fileNumber, FsOpenReq::S_SCHEMALOG); 01189 FsOpenReq::v1_setDisk(fsOpenReq->fileNumber, (fileNo + 1)); 01190 FsOpenReq::v1_setTable(fsOpenReq->fileNumber, (Uint32)-1); 01191 FsOpenReq::v1_setFragment(fsOpenReq->fileNumber, (Uint32)-1); 01192 FsOpenReq::v1_setS(fsOpenReq->fileNumber, (Uint32)-1); 01193 FsOpenReq::v1_setP(fsOpenReq->fileNumber, 0); 01194 /* ---------------------------------------------------------------- */ 01195 // File name : D1/DBDICT/P0.SchemaLog 01196 // D1 means Disk 1 (set by fileNo + 1). Writes to both D1 and D2 01197 // SchemaLog indicates that this is a file giving a list of current tables. 01198 /* ---------------------------------------------------------------- */ 01199 sendSignal(NDBFS_REF, GSN_FSOPENREQ, signal, FsOpenReq::SignalLength, JBA); 01200 }//openSchemaFile() 01201 01202 void Dbdict::writeSchemaFile(Signal* signal, Uint32 filePtr, Uint32 fsConPtr) 01203 { 01204 FsReadWriteReq * const fsRWReq = (FsReadWriteReq *)&signal->theData[0]; 01205 01206 // check write record 01207 WriteSchemaRecord & wr = c_writeSchemaRecord; 01208 ndbrequire(wr.pageId == (wr.pageId != 0) * NDB_SF_MAX_PAGES); 01209 ndbrequire(wr.noOfPages != 0); 01210 ndbrequire(wr.firstPage + wr.noOfPages <= NDB_SF_MAX_PAGES); 01211 01212 fsRWReq->filePointer = filePtr; 01213 fsRWReq->userReference = reference(); 01214 fsRWReq->userPointer = fsConPtr; 01215 fsRWReq->operationFlag = 0; // Initialise before bit changes 01216 FsReadWriteReq::setSyncFlag(fsRWReq->operationFlag, 1); 01217 FsReadWriteReq::setFormatFlag(fsRWReq->operationFlag, 01218 FsReadWriteReq::fsFormatArrayOfPages); 01219 fsRWReq->varIndex = ZBAT_SCHEMA_FILE; 01220 fsRWReq->numberOfPages = wr.noOfPages; 01221 // Write from memory page 01222 fsRWReq->data.arrayOfPages.varIndex = wr.pageId + wr.firstPage; 01223 fsRWReq->data.arrayOfPages.fileOffset = wr.firstPage; 01224 sendSignal(NDBFS_REF, GSN_FSWRITEREQ, signal, 8, JBA); 01225 }//writeSchemaFile() 01226 01227 void Dbdict::writeSchemaConf(Signal* signal, 01228 FsConnectRecordPtr fsPtr) 01229 { 01230 fsPtr.p->fsState = FsConnectRecord::CLOSE_WRITE_SCHEMA; 01231 closeFile(signal, fsPtr.p->filePtr, fsPtr.i); 01232 return; 01233 }//Dbdict::writeSchemaConf() 01234 01235 void Dbdict::closeFile(Signal* signal, Uint32 filePtr, Uint32 fsConPtr) 01236 { 01237 FsCloseReq * const fsCloseReq = (FsCloseReq *)&signal->theData[0]; 01238 fsCloseReq->filePointer = filePtr; 01239 fsCloseReq->userReference = reference(); 01240 fsCloseReq->userPointer = fsConPtr; 01241 FsCloseReq::setRemoveFileFlag(fsCloseReq->fileFlag, false); 01242 sendSignal(NDBFS_REF, GSN_FSCLOSEREQ, signal, FsCloseReq::SignalLength, JBA); 01243 return; 01244 }//closeFile() 01245 01246 void Dbdict::closeWriteSchemaConf(Signal* signal, 01247 FsConnectRecordPtr fsPtr) 01248 { 01249 c_writeSchemaRecord.noOfSchemaFilesHandled++; 01250 if (c_writeSchemaRecord.noOfSchemaFilesHandled < 2) { 01251 jam(); 01252 fsPtr.p->fsState = FsConnectRecord::OPEN_WRITE_SCHEMA; 01253 openSchemaFile(signal, 1, fsPtr.i, true, c_writeSchemaRecord.newFile); 01254 return; 01255 } 01256 ndbrequire(c_writeSchemaRecord.noOfSchemaFilesHandled == 2); 01257 01258 c_fsConnectRecordPool.release(fsPtr); 01259 01260 c_writeSchemaRecord.inUse = false; 01261 execute(signal, c_writeSchemaRecord.m_callback, 0); 01262 return; 01263 }//Dbdict::closeWriteSchemaConf() 01264 01265 void Dbdict::startReadSchemaFile(Signal* signal) 01266 { 01267 //globalSignalLoggers.log(number(), "startReadSchemaFile"); 01268 FsConnectRecordPtr fsPtr; 01269 c_fsConnectRecordPool.getPtr(fsPtr, getFsConnRecord()); 01270 fsPtr.p->fsState = FsConnectRecord::OPEN_READ_SCHEMA1; 01271 openSchemaFile(signal, 0, fsPtr.i, false, false); 01272 }//Dbdict::startReadSchemaFile() 01273 01274 void Dbdict::openReadSchemaRef(Signal* signal, 01275 FsConnectRecordPtr fsPtr) 01276 { 01277 fsPtr.p->fsState = FsConnectRecord::OPEN_READ_SCHEMA2; 01278 openSchemaFile(signal, 1, fsPtr.i, false, false); 01279 }//Dbdict::openReadSchemaRef() 01280 01281 void Dbdict::readSchemaFile(Signal* signal, Uint32 filePtr, Uint32 fsConPtr) 01282 { 01283 FsReadWriteReq * const fsRWReq = (FsReadWriteReq *)&signal->theData[0]; 01284 01285 // check read record 01286 ReadSchemaRecord & rr = c_readSchemaRecord; 01287 ndbrequire(rr.pageId == (rr.pageId != 0) * NDB_SF_MAX_PAGES); 01288 ndbrequire(rr.noOfPages != 0); 01289 ndbrequire(rr.firstPage + rr.noOfPages <= NDB_SF_MAX_PAGES); 01290 01291 fsRWReq->filePointer = filePtr; 01292 fsRWReq->userReference = reference(); 01293 fsRWReq->userPointer = fsConPtr; 01294 fsRWReq->operationFlag = 0; // Initialise before bit changes 01295 FsReadWriteReq::setSyncFlag(fsRWReq->operationFlag, 0); 01296 FsReadWriteReq::setFormatFlag(fsRWReq->operationFlag, 01297 FsReadWriteReq::fsFormatArrayOfPages); 01298 fsRWReq->varIndex = ZBAT_SCHEMA_FILE; 01299 fsRWReq->numberOfPages = rr.noOfPages; 01300 fsRWReq->data.arrayOfPages.varIndex = rr.pageId + rr.firstPage; 01301 fsRWReq->data.arrayOfPages.fileOffset = rr.firstPage; 01302 sendSignal(NDBFS_REF, GSN_FSREADREQ, signal, 8, JBA); 01303 }//readSchemaFile() 01304 01305 void Dbdict::readSchemaConf(Signal* signal, 01306 FsConnectRecordPtr fsPtr) 01307 { 01308 /* ---------------------------------------------------------------- */ 01309 // Verify the data read from disk 01310 /* ---------------------------------------------------------------- */ 01311 bool crashInd; 01312 if (fsPtr.p->fsState == FsConnectRecord::READ_SCHEMA1) { 01313 jam(); 01314 crashInd = false; 01315 } else { 01316 jam(); 01317 crashInd = true; 01318 }//if 01319 01320 ReadSchemaRecord & rr = c_readSchemaRecord; 01321 XSchemaFile * xsf = &c_schemaFile[rr.pageId != 0]; 01322 01323 if (rr.schemaReadState == ReadSchemaRecord::INITIAL_READ_HEAD) { 01324 jam(); 01325 ndbrequire(rr.firstPage == 0); 01326 SchemaFile * sf = &xsf->schemaPage[0]; 01327 Uint32 noOfPages; 01328 if (sf->NdbVersion < NDB_SF_VERSION_5_0_6) { 01329 jam(); 01330 const Uint32 pageSize_old = 32 * 1024; 01331 noOfPages = pageSize_old / NDB_SF_PAGE_SIZE - 1; 01332 } else { 01333 noOfPages = sf->FileSize / NDB_SF_PAGE_SIZE - 1; 01334 } 01335 rr.schemaReadState = ReadSchemaRecord::INITIAL_READ; 01336 if (noOfPages != 0) { 01337 rr.firstPage = 1; 01338 rr.noOfPages = noOfPages; 01339 readSchemaFile(signal, fsPtr.p->filePtr, fsPtr.i); 01340 return; 01341 } 01342 } 01343 01344 SchemaFile * sf0 = &xsf->schemaPage[0]; 01345 xsf->noOfPages = sf0->FileSize / NDB_SF_PAGE_SIZE; 01346 01347 if (sf0->NdbVersion < NDB_SF_VERSION_5_0_6 && 01348 ! convertSchemaFileTo_5_0_6(xsf)) { 01349 jam(); 01350 ndbrequire(! crashInd); 01351 ndbrequire(fsPtr.p->fsState == FsConnectRecord::READ_SCHEMA1); 01352 readSchemaRef(signal, fsPtr); 01353 return; 01354 } 01355 01356 for (Uint32 n = 0; n < xsf->noOfPages; n++) { 01357 SchemaFile * sf = &xsf->schemaPage[n]; 01358 bool ok = 01359 memcmp(sf->Magic, NDB_SF_MAGIC, sizeof(sf->Magic)) == 0 && 01360 sf->FileSize != 0 && 01361 sf->FileSize % NDB_SF_PAGE_SIZE == 0 && 01362 sf->FileSize == sf0->FileSize && 01363 sf->PageNumber == n && 01364 computeChecksum((Uint32*)sf, NDB_SF_PAGE_SIZE_IN_WORDS) == 0; 01365 ndbrequireErr(ok || !crashInd, NDBD_EXIT_SR_SCHEMAFILE); 01366 if (! ok) { 01367 jam(); 01368 ndbrequireErr(fsPtr.p->fsState == FsConnectRecord::READ_SCHEMA1, 01369 NDBD_EXIT_SR_SCHEMAFILE); 01370 readSchemaRef(signal, fsPtr); 01371 return; 01372 } 01373 } 01374 01375 fsPtr.p->fsState = FsConnectRecord::CLOSE_READ_SCHEMA; 01376 closeFile(signal, fsPtr.p->filePtr, fsPtr.i); 01377 return; 01378 }//Dbdict::readSchemaConf() 01379 01380 void Dbdict::readSchemaRef(Signal* signal, 01381 FsConnectRecordPtr fsPtr) 01382 { 01386 fsPtr.p->fsState = FsConnectRecord::OPEN_READ_SCHEMA2; 01387 closeFile(signal, fsPtr.p->filePtr, fsPtr.i); 01388 return; 01389 } 01390 01391 void Dbdict::closeReadSchemaConf(Signal* signal, 01392 FsConnectRecordPtr fsPtr) 01393 { 01394 c_fsConnectRecordPool.release(fsPtr); 01395 ReadSchemaRecord::SchemaReadState state = c_readSchemaRecord.schemaReadState; 01396 c_readSchemaRecord.schemaReadState = ReadSchemaRecord::IDLE; 01397 01398 switch(state) { 01399 case ReadSchemaRecord::INITIAL_READ : 01400 jam(); 01401 { 01402 // write back both copies 01403 01404 ndbrequire(c_writeSchemaRecord.inUse == false); 01405 XSchemaFile * xsf = &c_schemaFile[c_schemaRecord.oldSchemaPage != 0 ]; 01406 Uint32 noOfPages = 01407 (c_tableRecordPool.getSize() + NDB_SF_PAGE_ENTRIES - 1) / 01408 NDB_SF_PAGE_ENTRIES; 01409 resizeSchemaFile(xsf, noOfPages); 01410 01411 c_writeSchemaRecord.inUse = true; 01412 c_writeSchemaRecord.pageId = c_schemaRecord.oldSchemaPage; 01413 c_writeSchemaRecord.newFile = true; 01414 c_writeSchemaRecord.firstPage = 0; 01415 c_writeSchemaRecord.noOfPages = xsf->noOfPages; 01416 01417 c_writeSchemaRecord.m_callback.m_callbackFunction = 01418 safe_cast(&Dbdict::initSchemaFile_conf); 01419 01420 startWriteSchemaFile(signal); 01421 } 01422 break; 01423 01424 default : 01425 ndbrequire(false); 01426 break; 01427 01428 }//switch 01429 }//Dbdict::closeReadSchemaConf() 01430 01431 bool 01432 Dbdict::convertSchemaFileTo_5_0_6(XSchemaFile * xsf) 01433 { 01434 const Uint32 pageSize_old = 32 * 1024; 01435 Uint32 page_old[pageSize_old >> 2]; 01436 SchemaFile * sf_old = (SchemaFile *)page_old; 01437 01438 if (xsf->noOfPages * NDB_SF_PAGE_SIZE != pageSize_old) 01439 return false; 01440 SchemaFile * sf0 = &xsf->schemaPage[0]; 01441 memcpy(sf_old, sf0, pageSize_old); 01442 01443 // init max number new pages needed 01444 xsf->noOfPages = (sf_old->NoOfTableEntries + NDB_SF_PAGE_ENTRIES - 1) / 01445 NDB_SF_PAGE_ENTRIES; 01446 initSchemaFile(xsf, 0, xsf->noOfPages, true); 01447 01448 Uint32 noOfPages = 1; 01449 Uint32 n, i, j; 01450 for (n = 0; n < xsf->noOfPages; n++) { 01451 jam(); 01452 for (i = 0; i < NDB_SF_PAGE_ENTRIES; i++) { 01453 j = n * NDB_SF_PAGE_ENTRIES + i; 01454 if (j >= sf_old->NoOfTableEntries) 01455 continue; 01456 const SchemaFile::TableEntry_old & te_old = sf_old->TableEntries_old[j]; 01457 if (te_old.m_tableState == SchemaFile::INIT || 01458 te_old.m_tableState == SchemaFile::DROP_TABLE_COMMITTED || 01459 te_old.m_noOfPages == 0) 01460 continue; 01461 SchemaFile * sf = &xsf->schemaPage[n]; 01462 SchemaFile::TableEntry & te = sf->TableEntries[i]; 01463 te.m_tableState = te_old.m_tableState; 01464 te.m_tableVersion = te_old.m_tableVersion; 01465 te.m_tableType = te_old.m_tableType; 01466 te.m_info_words = te_old.m_noOfPages * ZSIZE_OF_PAGES_IN_WORDS - 01467 ZPAGE_HEADER_SIZE; 01468 te.m_gcp = te_old.m_gcp; 01469 if (noOfPages < n) 01470 noOfPages = n; 01471 } 01472 } 01473 xsf->noOfPages = noOfPages; 01474 initSchemaFile(xsf, 0, xsf->noOfPages, false); 01475 01476 return true; 01477 } 01478 01479 /* **************************************************************** */ 01480 /* ---------------------------------------------------------------- */ 01481 /* MODULE: INITIALISATION MODULE ------------------------- */ 01482 /* ---------------------------------------------------------------- */ 01483 /* */ 01484 /* This module contains initialisation of data at start/restart. */ 01485 /* ---------------------------------------------------------------- */ 01486 /* **************************************************************** */ 01487 01488 Dbdict::Dbdict(Block_context& ctx): 01489 SimulatedBlock(DBDICT, ctx), 01490 c_attributeRecordHash(c_attributeRecordPool), 01491 c_file_hash(c_file_pool), 01492 c_filegroup_hash(c_filegroup_pool), 01493 c_obj_hash(c_obj_pool), 01494 c_opCreateTable(c_opRecordPool), 01495 c_opDropTable(c_opRecordPool), 01496 c_opCreateIndex(c_opRecordPool), 01497 c_opDropIndex(c_opRecordPool), 01498 c_opAlterIndex(c_opRecordPool), 01499 c_opBuildIndex(c_opRecordPool), 01500 c_opCreateEvent(c_opRecordPool), 01501 c_opSubEvent(c_opRecordPool), 01502 c_opDropEvent(c_opRecordPool), 01503 c_opSignalUtil(c_opRecordPool), 01504 c_opCreateTrigger(c_opRecordPool), 01505 c_opDropTrigger(c_opRecordPool), 01506 c_opAlterTrigger(c_opRecordPool), 01507 c_schemaOp(c_opRecordPool), 01508 c_Trans(c_opRecordPool), 01509 c_opCreateObj(c_schemaOp), 01510 c_opDropObj(c_schemaOp), 01511 c_opRecordSequence(0), 01512 c_dictLockQueue(c_dictLockPool), 01513 c_dictLockPoll(false) 01514 { 01515 BLOCK_CONSTRUCTOR(Dbdict); 01516 01517 // Transit signals 01518 addRecSignal(GSN_DUMP_STATE_ORD, &Dbdict::execDUMP_STATE_ORD); 01519 addRecSignal(GSN_GET_TABINFOREQ, &Dbdict::execGET_TABINFOREQ); 01520 addRecSignal(GSN_GET_TABLEID_REQ, &Dbdict::execGET_TABLEDID_REQ); 01521 addRecSignal(GSN_GET_TABINFO_CONF, &Dbdict::execGET_TABINFO_CONF); 01522 addRecSignal(GSN_CONTINUEB, &Dbdict::execCONTINUEB); 01523 01524 addRecSignal(GSN_CREATE_TABLE_REQ, &Dbdict::execCREATE_TABLE_REQ); 01525 addRecSignal(GSN_CREATE_TAB_REQ, &Dbdict::execCREATE_TAB_REQ); 01526 addRecSignal(GSN_CREATE_TAB_REF, &Dbdict::execCREATE_TAB_REF); 01527 addRecSignal(GSN_CREATE_TAB_CONF, &Dbdict::execCREATE_TAB_CONF); 01528 addRecSignal(GSN_CREATE_FRAGMENTATION_REF, &Dbdict::execCREATE_FRAGMENTATION_REF); 01529 addRecSignal(GSN_CREATE_FRAGMENTATION_CONF, &Dbdict::execCREATE_FRAGMENTATION_CONF); 01530 addRecSignal(GSN_DIADDTABCONF, &Dbdict::execDIADDTABCONF); 01531 addRecSignal(GSN_DIADDTABREF, &Dbdict::execDIADDTABREF); 01532 addRecSignal(GSN_ADD_FRAGREQ, &Dbdict::execADD_FRAGREQ); 01533 addRecSignal(GSN_TAB_COMMITCONF, &Dbdict::execTAB_COMMITCONF); 01534 addRecSignal(GSN_TAB_COMMITREF, &Dbdict::execTAB_COMMITREF); 01535 addRecSignal(GSN_ALTER_TABLE_REQ, &Dbdict::execALTER_TABLE_REQ); 01536 addRecSignal(GSN_ALTER_TAB_REQ, &Dbdict::execALTER_TAB_REQ); 01537 addRecSignal(GSN_ALTER_TAB_REF, &Dbdict::execALTER_TAB_REF); 01538 addRecSignal(GSN_ALTER_TAB_CONF, &Dbdict::execALTER_TAB_CONF); 01539 01540 // Index signals 01541 addRecSignal(GSN_CREATE_INDX_REQ, &Dbdict::execCREATE_INDX_REQ); 01542 addRecSignal(GSN_CREATE_INDX_CONF, &Dbdict::execCREATE_INDX_CONF); 01543 addRecSignal(GSN_CREATE_INDX_REF, &Dbdict::execCREATE_INDX_REF); 01544 01545 addRecSignal(GSN_ALTER_INDX_REQ, &Dbdict::execALTER_INDX_REQ); 01546 addRecSignal(GSN_ALTER_INDX_CONF, &Dbdict::execALTER_INDX_CONF); 01547 addRecSignal(GSN_ALTER_INDX_REF, &Dbdict::execALTER_INDX_REF); 01548 01549 addRecSignal(GSN_CREATE_TABLE_CONF, &Dbdict::execCREATE_TABLE_CONF); 01550 addRecSignal(GSN_CREATE_TABLE_REF, &Dbdict::execCREATE_TABLE_REF); 01551 01552 addRecSignal(GSN_DROP_INDX_REQ, &Dbdict::execDROP_INDX_REQ); 01553 addRecSignal(GSN_DROP_INDX_CONF, &Dbdict::execDROP_INDX_CONF); 01554 addRecSignal(GSN_DROP_INDX_REF, &Dbdict::execDROP_INDX_REF); 01555 01556 addRecSignal(GSN_DROP_TABLE_CONF, &Dbdict::execDROP_TABLE_CONF); 01557 addRecSignal(GSN_DROP_TABLE_REF, &Dbdict::execDROP_TABLE_REF); 01558 01559 addRecSignal(GSN_BUILDINDXREQ, &Dbdict::execBUILDINDXREQ); 01560 addRecSignal(GSN_BUILDINDXCONF, &Dbdict::execBUILDINDXCONF); 01561 addRecSignal(GSN_BUILDINDXREF, &Dbdict::execBUILDINDXREF); 01562 01563 // Util signals 01564 addRecSignal(GSN_UTIL_PREPARE_CONF, &Dbdict::execUTIL_PREPARE_CONF); 01565 addRecSignal(GSN_UTIL_PREPARE_REF, &Dbdict::execUTIL_PREPARE_REF); 01566 01567 addRecSignal(GSN_UTIL_EXECUTE_CONF, &Dbdict::execUTIL_EXECUTE_CONF); 01568 addRecSignal(GSN_UTIL_EXECUTE_REF, &Dbdict::execUTIL_EXECUTE_REF); 01569 01570 addRecSignal(GSN_UTIL_RELEASE_CONF, &Dbdict::execUTIL_RELEASE_CONF); 01571 addRecSignal(GSN_UTIL_RELEASE_REF, &Dbdict::execUTIL_RELEASE_REF); 01572 01573 // Event signals 01574 addRecSignal(GSN_CREATE_EVNT_REQ, &Dbdict::execCREATE_EVNT_REQ); 01575 addRecSignal(GSN_CREATE_EVNT_CONF, &Dbdict::execCREATE_EVNT_CONF); 01576 addRecSignal(GSN_CREATE_EVNT_REF, &Dbdict::execCREATE_EVNT_REF); 01577 01578 addRecSignal(GSN_CREATE_SUBID_CONF, &Dbdict::execCREATE_SUBID_CONF); 01579 addRecSignal(GSN_CREATE_SUBID_REF, &Dbdict::execCREATE_SUBID_REF); 01580 01581 addRecSignal(GSN_SUB_CREATE_CONF, &Dbdict::execSUB_CREATE_CONF); 01582 addRecSignal(GSN_SUB_CREATE_REF, &Dbdict::execSUB_CREATE_REF); 01583 01584 addRecSignal(GSN_SUB_START_REQ, &Dbdict::execSUB_START_REQ); 01585 addRecSignal(GSN_SUB_START_CONF, &Dbdict::execSUB_START_CONF); 01586 addRecSignal(GSN_SUB_START_REF, &Dbdict::execSUB_START_REF); 01587 01588 addRecSignal(GSN_SUB_STOP_REQ, &Dbdict::execSUB_STOP_REQ); 01589 addRecSignal(GSN_SUB_STOP_CONF, &Dbdict::execSUB_STOP_CONF); 01590 addRecSignal(GSN_SUB_STOP_REF, &Dbdict::execSUB_STOP_REF); 01591 01592 addRecSignal(GSN_DROP_EVNT_REQ, &Dbdict::execDROP_EVNT_REQ); 01593 01594 addRecSignal(GSN_SUB_REMOVE_REQ, &Dbdict::execSUB_REMOVE_REQ); 01595 addRecSignal(GSN_SUB_REMOVE_CONF, &Dbdict::execSUB_REMOVE_CONF); 01596 addRecSignal(GSN_SUB_REMOVE_REF, &Dbdict::execSUB_REMOVE_REF); 01597 01598 // Trigger signals 01599 addRecSignal(GSN_CREATE_TRIG_REQ, &Dbdict::execCREATE_TRIG_REQ); 01600 addRecSignal(GSN_CREATE_TRIG_CONF, &Dbdict::execCREATE_TRIG_CONF); 01601 addRecSignal(GSN_CREATE_TRIG_REF, &Dbdict::execCREATE_TRIG_REF); 01602 addRecSignal(GSN_ALTER_TRIG_REQ, &Dbdict::execALTER_TRIG_REQ); 01603 addRecSignal(GSN_ALTER_TRIG_CONF, &Dbdict::execALTER_TRIG_CONF); 01604 addRecSignal(GSN_ALTER_TRIG_REF, &Dbdict::execALTER_TRIG_REF); 01605 addRecSignal(GSN_DROP_TRIG_REQ, &Dbdict::execDROP_TRIG_REQ); 01606 addRecSignal(GSN_DROP_TRIG_CONF, &Dbdict::execDROP_TRIG_CONF); 01607 addRecSignal(GSN_DROP_TRIG_REF, &Dbdict::execDROP_TRIG_REF); 01608 01609 // Received signals 01610 addRecSignal(GSN_HOT_SPAREREP, &Dbdict::execHOT_SPAREREP); 01611 addRecSignal(GSN_GET_SCHEMA_INFOREQ, &Dbdict::execGET_SCHEMA_INFOREQ); 01612 addRecSignal(GSN_SCHEMA_INFO, &Dbdict::execSCHEMA_INFO); 01613 addRecSignal(GSN_SCHEMA_INFOCONF, &Dbdict::execSCHEMA_INFOCONF); 01614 addRecSignal(GSN_DICTSTARTREQ, &Dbdict::execDICTSTARTREQ); 01615 addRecSignal(GSN_READ_NODESCONF, &Dbdict::execREAD_NODESCONF); 01616 addRecSignal(GSN_FSOPENCONF, &Dbdict::execFSOPENCONF); 01617 addRecSignal(GSN_FSOPENREF, &Dbdict::execFSOPENREF, true); 01618 addRecSignal(GSN_FSCLOSECONF, &Dbdict::execFSCLOSECONF); 01619 addRecSignal(GSN_FSWRITECONF, &Dbdict::execFSWRITECONF); 01620 addRecSignal(GSN_FSREADCONF, &Dbdict::execFSREADCONF); 01621 addRecSignal(GSN_FSREADREF, &Dbdict::execFSREADREF, true); 01622 addRecSignal(GSN_LQHFRAGCONF, &Dbdict::execLQHFRAGCONF); 01623 addRecSignal(GSN_LQHADDATTCONF, &Dbdict::execLQHADDATTCONF); 01624 addRecSignal(GSN_LQHADDATTREF, &Dbdict::execLQHADDATTREF); 01625 addRecSignal(GSN_LQHFRAGREF, &Dbdict::execLQHFRAGREF); 01626 addRecSignal(GSN_NDB_STTOR, &Dbdict::execNDB_STTOR); 01627 addRecSignal(GSN_READ_CONFIG_REQ, &Dbdict::execREAD_CONFIG_REQ, true); 01628 addRecSignal(GSN_STTOR, &Dbdict::execSTTOR); 01629 addRecSignal(GSN_TC_SCHVERCONF, &Dbdict::execTC_SCHVERCONF); 01630 addRecSignal(GSN_NODE_FAILREP, &Dbdict::execNODE_FAILREP); 01631 addRecSignal(GSN_INCL_NODEREQ, &Dbdict::execINCL_NODEREQ); 01632 addRecSignal(GSN_API_FAILREQ, &Dbdict::execAPI_FAILREQ); 01633 01634 addRecSignal(GSN_WAIT_GCP_REF, &Dbdict::execWAIT_GCP_REF); 01635 addRecSignal(GSN_WAIT_GCP_CONF, &Dbdict::execWAIT_GCP_CONF); 01636 01637 addRecSignal(GSN_LIST_TABLES_REQ, &Dbdict::execLIST_TABLES_REQ); 01638 01639 addRecSignal(GSN_DROP_TABLE_REQ, &Dbdict::execDROP_TABLE_REQ); 01640 01641 addRecSignal(GSN_PREP_DROP_TAB_REQ, &Dbdict::execPREP_DROP_TAB_REQ); 01642 addRecSignal(GSN_PREP_DROP_TAB_REF, &Dbdict::execPREP_DROP_TAB_REF); 01643 addRecSignal(GSN_PREP_DROP_TAB_CONF, &Dbdict::execPREP_DROP_TAB_CONF); 01644 01645 addRecSignal(GSN_DROP_TAB_REQ, &Dbdict::execDROP_TAB_REQ); 01646 addRecSignal(GSN_DROP_TAB_REF, &Dbdict::execDROP_TAB_REF); 01647 addRecSignal(GSN_DROP_TAB_CONF, &Dbdict::execDROP_TAB_CONF); 01648 01649 addRecSignal(GSN_CREATE_FILE_REQ, &Dbdict::execCREATE_FILE_REQ); 01650 addRecSignal(GSN_CREATE_FILEGROUP_REQ, &Dbdict::execCREATE_FILEGROUP_REQ); 01651 01652 addRecSignal(GSN_DROP_FILE_REQ, &Dbdict::execDROP_FILE_REQ); 01653 addRecSignal(GSN_DROP_FILE_REF, &Dbdict::execDROP_FILE_REF); 01654 addRecSignal(GSN_DROP_FILE_CONF, &Dbdict::execDROP_FILE_CONF); 01655 01656 addRecSignal(GSN_DROP_FILEGROUP_REQ, &Dbdict::execDROP_FILEGROUP_REQ); 01657 addRecSignal(GSN_DROP_FILEGROUP_REF, &Dbdict::execDROP_FILEGROUP_REF); 01658 addRecSignal(GSN_DROP_FILEGROUP_CONF, &Dbdict::execDROP_FILEGROUP_CONF); 01659 01660 addRecSignal(GSN_CREATE_OBJ_REQ, &Dbdict::execCREATE_OBJ_REQ); 01661 addRecSignal(GSN_CREATE_OBJ_REF, &Dbdict::execCREATE_OBJ_REF); 01662 addRecSignal(GSN_CREATE_OBJ_CONF, &Dbdict::execCREATE_OBJ_CONF); 01663 addRecSignal(GSN_DROP_OBJ_REQ, &Dbdict::execDROP_OBJ_REQ); 01664 addRecSignal(GSN_DROP_OBJ_REF, &Dbdict::execDROP_OBJ_REF); 01665 addRecSignal(GSN_DROP_OBJ_CONF, &Dbdict::execDROP_OBJ_CONF); 01666 01667 addRecSignal(GSN_CREATE_FILE_REF, &Dbdict::execCREATE_FILE_REF); 01668 addRecSignal(GSN_CREATE_FILE_CONF, &Dbdict::execCREATE_FILE_CONF); 01669 addRecSignal(GSN_CREATE_FILEGROUP_REF, &Dbdict::execCREATE_FILEGROUP_REF); 01670 addRecSignal(GSN_CREATE_FILEGROUP_CONF, &Dbdict::execCREATE_FILEGROUP_CONF); 01671 01672 addRecSignal(GSN_BACKUP_FRAGMENT_REQ, &Dbdict::execBACKUP_FRAGMENT_REQ); 01673 01674 addRecSignal(GSN_DICT_COMMIT_REQ, &Dbdict::execDICT_COMMIT_REQ); 01675 addRecSignal(GSN_DICT_COMMIT_REF, &Dbdict::execDICT_COMMIT_REF); 01676 addRecSignal(GSN_DICT_COMMIT_CONF, &Dbdict::execDICT_COMMIT_CONF); 01677 01678 addRecSignal(GSN_DICT_ABORT_REQ, &Dbdict::execDICT_ABORT_REQ); 01679 addRecSignal(GSN_DICT_ABORT_REF, &Dbdict::execDICT_ABORT_REF); 01680 addRecSignal(GSN_DICT_ABORT_CONF, &Dbdict::execDICT_ABORT_CONF); 01681 01682 addRecSignal(GSN_DICT_LOCK_REQ, &Dbdict::execDICT_LOCK_REQ); 01683 addRecSignal(GSN_DICT_UNLOCK_ORD, &Dbdict::execDICT_UNLOCK_ORD); 01684 }//Dbdict::Dbdict() 01685 01686 Dbdict::~Dbdict() 01687 { 01688 }//Dbdict::~Dbdict() 01689 01690 BLOCK_FUNCTIONS(Dbdict) 01691 01692 void Dbdict::initCommonData() 01693 { 01694 /* ---------------------------------------------------------------- */ 01695 // Initialise all common variables. 01696 /* ---------------------------------------------------------------- */ 01697 initRetrieveRecord(0, 0, 0); 01698 initSchemaRecord(); 01699 initRestartRecord(); 01700 initSendSchemaRecord(); 01701 initReadTableRecord(); 01702 initWriteTableRecord(); 01703 initReadSchemaRecord(); 01704 initWriteSchemaRecord(); 01705 01706 c_masterNodeId = ZNIL; 01707 c_numberNode = 0; 01708 c_noNodesFailed = 0; 01709 c_failureNr = 0; 01710 c_blockState = BS_IDLE; 01711 c_packTable.m_state = PackTable::PTS_IDLE; 01712 c_startPhase = 0; 01713 c_restartType = 255; //Ensure not used restartType 01714 c_tabinfoReceived = 0; 01715 c_initialStart = false; 01716 c_systemRestart = false; 01717 c_initialNodeRestart = false; 01718 c_nodeRestart = false; 01719 }//Dbdict::initCommonData() 01720 01721 void Dbdict::initRecords() 01722 { 01723 initNodeRecords(); 01724 initPageRecords(); 01725 initTableRecords(); 01726 initTriggerRecords(); 01727 }//Dbdict::initRecords() 01728 01729 void Dbdict::initSendSchemaRecord() 01730 { 01731 c_sendSchemaRecord.noOfWords = (Uint32)-1; 01732 c_sendSchemaRecord.pageId = RNIL; 01733 c_sendSchemaRecord.noOfWordsCurrentlySent = 0; 01734 c_sendSchemaRecord.noOfSignalsSentSinceDelay = 0; 01735 c_sendSchemaRecord.inUse = false; 01736 //c_sendSchemaRecord.sendSchemaState = SendSchemaRecord::IDLE; 01737 }//initSendSchemaRecord() 01738 01739 void Dbdict::initReadTableRecord() 01740 { 01741 c_readTableRecord.no_of_words= 0; 01742 c_readTableRecord.pageId = RNIL; 01743 c_readTableRecord.tableId = ZNIL; 01744 c_readTableRecord.inUse = false; 01745 }//initReadTableRecord() 01746 01747 void Dbdict::initWriteTableRecord() 01748 { 01749 c_writeTableRecord.no_of_words= 0; 01750 c_writeTableRecord.pageId = RNIL; 01751 c_writeTableRecord.noOfTableFilesHandled = 3; 01752 c_writeTableRecord.tableId = ZNIL; 01753 c_writeTableRecord.tableWriteState = WriteTableRecord::IDLE; 01754 }//initWriteTableRecord() 01755 01756 void Dbdict::initReadSchemaRecord() 01757 { 01758 c_readSchemaRecord.pageId = RNIL; 01759 c_readSchemaRecord.schemaReadState = ReadSchemaRecord::IDLE; 01760 }//initReadSchemaRecord() 01761 01762 void Dbdict::initWriteSchemaRecord() 01763 { 01764 c_writeSchemaRecord.inUse = false; 01765 c_writeSchemaRecord.pageId = RNIL; 01766 c_writeSchemaRecord.noOfSchemaFilesHandled = 3; 01767 }//initWriteSchemaRecord() 01768 01769 void Dbdict::initRetrieveRecord(Signal* signal, Uint32 i, Uint32 returnCode) 01770 { 01771 c_retrieveRecord.busyState = false; 01772 c_retrieveRecord.blockRef = 0; 01773 c_retrieveRecord.m_senderData = RNIL; 01774 c_retrieveRecord.tableId = RNIL; 01775 c_retrieveRecord.currentSent = 0; 01776 c_retrieveRecord.retrievedNoOfPages = 0; 01777 c_retrieveRecord.retrievedNoOfWords = 0; 01778 c_retrieveRecord.m_useLongSig = false; 01779 }//initRetrieveRecord() 01780 01781 void Dbdict::initSchemaRecord() 01782 { 01783 c_schemaRecord.schemaPage = RNIL; 01784 c_schemaRecord.oldSchemaPage = RNIL; 01785 }//Dbdict::initSchemaRecord() 01786 01787 void Dbdict::initRestartRecord() 01788 { 01789 c_restartRecord.gciToRestart = 0; 01790 c_restartRecord.activeTable = ZNIL; 01791 c_restartRecord.m_pass = 0; 01792 }//Dbdict::initRestartRecord() 01793 01794 void Dbdict::initNodeRecords() 01795 { 01796 jam(); 01797 for (unsigned i = 1; i < MAX_NODES; i++) { 01798 NodeRecordPtr nodePtr; 01799 c_nodes.getPtr(nodePtr, i); 01800 nodePtr.p->hotSpare = false; 01801 nodePtr.p->nodeState = NodeRecord::API_NODE; 01802 }//for 01803 }//Dbdict::initNodeRecords() 01804 01805 void Dbdict::initPageRecords() 01806 { 01807 c_retrieveRecord.retrievePage = ZMAX_PAGES_OF_TABLE_DEFINITION; 01808 ndbrequire(ZNUMBER_OF_PAGES >= (ZMAX_PAGES_OF_TABLE_DEFINITION + 1)); 01809 c_schemaRecord.schemaPage = 0; 01810 c_schemaRecord.oldSchemaPage = NDB_SF_MAX_PAGES; 01811 }//Dbdict::initPageRecords() 01812 01813 void Dbdict::initTableRecords() 01814 { 01815 TableRecordPtr tablePtr; 01816 while (1) { 01817 jam(); 01818 refresh_watch_dog(); 01819 c_tableRecordPool.seize(tablePtr); 01820 if (tablePtr.i == RNIL) { 01821 jam(); 01822 break; 01823 }//if 01824 initialiseTableRecord(tablePtr); 01825 }//while 01826 }//Dbdict::initTableRecords() 01827 01828 void Dbdict::initialiseTableRecord(TableRecordPtr tablePtr) 01829 { 01830 new (tablePtr.p) TableRecord(); 01831 tablePtr.p->activePage = RNIL; 01832 tablePtr.p->filePtr[0] = RNIL; 01833 tablePtr.p->filePtr[1] = RNIL; 01834 tablePtr.p->firstPage = RNIL; 01835 tablePtr.p->tableId = tablePtr.i; 01836 tablePtr.p->tableVersion = (Uint32)-1; 01837 tablePtr.p->tabState = TableRecord::NOT_DEFINED; 01838 tablePtr.p->tabReturnState = TableRecord::TRS_IDLE; 01839 tablePtr.p->fragmentType = DictTabInfo::AllNodesSmallTable; 01840 tablePtr.p->gciTableCreated = 0; 01841 tablePtr.p->noOfAttributes = ZNIL; 01842 tablePtr.p->noOfNullAttr = 0; 01843 tablePtr.p->fragmentCount = 0; 01844 /* 01845 tablePtr.p->lh3PageIndexBits = 0; 01846 tablePtr.p->lh3DistrBits = 0; 01847 tablePtr.p->lh3PageBits = 6; 01848 */ 01849 tablePtr.p->kValue = 6; 01850 tablePtr.p->localKeyLen = 1; 01851 tablePtr.p->maxLoadFactor = 80; 01852 tablePtr.p->minLoadFactor = 70; 01853 tablePtr.p->noOfPrimkey = 1; 01854 tablePtr.p->tupKeyLength = 1; 01855 tablePtr.p->maxRowsLow = 0; 01856 tablePtr.p->maxRowsHigh = 0; 01857 tablePtr.p->defaultNoPartFlag = true; 01858 tablePtr.p->linearHashFlag = true; 01859 tablePtr.p->m_bits = 0; 01860 tablePtr.p->minRowsLow = 0; 01861 tablePtr.p->minRowsHigh = 0; 01862 tablePtr.p->tableType = DictTabInfo::UserTable; 01863 tablePtr.p->primaryTableId = RNIL; 01864 // volatile elements 01865 tablePtr.p->indexState = TableRecord::IS_UNDEFINED; 01866 tablePtr.p->insertTriggerId = RNIL; 01867 tablePtr.p->updateTriggerId = RNIL; 01868 tablePtr.p->deleteTriggerId = RNIL; 01869 tablePtr.p->customTriggerId = RNIL; 01870 tablePtr.p->buildTriggerId = RNIL; 01871 tablePtr.p->indexLocal = 0; 01872 }//Dbdict::initialiseTableRecord() 01873 01874 void Dbdict::initTriggerRecords() 01875 { 01876 TriggerRecordPtr triggerPtr; 01877 while (1) { 01878 jam(); 01879 refresh_watch_dog(); 01880 c_triggerRecordPool.seize(triggerPtr); 01881 if (triggerPtr.i == RNIL) { 01882 jam(); 01883 break; 01884 }//if 01885 initialiseTriggerRecord(triggerPtr); 01886 }//while 01887 } 01888 01889 void Dbdict::initialiseTriggerRecord(TriggerRecordPtr triggerPtr) 01890 { 01891 new (triggerPtr.p) TriggerRecord(); 01892 triggerPtr.p->triggerState = TriggerRecord::TS_NOT_DEFINED; 01893 triggerPtr.p->triggerLocal = 0; 01894 triggerPtr.p->triggerId = RNIL; 01895 triggerPtr.p->tableId = RNIL; 01896 triggerPtr.p->triggerType = (TriggerType::Value)~0; 01897 triggerPtr.p->triggerActionTime = (TriggerActionTime::Value)~0; 01898 triggerPtr.p->triggerEvent = (TriggerEvent::Value)~0; 01899 triggerPtr.p->monitorReplicas = false; 01900 triggerPtr.p->monitorAllAttributes = false; 01901 triggerPtr.p->attributeMask.clear(); 01902 triggerPtr.p->indexId = RNIL; 01903 } 01904 01905 Uint32 Dbdict::getFsConnRecord() 01906 { 01907 FsConnectRecordPtr fsPtr; 01908 c_fsConnectRecordPool.seize(fsPtr); 01909 ndbrequire(fsPtr.i != RNIL); 01910 fsPtr.p->filePtr = (Uint32)-1; 01911 fsPtr.p->ownerPtr = RNIL; 01912 fsPtr.p->fsState = FsConnectRecord::IDLE; 01913 return fsPtr.i; 01914 }//Dbdict::getFsConnRecord() 01915 01916 /* 01917 * Search schemafile for free entry. Its index is used as 'logical id' 01918 * of new disk-stored object. 01919 */ 01920 Uint32 Dbdict::getFreeObjId(Uint32 minId) 01921 { 01922 const XSchemaFile * xsf = &c_schemaFile[c_schemaRecord.schemaPage != 0]; 01923 Uint32 noOfPages = xsf->noOfPages; 01924 Uint32 n, i; 01925 for (n = 0; n < noOfPages; n++) { 01926 jam(); 01927 const SchemaFile * sf = &xsf->schemaPage[n]; 01928 for (i = 0; i < NDB_SF_PAGE_ENTRIES; i++) { 01929 const SchemaFile::TableEntry& te = sf->TableEntries[i]; 01930 if (te.m_tableState == (Uint32)SchemaFile::INIT || 01931 te.m_tableState == (Uint32)SchemaFile::DROP_TABLE_COMMITTED) { 01932 // minId is obsolete anyway 01933 if (minId <= n * NDB_SF_PAGE_ENTRIES + i) 01934 return n * NDB_SF_PAGE_ENTRIES + i; 01935 } 01936 } 01937 } 01938 return RNIL; 01939 } 01940 01941 Uint32 Dbdict::getFreeTableRecord(Uint32 primaryTableId) 01942 { 01943 Uint32 minId = (primaryTableId == RNIL ? 0 : primaryTableId + 1); 01944 Uint32 i = getFreeObjId(minId); 01945 if (i == RNIL) { 01946 jam(); 01947 return RNIL; 01948 } 01949 if (i >= c_tableRecordPool.getSize()) { 01950 jam(); 01951 return RNIL; 01952 } 01953 TableRecordPtr tablePtr; 01954 c_tableRecordPool.getPtr(tablePtr, i); 01955 ndbrequire(tablePtr.p->tabState == TableRecord::NOT_DEFINED); 01956 initialiseTableRecord(tablePtr); 01957 tablePtr.p->tabState = TableRecord::DEFINING; 01958 return i; 01959 } 01960 01961 Uint32 Dbdict::getFreeTriggerRecord() 01962 { 01963 const Uint32 size = c_triggerRecordPool.getSize(); 01964 TriggerRecordPtr triggerPtr; 01965 for (triggerPtr.i = 0; triggerPtr.i < size; triggerPtr.i++) { 01966 jam(); 01967 c_triggerRecordPool.getPtr(triggerPtr); 01968 if (triggerPtr.p->triggerState == TriggerRecord::TS_NOT_DEFINED) { 01969 jam(); 01970 initialiseTriggerRecord(triggerPtr); 01971 return triggerPtr.i; 01972 } 01973 } 01974 return RNIL; 01975 } 01976 01977 /* **************************************************************** */ 01978 /* ---------------------------------------------------------------- */ 01979 /* MODULE: START/RESTART HANDLING ------------------------ */ 01980 /* ---------------------------------------------------------------- */ 01981 /* */ 01982 /* This module contains the code that is common for all */ 01983 /* start/restart types. */ 01984 /* ---------------------------------------------------------------- */ 01985 /* **************************************************************** */ 01986 01987 /* ---------------------------------------------------------------- */ 01988 // This is sent as the first signal during start/restart. 01989 /* ---------------------------------------------------------------- */ 01990 void Dbdict::execSTTOR(Signal* signal) 01991 { 01992 jamEntry(); 01993 c_startPhase = signal->theData[1]; 01994 switch (c_startPhase) { 01995 case 1: 01996 break; 01997 case 3: 01998 c_restartType = signal->theData[7]; /* valid if 3 */ 01999 ndbrequire(c_restartType == NodeState::ST_INITIAL_START || 02000 c_restartType == NodeState::ST_SYSTEM_RESTART || 02001 c_restartType == NodeState::ST_INITIAL_NODE_RESTART || 02002 c_restartType == NodeState::ST_NODE_RESTART); 02003 break; 02004 } 02005 sendSTTORRY(signal); 02006 }//execSTTOR() 02007 02008 void Dbdict::sendSTTORRY(Signal* signal) 02009 { 02010 signal->theData[0] = 0; /* garbage SIGNAL KEY */ 02011 signal->theData[1] = 0; /* garbage SIGNAL VERSION NUMBER */ 02012 signal->theData[2] = 0; /* garbage */ 02013 signal->theData[3] = 1; /* first wanted start phase */ 02014 signal->theData[4] = 3; /* get type of start */ 02015 signal->theData[5] = ZNOMOREPHASES; 02016 sendSignal(NDBCNTR_REF, GSN_STTORRY, signal, 6, JBB); 02017 } 02018 02019 /* ---------------------------------------------------------------- */ 02020 // We receive information about sizes of records. 02021 /* ---------------------------------------------------------------- */ 02022 void Dbdict::execREAD_CONFIG_REQ(Signal* signal) 02023 { 02024 const ReadConfigReq * req = (ReadConfigReq*)signal->getDataPtr(); 02025 Uint32 ref = req->senderRef; 02026 Uint32 senderData = req->senderData; 02027 ndbrequire(req->noOfParameters == 0); 02028 02029 jamEntry(); 02030 02031 const ndb_mgm_configuration_iterator * p = 02032 m_ctx.m_config.getOwnConfigIterator(); 02033 ndbrequire(p != 0); 02034 02035 Uint32 attributesize, tablerecSize; 02036 ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_DB_NO_TRIGGERS, 02037 &c_maxNoOfTriggers)); 02038 ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_DICT_ATTRIBUTE,&attributesize)); 02039 ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_DICT_TABLE, &tablerecSize)); 02040 02041 c_attributeRecordPool.setSize(attributesize); 02042 c_attributeRecordHash.setSize(64); 02043 c_fsConnectRecordPool.setSize(ZFS_CONNECT_SIZE); 02044 c_nodes.setSize(MAX_NODES); 02045 c_pageRecordArray.setSize(ZNUMBER_OF_PAGES); 02046 c_schemaPageRecordArray.setSize(2 * NDB_SF_MAX_PAGES); 02047 c_tableRecordPool.setSize(tablerecSize); 02048 g_key_descriptor_pool.setSize(tablerecSize); 02049 c_triggerRecordPool.setSize(c_maxNoOfTriggers); 02050 02051 c_obj_pool.setSize(tablerecSize+c_maxNoOfTriggers); 02052 c_obj_hash.setSize((tablerecSize+c_maxNoOfTriggers+1)/2); 02053 02054 Pool_context pc; 02055 pc.m_block = this; 02056 02057 c_file_hash.setSize(16); 02058 c_filegroup_hash.setSize(16); 02059 02060 c_file_pool.init(RT_DBDICT_FILE, pc); 02061 c_filegroup_pool.init(RT_DBDICT_FILEGROUP, pc); 02062 02063 c_opRecordPool.setSize(256); // XXX need config params 02064 c_opCreateTable.setSize(8); 02065 c_opDropTable.setSize(8); 02066 c_opCreateIndex.setSize(8); 02067 c_opCreateEvent.setSize(2); 02068 c_opSubEvent.setSize(2); 02069 c_opDropEvent.setSize(2); 02070 c_opSignalUtil.setSize(8); 02071 c_opDropIndex.setSize(8); 02072 c_opAlterIndex.setSize(8); 02073 c_opBuildIndex.setSize(8); 02074 c_opCreateTrigger.setSize(8); 02075 c_opDropTrigger.setSize(8); 02076 c_opAlterTrigger.setSize(8); 02077 02078 c_dictLockPool.setSize(32); 02079 02080 // Initialize schema file copies 02081 c_schemaFile[0].schemaPage = 02082 (SchemaFile*)c_schemaPageRecordArray.getPtr(0 * NDB_SF_MAX_PAGES); 02083 c_schemaFile[0].noOfPages = 0; 02084 c_schemaFile[1].schemaPage = 02085 (SchemaFile*)c_schemaPageRecordArray.getPtr(1 * NDB_SF_MAX_PAGES); 02086 c_schemaFile[1].noOfPages = 0; 02087 02088 c_schemaOp.setSize(8); 02089 //c_opDropObj.setSize(8); 02090 c_Trans.setSize(8); 02091 02092 Uint32 rps = 0; 02093 rps += tablerecSize * (MAX_TAB_NAME_SIZE + MAX_FRM_DATA_SIZE); 02094 rps += attributesize * (MAX_ATTR_NAME_SIZE + MAX_ATTR_DEFAULT_VALUE_SIZE); 02095 rps += c_maxNoOfTriggers * MAX_TAB_NAME_SIZE; 02096 rps += (10 + 10) * MAX_TAB_NAME_SIZE; 02097 02098 Uint32 sm = 5; 02099 ndb_mgm_get_int_parameter(p, CFG_DB_STRING_MEMORY, &sm); 02100 if (sm == 0) 02101 sm = 5; 02102 02103 Uint32 sb = 0; 02104 if (sm < 100) 02105 { 02106 sb = (rps * sm) / 100; 02107 } 02108 else 02109 { 02110 sb = sm; 02111 } 02112 02113 c_rope_pool.setSize(sb/28 + 100); 02114 02115 // Initialize BAT for interface to file system 02116 NewVARIABLE* bat = allocateBat(2); 02117 bat[0].WA = &c_schemaPageRecordArray.getPtr(0)->word[0]; 02118 bat[0].nrr = 2 * NDB_SF_MAX_PAGES; 02119 bat[0].ClusterSize = NDB_SF_PAGE_SIZE; 02120 bat[0].bits.q = NDB_SF_PAGE_SIZE_IN_WORDS_LOG2; 02121 bat[0].bits.v = 5; // 32 bits per element 02122 bat[1].WA = &c_pageRecordArray.getPtr(0)->word[0]; 02123 bat[1].nrr = ZNUMBER_OF_PAGES; 02124 bat[1].ClusterSize = ZSIZE_OF_PAGES_IN_WORDS * 4; 02125 bat[1].bits.q = ZLOG_SIZE_OF_PAGES_IN_WORDS; // 2**13 = 8192 elements 02126 bat[1].bits.v = 5; // 32 bits per element 02127 02128 initCommonData(); 02129 initRecords(); 02130 02131 ReadConfigConf * conf = (ReadConfigConf*)signal->getDataPtrSend(); 02132 conf->senderRef = reference(); 02133 conf->senderData = senderData; 02134 sendSignal(ref, GSN_READ_CONFIG_CONF, signal, 02135 ReadConfigConf::SignalLength, JBB); 02136 02137 { 02138 Ptr<DictObject> ptr; 02139 SLList<DictObject> objs(c_obj_pool); 02140 while(objs.seize(ptr)) 02141 new (ptr.p) DictObject(); 02142 objs.release(); 02143 } 02144 }//execSIZEALT_REP() 02145 02146 /* ---------------------------------------------------------------- */ 02147 // Start phase signals sent by CNTR. We reply with NDB_STTORRY when 02148 // we completed this phase. 02149 /* ---------------------------------------------------------------- */ 02150 void Dbdict::execNDB_STTOR(Signal* signal) 02151 { 02152 jamEntry(); 02153 c_startPhase = signal->theData[2]; 02154 const Uint32 restartType = signal->theData[3]; 02155 if (restartType == NodeState::ST_INITIAL_START) { 02156 jam(); 02157 c_initialStart = true; 02158 } else if (restartType == NodeState::ST_SYSTEM_RESTART) { 02159 jam(); 02160 c_systemRestart = true; 02161 } else if (restartType == NodeState::ST_INITIAL_NODE_RESTART) { 02162 jam(); 02163 c_initialNodeRestart = true; 02164 } else if (restartType == NodeState::ST_NODE_RESTART) { 02165 jam(); 02166 c_nodeRestart = true; 02167 } else { 02168 ndbrequire(false); 02169 }//if 02170 switch (c_startPhase) { 02171 case 1: 02172 jam(); 02173 initSchemaFile(signal); 02174 break; 02175 case 3: 02176 jam(); 02177 signal->theData[0] = reference(); 02178 sendSignal(NDBCNTR_REF, GSN_READ_NODESREQ, signal, 1, JBB); 02179 break; 02180 case 6: 02181 jam(); 02182 c_initialStart = false; 02183 c_systemRestart = false; 02184 c_initialNodeRestart = false; 02185 c_nodeRestart = false; 02186 sendNDB_STTORRY(signal); 02187 break; 02188 case 7: 02189 // uses c_restartType 02190 if(restartType == NodeState::ST_SYSTEM_RESTART && 02191 c_masterNodeId == getOwnNodeId()){ 02192 rebuildIndexes(signal, 0); 02193 return; 02194 } 02195 sendNDB_STTORRY(signal); 02196 break; 02197 default: 02198 jam(); 02199 sendNDB_STTORRY(signal); 02200 break; 02201 }//switch 02202 }//execNDB_STTOR() 02203 02204 void Dbdict::sendNDB_STTORRY(Signal* signal) 02205 { 02206 signal->theData[0] = reference(); 02207 sendSignal(NDBCNTR_REF, GSN_NDB_STTORRY, signal, 1, JBB); 02208 return; 02209 }//sendNDB_STTORRY() 02210 02211 /* ---------------------------------------------------------------- */ 02212 // We receive the information about which nodes that are up and down. 02213 /* ---------------------------------------------------------------- */ 02214 void Dbdict::execREAD_NODESCONF(Signal* signal) 02215 { 02216 jamEntry(); 02217 02218 ReadNodesConf * const readNodes = (ReadNodesConf *)&signal->theData[0]; 02219 c_numberNode = readNodes->noOfNodes; 02220 c_masterNodeId = readNodes->masterNodeId; 02221 02222 c_noNodesFailed = 0; 02223 c_aliveNodes.clear(); 02224 for (unsigned i = 1; i < MAX_NDB_NODES; i++) { 02225 jam(); 02226 NodeRecordPtr nodePtr; 02227 c_nodes.getPtr(nodePtr, i); 02228 02229 if (NodeBitmask::get(readNodes->allNodes, i)) { 02230 jam(); 02231 nodePtr.p->nodeState = NodeRecord::NDB_NODE_ALIVE; 02232 if (NodeBitmask::get(readNodes->inactiveNodes, i)) { 02233 jam(); 02241 nodePtr.p->nodeState = NodeRecord::NDB_NODE_DEAD; 02242 c_noNodesFailed++; 02243 } else { 02244 c_aliveNodes.set(i); 02245 } 02246 }//if 02247 }//for 02248 sendNDB_STTORRY(signal); 02249 }//execREAD_NODESCONF() 02250 02251 /* ---------------------------------------------------------------- */ 02252 // HOT_SPAREREP informs DBDICT about which nodes that have become 02253 // hot spare nodes. 02254 /* ---------------------------------------------------------------- */ 02255 void Dbdict::execHOT_SPAREREP(Signal* signal) 02256 { 02257 Uint32 hotSpareNodes = 0; 02258 jamEntry(); 02259 HotSpareRep * const hotSpare = (HotSpareRep*)&signal->theData[0]; 02260 for (unsigned i = 1; i < MAX_NDB_NODES; i++) { 02261 if (NodeBitmask::get(hotSpare->theHotSpareNodes, i)) { 02262 NodeRecordPtr nodePtr; 02263 c_nodes.getPtr(nodePtr, i); 02264 nodePtr.p->hotSpare = true; 02265 hotSpareNodes++; 02266 }//if 02267 }//for 02268 ndbrequire(hotSpareNodes == hotSpare->noHotSpareNodes); 02269 c_noHotSpareNodes = hotSpareNodes; 02270 return; 02271 }//execHOT_SPAREREP() 02272 02273 void Dbdict::initSchemaFile(Signal* signal) 02274 { 02275 XSchemaFile * xsf = &c_schemaFile[c_schemaRecord.schemaPage != 0]; 02276 xsf->noOfPages = (c_tableRecordPool.getSize() + NDB_SF_PAGE_ENTRIES - 1) 02277 / NDB_SF_PAGE_ENTRIES; 02278 initSchemaFile(xsf, 0, xsf->noOfPages, true); 02279 // init alt copy too for INR 02280 XSchemaFile * oldxsf = &c_schemaFile[c_schemaRecord.oldSchemaPage != 0]; 02281 oldxsf->noOfPages = xsf->noOfPages; 02282 memcpy(&oldxsf->schemaPage[0], &xsf->schemaPage[0], xsf->schemaPage[0].FileSize); 02283 02284 if (c_initialStart || c_initialNodeRestart) { 02285 jam(); 02286 ndbrequire(c_writeSchemaRecord.inUse == false); 02287 c_writeSchemaRecord.inUse = true; 02288 c_writeSchemaRecord.pageId = c_schemaRecord.schemaPage; 02289 c_writeSchemaRecord.newFile = true; 02290 c_writeSchemaRecord.firstPage = 0; 02291 c_writeSchemaRecord.noOfPages = xsf->noOfPages; 02292 02293 c_writeSchemaRecord.m_callback.m_callbackFunction = 02294 safe_cast(&Dbdict::initSchemaFile_conf); 02295 02296 startWriteSchemaFile(signal); 02297 } else if (c_systemRestart || c_nodeRestart) { 02298 jam(); 02299 ndbrequire(c_readSchemaRecord.schemaReadState == ReadSchemaRecord::IDLE); 02300 c_readSchemaRecord.pageId = c_schemaRecord.oldSchemaPage; 02301 c_readSchemaRecord.firstPage = 0; 02302 c_readSchemaRecord.noOfPages = 1; 02303 c_readSchemaRecord.schemaReadState = ReadSchemaRecord::INITIAL_READ_HEAD; 02304 startReadSchemaFile(signal); 02305 } else { 02306 ndbrequire(false); 02307 }//if 02308 }//Dbdict::initSchemaFile() 02309 02310 void 02311 Dbdict::initSchemaFile_conf(Signal* signal, Uint32 callbackData, Uint32 rv){ 02312 jam(); 02313 sendNDB_STTORRY(signal); 02314 } 02315 02316 void 02317 Dbdict::activateIndexes(Signal* signal, Uint32 i) 02318 { 02319 AlterIndxReq* req = (AlterIndxReq*)signal->getDataPtrSend(); 02320 TableRecordPtr tablePtr; 02321 for (; i < c_tableRecordPool.getSize(); i++) { 02322 tablePtr.i = i; 02323 c_tableRecordPool.getPtr(tablePtr); 02324 if (tablePtr.p->tabState != TableRecord::DEFINED) 02325 continue; 02326 if (! tablePtr.p->isIndex()) 02327 continue; 02328 jam(); 02329 req->setUserRef(reference()); 02330 req->setConnectionPtr(i); 02331 req->setTableId(tablePtr.p->primaryTableId); 02332 req->setIndexId(tablePtr.i); 02333 req->setIndexVersion(tablePtr.p->tableVersion); 02334 req->setOnline(true); 02335 if (c_restartType == NodeState::ST_SYSTEM_RESTART) { 02336 if (c_masterNodeId != getOwnNodeId()) 02337 continue; 02338 // from file index state is not defined currently 02339 req->setRequestType(AlterIndxReq::RT_SYSTEMRESTART); 02340 req->addRequestFlag((Uint32)RequestFlag::RF_NOBUILD); 02341 } 02342 else if ( 02343 c_restartType == NodeState::ST_NODE_RESTART || 02344 c_restartType == NodeState::ST_INITIAL_NODE_RESTART) { 02345 // from master index must be online 02346 if (tablePtr.p->indexState != TableRecord::IS_ONLINE) 02347 continue; 02348 req->setRequestType(AlterIndxReq::RT_NODERESTART); 02349 // activate locally, rebuild not needed 02350 req->addRequestFlag((Uint32)RequestFlag::RF_LOCAL); 02351 req->addRequestFlag((Uint32)RequestFlag::RF_NOBUILD); 02352 } else { 02353 ndbrequire(false); 02354 } 02355 sendSignal(reference(), GSN_ALTER_INDX_REQ, 02356 signal, AlterIndxReq::SignalLength, JBB); 02357 return; 02358 } 02359 signal->theData[0] = reference(); 02360 sendSignal(c_restartRecord.returnBlockRef, GSN_DICTSTARTCONF, 02361 signal, 1, JBB); 02362 } 02363 02364 void 02365 Dbdict::rebuildIndexes(Signal* signal, Uint32 i){ 02366 BuildIndxReq* const req = (BuildIndxReq*)signal->getDataPtrSend(); 02367 02368 TableRecordPtr indexPtr; 02369 for (; i < c_tableRecordPool.getSize(); i++) { 02370 indexPtr.i = i; 02371 c_tableRecordPool.getPtr(indexPtr); 02372 if (indexPtr.p->tabState != TableRecord::DEFINED) 02373 continue; 02374 if (! indexPtr.p->isIndex()) 02375 continue; 02376 02377 jam(); 02378 02379 req->setUserRef(reference()); 02380 req->setConnectionPtr(i); 02381 req->setRequestType(BuildIndxReq::RT_SYSTEMRESTART); 02382 req->setBuildId(0); // not used 02383 req->setBuildKey(0); // not used 02384 req->setIndexType(indexPtr.p->tableType); 02385 req->setIndexId(indexPtr.i); 02386 req->setTableId(indexPtr.p->primaryTableId); 02387 req->setParallelism(16); 02388 02389 // from file index state is not defined currently 02390 if (indexPtr.p->m_bits & TableRecord::TR_Logged) { 02391 // rebuild not needed 02392 req->addRequestFlag((Uint32)RequestFlag::RF_NOBUILD); 02393 } 02394 02395 // send 02396 sendSignal(reference(), GSN_BUILDINDXREQ, 02397 signal, BuildIndxReq::SignalLength, JBB); 02398 return; 02399 } 02400 sendNDB_STTORRY(signal); 02401 } 02402 02403 02404 /* **************************************************************** */ 02405 /* ---------------------------------------------------------------- */ 02406 /* MODULE: SYSTEM RESTART MODULE ------------------------- */ 02407 /* ---------------------------------------------------------------- */ 02408 /* */ 02409 /* This module contains code specific for system restart */ 02410 /* ---------------------------------------------------------------- */ 02411 /* **************************************************************** */ 02412 02413 /* ---------------------------------------------------------------- */ 02414 // DIH asks DICT to read in table data from disk during system 02415 // restart. DIH also asks DICT to send information about which 02416 // tables that should be started as part of this system restart. 02417 // DICT will also activate the tables in TC as part of this process. 02418 /* ---------------------------------------------------------------- */ 02419 void Dbdict::execDICTSTARTREQ(Signal* signal) 02420 { 02421 jamEntry(); 02422 c_restartRecord.gciToRestart = signal->theData[0]; 02423 c_restartRecord.returnBlockRef = signal->theData[1]; 02424 if (c_nodeRestart || c_initialNodeRestart) { 02425 jam(); 02426 02427 CRASH_INSERTION(6000); 02428 02429 BlockReference dictRef = calcDictBlockRef(c_masterNodeId); 02430 signal->theData[0] = getOwnNodeId(); 02431 sendSignal(dictRef, GSN_GET_SCHEMA_INFOREQ, signal, 1, JBB); 02432 return; 02433 } 02434 ndbrequire(c_systemRestart); 02435 ndbrequire(c_masterNodeId == getOwnNodeId()); 02436 02437 c_schemaRecord.m_callback.m_callbackData = 0; 02438 c_schemaRecord.m_callback.m_callbackFunction = 02439 safe_cast(&Dbdict::masterRestart_checkSchemaStatusComplete); 02440 02441 c_restartRecord.m_pass = 0; 02442 c_restartRecord.activeTable = 0; 02443 c_schemaRecord.schemaPage = c_schemaRecord.oldSchemaPage; // ugly 02444 checkSchemaStatus(signal); 02445 }//execDICTSTARTREQ() 02446 02447 void 02448 Dbdict::masterRestart_checkSchemaStatusComplete(Signal* signal, 02449 Uint32 callbackData, 02450 Uint32 returnCode){ 02451 02452 c_schemaRecord.schemaPage = 0; // ugly 02453 XSchemaFile * oldxsf = &c_schemaFile[c_schemaRecord.oldSchemaPage != 0]; 02454 ndbrequire(oldxsf->noOfPages != 0); 02455 02456 LinearSectionPtr ptr[3]; 02457 ptr[0].p = (Uint32*)&oldxsf->schemaPage[0]; 02458 ptr[0].sz = oldxsf->noOfPages * NDB_SF_PAGE_SIZE_IN_WORDS; 02459 02460 c_sendSchemaRecord.m_SCHEMAINFO_Counter = c_aliveNodes; 02461 NodeReceiverGroup rg(DBDICT, c_aliveNodes); 02462 02463 rg.m_nodes.clear(getOwnNodeId()); 02464 Callback c = { 0, 0 }; 02465 sendFragmentedSignal(rg, 02466 GSN_SCHEMA_INFO, 02467 signal, 02468 1, //SchemaInfo::SignalLength, 02469 JBB, 02470 ptr, 02471 1, 02472 c); 02473 02474 XSchemaFile * newxsf = &c_schemaFile[c_schemaRecord.schemaPage != 0]; 02475 newxsf->noOfPages = oldxsf->noOfPages; 02476 memcpy(&newxsf->schemaPage[0], &oldxsf->schemaPage[0], 02477 oldxsf->noOfPages * NDB_SF_PAGE_SIZE); 02478 02479 signal->theData[0] = getOwnNodeId(); 02480 sendSignal(reference(), GSN_SCHEMA_INFOCONF, signal, 1, JBB); 02481 } 02482 02483 void 02484 Dbdict::execGET_SCHEMA_INFOREQ(Signal* signal){ 02485 02486 const Uint32 ref = signal->getSendersBlockRef(); 02487 //const Uint32 senderData = signal->theData[0]; 02488 02489 ndbrequire(c_sendSchemaRecord.inUse == false); 02490 c_sendSchemaRecord.inUse = true; 02491 02492 LinearSectionPtr ptr[3]; 02493 02494 XSchemaFile * xsf = &c_schemaFile[c_schemaRecord.schemaPage != 0]; 02495 ndbrequire(xsf->noOfPages != 0); 02496 02497 ptr[0].p = (Uint32*)&xsf->schemaPage[0]; 02498 ptr[0].sz = xsf->noOfPages * NDB_SF_PAGE_SIZE_IN_WORDS; 02499 02500 Callback c = { safe_cast(&Dbdict::sendSchemaComplete), 0 }; 02501 sendFragmentedSignal(ref, 02502 GSN_SCHEMA_INFO, 02503 signal, 02504 1, //GetSchemaInfoConf::SignalLength, 02505 JBB, 02506 ptr, 02507 1, 02508 c); 02509 }//Dbdict::execGET_SCHEMA_INFOREQ() 02510 02511 void 02512 Dbdict::sendSchemaComplete(Signal * signal, 02513 Uint32 callbackData, 02514 Uint32 returnCode){ 02515 ndbrequire(c_sendSchemaRecord.inUse == true); 02516 c_sendSchemaRecord.inUse = false; 02517 02518 } 02519 02520 02521 /* ---------------------------------------------------------------- */ 02522 // We receive the schema info from master as part of all restarts 02523 // except the initial start where no tables exists. 02524 /* ---------------------------------------------------------------- */ 02525 void Dbdict::execSCHEMA_INFO(Signal* signal) 02526 { 02527 jamEntry(); 02528 if(!assembleFragments(signal)){ 02529 jam(); 02530 return; 02531 } 02532 02533 if(getNodeState().getNodeRestartInProgress()){ 02534 CRASH_INSERTION(6001); 02535 } 02536 02537 SegmentedSectionPtr schemaDataPtr; 02538 signal->getSection(schemaDataPtr, 0); 02539 02540 XSchemaFile * xsf = &c_schemaFile[c_schemaRecord.schemaPage != 0]; 02541 ndbrequire(schemaDataPtr.sz % NDB_SF_PAGE_SIZE_IN_WORDS == 0); 02542 xsf->noOfPages = schemaDataPtr.sz / NDB_SF_PAGE_SIZE_IN_WORDS; 02543 copy((Uint32*)&xsf->schemaPage[0], schemaDataPtr); 02544 releaseSections(signal); 02545 02546 SchemaFile * sf0 = &xsf->schemaPage[0]; 02547 if (sf0->NdbVersion < NDB_SF_VERSION_5_0_6) { 02548 bool ok = convertSchemaFileTo_5_0_6(xsf); 02549 ndbrequire(ok); 02550 } 02551 02552 validateChecksum(xsf); 02553 02554 XSchemaFile * oldxsf = &c_schemaFile[c_schemaRecord.oldSchemaPage != 0]; 02555 resizeSchemaFile(xsf, oldxsf->noOfPages); 02556 02557 ndbrequire(signal->getSendersBlockRef() != reference()); 02558 02559 /* ---------------------------------------------------------------- */ 02560 // Synchronise our view on data with other nodes in the cluster. 02561 // This is an important part of restart handling where we will handle 02562 // cases where the table have been added but only partially, where 02563 // tables have been deleted but not completed the deletion yet and 02564 // other scenarios needing synchronisation. 02565 /* ---------------------------------------------------------------- */ 02566 c_schemaRecord.m_callback.m_callbackData = 0; 02567 c_schemaRecord.m_callback.m_callbackFunction = 02568 safe_cast(&Dbdict::restart_checkSchemaStatusComplete); 02569 02570 c_restartRecord.m_pass= 0; 02571 c_restartRecord.activeTable = 0; 02572 checkSchemaStatus(signal); 02573 }//execSCHEMA_INFO() 02574 02575 void 02576 Dbdict::restart_checkSchemaStatusComplete(Signal * signal, 02577 Uint32 callbackData, 02578 Uint32 returnCode){ 02579 02580 ndbrequire(c_writeSchemaRecord.inUse == false); 02581 c_writeSchemaRecord.inUse = true; 02582 XSchemaFile * xsf = &c_schemaFile[c_schemaRecord.schemaPage != 0]; 02583 c_writeSchemaRecord.pageId = c_schemaRecord.schemaPage; 02584 c_writeSchemaRecord.newFile = true; 02585 c_writeSchemaRecord.firstPage = 0; 02586 c_writeSchemaRecord.noOfPages = xsf->noOfPages; 02587 c_writeSchemaRecord.m_callback.m_callbackData = 0; 02588 c_writeSchemaRecord.m_callback.m_callbackFunction = 02589 safe_cast(&Dbdict::restart_writeSchemaConf); 02590 02591 for(Uint32 i = 0; i<xsf->noOfPages; i++) 02592 computeChecksum(xsf, i); 02593 02594 startWriteSchemaFile(signal); 02595 } 02596 02597 void 02598 Dbdict::restart_writeSchemaConf(Signal * signal, 02599 Uint32 callbackData, 02600 Uint32 returnCode){ 02601 02602 if(c_systemRestart){ 02603 jam(); 02604 signal->theData[0] = getOwnNodeId(); 02605 sendSignal(calcDictBlockRef(c_masterNodeId), GSN_SCHEMA_INFOCONF, 02606 signal, 1, JBB); 02607 return; 02608 } 02609 02610 ndbrequire(c_nodeRestart || c_initialNodeRestart); 02611 c_blockState = BS_IDLE; 02612 activateIndexes(signal, 0); 02613 return; 02614 } 02615 02616 void Dbdict::execSCHEMA_INFOCONF(Signal* signal) 02617 { 02618 jamEntry(); 02619 ndbrequire(signal->getNoOfSections() == 0); 02620 02621 /* ---------------------------------------------------------------- */ 02622 // This signal is received in the master as part of system restart 02623 // from all nodes (including the master) after they have synchronised 02624 // their data with the master node's schema information. 02625 /* ---------------------------------------------------------------- */ 02626 const Uint32 nodeId = signal->theData[0]; 02627 c_sendSchemaRecord.m_SCHEMAINFO_Counter.clearWaitingFor(nodeId); 02628 02629 if (!c_sendSchemaRecord.m_SCHEMAINFO_Counter.done()){ 02630 jam(); 02631 return; 02632 }//if 02633 activateIndexes(signal, 0); 02634 }//execSCHEMA_INFOCONF() 02635 02636 static bool 02637 checkSchemaStatus(Uint32 tableType, Uint32 pass) 02638 { 02639 switch(tableType){ 02640 case DictTabInfo::UndefTableType: 02641 return true; 02642 case DictTabInfo::HashIndexTrigger: 02643 case DictTabInfo::SubscriptionTrigger: 02644 case DictTabInfo::ReadOnlyConstraint: 02645 case DictTabInfo::IndexTrigger: 02646 return false; 02647 case DictTabInfo::LogfileGroup: 02648 return pass == 0; 02649 case DictTabInfo::Tablespace: 02650 return pass == 1; 02651 case DictTabInfo::Datafile: 02652 case DictTabInfo::Undofile: 02653 return pass == 2; 02654 case DictTabInfo::SystemTable: 02655 case DictTabInfo::UserTable: 02656 return pass == 3; 02657 case DictTabInfo::UniqueHashIndex: 02658 case DictTabInfo::HashIndex: 02659 case DictTabInfo::UniqueOrderedIndex: 02660 case DictTabInfo::OrderedIndex: 02661 return pass == 4; 02662 } 02663 02664 return false; 02665 } 02666 02667 void Dbdict::checkSchemaStatus(Signal* signal) 02668 { 02669 XSchemaFile * newxsf = &c_schemaFile[c_schemaRecord.schemaPage != 0]; 02670 XSchemaFile * oldxsf = &c_schemaFile[c_schemaRecord.oldSchemaPage != 0]; 02671 ndbrequire(newxsf->noOfPages == oldxsf->noOfPages); 02672 const Uint32 noOfEntries = newxsf->noOfPages * NDB_SF_PAGE_ENTRIES; 02673 02674 for (; c_restartRecord.activeTable < noOfEntries; 02675 c_restartRecord.activeTable++) { 02676 jam(); 02677 02678 Uint32 tableId = c_restartRecord.activeTable; 02679 SchemaFile::TableEntry *newEntry = getTableEntry(newxsf, tableId); 02680 SchemaFile::TableEntry *oldEntry = getTableEntry(oldxsf, tableId); 02681 SchemaFile::TableState schemaState = 02682 (SchemaFile::TableState)newEntry->m_tableState; 02683 SchemaFile::TableState oldSchemaState = 02684 (SchemaFile::TableState)oldEntry->m_tableState; 02685 02686 if (c_restartRecord.activeTable >= c_tableRecordPool.getSize()) { 02687 jam(); 02688 ndbrequire(schemaState == SchemaFile::INIT); 02689 ndbrequire(oldSchemaState == SchemaFile::INIT); 02690 continue; 02691 }//if 02692 02693 if(!::checkSchemaStatus(oldEntry->m_tableType, c_restartRecord.m_pass)) 02694 continue; 02695 02696 if(!::checkSchemaStatus(newEntry->m_tableType, c_restartRecord.m_pass)) 02697 continue; 02698 02699 switch(schemaState){ 02700 case SchemaFile::INIT:{ 02701 jam(); 02702 bool ok = false; 02703 switch(oldSchemaState) { 02704 case SchemaFile::INIT: 02705 jam(); 02706 case SchemaFile::DROP_TABLE_COMMITTED: 02707 jam(); 02708 ok = true; 02709 jam(); 02710 break; 02711 02712 case SchemaFile::ADD_STARTED: 02713 jam(); 02714 case SchemaFile::TABLE_ADD_COMMITTED: 02715 jam(); 02716 case SchemaFile::DROP_TABLE_STARTED: 02717 jam(); 02718 case SchemaFile::ALTER_TABLE_COMMITTED: 02719 jam(); 02720 ok = true; 02721 jam(); 02722 newEntry->m_tableState = SchemaFile::INIT; 02723 restartDropTab(signal, tableId); 02724 return; 02725 }//switch 02726 ndbrequire(ok); 02727 break; 02728 } 02729 case SchemaFile::ADD_STARTED:{ 02730 jam(); 02731 bool ok = false; 02732 switch(oldSchemaState) { 02733 case SchemaFile::INIT: 02734 jam(); 02735 case SchemaFile::DROP_TABLE_COMMITTED: 02736 jam(); 02737 ok = true; 02738 break; 02739 case SchemaFile::ADD_STARTED: 02740 jam(); 02741 case SchemaFile::DROP_TABLE_STARTED: 02742 jam(); 02743 case SchemaFile::TABLE_ADD_COMMITTED: 02744 jam(); 02745 case SchemaFile::ALTER_TABLE_COMMITTED: 02746 jam(); 02747 ok = true; 02748 //------------------------------------------------------------------ 02749 // Add Table was started but not completed. Will be dropped in all 02750 // nodes. Update schema information (restore table version). 02751 //------------------------------------------------------------------ 02752 newEntry->m_tableState = SchemaFile::INIT; 02753 restartDropTab(signal, tableId); 02754 return; 02755 } 02756 ndbrequire(ok); 02757 break; 02758 } 02759 case SchemaFile::TABLE_ADD_COMMITTED:{ 02760 jam(); 02761 bool ok = false; 02762 switch(oldSchemaState) { 02763 case SchemaFile::INIT: 02764 jam(); 02765 case SchemaFile::ADD_STARTED: 02766 jam(); 02767 case SchemaFile::DROP_TABLE_STARTED: 02768 jam(); 02769 case SchemaFile::DROP_TABLE_COMMITTED: 02770 jam(); 02771 ok = true; 02772 //------------------------------------------------------------------ 02773 // Table was added in the master node but not in our node. We can 02774 // retrieve the table definition from the master. 02775 //------------------------------------------------------------------ 02776 restartCreateTab(signal, tableId, oldEntry, newEntry, false); 02777 return; 02778 break; 02779 case SchemaFile::TABLE_ADD_COMMITTED: 02780 jam(); 02781 case SchemaFile::ALTER_TABLE_COMMITTED: 02782 jam(); 02783 ok = true; 02784 //------------------------------------------------------------------ 02785 // Table was added in both our node and the master node. We can 02786 // retrieve the table definition from our own disk. 02787 //------------------------------------------------------------------ 02788 if(newEntry->m_tableVersion == oldEntry->m_tableVersion) 02789 { 02790 jam(); 02791 ndbrequire(newEntry->m_gcp == oldEntry->m_gcp); 02792 ndbrequire(newEntry->m_tableType == oldEntry->m_tableType); 02793 Uint32 type= oldEntry->m_tableType; 02794 // On NR get index from master because index state is not on file 02795 const bool file = c_systemRestart || !DictTabInfo::isIndex(type); 02796 newEntry->m_info_words= oldEntry->m_info_words; 02797 restartCreateTab(signal, tableId, oldEntry, newEntry, file); 02798 02799 return; 02800 } else { 02801 //------------------------------------------------------------------ 02802 // Must be a new version of the table if anything differs. Both table 02803 // version and global checkpoint must be different. 02804 // This should not happen for the master node. This can happen after 02805 // drop table followed by add table or after change table. 02806 // Not supported in this version. 02807 //------------------------------------------------------------------ 02808 ndbrequire(c_masterNodeId != getOwnNodeId()); 02809 ndbrequire(newEntry->m_tableVersion != oldEntry->m_tableVersion); 02810 jam(); 02811 02812 restartCreateTab(signal, tableId, oldEntry, newEntry, false); 02813 return; 02814 }//if 02815 } 02816 ndbrequire(ok); 02817 break; 02818 } 02819 case SchemaFile::DROP_TABLE_STARTED: 02820 jam(); 02821 case SchemaFile::DROP_TABLE_COMMITTED:{ 02822 jam(); 02823 bool ok = false; 02824 switch(oldSchemaState){ 02825 case SchemaFile::INIT: 02826 jam(); 02827 case SchemaFile::DROP_TABLE_COMMITTED: 02828 jam(); 02829 ok = true; 02830 break; 02831 case SchemaFile::ADD_STARTED: 02832 jam(); 02833 case SchemaFile::TABLE_ADD_COMMITTED: 02834 jam(); 02835 case SchemaFile::DROP_TABLE_STARTED: 02836 jam(); 02837 case SchemaFile::ALTER_TABLE_COMMITTED: 02838 jam(); 02839 newEntry->m_tableState = SchemaFile::INIT; 02840 restartDropTab(signal, tableId); 02841 return; 02842 } 02843 ndbrequire(ok); 02844 break; 02845 } 02846 case SchemaFile::ALTER_TABLE_COMMITTED: { 02847 jam(); 02848 bool ok = false; 02849 switch(oldSchemaState) { 02850 case SchemaFile::INIT: 02851 jam(); 02852 case SchemaFile::ADD_STARTED: 02853 jam(); 02854 case SchemaFile::DROP_TABLE_STARTED: 02855 jam(); 02856 case SchemaFile::DROP_TABLE_COMMITTED: 02857 jam(); 02858 case SchemaFile::TABLE_ADD_COMMITTED: 02859 jam(); 02860 ok = true; 02861 //------------------------------------------------------------------ 02862 // Table was altered in the master node but not in our node. We can 02863 // retrieve the altered table definition from the master. 02864 //------------------------------------------------------------------ 02865 restartCreateTab(signal, tableId, oldEntry, newEntry, false); 02866 return; 02867 break; 02868 case SchemaFile::ALTER_TABLE_COMMITTED: 02869 jam(); 02870 ok = true; 02871 02872 //------------------------------------------------------------------ 02873 // Table was altered in both our node and the master node. We can 02874 // retrieve the table definition from our own disk. 02875 //------------------------------------------------------------------ 02876 02877 // On NR get index from master because index state is not on file 02878 Uint32 type= oldEntry->m_tableType; 02879 const bool file = c_systemRestart || !DictTabInfo::isIndex(type); 02880 newEntry->m_info_words= oldEntry->m_info_words; 02881 restartCreateTab(signal, tableId, oldEntry, newEntry, file); 02882 02883 return; 02884 } 02885 ndbrequire(ok); 02886 break; 02887 } 02888 } 02889 } 02890 02891 c_restartRecord.m_pass++; 02892 c_restartRecord.activeTable= 0; 02893 if(c_restartRecord.m_pass <= 4) 02894 { 02895 checkSchemaStatus(signal); 02896 } 02897 else 02898 { 02899 execute(signal, c_schemaRecord.m_callback, 0); 02900 } 02901 }//checkSchemaStatus() 02902 02903 void 02904 Dbdict::restartCreateTab(Signal* signal, Uint32 tableId, 02905 const SchemaFile::TableEntry * old_entry, 02906 const SchemaFile::TableEntry * new_entry, 02907 bool file){ 02908 jam(); 02909 02910 switch(new_entry->m_tableType){ 02911 case DictTabInfo::UndefTableType: 02912 case DictTabInfo::HashIndexTrigger: 02913 case DictTabInfo::SubscriptionTrigger: 02914 case DictTabInfo::ReadOnlyConstraint: 02915 case DictTabInfo::IndexTrigger: 02916 ndbrequire(false); 02917 case DictTabInfo::SystemTable: 02918 case DictTabInfo::UserTable: 02919 case DictTabInfo::UniqueHashIndex: 02920 case DictTabInfo::HashIndex: 02921 case DictTabInfo::UniqueOrderedIndex: 02922 case DictTabInfo::OrderedIndex: 02923 break; 02924 case DictTabInfo::Tablespace: 02925 case DictTabInfo::LogfileGroup: 02926 case DictTabInfo::Datafile: 02927 case DictTabInfo::Undofile: 02928 restartCreateObj(signal, tableId, old_entry, new_entry, file); 02929 return; 02930 } 02931 02932 CreateTableRecordPtr createTabPtr; 02933 c_opCreateTable.seize(createTabPtr); 02934 ndbrequire(!createTabPtr.isNull()); 02935 02936 createTabPtr.p->key = ++c_opRecordSequence; 02937 c_opCreateTable.add(createTabPtr); 02938 02939 createTabPtr.p->m_errorCode = 0; 02940 createTabPtr.p->m_tablePtrI = tableId; 02941 createTabPtr.p->m_coordinatorRef = reference(); 02942 createTabPtr.p->m_senderRef = 0; 02943 createTabPtr.p->m_senderData = RNIL; 02944 createTabPtr.p->m_tabInfoPtrI = RNIL; 02945 createTabPtr.p->m_dihAddFragPtr = RNIL; 02946 02947 if(file && !ERROR_INSERTED(6002)){ 02948 jam(); 02949 02950 c_readTableRecord.no_of_words = old_entry->m_info_words; 02951 c_readTableRecord.pageId = 0; 02952 c_readTableRecord.m_callback.m_callbackData = createTabPtr.p->key; 02953 c_readTableRecord.m_callback.m_callbackFunction = 02954 safe_cast(&Dbdict::restartCreateTab_readTableConf); 02955 02956 startReadTableFile(signal, tableId); 02957 return; 02958 } else { 02959 02960 ndbrequire(c_masterNodeId != getOwnNodeId()); 02961 02965 GetTabInfoReq * const req = (GetTabInfoReq *)&signal->theData[0]; 02966 req->senderRef = reference(); 02967 req->senderData = createTabPtr.p->key; 02968 req->requestType = GetTabInfoReq::RequestById | 02969 GetTabInfoReq::LongSignalConf; 02970 req->tableId = tableId; 02971 sendSignal(calcDictBlockRef(c_masterNodeId), GSN_GET_TABINFOREQ, signal, 02972 GetTabInfoReq::SignalLength, JBB); 02973 02974 if(ERROR_INSERTED(6002)){ 02975 NdbSleep_MilliSleep(10); 02976 CRASH_INSERTION(6002); 02977 } 02978 } 02979 } 02980 02981 void 02982 Dbdict::restartCreateTab_readTableConf(Signal* signal, 02983 Uint32 callbackData, 02984 Uint32 returnCode){ 02985 jam(); 02986 02987 PageRecordPtr pageRecPtr; 02988 c_pageRecordArray.getPtr(pageRecPtr, c_readTableRecord.pageId); 02989 02990 ParseDictTabInfoRecord parseRecord; 02991 parseRecord.requestType = DictTabInfo::GetTabInfoConf; 02992 parseRecord.errorCode = 0; 02993 02994 Uint32 sz = c_readTableRecord.no_of_words; 02995 SimplePropertiesLinearReader r(pageRecPtr.p->word+ZPAGE_HEADER_SIZE, sz); 02996 handleTabInfoInit(r, &parseRecord); 02997 if (parseRecord.errorCode != 0) 02998 { 02999 char buf[255]; 03000 BaseString::snprintf(buf, sizeof(buf), 03001 "Unable to restart, fail while creating table %d" 03002 " error: %d. Most likely change of configuration", 03003 c_readTableRecord.tableId, 03004 parseRecord.errorCode); 03005 progError(__LINE__, 03006 NDBD_EXIT_INVALID_CONFIG, 03007 buf); 03008 ndbrequire(parseRecord.errorCode == 0); 03009 } 03010 03011 /* ---------------------------------------------------------------- */ 03012 // We have read the table description from disk as part of system restart. 03013 // We will also write it back again to ensure that both copies are ok. 03014 /* ---------------------------------------------------------------- */ 03015 ndbrequire(c_writeTableRecord.tableWriteState == WriteTableRecord::IDLE); 03016 c_writeTableRecord.no_of_words = c_readTableRecord.no_of_words; 03017 c_writeTableRecord.pageId = c_readTableRecord.pageId; 03018 c_writeTableRecord.tableWriteState = WriteTableRecord::TWR_CALLBACK; 03019 c_writeTableRecord.m_callback.m_callbackData = callbackData; 03020 c_writeTableRecord.m_callback.m_callbackFunction = 03021 safe_cast(&Dbdict::restartCreateTab_writeTableConf); 03022 startWriteTableFile(signal, c_readTableRecord.tableId); 03023 } 03024 03025 void 03026 Dbdict::execGET_TABINFO_CONF(Signal* signal){ 03027 jamEntry(); 03028 03029 if(!assembleFragments(signal)){ 03030 jam(); 03031 return; 03032 } 03033 03034 GetTabInfoConf * const conf = (GetTabInfoConf*)signal->getDataPtr(); 03035 03036 switch(conf->tableType){ 03037 case DictTabInfo::UndefTableType: 03038 case DictTabInfo::HashIndexTrigger: 03039 case DictTabInfo::SubscriptionTrigger: 03040 case DictTabInfo::ReadOnlyConstraint: 03041 case DictTabInfo::IndexTrigger: 03042 ndbrequire(false); 03043 case DictTabInfo::SystemTable: 03044 case DictTabInfo::UserTable: 03045 case DictTabInfo::UniqueHashIndex: 03046 case DictTabInfo::HashIndex: 03047 case DictTabInfo::UniqueOrderedIndex: 03048 case DictTabInfo::OrderedIndex: 03049 break; 03050 case DictTabInfo::Tablespace: 03051 case DictTabInfo::LogfileGroup: 03052 case DictTabInfo::Datafile: 03053 case DictTabInfo::Undofile: 03054 if(refToBlock(conf->senderRef) == TSMAN 03055 && (refToNode(conf->senderRef) == 0 03056 || refToNode(conf->senderRef) == getOwnNodeId())) 03057 { 03058 jam(); 03059 FilePtr fg_ptr; 03060 ndbrequire(c_file_hash.find(fg_ptr, conf->tableId)); 03061 const Uint32 free_extents= conf->freeExtents; 03062 const Uint32 id= conf->tableId; 03063 const Uint32 type= conf->tableType; 03064 const Uint32 data= conf->senderData; 03065 signal->theData[0]= ZPACK_TABLE_INTO_PAGES; 03066 signal->theData[1]= id; 03067 signal->theData[2]= type; 03068 signal->theData[3]= data; 03069 signal->theData[4]= free_extents; 03070 sendSignal(reference(), GSN_CONTINUEB, signal, 5, JBB); 03071 } 03072 else if(refToBlock(conf->senderRef) == LGMAN 03073 && (refToNode(conf->senderRef) == 0 03074 || refToNode(conf->senderRef) == getOwnNodeId())) 03075 { 03076 jam(); 03077 FilegroupPtr fg_ptr; 03078 ndbrequire(c_filegroup_hash.find(fg_ptr, conf->tableId)); 03079 const Uint32 free_hi= conf->freeWordsHi; 03080 const Uint32 free_lo= conf->freeWordsLo; 03081 const Uint32 id= conf->tableId; 03082 const Uint32 type= conf->tableType; 03083 const Uint32 data= conf->senderData; 03084 signal->theData[0]= ZPACK_TABLE_INTO_PAGES; 03085 signal->theData[1]= id; 03086 signal->theData[2]= type; 03087 signal->theData[3]= data; 03088 signal->theData[4]= free_hi; 03089 signal->theData[5]= free_lo; 03090 sendSignal(reference(), GSN_CONTINUEB, signal, 6, JBB); 03091 } 03092 else 03093 { 03094 jam(); 03095 restartCreateObj_getTabInfoConf(signal); 03096 } 03097 return; 03098 } 03099 03100 const Uint32 tableId = conf->tableId; 03101 const Uint32 senderData = conf->senderData; 03102 03103 SegmentedSectionPtr tabInfoPtr; 03104 signal->getSection(tabInfoPtr, GetTabInfoConf::DICT_TAB_INFO); 03105 03106 CreateTableRecordPtr createTabPtr; 03107 ndbrequire(c_opCreateTable.find(createTabPtr, senderData)); 03108 ndbrequire(!createTabPtr.isNull()); 03109 ndbrequire(createTabPtr.p->m_tablePtrI == tableId); 03110 03114 ParseDictTabInfoRecord parseRecord; 03115 parseRecord.requestType = DictTabInfo::GetTabInfoConf; 03116 parseRecord.errorCode = 0; 03117 03118 SimplePropertiesSectionReader r(tabInfoPtr, getSectionSegmentPool()); 03119 handleTabInfoInit(r, &parseRecord); 03120 ndbrequire(parseRecord.errorCode == 0); 03121 03122 ndbrequire(tableId < c_tableRecordPool.getSize()); 03123 XSchemaFile * xsf = &c_schemaFile[c_schemaRecord.schemaPage != 0]; 03124 SchemaFile::TableEntry * tableEntry = getTableEntry(xsf, tableId); 03125 tableEntry->m_info_words= tabInfoPtr.sz; 03126 03127 Callback callback; 03128 callback.m_callbackData = createTabPtr.p->key; 03129 callback.m_callbackFunction = 03130 safe_cast(&Dbdict::restartCreateTab_writeTableConf); 03131 03132 signal->header.m_noOfSections = 0; 03133 writeTableFile(signal, createTabPtr.p->m_tablePtrI, tabInfoPtr, &callback); 03134 signal->setSection(tabInfoPtr, 0); 03135 releaseSections(signal); 03136 } 03137 03138 void 03139 Dbdict::restartCreateTab_writeTableConf(Signal* signal, 03140 Uint32 callbackData, 03141 Uint32 returnCode){ 03142 jam(); 03143 03144 CreateTableRecordPtr createTabPtr; 03145 ndbrequire(c_opCreateTable.find(createTabPtr, callbackData)); 03146 03147 Callback callback; 03148 callback.m_callbackData = callbackData; 03149 callback.m_callbackFunction = 03150 safe_cast(&Dbdict::restartCreateTab_dihComplete); 03151 03152 SegmentedSectionPtr fragDataPtr; 03153 fragDataPtr.sz = 0; 03154 fragDataPtr.setNull(); 03155 createTab_dih(signal, createTabPtr, fragDataPtr, &callback); 03156 } 03157 03158 void 03159 Dbdict::restartCreateTab_dihComplete(Signal* signal, 03160 Uint32 callbackData, 03161 Uint32 returnCode){ 03162 jam(); 03163 03164 CreateTableRecordPtr createTabPtr; 03165 ndbrequire(c_opCreateTable.find(createTabPtr, callbackData)); 03166 03167 //@todo check error 03168 ndbrequire(createTabPtr.p->m_errorCode == 0); 03169 03170 Callback callback; 03171 callback.m_callbackData = callbackData; 03172 callback.m_callbackFunction = 03173 safe_cast(&Dbdict::restartCreateTab_activateComplete); 03174 03175 alterTab_activate(signal, createTabPtr, &callback); 03176 } 03177 03178 void 03179 Dbdict::restartCreateTab_activateComplete(Signal* signal, 03180 Uint32 callbackData, 03181 Uint32 returnCode){ 03182 jam(); 03183 03184 CreateTableRecordPtr createTabPtr; 03185 ndbrequire(c_opCreateTable.find(createTabPtr, callbackData)); 03186 03187 TableRecordPtr tabPtr; 03188 c_tableRecordPool.getPtr(tabPtr, createTabPtr.p->m_tablePtrI); 03189 tabPtr.p->tabState = TableRecord::DEFINED; 03190 03191 releaseCreateTableOp(signal,createTabPtr); 03192 03193 c_restartRecord.activeTable++; 03194 checkSchemaStatus(signal); 03195 } 03196 03197 void 03198 Dbdict::releaseCreateTableOp(Signal* signal, CreateTableRecordPtr createTabPtr) 03199 { 03200 if (createTabPtr.p->m_tabInfoPtrI != RNIL) 03201 { 03202 jam(); 03203 SegmentedSectionPtr tabInfoPtr; 03204 getSection(tabInfoPtr, createTabPtr.p->m_tabInfoPtrI); 03205 signal->setSection(tabInfoPtr, 0); 03206 releaseSections(signal); 03207 } 03208 c_opCreateTable.release(createTabPtr); 03209 } 03210 03211 void 03212 Dbdict::restartDropTab(Signal* signal, Uint32 tableId){ 03213 03214 const Uint32 key = ++c_opRecordSequence; 03215 03216 DropTableRecordPtr dropTabPtr; 03217 ndbrequire(c_opDropTable.seize(dropTabPtr)); 03218 03219 dropTabPtr.p->key = key; 03220 c_opDropTable.add(dropTabPtr); 03221 03222 dropTabPtr.p->m_errorCode = 0; 03223 dropTabPtr.p->m_request.tableId = tableId; 03224 dropTabPtr.p->m_coordinatorRef = 0; 03225 dropTabPtr.p->m_requestType = DropTabReq::RestartDropTab; 03226 dropTabPtr.p->m_participantData.m_gsn = GSN_DROP_TAB_REQ; 03227 03228 dropTabPtr.p->m_participantData.m_block = 0; 03229 dropTabPtr.p->m_participantData.m_callback.m_callbackData = key; 03230 dropTabPtr.p->m_participantData.m_callback.m_callbackFunction = 03231 safe_cast(&Dbdict::restartDropTab_complete); 03232 dropTab_nextStep(signal, dropTabPtr); 03233 } 03234 03235 void 03236 Dbdict::restartDropTab_complete(Signal* signal, 03237 Uint32 callbackData, 03238 Uint32 returnCode){ 03239 jam(); 03240 03241 DropTableRecordPtr dropTabPtr; 03242 ndbrequire(c_opDropTable.find(dropTabPtr, callbackData)); 03243 03244 //@todo check error 03245 03246 c_opDropTable.release(dropTabPtr); 03247 03248 c_restartRecord.activeTable++; 03249 checkSchemaStatus(signal); 03250 } 03251 03252 void 03253 Dbdict::restartCreateObj(Signal* signal, 03254 Uint32 tableId, 03255 const SchemaFile::TableEntry * old_entry, 03256 const SchemaFile::TableEntry * new_entry, 03257 bool file){ 03258 jam(); 03259 03260 CreateObjRecordPtr createObjPtr; 03261 ndbrequire(c_opCreateObj.seize(createObjPtr)); 03262 03263 const Uint32 key = ++c_opRecordSequence; 03264 createObjPtr.p->key = key; 03265 c_opCreateObj.add(createObjPtr); 03266 createObjPtr.p->m_errorCode = 0; 03267 createObjPtr.p->m_senderRef = reference(); 03268 createObjPtr.p->m_senderData = tableId; 03269 createObjPtr.p->m_clientRef = reference(); 03270 createObjPtr.p->m_clientData = tableId; 03271 03272 createObjPtr.p->m_obj_id = tableId; 03273 createObjPtr.p->m_obj_type = new_entry->m_tableType; 03274 createObjPtr.p->m_obj_version = new_entry->m_tableVersion; 03275 03276 createObjPtr.p->m_callback.m_callbackData = key; 03277 createObjPtr.p->m_callback.m_callbackFunction= 03278 safe_cast(&Dbdict::restartCreateObj_prepare_start_done); 03279 03280 createObjPtr.p->m_restart= file ? 1 : 2; 03281 switch(new_entry->m_tableType){ 03282 case DictTabInfo::Tablespace: 03283 case DictTabInfo::LogfileGroup: 03284 createObjPtr.p->m_vt_index = 0; 03285 break; 03286 case DictTabInfo::Datafile: 03287 case DictTabInfo::Undofile: 03288 createObjPtr.p->m_vt_index = 1; 03289 break; 03290 default: 03291 ndbrequire(false); 03292 } 03293 03294 createObjPtr.p->m_obj_info_ptr_i = RNIL; 03295 if(file) 03296 { 03297 c_readTableRecord.no_of_words = old_entry->m_info_words; 03298 c_readTableRecord.pageId = 0; 03299 c_readTableRecord.m_callback.m_callbackData = key; 03300 c_readTableRecord.m_callback.m_callbackFunction = 03301 safe_cast(&Dbdict::restartCreateObj_readConf); 03302 03303 startReadTableFile(signal, tableId); 03304 } 03305 else 03306 { 03310 GetTabInfoReq * const req = (GetTabInfoReq *)&signal->theData[0]; 03311 req->senderRef = reference(); 03312 req->senderData = key; 03313 req->requestType = GetTabInfoReq::RequestById | 03314 GetTabInfoReq::LongSignalConf; 03315 req->tableId = tableId; 03316 sendSignal(calcDictBlockRef(c_masterNodeId), GSN_GET_TABINFOREQ, signal, 03317 GetTabInfoReq::SignalLength, JBB); 03318 } 03319 } 03320 03321 void 03322 Dbdict::restartCreateObj_getTabInfoConf(Signal* signal) 03323 { 03324 jam(); 03325 03326 GetTabInfoConf * const conf = (GetTabInfoConf*)signal->getDataPtr(); 03327 03328 const Uint32 objId = conf->tableId; 03329 const Uint32 senderData = conf->senderData; 03330 03331 SegmentedSectionPtr objInfoPtr; 03332 signal->getSection(objInfoPtr, GetTabInfoConf::DICT_TAB_INFO); 03333 03334 CreateObjRecordPtr createObjPtr; 03335 ndbrequire(c_opCreateObj.find(createObjPtr, senderData)); 03336 ndbrequire(createObjPtr.p->m_obj_id == objId); 03337 03338 createObjPtr.p->m_obj_info_ptr_i= objInfoPtr.i; 03339 signal->header.m_noOfSections = 0; 03340 03341 (this->*f_dict_op[createObjPtr.p->m_vt_index].m_prepare_start) 03342 (signal, createObjPtr.p); 03343 } 03344 03345 void 03346 Dbdict::restartCreateObj_readConf(Signal* signal, 03347 Uint32 callbackData, 03348 Uint32 returnCode) 03349 { 03350 jam(); 03351 ndbrequire(returnCode == 0); 03352 CreateObjRecordPtr createObjPtr; 03353 ndbrequire(c_opCreateObj.find(createObjPtr, callbackData)); 03354 ndbrequire(createObjPtr.p->m_errorCode == 0); 03355 03356 PageRecordPtr pageRecPtr; 03357 c_pageRecordArray.getPtr(pageRecPtr, c_readTableRecord.pageId); 03358 03359 Uint32 sz = c_readTableRecord.no_of_words; 03360 03361 Ptr<SectionSegment> ptr; 03362 ndbrequire(import(ptr, pageRecPtr.p->word+ZPAGE_HEADER_SIZE, sz)); 03363 createObjPtr.p->m_obj_info_ptr_i= ptr.i; 03364 03365 if (f_dict_op[createObjPtr.p->m_vt_index].m_prepare_start) 03366 (this->*f_dict_op[createObjPtr.p->m_vt_index].m_prepare_start) 03367 (signal, createObjPtr.p); 03368 else 03369 execute(signal, createObjPtr.p->m_callback, 0); 03370 } 03371 03372 void 03373 Dbdict::restartCreateObj_prepare_start_done(Signal* signal, 03374 Uint32 callbackData, 03375 Uint32 returnCode) 03376 { 03377 jam(); 03378 ndbrequire(returnCode == 0); 03379 CreateObjRecordPtr createObjPtr; 03380 ndbrequire(c_opCreateObj.find(createObjPtr, callbackData)); 03381 ndbrequire(createObjPtr.p->m_errorCode == 0); 03382 03383 Callback callback; 03384 callback.m_callbackData = callbackData; 03385 callback.m_callbackFunction = 03386 safe_cast(&Dbdict::restartCreateObj_write_complete); 03387 03388 SegmentedSectionPtr objInfoPtr; 03389 getSection(objInfoPtr, createObjPtr.p->m_obj_info_ptr_i); 03390 03391 writeTableFile(signal, createObjPtr.p->m_obj_id, objInfoPtr, &callback); 03392 } 03393 03394 void 03395 Dbdict::restartCreateObj_write_complete(Signal* signal, 03396 Uint32 callbackData, 03397 Uint32 returnCode) 03398 { 03399 ndbrequire(returnCode == 0); 03400 CreateObjRecordPtr createObjPtr; 03401 ndbrequire(c_opCreateObj.find(createObjPtr, callbackData)); 03402 ndbrequire(createObjPtr.p->m_errorCode == 0); 03403 03404 SegmentedSectionPtr objInfoPtr; 03405 getSection(objInfoPtr, createObjPtr.p->m_obj_info_ptr_i); 03406 signal->setSection(objInfoPtr, 0); 03407 releaseSections(signal); 03408 createObjPtr.p->m_obj_info_ptr_i = RNIL; 03409 03410 createObjPtr.p->m_callback.m_callbackFunction = 03411 safe_cast(&Dbdict::restartCreateObj_prepare_complete_done); 03412 03413 if (f_dict_op[createObjPtr.p->m_vt_index].m_prepare_complete) 03414 (this->*f_dict_op[createObjPtr.p->m_vt_index].m_prepare_complete) 03415 (signal, createObjPtr.p); 03416 else 03417 execute(signal, createObjPtr.p->m_callback, 0); 03418 } 03419 03420 void 03421 Dbdict::restartCreateObj_prepare_complete_done(Signal* signal, 03422 Uint32 callbackData, 03423 Uint32 returnCode) 03424 { 03425 jam(); 03426 ndbrequire(returnCode == 0); 03427 CreateObjRecordPtr createObjPtr; 03428 ndbrequire(c_opCreateObj.find(createObjPtr, callbackData)); 03429 ndbrequire(createObjPtr.p->m_errorCode == 0); 03430 03431 createObjPtr.p->m_callback.m_callbackFunction = 03432 safe_cast(&Dbdict::restartCreateObj_commit_start_done); 03433 03434 if (f_dict_op[createObjPtr.p->m_vt_index].m_commit_start) 03435 (this->*f_dict_op[createObjPtr.p->m_vt_index].m_commit_start) 03436 (signal, createObjPtr.p); 03437 else 03438 execute(signal, createObjPtr.p->m_callback, 0); 03439 } 03440 03441 void 03442 Dbdict::restartCreateObj_commit_start_done(Signal* signal, 03443 Uint32 callbackData, 03444 Uint32 returnCode) 03445 { 03446 jam(); 03447 ndbrequire(returnCode == 0); 03448 CreateObjRecordPtr createObjPtr; 03449 ndbrequire(c_opCreateObj.find(createObjPtr, callbackData)); 03450 ndbrequire(createObjPtr.p->m_errorCode == 0); 03451 03452 createObjPtr.p->m_callback.m_callbackFunction = 03453 safe_cast(&Dbdict::restartCreateObj_commit_complete_done); 03454 03455 if (f_dict_op[createObjPtr.p->m_vt_index].m_commit_complete) 03456 (this->*f_dict_op[createObjPtr.p->m_vt_index].m_commit_complete) 03457 (signal, createObjPtr.p); 03458 else 03459 execute(signal, createObjPtr.p->m_callback, 0); 03460 } 03461 03462 03463 void 03464 Dbdict::restartCreateObj_commit_complete_done(Signal* signal, 03465 Uint32 callbackData, 03466 Uint32 returnCode) 03467 { 03468 jam(); 03469 ndbrequire(returnCode == 0); 03470 CreateObjRecordPtr createObjPtr; 03471 ndbrequire(c_opCreateObj.find(createObjPtr, callbackData)); 03472 ndbrequire(createObjPtr.p->m_errorCode == 0); 03473 03474 c_opCreateObj.release(createObjPtr); 03475 03476 c_restartRecord.activeTable++; 03477 checkSchemaStatus(signal); 03478 } 03479 03480 /* **************************************************************** */ 03481 /* ---------------------------------------------------------------- */ 03482 /* MODULE: NODE FAILURE HANDLING ------------------------- */ 03483 /* ---------------------------------------------------------------- */ 03484 /* */ 03485 /* This module contains the code that is used when nodes */ 03486 /* (kernel/api) fails. */ 03487 /* ---------------------------------------------------------------- */ 03488 /* **************************************************************** */ 03489 03490 /* ---------------------------------------------------------------- */ 03491 // We receive a report of an API that failed. 03492 /* ---------------------------------------------------------------- */ 03493 void Dbdict::execAPI_FAILREQ(Signal* signal) 03494 { 03495 jamEntry(); 03496 Uint32 failedApiNode = signal->theData[0]; 03497 BlockReference retRef = signal->theData[1]; 03498 03499 #if 0 03500 Uint32 userNode = refToNode(c_connRecord.userBlockRef); 03501 if (userNode == failedApiNode) { 03502 jam(); 03503 c_connRecord.userBlockRef = (Uint32)-1; 03504 }//if 03505 #endif 03506 03507 signal->theData[0] = failedApiNode; 03508 signal->theData[1] = reference(); 03509 sendSignal(retRef, GSN_API_FAILCONF, signal, 2, JBB); 03510 }//execAPI_FAILREQ() 03511 03512 /* ---------------------------------------------------------------- */ 03513 // We receive a report of one or more node failures of kernel nodes. 03514 /* ---------------------------------------------------------------- */ 03515 void Dbdict::execNODE_FAILREP(Signal* signal) 03516 { 03517 jamEntry(); 03518 NodeFailRep * const nodeFail = (NodeFailRep *)&signal->theData[0]; 03519 03520 c_failureNr = nodeFail->failNo; 03521 const Uint32 numberOfFailedNodes = nodeFail->noOfNodes; 03522 const bool masterFailed = (c_masterNodeId != nodeFail->masterNodeId); 03523 c_masterNodeId = nodeFail->masterNodeId; 03524 03525 c_noNodesFailed += numberOfFailedNodes; 03526 Uint32 theFailedNodes[NodeBitmask::Size]; 03527 memcpy(theFailedNodes, nodeFail->theNodes, sizeof(theFailedNodes)); 03528 03529 c_counterMgr.execNODE_FAILREP(signal); 03530 03531 bool ok = false; 03532 switch(c_blockState){ 03533 case BS_IDLE: 03534 jam(); 03535 ok = true; 03536 if(c_opRecordPool.getSize() != c_opRecordPool.getNoOfFree()){ 03537 jam(); 03538 c_blockState = BS_NODE_FAILURE; 03539 } 03540 break; 03541 case BS_CREATE_TAB: 03542 jam(); 03543 ok = true; 03544 if(!masterFailed) 03545 break; 03546 // fall through 03547 case BS_BUSY: 03548 case BS_NODE_FAILURE: 03549 jam(); 03550 c_blockState = BS_NODE_FAILURE; 03551 ok = true; 03552 break; 03553 case BS_NODE_RESTART: 03554 jam(); 03555 ok = true; 03556 break; 03557 } 03558 ndbrequire(ok); 03559 03560 for(unsigned i = 1; i < MAX_NDB_NODES; i++) { 03561 jam(); 03562 if(NodeBitmask::get(theFailedNodes, i)) { 03563 jam(); 03564 NodeRecordPtr nodePtr; 03565 c_nodes.getPtr(nodePtr, i); 03566 03567 nodePtr.p->nodeState = NodeRecord::NDB_NODE_DEAD; 03568 NFCompleteRep * const nfCompRep = (NFCompleteRep *)&signal->theData[0]; 03569 nfCompRep->blockNo = DBDICT; 03570 nfCompRep->nodeId = getOwnNodeId(); 03571 nfCompRep->failedNodeId = nodePtr.i; 03572 sendSignal(DBDIH_REF, GSN_NF_COMPLETEREP, signal, 03573 NFCompleteRep::SignalLength, JBB); 03574 03575 c_aliveNodes.clear(i); 03576 }//if 03577 }//for 03578 03579 /* 03580 * NODE_FAILREP guarantees that no "in flight" signal from 03581 * a dead node is accepted, and also that the job buffer contains 03582 * no such (un-executed) signals. Therefore no DICT_UNLOCK_ORD 03583 * from a dead node (leading to master crash) is possible after 03584 * this clean-up removes the lock record. 03585 */ 03586 removeStaleDictLocks(signal, theFailedNodes); 03587 03588 }//execNODE_FAILREP() 03589 03590 03591 /* **************************************************************** */ 03592 /* ---------------------------------------------------------------- */ 03593 /* MODULE: NODE START HANDLING --------------------------- */ 03594 /* ---------------------------------------------------------------- */ 03595 /* */ 03596 /* This module contains the code that is used when kernel nodes */ 03597 /* starts. */ 03598 /* ---------------------------------------------------------------- */ 03599 /* **************************************************************** */ 03600 03601 /* ---------------------------------------------------------------- */ 03602 // Include a starting node in list of nodes to be part of adding 03603 // and dropping tables. 03604 /* ---------------------------------------------------------------- */ 03605 void Dbdict::execINCL_NODEREQ(Signal* signal) 03606 { 03607 jamEntry(); 03608 NodeRecordPtr nodePtr; 03609 BlockReference retRef = signal->theData[0]; 03610 nodePtr.i = signal->theData[1]; 03611 03612 ndbrequire(c_noNodesFailed > 0); 03613 c_noNodesFailed--; 03614 03615 c_nodes.getPtr(nodePtr); 03616 ndbrequire(nodePtr.p->nodeState == NodeRecord::NDB_NODE_DEAD); 03617 nodePtr.p->nodeState = NodeRecord::NDB_NODE_ALIVE; 03618 signal->theData[0] = reference(); 03619 sendSignal(retRef, GSN_INCL_NODECONF, signal, 1, JBB); 03620 03621 c_aliveNodes.set(nodePtr.i); 03622 }//execINCL_NODEREQ() 03623 03624 /* **************************************************************** */ 03625 /* ---------------------------------------------------------------- */ 03626 /* MODULE: ADD TABLE HANDLING ---------------------------- */ 03627 /* ---------------------------------------------------------------- */ 03628 /* */ 03629 /* This module contains the code that is used when adding a table. */ 03630 /* ---------------------------------------------------------------- */ 03631 /* **************************************************************** */ 03632 03633 /* ---------------------------------------------------------------- */ 03634 // This signal receives information about a table from either: 03635 // API, Ndbcntr or from other DICT. 03636 /* ---------------------------------------------------------------- */ 03637 void 03638 Dbdict::execCREATE_TABLE_REQ(Signal* signal){ 03639 jamEntry(); 03640 if(!assembleFragments(signal)){ 03641 return; 03642 } 03643 03644 CreateTableReq* const req = (CreateTableReq*)signal->getDataPtr(); 03645 const Uint32 senderRef = req->senderRef; 03646 const Uint32 senderData = req->senderData; 03647 03648 ParseDictTabInfoRecord parseRecord; 03649 do { 03650 if(getOwnNodeId() != c_masterNodeId){ 03651 jam(); 03652 parseRecord.errorCode = CreateTableRef::NotMaster; 03653 break; 03654 } 03655 03656 if (c_blockState == BS_NODE_RESTART){ 03657 jam(); 03658 parseRecord.errorCode = CreateTableRef::BusyWithNR; 03659 break; 03660 } 03661 03662 if (c_blockState != BS_IDLE){ 03663 jam(); 03664 parseRecord.errorCode = CreateTableRef::Busy; 03665 break; 03666 } 03667 03668 CreateTableRecordPtr createTabPtr; 03669 c_opCreateTable.seize(createTabPtr); 03670 03671 if(createTabPtr.isNull()){ 03672 jam(); 03673 parseRecord.errorCode = CreateTableRef::Busy; 03674 break; 03675 } 03676 03677 parseRecord.requestType = DictTabInfo::CreateTableFromAPI; 03678 parseRecord.errorCode = 0; 03679 03680 SegmentedSectionPtr ptr; 03681 signal->getSection(ptr, CreateTableReq::DICT_TAB_INFO); 03682 SimplePropertiesSectionReader r(ptr, getSectionSegmentPool()); 03683 03684 handleTabInfoInit(r, &parseRecord); 03685 releaseSections(signal); 03686 03687 if(parseRecord.errorCode != 0){ 03688 jam(); 03689 c_opCreateTable.release(createTabPtr); 03690 break; 03691 } 03692 03693 createTabPtr.p->m_errorCode = 0; 03694 createTabPtr.p->m_senderRef = senderRef; 03695 createTabPtr.p->m_senderData = senderData; 03696 createTabPtr.p->m_tablePtrI = parseRecord.tablePtr.i; 03697 createTabPtr.p->m_coordinatorRef = reference(); 03698 createTabPtr.p->m_fragmentsPtrI = RNIL; 03699 createTabPtr.p->m_dihAddFragPtr = RNIL; 03700 03701 Uint32 key = c_opRecordSequence + 1; 03702 Uint32 *theData = signal->getDataPtrSend(), i; 03703 Uint16 *frag_data= (Uint16*)&signal->theData[25]; 03704 CreateFragmentationReq * const req = (CreateFragmentationReq*)theData; 03705 req->senderRef = reference(); 03706 req->senderData = key; 03707 req->primaryTableId = parseRecord.tablePtr.p->primaryTableId; 03708 req->noOfFragments = parseRecord.tablePtr.p->fragmentCount; 03709 req->fragmentationType = parseRecord.tablePtr.p->fragmentType; 03710 MEMCOPY_NO_WORDS(frag_data, c_fragData, c_fragDataLen); 03711 03712 if (parseRecord.tablePtr.p->isOrderedIndex()) { 03713 jam(); 03714 // ordered index has same fragmentation as the table 03715 req->primaryTableId = parseRecord.tablePtr.p->primaryTableId; 03716 req->fragmentationType = DictTabInfo::DistrKeyOrderedIndex; 03717 } 03718 else if (parseRecord.tablePtr.p->isHashIndex()) 03719 { 03720 jam(); 03721 /* 03722 Unique hash indexes has same amount of fragments as primary table 03723 and distributed in the same manner but has always a normal hash 03724 fragmentation. 03725 */ 03726 req->primaryTableId = parseRecord.tablePtr.p->primaryTableId; 03727 req->fragmentationType = DictTabInfo::DistrKeyUniqueHashIndex; 03728 } 03729 else 03730 { 03731 jam(); 03732 /* 03733 Blob tables come here with primaryTableId != RNIL but we only need 03734 it for creating the fragments so we set it to RNIL now that we got 03735 what we wanted from it to avoid other side effects. 03736 */ 03737 parseRecord.tablePtr.p->primaryTableId = RNIL; 03738 } 03739 EXECUTE_DIRECT(DBDIH, GSN_CREATE_FRAGMENTATION_REQ, signal, 03740 CreateFragmentationReq::SignalLength); 03741 jamEntry(); 03742 if (signal->theData[0] != 0) 03743 { 03744 jam(); 03745 parseRecord.errorCode= signal->theData[0]; 03746 c_opCreateTable.release(createTabPtr); 03747 releaseTableObject(parseRecord.tablePtr.i, true); 03748 break; 03749 } 03750 createTabPtr.p->key = key; 03751 c_opRecordSequence++; 03752 c_opCreateTable.add(createTabPtr); 03753 c_blockState = BS_CREATE_TAB; 03754 return; 03755 } while(0); 03756 03761 releaseSections(signal); 03762 CreateTableRef * ref = (CreateTableRef*)signal->getDataPtrSend(); 03763 ref->senderData = senderData; 03764 ref->senderRef = reference(); 03765 ref->masterNodeId = c_masterNodeId; 03766 ref->errorCode = parseRecord.errorCode; 03767 ref->errorLine = parseRecord.errorLine; 03768 ref->errorKey = parseRecord.errorKey; 03769 ref->status = parseRecord.status; 03770 sendSignal(senderRef, GSN_CREATE_TABLE_REF, signal, 03771 CreateTableRef::SignalLength, JBB); 03772 } 03773 03774 void 03775 Dbdict::execBACKUP_FRAGMENT_REQ(Signal* signal) 03776 { 03777 jamEntry(); 03778 Uint32 tableId = signal->theData[0]; 03779 Uint32 lock = signal->theData[1]; 03780 03781 TableRecordPtr tablePtr; 03782 c_tableRecordPool.getPtr(tablePtr, tableId, true); 03783 03784 if(lock) 03785 { 03786 ndbrequire(tablePtr.p->tabState == TableRecord::DEFINED); 03787 tablePtr.p->tabState = TableRecord::BACKUP_ONGOING; 03788 } 03789 else if(tablePtr.p->tabState == TableRecord::BACKUP_ONGOING) 03790 { 03791 tablePtr.p->tabState = TableRecord::DEFINED; 03792 } 03793 } 03794 03795 bool 03796 Dbdict::check_ndb_versions() const 03797 { 03798 Uint32 node = 0; 03799 Uint32 version = getNodeInfo(getOwnNodeId()).m_version; 03800 while((node = c_aliveNodes.find(node + 1)) != BitmaskImpl::NotFound) 03801 { 03802 if(getNodeInfo(node).m_version != version) 03803 { 03804 return false; 03805 } 03806 } 03807 return true; 03808 } 03809 03810 void 03811 Dbdict::execALTER_TABLE_REQ(Signal* signal) 03812 { 03813 // Received by master 03814 jamEntry(); 03815 if(!assembleFragments(signal)){ 03816 return; 03817 } 03818 AlterTableReq* const req = (AlterTableReq*)signal->getDataPtr(); 03819 const Uint32 senderRef = req->senderRef; 03820 const Uint32 senderData = req->senderData; 03821 const Uint32 changeMask = req->changeMask; 03822 const Uint32 tableId = req->tableId; 03823 const Uint32 tableVersion = req->tableVersion; 03824 ParseDictTabInfoRecord* aParseRecord; 03825 03826 // Get table definition 03827 TableRecordPtr tablePtr; 03828 c_tableRecordPool.getPtr(tablePtr, tableId, false); 03829 if(tablePtr.isNull()){ 03830 jam(); 03831 alterTableRef(signal, req, AlterTableRef::NoSuchTable); 03832 return; 03833 } 03834 03835 if(getOwnNodeId() != c_masterNodeId){ 03836 jam(); 03837 alterTableRef(signal, req, AlterTableRef::NotMaster); 03838 return; 03839 } 03840 03841 if(c_blockState == BS_NODE_RESTART){ 03842 jam(); 03843 alterTableRef(signal, req, AlterTableRef::BusyWithNR); 03844 return; 03845 } 03846 03847 if(c_blockState != BS_IDLE){ 03848 jam(); 03849 alterTableRef(signal, req, AlterTableRef::Busy); 03850 return; 03851 } 03852 03853 if (!check_ndb_versions()) 03854 { 03855 jam(); 03856 alterTableRef(signal, req, AlterTableRef::IncompatibleVersions); 03857 return; 03858 } 03859 03860 const TableRecord::TabState tabState = tablePtr.p->tabState; 03861 bool ok = false; 03862 switch(tabState){ 03863 case TableRecord::NOT_DEFINED: 03864 case TableRecord::REORG_TABLE_PREPARED: 03865 case TableRecord::DEFINING: 03866 case TableRecord::CHECKED: 03867 jam(); 03868 alterTableRef(signal, req, AlterTableRef::NoSuchTable); 03869 return; 03870 case TableRecord::DEFINED: 03871 ok = true; 03872 jam(); 03873 break; 03874 case TableRecord::BACKUP_ONGOING: 03875 jam(); 03876 alterTableRef(signal, req, AlterTableRef::BackupInProgress); 03877 return; 03878 case TableRecord::PREPARE_DROPPING: 03879 case TableRecord::DROPPING: 03880 jam(); 03881 alterTableRef(signal, req, AlterTableRef::DropInProgress); 03882 return; 03883 } 03884 ndbrequire(ok); 03885 03886 if(tablePtr.p->tableVersion != tableVersion){ 03887 jam(); 03888 alterTableRef(signal, req, AlterTableRef::InvalidTableVersion); 03889 return; 03890 } 03891 // Parse new table defintion 03892 ParseDictTabInfoRecord parseRecord; 03893 aParseRecord = &parseRecord; 03894 03895 CreateTableRecordPtr alterTabPtr; // Reuse create table records 03896 c_opCreateTable.seize(alterTabPtr); 03897 03898 if(alterTabPtr.isNull()){ 03899 jam(); 03900 alterTableRef(signal, req, AlterTableRef::Busy); 03901 return; 03902 } 03903 03904 alterTabPtr.p->m_changeMask = changeMask; 03905 parseRecord.requestType = DictTabInfo::AlterTableFromAPI; 03906 parseRecord.errorCode = 0; 03907 03908 SegmentedSectionPtr ptr; 03909 signal->getSection(ptr, AlterTableReq::DICT_TAB_INFO); 03910 SimplePropertiesSectionReader r(ptr, getSectionSegmentPool()); 03911 03912 handleTabInfoInit(r, &parseRecord, false); // Will not save info 03913 03914 if(parseRecord.errorCode != 0){ 03915 jam(); 03916 c_opCreateTable.release(alterTabPtr); 03917 alterTableRef(signal, req, 03918 (AlterTableRef::ErrorCode) parseRecord.errorCode, 03919 aParseRecord); 03920 return; 03921 } 03922 03923 releaseSections(signal); 03924 alterTabPtr.p->key = ++c_opRecordSequence; 03925 c_opCreateTable.add(alterTabPtr); 03926 ndbrequire(c_opCreateTable.find(alterTabPtr, alterTabPtr.p->key)); 03927 alterTabPtr.p->m_errorCode = 0; 03928 alterTabPtr.p->m_senderRef = senderRef; 03929 alterTabPtr.p->m_senderData = senderData; 03930 alterTabPtr.p->m_tablePtrI = parseRecord.tablePtr.i; 03931 alterTabPtr.p->m_alterTableFailed = false; 03932 alterTabPtr.p->m_coordinatorRef = reference(); 03933 alterTabPtr.p->m_fragmentsPtrI = RNIL; 03934 alterTabPtr.p->m_dihAddFragPtr = RNIL; 03935 alterTabPtr.p->m_alterTableId = tablePtr.p->tableId; 03936 03937 // Send prepare request to all alive nodes 03938 SimplePropertiesSectionWriter w(getSectionSegmentPool()); 03939 packTableIntoPages(w, parseRecord.tablePtr); 03940 03941 SegmentedSectionPtr tabInfoPtr; 03942 w.getPtr(tabInfoPtr); 03943 03944 alterTabPtr.p->m_tabInfoPtrI = tabInfoPtr.i; 03945 03946 // Alter table on all nodes 03947 c_blockState = BS_BUSY; 03948 03949 Mutex mutex(signal, c_mutexMgr, alterTabPtr.p->m_startLcpMutex); 03950 Callback c = { safe_cast(&Dbdict::alterTable_backup_mutex_locked), 03951 alterTabPtr.p->key }; 03952 03953 ndbrequire(mutex.lock(c)); 03954 } 03955 03956 void 03957 Dbdict::alterTable_backup_mutex_locked(Signal* signal, 03958 Uint32 callbackData, 03959 Uint32 retValue) 03960 { 03961 jamEntry(); 03962 03963 ndbrequire(retValue == 0); 03964 03965 CreateTableRecordPtr alterTabPtr; 03966 ndbrequire(c_opCreateTable.find(alterTabPtr, callbackData)); 03967 03968 TableRecordPtr tablePtr; 03969 c_tableRecordPool.getPtr(tablePtr, alterTabPtr.p->m_alterTableId, true); 03970 03971 Mutex mutex(signal, c_mutexMgr, alterTabPtr.p->m_startLcpMutex); 03972 mutex.unlock(); // ignore response 03973 03974 SegmentedSectionPtr tabInfoPtr; 03975 getSection(tabInfoPtr, alterTabPtr.p->m_tabInfoPtrI); 03976 signal->setSection(tabInfoPtr, AlterTabReq::DICT_TAB_INFO); 03977 03978 alterTabPtr.p->m_tabInfoPtrI = RNIL; 03979 03980 if(tablePtr.p->tabState == TableRecord::BACKUP_ONGOING) 03981 { 03982 jam(); 03983 AlterTableReq* req = (AlterTableReq*)signal->getDataPtr(); 03984 req->senderData = alterTabPtr.p->m_senderData; 03985 req->senderRef = alterTabPtr.p->m_senderRef; 03986 alterTableRef(signal, req, AlterTableRef::BackupInProgress); 03987 03988 c_tableRecordPool.getPtr(tablePtr, alterTabPtr.p->m_tablePtrI); 03989 releaseTableObject(tablePtr.i, false); 03990 03991 c_opCreateTable.release(alterTabPtr); 03992 c_blockState = BS_IDLE; 03993 return; 03994 } 03995 03996 NodeReceiverGroup rg(DBDICT, c_aliveNodes); 03997 alterTabPtr.p->m_coordinatorData.m_gsn = GSN_ALTER_TAB_REQ; 03998 SafeCounter safeCounter(c_counterMgr, 03999 alterTabPtr.p->m_coordinatorData.m_counter); 04000 safeCounter.init<AlterTabRef>(rg, alterTabPtr.p->key); 04001 04002 AlterTabReq * const lreq = (AlterTabReq*)signal->getDataPtrSend(); 04003 lreq->senderRef = reference(); 04004 lreq->senderData = alterTabPtr.p->key; 04005 lreq->clientRef = alterTabPtr.p->m_senderRef; 04006 lreq->clientData = alterTabPtr.p->m_senderData; 04007 lreq->changeMask = alterTabPtr.p->m_changeMask; 04008 lreq->tableId = tablePtr.p->tableId; 04009 lreq->tableVersion = alter_obj_inc_schema_version(tablePtr.p->tableVersion); 04010 lreq->gci = tablePtr.p->gciTableCreated; 04011 lreq->requestType = AlterTabReq::AlterTablePrepare; 04012 04013 sendFragmentedSignal(rg, GSN_ALTER_TAB_REQ, signal, 04014 AlterTabReq::SignalLength, JBB); 04015 } 04016 04017 void Dbdict::alterTableRef(Signal * signal, 04018 AlterTableReq * req, 04019 AlterTableRef::ErrorCode errCode, 04020 ParseDictTabInfoRecord* parseRecord) 04021 { 04022 jam(); 04023 releaseSections(signal); 04024 AlterTableRef * ref = (AlterTableRef*)signal->getDataPtrSend(); 04025 Uint32 senderRef = req->senderRef; 04026 ref->senderData = req->senderData; 04027 ref->senderRef = reference(); 04028 ref->masterNodeId = c_masterNodeId; 04029 if (parseRecord) { 04030 ref->errorCode = parseRecord->errorCode; 04031 ref->errorLine = parseRecord->errorLine; 04032 ref->errorKey = parseRecord->errorKey; 04033 ref->status = parseRecord->status; 04034 } 04035 else { 04036 ref->errorCode = errCode; 04037 ref->errorLine = 0; 04038 ref->errorKey = 0; 04039 ref->status = 0; 04040 } 04041 sendSignal(senderRef, GSN_ALTER_TABLE_REF, signal, 04042 AlterTableRef::SignalLength, JBB); 04043 } 04044 04045 void 04046 Dbdict::execALTER_TAB_REQ(Signal * signal) 04047 { 04048 // Received in all nodes to handle change locally 04049 jamEntry(); 04050 04051 if(!assembleFragments(signal)){ 04052 return; 04053 } 04054 AlterTabReq* const req = (AlterTabReq*)signal->getDataPtr(); 04055 const Uint32 senderRef = req->senderRef; 04056 const Uint32 senderData = req->senderData; 04057 const Uint32 changeMask = req->changeMask; 04058 const Uint32 tableId = req->tableId; 04059 const Uint32 tableVersion = req->tableVersion; 04060 const Uint32 gci = req->gci; 04061 AlterTabReq::RequestType requestType = 04062 (AlterTabReq::RequestType) req->requestType; 04063 04064 SegmentedSectionPtr tabInfoPtr; 04065 signal->getSection(tabInfoPtr, AlterTabReq::DICT_TAB_INFO); 04066 04067 CreateTableRecordPtr alterTabPtr; // Reuse create table records 04068 04069 if (senderRef != reference()) { 04070 jam(); 04071 c_blockState = BS_BUSY; 04072 } 04073 if ((requestType == AlterTabReq::AlterTablePrepare) 04074 && (senderRef != reference())) { 04075 jam(); 04076 c_opCreateTable.seize(alterTabPtr); 04077 if(!alterTabPtr.isNull()) 04078 alterTabPtr.p->m_changeMask = changeMask; 04079 } 04080 else { 04081 jam(); 04082 ndbrequire(c_opCreateTable.find(alterTabPtr, senderData)); 04083 } 04084 if(alterTabPtr.isNull()){ 04085 jam(); 04086 alterTabRef(signal, req, AlterTableRef::Busy); 04087 return; 04088 } 04089 04090 if (!check_ndb_versions()) 04091 { 04092 jam(); 04093 alterTabRef(signal, req, AlterTableRef::IncompatibleVersions); 04094 return; 04095 } 04096 04097 alterTabPtr.p->m_alterTableId = tableId; 04098 alterTabPtr.p->m_coordinatorRef = senderRef; 04099 04100 // Get table definition 04101 TableRecordPtr tablePtr; 04102 c_tableRecordPool.getPtr(tablePtr, tableId, false); 04103 if(tablePtr.isNull()){ 04104 jam(); 04105 alterTabRef(signal, req, AlterTableRef::NoSuchTable); 04106 return; 04107 } 04108 04109 switch(requestType) { 04110 case(AlterTabReq::AlterTablePrepare): { 04111 ParseDictTabInfoRecord* aParseRecord; 04112 04113 const TableRecord::TabState tabState = tablePtr.p->tabState; 04114 bool ok = false; 04115 switch(tabState){ 04116 case TableRecord::NOT_DEFINED: 04117 case TableRecord::REORG_TABLE_PREPARED: 04118 case TableRecord::DEFINING: 04119 case TableRecord::CHECKED: 04120 jam(); 04121 alterTabRef(signal, req, AlterTableRef::NoSuchTable); 04122 return; 04123 case TableRecord::DEFINED: 04124 ok = true; 04125 jam(); 04126 break; 04127 case TableRecord::PREPARE_DROPPING: 04128 case TableRecord::DROPPING: 04129 jam(); 04130 alterTabRef(signal, req, AlterTableRef::DropInProgress); 04131 return; 04132 case TableRecord::BACKUP_ONGOING: 04133 jam(); 04134 alterTabRef(signal, req, AlterTableRef::BackupInProgress); 04135 return; 04136 } 04137 ndbrequire(ok); 04138 04139 if(alter_obj_inc_schema_version(tablePtr.p->tableVersion) != tableVersion){ 04140 jam(); 04141 alterTabRef(signal, req, AlterTableRef::InvalidTableVersion); 04142 return; 04143 } 04144 TableRecordPtr newTablePtr; 04145 if (senderRef != reference()) { 04146 jam(); 04147 // Parse altered table defintion 04148 ParseDictTabInfoRecord parseRecord; 04149 aParseRecord = &parseRecord; 04150 04151 parseRecord.requestType = DictTabInfo::AlterTableFromAPI; 04152 parseRecord.errorCode = 0; 04153 04154 SimplePropertiesSectionReader r(tabInfoPtr, getSectionSegmentPool()); 04155 04156 handleTabInfoInit(r, &parseRecord, false); // Will not save info 04157 04158 if(parseRecord.errorCode != 0){ 04159 jam(); 04160 c_opCreateTable.release(alterTabPtr); 04161 alterTabRef(signal, req, 04162 (AlterTableRef::ErrorCode) parseRecord.errorCode, 04163 aParseRecord); 04164 return; 04165 } 04166 alterTabPtr.p->key = senderData; 04167 c_opCreateTable.add(alterTabPtr); 04168 alterTabPtr.p->m_errorCode = 0; 04169 alterTabPtr.p->m_senderRef = senderRef; 04170 alterTabPtr.p->m_senderData = senderData; 04171 alterTabPtr.p->m_tablePtrI = parseRecord.tablePtr.i; 04172 alterTabPtr.p->m_fragmentsPtrI = RNIL; 04173 alterTabPtr.p->m_dihAddFragPtr = RNIL; 04174 newTablePtr = parseRecord.tablePtr; 04175 newTablePtr.p->tableVersion = tableVersion; 04176 } 04177 else { // (req->senderRef == reference()) 04178 jam(); 04179 c_tableRecordPool.getPtr(newTablePtr, alterTabPtr.p->m_tablePtrI); 04180 newTablePtr.p->tableVersion = tableVersion; 04181 } 04182 if (handleAlterTab(req, alterTabPtr.p, tablePtr, newTablePtr) == -1) { 04183 jam(); 04184 c_opCreateTable.release(alterTabPtr); 04185 alterTabRef(signal, req, AlterTableRef::UnsupportedChange); 04186 return; 04187 } 04188 releaseSections(signal); 04189 // Propagate alter table to other local blocks 04190 AlterTabReq * req = (AlterTabReq*)signal->getDataPtrSend(); 04191 req->senderRef = reference(); 04192 req->senderData = senderData; 04193 req->changeMask = changeMask; 04194 req->tableId = tableId; 04195 req->tableVersion = tableVersion; 04196 req->gci = gci; 04197 req->requestType = requestType; 04198 sendSignal(DBLQH_REF, GSN_ALTER_TAB_REQ, signal, 04199 AlterTabReq::SignalLength, JBB); 04200 return; 04201 } 04202 case(AlterTabReq::AlterTableCommit): { 04203 jam(); 04204 // Write schema for altered table to disk 04205 SegmentedSectionPtr tabInfoPtr; 04206 signal->getSection(tabInfoPtr, AlterTabReq::DICT_TAB_INFO); 04207 alterTabPtr.p->m_tabInfoPtrI = tabInfoPtr.i; 04208 04209 signal->header.m_noOfSections = 0; 04210 04211 // Update table record 04212 tablePtr.p->packedSize = tabInfoPtr.sz; 04213 tablePtr.p->tableVersion = tableVersion; 04214 tablePtr.p->gciTableCreated = gci; 04215 04216 SchemaFile::TableEntry tabEntry; 04217 tabEntry.m_tableVersion = tableVersion; 04218 tabEntry.m_tableType = tablePtr.p->tableType; 04219 tabEntry.m_tableState = SchemaFile::ALTER_TABLE_COMMITTED; 04220 tabEntry.m_gcp = gci; 04221 tabEntry.m_info_words = tabInfoPtr.sz; 04222 memset(tabEntry.m_unused, 0, sizeof(tabEntry.m_unused)); 04223 04224 Callback callback; 04225 callback.m_callbackData = senderData; 04226 callback.m_callbackFunction = 04227 safe_cast(&Dbdict::alterTab_writeSchemaConf); 04228 04229 updateSchemaState(signal, tableId, &tabEntry, &callback); 04230 break; 04231 } 04232 case(AlterTabReq::AlterTableRevert): { 04233 jam(); 04234 // Revert failed alter table 04235 revertAlterTable(signal, changeMask, tableId, alterTabPtr.p); 04236 // Acknowledge the reverted alter table 04237 AlterTabConf * conf = (AlterTabConf*)signal->getDataPtrSend(); 04238 conf->senderRef = reference(); 04239 conf->senderData = senderData; 04240 conf->changeMask = changeMask; 04241 conf->tableId = tableId; 04242 conf->tableVersion = tableVersion; 04243 conf->gci = gci; 04244 conf->requestType = requestType; 04245 sendSignal(senderRef, GSN_ALTER_TAB_CONF, signal, 04246 AlterTabConf::SignalLength, JBB); 04247 break; 04248 } 04249 default: ndbrequire(false); 04250 } 04251 } 04252 04253 void Dbdict::alterTabRef(Signal * signal, 04254 AlterTabReq * req, 04255 AlterTableRef::ErrorCode errCode, 04256 ParseDictTabInfoRecord* parseRecord) 04257 { 04258 jam(); 04259 releaseSections(signal); 04260 AlterTabRef * ref = (AlterTabRef*)signal->getDataPtrSend(); 04261 Uint32 senderRef = req->senderRef; 04262 ref->senderData = req->senderData; 04263 ref->senderRef = reference(); 04264 if (parseRecord) { 04265 jam(); 04266 ref->errorCode = parseRecord->errorCode; 04267 ref->errorLine = parseRecord->errorLine; 04268 ref->errorKey = parseRecord->errorKey; 04269 ref->errorStatus = parseRecord->status; 04270 } 04271 else { 04272 jam(); 04273 ref->errorCode = errCode; 04274 ref->errorLine = 0; 04275 ref->errorKey = 0; 04276 ref->errorStatus = 0; 04277 } 04278 sendSignal(senderRef, GSN_ALTER_TAB_REF, signal, 04279 AlterTabRef::SignalLength, JBB); 04280 04281 c_blockState = BS_IDLE; 04282 } 04283 04284 void Dbdict::execALTER_TAB_REF(Signal * signal){ 04285 jamEntry(); 04286 04287 AlterTabRef * ref = (AlterTabRef*)signal->getDataPtr(); 04288 04289 Uint32 senderRef = ref->senderRef; 04290 Uint32 senderData = ref->senderData; 04291 Uint32 errorCode = ref->errorCode; 04292 Uint32 errorLine = ref->errorLine; 04293 Uint32 errorKey = ref->errorKey; 04294 Uint32 errorStatus = ref->errorStatus; 04295 AlterTabReq::RequestType requestType = 04296 (AlterTabReq::RequestType) ref->requestType; 04297 CreateTableRecordPtr alterTabPtr; 04298 ndbrequire(c_opCreateTable.find(alterTabPtr, senderData)); 04299 Uint32 changeMask = alterTabPtr.p->m_changeMask; 04300 SafeCounter safeCounter(c_counterMgr, alterTabPtr.p->m_coordinatorData.m_counter); 04301 safeCounter.clearWaitingFor(refToNode(senderRef)); 04302 switch (requestType) { 04303 case(AlterTabReq::AlterTablePrepare): { 04304 if (safeCounter.done()) { 04305 jam(); 04306 // Send revert request to all alive nodes 04307 TableRecordPtr tablePtr; 04308 c_tableRecordPool.getPtr(tablePtr, alterTabPtr.p->m_alterTableId); 04309 Uint32 tableId = tablePtr.p->tableId; 04310 Uint32 tableVersion = tablePtr.p->tableVersion; 04311 Uint32 gci = tablePtr.p->gciTableCreated; 04312 SimplePropertiesSectionWriter w(getSectionSegmentPool()); 04313 packTableIntoPages(w, tablePtr); 04314 SegmentedSectionPtr spDataPtr; 04315 w.getPtr(spDataPtr); 04316 signal->setSection(spDataPtr, AlterTabReq::DICT_TAB_INFO); 04317 04318 NodeReceiverGroup rg(DBDICT, c_aliveNodes); 04319 alterTabPtr.p->m_coordinatorData.m_gsn = GSN_ALTER_TAB_REQ; 04320 safeCounter.init<AlterTabRef>(rg, alterTabPtr.p->key); 04321 04322 AlterTabReq * const lreq = (AlterTabReq*)signal->getDataPtrSend(); 04323 lreq->senderRef = reference(); 04324 lreq->senderData = alterTabPtr.p->key; 04325 lreq->clientRef = alterTabPtr.p->m_senderRef; 04326 lreq->clientData = alterTabPtr.p->m_senderData; 04327 lreq->changeMask = changeMask; 04328 lreq->tableId = tableId; 04329 lreq->tableVersion = tableVersion; 04330 lreq->gci = gci; 04331 lreq->requestType = AlterTabReq::AlterTableRevert; 04332 04333 sendSignal(rg, GSN_ALTER_TAB_REQ, signal, 04334 AlterTabReq::SignalLength, JBB); 04335 } 04336 else { 04337 jam(); 04338 alterTabPtr.p->m_alterTableFailed = true; 04339 } 04340 break; 04341 } 04342 case(AlterTabReq::AlterTableCommit): 04343 jam(); 04344 case(AlterTabReq::AlterTableRevert): { 04345 AlterTableRef * apiRef = (AlterTableRef*)signal->getDataPtrSend(); 04346 04347 apiRef->senderData = senderData; 04348 apiRef->senderRef = reference(); 04349 apiRef->masterNodeId = c_masterNodeId; 04350 apiRef->errorCode = errorCode; 04351 apiRef->errorLine = errorLine; 04352 apiRef->errorKey = errorKey; 04353 apiRef->status = errorStatus; 04354 if (safeCounter.done()) { 04355 jam(); 04356 sendSignal(senderRef, GSN_ALTER_TABLE_REF, signal, 04357 AlterTableRef::SignalLength, JBB); 04358 c_blockState = BS_IDLE; 04359 } 04360 else { 04361 jam(); 04362 alterTabPtr.p->m_alterTableFailed = true; 04363 alterTabPtr.p->m_alterTableRef = *apiRef; 04364 } 04365 break; 04366 } 04367 default: ndbrequire(false); 04368 } 04369 } 04370 04371 void 04372 Dbdict::execALTER_TAB_CONF(Signal * signal){ 04373 jamEntry(); 04374 AlterTabConf * const conf = (AlterTabConf*)signal->getDataPtr(); 04375 Uint32 senderRef = conf->senderRef; 04376 Uint32 senderData = conf->senderData; 04377 Uint32 changeMask = conf->changeMask; 04378 Uint32 tableId = conf->tableId; 04379 Uint32 tableVersion = conf->tableVersion; 04380 Uint32 gci = conf->gci; 04381 AlterTabReq::RequestType requestType = 04382 (AlterTabReq::RequestType) conf->requestType; 04383 CreateTableRecordPtr alterTabPtr; 04384 ndbrequire(c_opCreateTable.find(alterTabPtr, senderData)); 04385 04386 switch (requestType) { 04387 case(AlterTabReq::AlterTablePrepare): { 04388 switch(refToBlock(signal->getSendersBlockRef())) { 04389 case DBLQH: { 04390 jam(); 04391 AlterTabReq * req = (AlterTabReq*)signal->getDataPtrSend(); 04392 req->senderRef = reference(); 04393 req->senderData = senderData; 04394 req->changeMask = changeMask; 04395 req->tableId = tableId; 04396 req->tableVersion = tableVersion; 04397 req->gci = gci; 04398 req->requestType = requestType; 04399 sendSignal(DBDIH_REF, GSN_ALTER_TAB_REQ, signal, 04400 AlterTabReq::SignalLength, JBB); 04401 return; 04402 } 04403 case DBDIH: { 04404 jam(); 04405 AlterTabReq * req = (AlterTabReq*)signal->getDataPtrSend(); 04406 req->senderRef = reference(); 04407 req->senderData = senderData; 04408 req->changeMask = changeMask; 04409 req->tableId = tableId; 04410 req->tableVersion = tableVersion; 04411 req->gci = gci; 04412 req->requestType = requestType; 04413 sendSignal(DBTC_REF, GSN_ALTER_TAB_REQ, signal, 04414 AlterTabReq::SignalLength, JBB); 04415 return; 04416 } 04417 case DBTC: { 04418 jam(); 04419 // Participant is done with prepare phase, send conf to coordinator 04420 AlterTabConf * conf = (AlterTabConf*)signal->getDataPtrSend(); 04421 conf->senderRef = reference(); 04422 conf->senderData = senderData; 04423 conf->changeMask = changeMask; 04424 conf->tableId = tableId; 04425 conf->tableVersion = tableVersion; 04426 conf->gci = gci; 04427 conf->requestType = requestType; 04428 sendSignal(alterTabPtr.p->m_coordinatorRef, GSN_ALTER_TAB_CONF, signal, 04429 AlterTabConf::SignalLength, JBB); 04430 return; 04431 } 04432 default :break; 04433 } 04434 // Coordinator only 04435 SafeCounter safeCounter(c_counterMgr, alterTabPtr.p->m_coordinatorData.m_counter); 04436 safeCounter.clearWaitingFor(refToNode(senderRef)); 04437 if (safeCounter.done()) { 04438 jam(); 04439 // We have received all local confirmations 04440 if (alterTabPtr.p->m_alterTableFailed) { 04441 jam(); 04442 // Send revert request to all alive nodes 04443 TableRecordPtr tablePtr; 04444 c_tableRecordPool.getPtr(tablePtr, alterTabPtr.p->m_alterTableId); 04445 Uint32 tableId = tablePtr.p->tableId; 04446 Uint32 tableVersion = tablePtr.p->tableVersion; 04447 Uint32 gci = tablePtr.p->gciTableCreated; 04448 SimplePropertiesSectionWriter w(getSectionSegmentPool()); 04449 packTableIntoPages(w, tablePtr); 04450 SegmentedSectionPtr spDataPtr; 04451 w.getPtr(spDataPtr); 04452 signal->setSection(spDataPtr, AlterTabReq::DICT_TAB_INFO); 04453 04454 NodeReceiverGroup rg(DBDICT, c_aliveNodes); 04455 alterTabPtr.p->m_coordinatorData.m_gsn = GSN_ALTER_TAB_REQ; 04456 safeCounter.init<AlterTabRef>(rg, alterTabPtr.p->key); 04457 04458 AlterTabReq * const lreq = (AlterTabReq*)signal->getDataPtrSend(); 04459 lreq->senderRef = reference(); 04460 lreq->senderData = alterTabPtr.p->key; 04461 lreq->clientRef = alterTabPtr.p->m_senderRef; 04462 lreq->clientData = alterTabPtr.p->m_senderData; 04463 lreq->changeMask = changeMask; 04464 lreq->tableId = tableId; 04465 lreq->tableVersion = tableVersion; 04466 lreq->gci = gci; 04467 lreq->requestType = AlterTabReq::AlterTableRevert; 04468 04469 sendSignal(rg, GSN_ALTER_TAB_REQ, signal, 04470 AlterTabReq::SignalLength, JBB); 04471 } 04472 else { 04473 jam(); 04474 // Send commit request to all alive nodes 04475 TableRecordPtr tablePtr; 04476 c_tableRecordPool.getPtr(tablePtr, tableId); 04477 SimplePropertiesSectionWriter w(getSectionSegmentPool()); 04478 packTableIntoPages(w, tablePtr); 04479 SegmentedSectionPtr spDataPtr; 04480 w.getPtr(spDataPtr); 04481 signal->setSection(spDataPtr, AlterTabReq::DICT_TAB_INFO); 04482 04483 NodeReceiverGroup rg(DBDICT, c_aliveNodes); 04484 alterTabPtr.p->m_coordinatorData.m_gsn = GSN_ALTER_TAB_REQ; 04485 safeCounter.init<AlterTabRef>(rg, alterTabPtr.p->key); 04486 04487 AlterTabReq * const lreq = (AlterTabReq*)signal->getDataPtrSend(); 04488 lreq->senderRef = reference(); 04489 lreq->senderData = alterTabPtr.p->key; 04490 lreq->clientRef = alterTabPtr.p->m_senderRef; 04491 lreq->clientData = alterTabPtr.p->m_senderData; 04492 lreq->changeMask = changeMask; 04493 lreq->tableId = tableId; 04494 lreq->tableVersion = tableVersion; 04495 lreq->gci = gci; 04496 lreq->requestType = AlterTabReq::AlterTableCommit; 04497 04498 sendFragmentedSignal(rg, GSN_ALTER_TAB_REQ, signal, 04499 AlterTabReq::SignalLength, JBB); 04500 } 04501 } 04502 else { 04503 // (!safeCounter.done()) 04504 jam(); 04505 } 04506 break; 04507 } 04508 case(AlterTabReq::AlterTableRevert): 04509 jam(); 04510 case(AlterTabReq::AlterTableCommit): { 04511 SafeCounter safeCounter(c_counterMgr, alterTabPtr.p->m_coordinatorData.m_counter); 04512 safeCounter.clearWaitingFor(refToNode(senderRef)); 04513 if (safeCounter.done()) { 04514 jam(); 04515 // We have received all local confirmations 04516 releaseSections(signal); 04517 if (alterTabPtr.p->m_alterTableFailed) { 04518 jam(); 04519 AlterTableRef * apiRef = 04520 (AlterTableRef*)signal->getDataPtrSend(); 04521 *apiRef = alterTabPtr.p->m_alterTableRef; 04522 sendSignal(alterTabPtr.p->m_senderRef, GSN_ALTER_TABLE_REF, signal, 04523 AlterTableRef::SignalLength, JBB); 04524 } 04525 else { 04526 jam(); 04527 // Alter table completed, inform API 04528 AlterTableConf * const apiConf = 04529 (AlterTableConf*)signal->getDataPtrSend(); 04530 apiConf->senderRef = reference(); 04531 apiConf->senderData = alterTabPtr.p->m_senderData; 04532 apiConf->tableId = tableId; 04533 apiConf->tableVersion = tableVersion; 04534 04535 //@todo check api failed 04536 sendSignal(alterTabPtr.p->m_senderRef, GSN_ALTER_TABLE_CONF, signal, 04537 AlterTableConf::SignalLength, JBB); 04538 } 04539 04540 // Release resources 04541 TableRecordPtr tabPtr; 04542 c_tableRecordPool.getPtr(tabPtr, alterTabPtr.p->m_tablePtrI); 04543 releaseTableObject(tabPtr.i, false); 04544 releaseCreateTableOp(signal,alterTabPtr); 04545 c_blockState = BS_IDLE; 04546 } 04547 else { 04548 // (!safeCounter.done()) 04549 jam(); 04550 } 04551 break; 04552 } 04553 default: ndbrequire(false); 04554 } 04555 } 04556 04557 // For debugging 04558 inline 04559 void Dbdict::printTables() 04560 { 04561 DLHashTable<DictObject>::Iterator iter; 04562 bool moreTables = c_obj_hash.first(iter); 04563 printf("OBJECTS IN DICT:\n"); 04564 char name[MAX_TAB_NAME_SIZE]; 04565 while (moreTables) { 04566 Ptr<DictObject> tablePtr = iter.curr; 04567 ConstRope r(c_rope_pool, tablePtr.p->m_name); 04568 r.copy(name); 04569 printf("%s ", name); 04570 moreTables = c_obj_hash.next(iter); 04571 } 04572 printf("\n"); 04573 } 04574 04575 int Dbdict::handleAlterTab(AlterTabReq * req, 04576 CreateTableRecord * alterTabPtrP, 04577 TableRecordPtr origTablePtr, 04578 TableRecordPtr newTablePtr) 04579 { 04580 bool supportedAlteration = false; 04581 Uint32 changeMask = req->changeMask; 04582 04583 if (AlterTableReq::getNameFlag(changeMask)) { 04584 jam(); 04585 // Table rename 04586 supportedAlteration = true; 04587 // Remove from hashtable 04588 Ptr<DictObject> obj_ptr; 04589 c_obj_pool.getPtr(obj_ptr, origTablePtr.p->m_obj_ptr_i); 04590 c_obj_hash.remove(obj_ptr); 04591 { 04592 Rope org(c_rope_pool, origTablePtr.p->tableName); 04593 org.copy(alterTabPtrP->previousTableName); 04594 04595 ConstRope src(c_rope_pool, newTablePtr.p->tableName); 04596 char tmp[MAX_TAB_NAME_SIZE]; 04597 const int len = src.size(); 04598 src.copy(tmp); 04599 ndbrequire(org.assign(tmp, len)); 04600 } 04601 obj_ptr.p->m_name = origTablePtr.p->tableName; 04602 // Put it back 04603 c_obj_hash.add(obj_ptr); 04604 } 04605 04606 if (AlterTableReq::getFrmFlag(changeMask)) { 04607 // Table definition changed (new frm) 04608 supportedAlteration = true; 04609 // Save old definition 04610 Rope org(c_rope_pool, origTablePtr.p->frmData); 04611 org.copy(alterTabPtrP->previousFrmData); 04612 alterTabPtrP->previousFrmLen = org.size(); 04613 04614 // Set new definition 04615 ConstRope src(c_rope_pool, newTablePtr.p->frmData); 04616 char tmp[MAX_FRM_DATA_SIZE]; 04617 src.copy(tmp); 04618 ndbrequire(org.assign(tmp, src.size())); 04619 } 04620 04621 /* 04622 TODO RONM: Lite ny kod för FragmentData och RangeOrListData 04623 */ 04624 if (supportedAlteration) 04625 { 04626 // Set new schema version 04627 origTablePtr.p->tableVersion = newTablePtr.p->tableVersion; 04628 return 0; 04629 } 04630 else 04631 { 04632 jam(); 04633 return -1; 04634 } 04635 } 04636 04637 void Dbdict::revertAlterTable(Signal * signal, 04638 Uint32 changeMask, 04639 Uint32 tableId, 04640 CreateTableRecord * alterTabPtrP) 04641 { 04642 bool supportedAlteration = false; 04643 04644 TableRecordPtr tablePtr; 04645 c_tableRecordPool.getPtr(tablePtr, tableId); 04646 04647 if (AlterTableReq::getNameFlag(changeMask)) { 04648 jam(); 04649 // Table rename 04650 supportedAlteration = true; 04651 // Restore previous name 04652 04653 Ptr<DictObject> obj_ptr; 04654 c_obj_pool.getPtr(obj_ptr, tablePtr.p->m_obj_ptr_i); 04655 c_obj_hash.remove(obj_ptr); 04656 04657 { 04658 // Restore name 04659 Rope org(c_rope_pool, tablePtr.p->tableName); 04660 ndbrequire(org.assign(alterTabPtrP->previousTableName)); 04661 } 04662 obj_ptr.p->m_name = tablePtr.p->tableName; 04663 // Put it back 04664 c_obj_hash.add(obj_ptr); 04665 } 04666 04667 if (AlterTableReq::getFrmFlag(changeMask)) 04668 { 04669 jam(); 04670 // Table redefinition 04671 supportedAlteration = true; 04672 // Restore previous frm 04673 Rope org(c_rope_pool, tablePtr.p->tableName); 04674 ndbrequire(org.assign(alterTabPtrP->previousFrmData, 04675 alterTabPtrP->previousFrmLen)); 04676 04677 } 04678 04679 04680 if (supportedAlteration) 04681 { 04682 tablePtr.p->tableVersion = 04683 alter_obj_dec_schema_version(tablePtr.p->tableVersion); 04684 return; 04685 } 04686 04687 ndbrequire(false); 04688 } 04689 04690 void 04691 Dbdict::alterTab_writeSchemaConf(Signal* signal, 04692 Uint32 callbackData, 04693 Uint32 returnCode) 04694 { 04695 jam(); 04696 Uint32 key = callbackData; 04697 CreateTableRecordPtr alterTabPtr; 04698 ndbrequire(c_opCreateTable.find(alterTabPtr, key)); 04699 Uint32 tableId = alterTabPtr.p->m_alterTableId; 04700 04701 Callback callback; 04702 callback.m_callbackData = alterTabPtr.p->key; 04703 callback.m_callbackFunction = 04704 safe_cast(&Dbdict::alterTab_writeTableConf); 04705 04706 SegmentedSectionPtr tabInfoPtr; 04707 getSection(tabInfoPtr, alterTabPtr.p->m_tabInfoPtrI); 04708 writeTableFile(signal, tableId, tabInfoPtr, &callback); 04709 } 04710 04711 void 04712 Dbdict::alterTab_writeTableConf(Signal* signal, 04713 Uint32 callbackData, 04714 Uint32 returnCode) 04715 { 04716 jam(); 04717 CreateTableRecordPtr alterTabPtr; 04718 ndbrequire(c_opCreateTable.find(alterTabPtr, callbackData)); 04719 Uint32 coordinatorRef = alterTabPtr.p->m_coordinatorRef; 04720 TableRecordPtr tabPtr; 04721 c_tableRecordPool.getPtr(tabPtr, alterTabPtr.p->m_alterTableId); 04722 // Alter table commit request handled successfully 04723 // Inform Suma so it can send events to any subscribers of the table 04724 AlterTabReq * req = (AlterTabReq*)signal->getDataPtrSend(); 04725 if (coordinatorRef == reference()) 04726 req->senderRef = alterTabPtr.p->m_senderRef; 04727 else 04728 req->senderRef = 0; 04729 req->senderData = callbackData; 04730 req->tableId = tabPtr.p->tableId; 04731 req->tableVersion = tabPtr.p->tableVersion; 04732 req->gci = tabPtr.p->gciTableCreated; 04733 req->requestType = AlterTabReq::AlterTableCommit; 04734 req->changeMask = alterTabPtr.p->m_changeMask; 04735 SegmentedSectionPtr tabInfoPtr; 04736 getSection(tabInfoPtr, alterTabPtr.p->m_tabInfoPtrI); 04737 signal->setSection(tabInfoPtr, AlterTabReq::DICT_TAB_INFO); 04738 EXECUTE_DIRECT(SUMA, GSN_ALTER_TAB_REQ, signal, 04739 AlterTabReq::SignalLength); 04740 releaseSections(signal); 04741 alterTabPtr.p->m_tabInfoPtrI = RNIL; 04742 jamEntry(); 04743 AlterTabConf * conf = (AlterTabConf*)signal->getDataPtrSend(); 04744 conf->senderRef = reference(); 04745 conf->senderData = callbackData; 04746 conf->tableId = tabPtr.p->tableId; 04747 conf->tableVersion = tabPtr.p->tableVersion; 04748 conf->gci = tabPtr.p->gciTableCreated; 04749 conf->requestType = AlterTabReq::AlterTableCommit; 04750 conf->changeMask = alterTabPtr.p->m_changeMask; 04751 sendSignal(coordinatorRef, GSN_ALTER_TAB_CONF, signal, 04752 AlterTabConf::SignalLength, JBB); 04753 04754 04755 { 04756 ApiBroadcastRep* api= (ApiBroadcastRep*)signal->getDataPtrSend(); 04757 api->gsn = GSN_ALTER_TABLE_REP; 04758 api->minVersion = MAKE_VERSION(4,1,15); 04759 04760 AlterTableRep* rep = (AlterTableRep*)api->theData; 04761 rep->tableId = tabPtr.p->tableId; 04762 rep->tableVersion = alter_obj_dec_schema_version(tabPtr.p->tableVersion); 04763 rep->changeType = AlterTableRep::CT_ALTERED; 04764 04765 LinearSectionPtr ptr[3]; 04766 ptr[0].p = (Uint32*)alterTabPtr.p->previousTableName; 04767 ptr[0].sz = (sizeof(alterTabPtr.p->previousTableName) + 3) >> 2; 04768 04769 sendSignal(QMGR_REF, GSN_API_BROADCAST_REP, signal, 04770 ApiBroadcastRep::SignalLength + AlterTableRep::SignalLength, 04771 JBB, ptr,1); 04772 } 04773 04774 if(coordinatorRef != reference()) { 04775 jam(); 04776 // Release resources 04777 c_tableRecordPool.getPtr(tabPtr, alterTabPtr.p->m_tablePtrI); 04778 releaseTableObject(tabPtr.i, false); 04779 releaseCreateTableOp(signal,alterTabPtr); 04780 c_blockState = BS_IDLE; 04781 } 04782 } 04783 04784 void 04785 Dbdict::execCREATE_FRAGMENTATION_REF(Signal * signal){ 04786 jamEntry(); 04787 const Uint32 * theData = signal->getDataPtr(); 04788 CreateFragmentationRef * const ref = (CreateFragmentationRef*)theData; 04789 (void)ref; 04790 ndbrequire(false); 04791 } 04792 04793 void 04794 Dbdict::execCREATE_FRAGMENTATION_CONF(Signal* signal){ 04795 jamEntry(); 04796 const Uint32 * theData = signal->getDataPtr(); 04797 CreateFragmentationConf * const conf = (CreateFragmentationConf*)theData; 04798 04799 CreateTableRecordPtr createTabPtr; 04800 ndbrequire(c_opCreateTable.find(createTabPtr, conf->senderData)); 04801 04802 ndbrequire(signal->getNoOfSections() == 1); 04803 04804 SegmentedSectionPtr fragDataPtr; 04805 signal->getSection(fragDataPtr, CreateFragmentationConf::FRAGMENTS); 04806 signal->header.m_noOfSections = 0; 04807 04811 TableRecordPtr tabPtr; 04812 c_tableRecordPool.getPtr(tabPtr, createTabPtr.p->m_tablePtrI); 04813 04817 tabPtr.p->fragmentCount = conf->noOfFragments; 04818 04822 XSchemaFile * xsf = &c_schemaFile[c_schemaRecord.schemaPage != 0]; 04823 SchemaFile::TableEntry * tabEntry = getTableEntry(xsf, tabPtr.i); 04824 04825 tabPtr.p->tableVersion = 04826 create_obj_inc_schema_version(tabEntry->m_tableVersion); 04827 04831 SimplePropertiesSectionWriter w(getSectionSegmentPool()); 04832 packTableIntoPages(w, tabPtr); 04833 04834 SegmentedSectionPtr spDataPtr; 04835 Ptr<SectionSegment> tmpTsPtr; 04836 w.getPtr(spDataPtr); 04837 04838 signal->setSection(spDataPtr, CreateTabReq::DICT_TAB_INFO); 04839 signal->setSection(fragDataPtr, CreateTabReq::FRAGMENTATION); 04840 04841 NodeReceiverGroup rg(DBDICT, c_aliveNodes); 04842 SafeCounter tmp(c_counterMgr, createTabPtr.p->m_coordinatorData.m_counter); 04843 createTabPtr.p->m_coordinatorData.m_gsn = GSN_CREATE_TAB_REQ; 04844 createTabPtr.p->m_coordinatorData.m_requestType = CreateTabReq::CreateTablePrepare; 04845 tmp.init<CreateTabRef>(rg, GSN_CREATE_TAB_REF, createTabPtr.p->key); 04846 04847 CreateTabReq * const req = (CreateTabReq*)theData; 04848 req->senderRef = reference(); 04849 req->senderData = createTabPtr.p->key; 04850 req->clientRef = createTabPtr.p->m_senderRef; 04851 req->clientData = createTabPtr.p->m_senderData; 04852 req->requestType = CreateTabReq::CreateTablePrepare; 04853 04854 req->gci = 0; 04855 req->tableId = tabPtr.i; 04856 req->tableVersion = create_obj_inc_schema_version(tabEntry->m_tableVersion); 04857 04858 sendFragmentedSignal(rg, GSN_CREATE_TAB_REQ, signal, 04859 CreateTabReq::SignalLength, JBB); 04860 04861 return; 04862 } 04863 04864 void 04865 Dbdict::execCREATE_TAB_REF(Signal* signal){ 04866 jamEntry(); 04867 04868 CreateTabRef * const ref = (CreateTabRef*)signal->getDataPtr(); 04869 04870 CreateTableRecordPtr createTabPtr; 04871 ndbrequire(c_opCreateTable.find(createTabPtr, ref->senderData)); 04872 04873 ndbrequire(createTabPtr.p->m_coordinatorRef == reference()); 04874 ndbrequire(createTabPtr.p->m_coordinatorData.m_gsn == GSN_CREATE_TAB_REQ); 04875 04876 if(ref->errorCode != CreateTabRef::NF_FakeErrorREF){ 04877 createTabPtr.p->setErrorCode(ref->errorCode); 04878 } 04879 createTab_reply(signal, createTabPtr, refToNode(ref->senderRef)); 04880 } 04881 04882 void 04883 Dbdict::execCREATE_TAB_CONF(Signal* signal){ 04884 jamEntry(); 04885 04886 ndbrequire(signal->getNoOfSections() == 0); 04887 04888 CreateTabConf * const conf = (CreateTabConf*)signal->getDataPtr(); 04889 04890 CreateTableRecordPtr createTabPtr; 04891 ndbrequire(c_opCreateTable.find(createTabPtr, conf->senderData)); 04892 04893 ndbrequire(createTabPtr.p->m_coordinatorRef == reference()); 04894 ndbrequire(createTabPtr.p->m_coordinatorData.m_gsn == GSN_CREATE_TAB_REQ); 04895 04896 createTab_reply(signal, createTabPtr, refToNode(conf->senderRef)); 04897 } 04898 04899 void 04900 Dbdict::createTab_reply(Signal* signal, 04901 CreateTableRecordPtr createTabPtr, 04902 Uint32 nodeId) 04903 { 04904 04905 SafeCounter tmp(c_counterMgr, createTabPtr.p->m_coordinatorData.m_counter); 04906 if(!tmp.clearWaitingFor(nodeId)){ 04907 jam(); 04908 return; 04909 } 04910 04911 switch(createTabPtr.p->m_coordinatorData.m_requestType){ 04912 case CreateTabReq::CreateTablePrepare:{ 04913 04914 if(createTabPtr.p->m_errorCode != 0){ 04915 jam(); 04919 NodeReceiverGroup rg(DBDICT, c_aliveNodes); 04920 createTabPtr.p->m_coordinatorData.m_gsn = GSN_CREATE_TAB_REQ; 04921 createTabPtr.p->m_coordinatorData.m_requestType = CreateTabReq::CreateTableDrop; 04922 ndbrequire(tmp.init<CreateTabRef>(rg, createTabPtr.p->key)); 04923 04924 CreateTabReq * const req = (CreateTabReq*)signal->getDataPtrSend(); 04925 req->senderRef = reference(); 04926 req->senderData = createTabPtr.p->key; 04927 req->requestType = CreateTabReq::CreateTableDrop; 04928 04929 sendSignal(rg, GSN_CREATE_TAB_REQ, signal, 04930 CreateTabReq::SignalLength, JBB); 04931 return; 04932 } 04933 04937 Mutex mutex(signal, c_mutexMgr, createTabPtr.p->m_startLcpMutex); 04938 Callback c = { safe_cast(&Dbdict::createTab_startLcpMutex_locked), 04939 createTabPtr.p->key}; 04940 04941 ndbrequire(mutex.lock(c)); 04942 return; 04943 } 04944 case CreateTabReq::CreateTableCommit:{ 04945 jam(); 04946 ndbrequire(createTabPtr.p->m_errorCode == 0); 04947 04951 Mutex mutex(signal, c_mutexMgr, createTabPtr.p->m_startLcpMutex); 04952 Callback c = { safe_cast(&Dbdict::createTab_startLcpMutex_unlocked), 04953 createTabPtr.p->key}; 04954 mutex.unlock(c); 04955 return; 04956 } 04957 case CreateTabReq::CreateTableDrop:{ 04958 jam(); 04959 CreateTableRef * const ref = (CreateTableRef*)signal->getDataPtr(); 04960 ref->senderRef = reference(); 04961 ref->senderData = createTabPtr.p->m_senderData; 04962 ref->errorCode = createTabPtr.p->m_errorCode; 04963 ref->masterNodeId = c_masterNodeId; 04964 ref->status = 0; 04965 ref->errorKey = 0; 04966 ref->errorLine = 0; 04967 04968 //@todo check api failed 04969 sendSignal(createTabPtr.p->m_senderRef, GSN_CREATE_TABLE_REF, signal, 04970 CreateTableRef::SignalLength, JBB); 04971 releaseCreateTableOp(signal,createTabPtr); 04972 c_blockState = BS_IDLE; 04973 return; 04974 } 04975 } 04976 ndbrequire(false); 04977 } 04978 04979 void 04980 Dbdict::createTab_startLcpMutex_locked(Signal* signal, 04981 Uint32 callbackData, 04982 Uint32 retValue){ 04983 jamEntry(); 04984 04985 ndbrequire(retValue == 0); 04986 04987 CreateTableRecordPtr createTabPtr; 04988 ndbrequire(c_opCreateTable.find(createTabPtr, callbackData)); 04989 04990 NodeReceiverGroup rg(DBDICT, c_aliveNodes); 04991 createTabPtr.p->m_coordinatorData.m_gsn = GSN_CREATE_TAB_REQ; 04992 createTabPtr.p->m_coordinatorData.m_requestType = CreateTabReq::CreateTableCommit; 04993 SafeCounter tmp(c_counterMgr, createTabPtr.p->m_coordinatorData.m_counter); 04994 tmp.init<CreateTabRef>(rg, GSN_CREATE_TAB_REF, createTabPtr.p->key); 04995 04996 CreateTabReq * const req = (CreateTabReq*)signal->getDataPtrSend(); 04997 req->senderRef = reference(); 04998 req->senderData = createTabPtr.p->key; 04999 req->requestType = CreateTabReq::CreateTableCommit; 05000 05001 sendSignal(rg, GSN_CREATE_TAB_REQ, signal, 05002 CreateTabReq::SignalLength, JBB); 05003 } 05004 05005 void 05006 Dbdict::createTab_startLcpMutex_unlocked(Signal* signal, 05007 Uint32 callbackData, 05008 Uint32 retValue){ 05009 jamEntry(); 05010 05011 ndbrequire(retValue == 0); 05012 05013 CreateTableRecordPtr createTabPtr; 05014 ndbrequire(c_opCreateTable.find(createTabPtr, callbackData)); 05015 05016 createTabPtr.p->m_startLcpMutex.release(c_mutexMgr); 05017 05018 TableRecordPtr tabPtr; 05019 c_tableRecordPool.getPtr(tabPtr, createTabPtr.p->m_tablePtrI); 05020 05021 CreateTableConf * const conf = (CreateTableConf*)signal->getDataPtr(); 05022 conf->senderRef = reference(); 05023 conf->senderData = createTabPtr.p->m_senderData; 05024 conf->tableId = createTabPtr.p->m_tablePtrI; 05025 conf->tableVersion = tabPtr.p->tableVersion; 05026 05027 //@todo check api failed 05028 sendSignal(createTabPtr.p->m_senderRef, GSN_CREATE_TABLE_CONF, signal, 05029 CreateTableConf::SignalLength, JBB); 05030 releaseCreateTableOp(signal,createTabPtr); 05031 c_blockState = BS_IDLE; 05032 return; 05033 } 05034 05035 /*********************************************************** 05036 * CreateTable participant code 05037 **********************************************************/ 05038 void 05039 Dbdict::execCREATE_TAB_REQ(Signal* signal){ 05040 jamEntry(); 05041 05042 if(!assembleFragments(signal)){ 05043 jam(); 05044 return; 05045 } 05046 05047 CreateTabReq * const req = (CreateTabReq*)signal->getDataPtr(); 05048 05049 CreateTabReq::RequestType rt = (CreateTabReq::RequestType)req->requestType; 05050 switch(rt){ 05051 case CreateTabReq::CreateTablePrepare: 05052 CRASH_INSERTION2(6003, getOwnNodeId() != c_masterNodeId); 05053 createTab_prepare(signal, req); 05054 return; 05055 case CreateTabReq::CreateTableCommit: 05056 CRASH_INSERTION2(6004, getOwnNodeId() != c_masterNodeId); 05057 createTab_commit(signal, req); 05058 return; 05059 case CreateTabReq::CreateTableDrop: 05060 CRASH_INSERTION2(6005, getOwnNodeId() != c_masterNodeId); 05061 createTab_drop(signal, req); 05062 return; 05063 } 05064 ndbrequire(false); 05065 } 05066 05067 void 05068 Dbdict::createTab_prepare(Signal* signal, CreateTabReq * req){ 05069 05070 const Uint32 gci = req->gci; 05071 const Uint32 tableId = req->tableId; 05072 const Uint32 tableVersion = req->tableVersion; 05073 05074 SegmentedSectionPtr tabInfoPtr; 05075 signal->getSection(tabInfoPtr, CreateTabReq::DICT_TAB_INFO); 05076 05077 CreateTableRecordPtr createTabPtr; 05078 if(req->senderRef == reference()){ 05079 jam(); 05080 ndbrequire(c_opCreateTable.find(createTabPtr, req->senderData)); 05081 } else { 05082 jam(); 05083 c_opCreateTable.seize(createTabPtr); 05084 05085 ndbrequire(!createTabPtr.isNull()); 05086 05087 createTabPtr.p->key = req->senderData; 05088 c_opCreateTable.add(createTabPtr); 05089 createTabPtr.p->m_errorCode = 0; 05090 createTabPtr.p->m_tablePtrI = tableId; 05091 createTabPtr.p->m_coordinatorRef = req->senderRef; 05092 createTabPtr.p->m_senderRef = req->clientRef; 05093 createTabPtr.p->m_senderData = req->clientData; 05094 createTabPtr.p->m_dihAddFragPtr = RNIL; 05095 05099 ParseDictTabInfoRecord parseRecord; 05100 parseRecord.requestType = DictTabInfo::AddTableFromDict; 05101 parseRecord.errorCode = 0; 05102 05103 SimplePropertiesSectionReader r(tabInfoPtr, getSectionSegmentPool()); 05104 05105 handleTabInfoInit(r, &parseRecord); 05106 05107 ndbrequire(parseRecord.errorCode == 0); 05108 } 05109 05110 ndbrequire(!createTabPtr.isNull()); 05111 05112 SegmentedSectionPtr fragPtr; 05113 signal->getSection(fragPtr, CreateTabReq::FRAGMENTATION); 05114 05115 createTabPtr.p->m_tabInfoPtrI = tabInfoPtr.i; 05116 createTabPtr.p->m_fragmentsPtrI = fragPtr.i; 05117 05118 signal->header.m_noOfSections = 0; 05119 05120 TableRecordPtr tabPtr; 05121 c_tableRecordPool.getPtr(tabPtr, tableId); 05122 tabPtr.p->packedSize = tabInfoPtr.sz; 05123 tabPtr.p->tableVersion = tableVersion; 05124 tabPtr.p->gciTableCreated = gci; 05125 05126 SchemaFile::TableEntry tabEntry; 05127 tabEntry.m_tableVersion = tableVersion; 05128 tabEntry.m_tableType = tabPtr.p->tableType; 05129 tabEntry.m_tableState = SchemaFile::ADD_STARTED; 05130 tabEntry.m_gcp = gci; 05131 tabEntry.m_info_words = tabInfoPtr.sz; 05132 memset(tabEntry.m_unused, 0, sizeof(tabEntry.m_unused)); 05133 05134 Callback callback; 05135 callback.m_callbackData = createTabPtr.p->key; 05136 callback.m_callbackFunction = 05137 safe_cast(&Dbdict::createTab_writeSchemaConf1); 05138 05139 updateSchemaState(signal, tableId, &tabEntry, &callback); 05140 } 05141 05142 void getSection(SegmentedSectionPtr & ptr, Uint32 i); 05143 05144 void 05145 Dbdict::createTab_writeSchemaConf1(Signal* signal, 05146 Uint32 callbackData, 05147 Uint32 returnCode){ 05148 jam(); 05149 05150 CreateTableRecordPtr createTabPtr; 05151 ndbrequire(c_opCreateTable.find(createTabPtr, callbackData)); 05152 05153 Callback callback; 05154 callback.m_callbackData = createTabPtr.p->key; 05155 callback.m_callbackFunction = 05156 safe_cast(&Dbdict::createTab_writeTableConf); 05157 05158 SegmentedSectionPtr tabInfoPtr; 05159 getSection(tabInfoPtr, createTabPtr.p->m_tabInfoPtrI); 05160 writeTableFile(signal, createTabPtr.p->m_tablePtrI, tabInfoPtr, &callback); 05161 #if 0 05162 createTabPtr.p->m_tabInfoPtrI = RNIL; 05163 signal->setSection(tabInfoPtr, 0); 05164 releaseSections(signal); 05165 #endif 05166 } 05167 05168 void 05169 Dbdict::createTab_writeTableConf(Signal* signal, 05170 Uint32 callbackData, 05171 Uint32 returnCode){ 05172 jam(); 05173 05174 CreateTableRecordPtr createTabPtr; 05175 ndbrequire(c_opCreateTable.find(createTabPtr, callbackData)); 05176 05177 SegmentedSectionPtr fragDataPtr; 05178 getSection(fragDataPtr, createTabPtr.p->m_fragmentsPtrI); 05179 05180 Callback callback; 05181 callback.m_callbackData = callbackData; 05182 callback.m_callbackFunction = 05183 safe_cast(&Dbdict::createTab_dihComplete); 05184 05185 createTab_dih(signal, createTabPtr, fragDataPtr, &callback); 05186 } 05187 05188 void 05189 Dbdict::createTab_dih(Signal* signal, 05190 CreateTableRecordPtr createTabPtr, 05191 SegmentedSectionPtr fragDataPtr, 05192 Callback * c){ 05193 jam(); 05194 05195 createTabPtr.p->m_callback = * c; 05196 05197 TableRecordPtr tabPtr; 05198 c_tableRecordPool.getPtr(tabPtr, createTabPtr.p->m_tablePtrI); 05199 05200 DiAddTabReq * req = (DiAddTabReq*)signal->getDataPtrSend(); 05201 req->connectPtr = createTabPtr.p->key; 05202 req->tableId = tabPtr.i; 05203 req->fragType = tabPtr.p->fragmentType; 05204 req->kValue = tabPtr.p->kValue; 05205 req->noOfReplicas = 0; 05206 req->storedTable = !!(tabPtr.p->m_bits & TableRecord::TR_Logged); 05207 req->tableType = tabPtr.p->tableType; 05208 req->schemaVersion = tabPtr.p->tableVersion; 05209 req->primaryTableId = tabPtr.p->primaryTableId; 05210 05211 /* 05212 Behöver fiska upp fragDataPtr från table object istället 05213 */ 05214 if(!fragDataPtr.isNull()){ 05215 signal->setSection(fragDataPtr, DiAddTabReq::FRAGMENTATION); 05216 } 05217 05218 sendSignal(DBDIH_REF, GSN_DIADDTABREQ, signal, 05219 DiAddTabReq::SignalLength, JBB); 05220 05224 KeyDescriptor* desc= g_key_descriptor_pool.getPtr(tabPtr.i); 05225 new (desc) KeyDescriptor(); 05226 05227 Uint32 key = 0; 05228 Ptr<AttributeRecord> attrPtr; 05229 LocalDLFifoList<AttributeRecord> list(c_attributeRecordPool, 05230 tabPtr.p->m_attributes); 05231 for(list.first(attrPtr); !attrPtr.isNull(); list.next(attrPtr)) 05232 { 05233 AttributeRecord* aRec = attrPtr.p; 05234 if (aRec->tupleKey) 05235 { 05236 Uint32 attr = aRec->attributeDescriptor; 05237 05238 desc->noOfKeyAttr ++; 05239 desc->keyAttr[key].attributeDescriptor = attr; 05240 Uint32 csNumber = (aRec->extPrecision >> 16); 05241 if (csNumber) 05242 { 05243 desc->keyAttr[key].charsetInfo = all_charsets[csNumber]; 05244 ndbrequire(all_charsets[csNumber] != 0); 05245 desc->hasCharAttr = 1; 05246 } 05247 else 05248 { 05249 desc->keyAttr[key].charsetInfo = 0; 05250 } 05251 if (AttributeDescriptor::getDKey(attr)) 05252 { 05253 desc->noOfDistrKeys ++; 05254 } 05255 if (AttributeDescriptor::getArrayType(attr) != NDB_ARRAYTYPE_FIXED) 05256 { 05257 desc->noOfVarKeys ++; 05258 } 05259 key++; 05260 } 05261 } 05262 ndbrequire(key == tabPtr.p->noOfPrimkey); 05263 } 05264 05265 static 05266 void 05267 calcLHbits(Uint32 * lhPageBits, Uint32 * lhDistrBits, 05268 Uint32 fid, Uint32 totalFragments) 05269 { 05270 Uint32 distrBits = 0; 05271 Uint32 pageBits = 0; 05272 05273 Uint32 tmp = 1; 05274 while (tmp < totalFragments) { 05275 jam(); 05276 tmp <<= 1; 05277 distrBits++; 05278 }//while 05279 #ifdef ndb_classical_lhdistrbits 05280 if (tmp != totalFragments) { 05281 tmp >>= 1; 05282 if ((fid >= (totalFragments - tmp)) && (fid < (tmp - 1))) { 05283 distrBits--; 05284 }//if 05285 }//if 05286 #endif 05287 * lhPageBits = pageBits; 05288 * lhDistrBits = distrBits; 05289 05290 }//calcLHbits() 05291 05292 05293 void 05294 Dbdict::execADD_FRAGREQ(Signal* signal) { 05295 jamEntry(); 05296 05297 AddFragReq * const req = (AddFragReq*)signal->getDataPtr(); 05298 05299 Uint32 dihPtr = req->dihPtr; 05300 Uint32 senderData = req->senderData; 05301 Uint32 tableId = req->tableId; 05302 Uint32 fragId = req->fragmentId; 05303 Uint32 node = req->nodeId; 05304 Uint32 lcpNo = req->nextLCP; 05305 Uint32 fragCount = req->totalFragments; 05306 Uint32 requestInfo = req->requestInfo; 05307 Uint32 startGci = req->startGci; 05308 Uint32 tablespace_id= req->tablespaceId; 05309 Uint32 logPart = req->logPartId; 05310 05311 ndbrequire(node == getOwnNodeId()); 05312 05313 CreateTableRecordPtr createTabPtr; 05314 ndbrequire(c_opCreateTable.find(createTabPtr, senderData)); 05315 05316 createTabPtr.p->m_dihAddFragPtr = dihPtr; 05317 05318 TableRecordPtr tabPtr; 05319 c_tableRecordPool.getPtr(tabPtr, tableId); 05320 05321 #if 0 05322 tabPtr.p->gciTableCreated = (startGci > tabPtr.p->gciTableCreated ? startGci: 05323 startGci > tabPtr.p->gciTableCreated); 05324 #endif 05325 05329 Uint32 lhDistrBits = 0; 05330 Uint32 lhPageBits = 0; 05331 ::calcLHbits(&lhPageBits, &lhDistrBits, fragId, fragCount); 05332 05333 Uint64 maxRows = tabPtr.p->maxRowsLow + 05334 (((Uint64)tabPtr.p->maxRowsHigh) << 32); 05335 Uint64 minRows = tabPtr.p->minRowsLow + 05336 (((Uint64)tabPtr.p->minRowsHigh) << 32); 05337 maxRows = (maxRows + fragCount - 1) / fragCount; 05338 minRows = (minRows + fragCount - 1) / fragCount; 05339 05340 { 05341 LqhFragReq* req = (LqhFragReq*)signal->getDataPtrSend(); 05342 req->senderData = senderData; 05343 req->senderRef = reference(); 05344 req->fragmentId = fragId; 05345 req->requestInfo = requestInfo; 05346 req->tableId = tableId; 05347 req->localKeyLength = tabPtr.p->localKeyLen; 05348 req->maxLoadFactor = tabPtr.p->maxLoadFactor; 05349 req->minLoadFactor = tabPtr.p->minLoadFactor; 05350 req->kValue = tabPtr.p->kValue; 05351 req->lh3DistrBits = 0; //lhDistrBits; 05352 req->lh3PageBits = 0; //lhPageBits; 05353 req->noOfAttributes = tabPtr.p->noOfAttributes; 05354 req->noOfNullAttributes = tabPtr.p->noOfNullBits; 05355 req->maxRowsLow = maxRows & 0xFFFFFFFF; 05356 req->maxRowsHigh = maxRows >> 32; 05357 req->minRowsLow = minRows & 0xFFFFFFFF; 05358 req->minRowsHigh = minRows >> 32; 05359 req->schemaVersion = tabPtr.p->tableVersion; 05360 Uint32 keyLen = tabPtr.p->tupKeyLength; 05361 req->keyLength = keyLen; // wl-2066 no more "long keys" 05362 req->nextLCP = lcpNo; 05363 05364 req->noOfKeyAttr = tabPtr.p->noOfPrimkey; 05365 req->noOfCharsets = tabPtr.p->noOfCharsets; 05366 req->checksumIndicator = 1; 05367 req->GCPIndicator = 1; 05368 req->startGci = startGci; 05369 req->tableType = tabPtr.p->tableType; 05370 req->primaryTableId = tabPtr.p->primaryTableId; 05371 req->tablespace_id= tabPtr.p->m_tablespace_id; 05372 //req->tablespace_id= tablespace_id; 05373 req->logPartId = logPart; 05374 sendSignal(DBLQH_REF, GSN_LQHFRAGREQ, signal, 05375 LqhFragReq::SignalLength, JBB); 05376 } 05377 } 05378 05379 void 05380 Dbdict::execLQHFRAGREF(Signal * signal){ 05381 jamEntry(); 05382 LqhFragRef * const ref = (LqhFragRef*)signal->getDataPtr(); 05383 05384 CreateTableRecordPtr createTabPtr; 05385 ndbrequire(c_opCreateTable.find(createTabPtr, ref->senderData)); 05386 05387 createTabPtr.p->setErrorCode(ref->errorCode); 05388 05389 { 05390 AddFragRef * const ref = (AddFragRef*)signal->getDataPtr(); 05391 ref->dihPtr = createTabPtr.p->m_dihAddFragPtr; 05392 sendSignal(DBDIH_REF, GSN_ADD_FRAGREF, signal, 05393 AddFragRef::SignalLength, JBB); 05394 } 05395 } 05396 05397 void 05398 Dbdict::execLQHFRAGCONF(Signal * signal){ 05399 jamEntry(); 05400 LqhFragConf * const conf = (LqhFragConf*)signal->getDataPtr(); 05401 05402 CreateTableRecordPtr createTabPtr; 05403 ndbrequire(c_opCreateTable.find(createTabPtr, conf->senderData)); 05404 05405 createTabPtr.p->m_lqhFragPtr = conf->lqhFragPtr; 05406 05407 TableRecordPtr tabPtr; 05408 c_tableRecordPool.getPtr(tabPtr, createTabPtr.p->m_tablePtrI); 05409 sendLQHADDATTRREQ(signal, createTabPtr, tabPtr.p->m_attributes.firstItem); 05410 } 05411 05412 void 05413 Dbdict::sendLQHADDATTRREQ(Signal* signal, 05414 CreateTableRecordPtr createTabPtr, 05415 Uint32 attributePtrI){ 05416 jam(); 05417 TableRecordPtr tabPtr; 05418 c_tableRecordPool.getPtr(tabPtr, createTabPtr.p->m_tablePtrI); 05419 LqhAddAttrReq * const req = (LqhAddAttrReq*)signal->getDataPtrSend(); 05420 Uint32 i = 0; 05421 for(i = 0; i<LqhAddAttrReq::MAX_ATTRIBUTES && attributePtrI != RNIL; i++){ 05422 jam(); 05423 AttributeRecordPtr attrPtr; 05424 c_attributeRecordPool.getPtr(attrPtr, attributePtrI); 05425 LqhAddAttrReq::Entry& entry = req->attributes[i]; 05426 entry.attrId = attrPtr.p->attributeId; 05427 entry.attrDescriptor = attrPtr.p->attributeDescriptor; 05428 entry.extTypeInfo = 0; 05429 // charset number passed to TUP, TUX in upper half 05430 entry.extTypeInfo |= (attrPtr.p->extPrecision & ~0xFFFF); 05431 if (tabPtr.p->isIndex()) { 05432 Uint32 primaryAttrId; 05433 if (attrPtr.p->nextList != RNIL) { 05434 getIndexAttr(tabPtr, attributePtrI, &primaryAttrId); 05435 } else { 05436 primaryAttrId = ZNIL; 05437 if (tabPtr.p->isOrderedIndex()) 05438 entry.attrId = 0; // attribute goes to TUP 05439 } 05440 entry.attrId |= (primaryAttrId << 16); 05441 } 05442 attributePtrI = attrPtr.p->nextList; 05443 } 05444 req->lqhFragPtr = createTabPtr.p->m_lqhFragPtr; 05445 req->senderData = createTabPtr.p->key; 05446 req->senderAttrPtr = attributePtrI; 05447 req->noOfAttributes = i; 05448 05449 sendSignal(DBLQH_REF, GSN_LQHADDATTREQ, signal, 05450 LqhAddAttrReq::HeaderLength + LqhAddAttrReq::EntryLength * i, JBB); 05451 } 05452 05453 void 05454 Dbdict::execLQHADDATTREF(Signal * signal){ 05455 jamEntry(); 05456 LqhAddAttrRef * const ref = (LqhAddAttrRef*)signal->getDataPtr(); 05457 05458 CreateTableRecordPtr createTabPtr; 05459 ndbrequire(c_opCreateTable.find(createTabPtr, ref->senderData)); 05460 05461 createTabPtr.p->setErrorCode(ref->errorCode); 05462 05463 { 05464 AddFragRef * const ref = (AddFragRef*)signal->getDataPtr(); 05465 ref->dihPtr = createTabPtr.p->m_dihAddFragPtr; 05466 sendSignal(DBDIH_REF, GSN_ADD_FRAGREF, signal, 05467 AddFragRef::SignalLength, JBB); 05468 } 05469 05470 } 05471 05472 void 05473 Dbdict::execLQHADDATTCONF(Signal * signal){ 05474 jamEntry(); 05475 LqhAddAttrConf * const conf = (LqhAddAttrConf*)signal->getDataPtr(); 05476 05477 CreateTableRecordPtr createTabPtr; 05478 ndbrequire(c_opCreateTable.find(createTabPtr, conf->senderData)); 05479 05480 const Uint32 fragId = conf->fragId; 05481 const Uint32 nextAttrPtr = conf->senderAttrPtr; 05482 if(nextAttrPtr != RNIL){ 05483 jam(); 05484 sendLQHADDATTRREQ(signal, createTabPtr, nextAttrPtr); 05485 return; 05486 } 05487 05488 { 05489 AddFragConf * const conf = (AddFragConf*)signal->getDataPtr(); 05490 conf->dihPtr = createTabPtr.p->m_dihAddFragPtr; 05491 conf->fragId = fragId; 05492 sendSignal(DBDIH_REF, GSN_ADD_FRAGCONF, signal, 05493 AddFragConf::SignalLength, JBB); 05494 } 05495 } 05496 05497 void 05498 Dbdict::execDIADDTABREF(Signal* signal){ 05499 jam(); 05500 05501 DiAddTabRef * const ref = (DiAddTabRef*)signal->getDataPtr(); 05502 05503 CreateTableRecordPtr createTabPtr; 05504 ndbrequire(c_opCreateTable.find(createTabPtr, ref->senderData)); 05505 05506 createTabPtr.p->setErrorCode(ref->errorCode); 05507 execute(signal, createTabPtr.p->m_callback, 0); 05508 } 05509 05510 void 05511 Dbdict::execDIADDTABCONF(Signal* signal){ 05512 jam(); 05513 05514 DiAddTabConf * const conf = (DiAddTabConf*)signal->getDataPtr(); 05515 05516 CreateTableRecordPtr createTabPtr; 05517 ndbrequire(c_opCreateTable.find(createTabPtr, conf->senderData)); 05518 05519 signal->theData[0] = createTabPtr.p->key; 05520 signal->theData[1] = reference(); 05521 signal->theData[2] = createTabPtr.p->m_tablePtrI; 05522 05523 if(createTabPtr.p->m_dihAddFragPtr != RNIL){ 05524 jam(); 05525 05529 sendSignal(DBLQH_REF, GSN_TAB_COMMITREQ, signal, 3, JBB); 05530 return; 05531 } else { 05535 execute(signal, createTabPtr.p->m_callback, 0); 05536 return; 05537 //sendSignal(DBDIH_REF, GSN_TAB_COMMITREQ, signal, 3, JBB); 05538 } 05539 } 05540 05541 void 05542 Dbdict::execTAB_COMMITREF(Signal* signal) { 05543 jamEntry(); 05544 ndbrequire(false); 05545 }//execTAB_COMMITREF() 05546 05547 void 05548 Dbdict::execTAB_COMMITCONF(Signal* signal){ 05549 jamEntry(); 05550 05551 CreateTableRecordPtr createTabPtr; 05552 ndbrequire(c_opCreateTable.find(createTabPtr, signal->theData[0])); 05553 05554 if(refToBlock(signal->getSendersBlockRef()) == DBLQH){ 05555 05556 execute(signal, createTabPtr.p->m_callback, 0); 05557 return; 05558 } 05559 05560 if(refToBlock(signal->getSendersBlockRef()) == DBDIH){ 05561 TableRecordPtr tabPtr; 05562 c_tableRecordPool.getPtr(tabPtr, createTabPtr.p->m_tablePtrI); 05563 05564 signal->theData[0] = tabPtr.i; 05565 signal->theData[1] = tabPtr.p->tableVersion; 05566 signal->theData[2] = (Uint32)!!(tabPtr.p->m_bits & TableRecord::TR_Logged); 05567 signal->theData[3] = reference(); 05568 signal->theData[4] = (Uint32)tabPtr.p->tableType; 05569 signal->theData[5] = createTabPtr.p->key; 05570 signal->theData[6] = (Uint32)tabPtr.p->noOfPrimkey; 05571 sendSignal(DBTC_REF, GSN_TC_SCHVERREQ, signal, 7, JBB); 05572 return; 05573 } 05574 05575 ndbrequire(false); 05576 } 05577 05578 void 05579 Dbdict::createTab_dihComplete(Signal* signal, 05580 Uint32 callbackData, 05581 Uint32 returnCode){ 05582 jam(); 05583 05584 CreateTableRecordPtr createTabPtr; 05585 ndbrequire(c_opCreateTable.find(createTabPtr, callbackData)); 05586 05587 //@todo check for master failed 05588 05589 if(createTabPtr.p->m_errorCode == 0){ 05590 jam(); 05591 05592 CreateTabConf * const conf = (CreateTabConf*)signal->getDataPtr(); 05593 conf->senderRef = reference(); 05594 conf->senderData = createTabPtr.p->key; 05595 sendSignal(createTabPtr.p->m_coordinatorRef, GSN_CREATE_TAB_CONF, 05596 signal, CreateTabConf::SignalLength, JBB); 05597 return; 05598 } 05599 05600 CreateTabRef * const ref = (CreateTabRef*)signal->getDataPtr(); 05601 ref->senderRef = reference(); 05602 ref->senderData = createTabPtr.p->key; 05603 ref->errorCode = createTabPtr.p->m_errorCode; 05604 ref->errorLine = 0; 05605 ref->errorKey = 0; 05606 ref->errorStatus = 0; 05607 05608 sendSignal(createTabPtr.p->m_coordinatorRef, GSN_CREATE_TAB_REF, 05609 signal, CreateTabRef::SignalLength, JBB); 05610 } 05611 05612 void 05613 Dbdict::createTab_commit(Signal * signal, CreateTabReq * req){ 05614 jam(); 05615 05616 CreateTableRecordPtr createTabPtr; 05617 ndbrequire(c_opCreateTable.find(createTabPtr, req->senderData)); 05618 05619 TableRecordPtr tabPtr; 05620 c_tableRecordPool.getPtr(tabPtr, createTabPtr.p->m_tablePtrI); 05621 05622 SchemaFile::TableEntry tabEntry; 05623 tabEntry.m_tableVersion = tabPtr.p->tableVersion; 05624 tabEntry.m_tableType = tabPtr.p->tableType; 05625 tabEntry.m_tableState = SchemaFile::TABLE_ADD_COMMITTED; 05626 tabEntry.m_gcp = tabPtr.p->gciTableCreated; 05627 tabEntry.m_info_words = tabPtr.p->packedSize; 05628 memset(tabEntry.m_unused, 0, sizeof(tabEntry.m_unused)); 05629 05630 Callback callback; 05631 callback.m_callbackData = createTabPtr.p->key; 05632 callback.m_callbackFunction = 05633 safe_cast(&Dbdict::createTab_writeSchemaConf2); 05634 05635 updateSchemaState(signal, tabPtr.i, &tabEntry, &callback); 05636 } 05637 05638 void 05639 Dbdict::createTab_writeSchemaConf2(Signal* signal, 05640 Uint32 callbackData, 05641 Uint32 returnCode){ 05642 jam(); 05643 05644 CreateTableRecordPtr createTabPtr; 05645 ndbrequire(c_opCreateTable.find(createTabPtr, callbackData)); 05646 05647 Callback c; 05648 c.m_callbackData = callbackData; 05649 c.m_callbackFunction = safe_cast(&Dbdict::createTab_alterComplete); 05650 alterTab_activate(signal, createTabPtr, &c); 05651 } 05652 05653 void 05654 Dbdict::createTab_alterComplete(Signal* signal, 05655 Uint32 callbackData, 05656 Uint32 returnCode){ 05657 jam(); 05658 05659 CreateTableRecordPtr createTabPtr; 05660 ndbrequire(c_opCreateTable.find(createTabPtr, callbackData)); 05661 05662 TableRecordPtr tabPtr; 05663 c_tableRecordPool.getPtr(tabPtr, createTabPtr.p->m_tablePtrI); 05664 tabPtr.p->tabState = TableRecord::DEFINED; 05665 05666 //@todo check error 05667 //@todo check master failed 05668 05669 CreateTabConf * const conf = (CreateTabConf*)signal->getDataPtr(); 05670 conf->senderRef = reference(); 05671 conf->senderData = createTabPtr.p->key; 05672 { 05673 CreateTabConf tmp= *conf; 05674 conf->senderData = createTabPtr.p->m_tablePtrI; 05675 #if 0 05676 signal->header.m_noOfSections = 1; 05677 SegmentedSectionPtr tabInfoPtr; 05678 getSection(tabInfoPtr, createTabPtr.p->m_tabInfoPtrI); 05679 signal->setSection(tabInfoPtr, 0); 05680 #endif 05681 sendSignal(SUMA_REF, GSN_CREATE_TAB_CONF, signal, 05682 CreateTabConf::SignalLength, JBB); 05683 *conf= tmp; 05684 #if 0 05685 signal->header.m_noOfSections = 0; 05686 #endif 05687 } 05688 sendSignal(createTabPtr.p->m_coordinatorRef, GSN_CREATE_TAB_CONF, 05689 signal, CreateTabConf::SignalLength, JBB); 05690 05691 if(createTabPtr.p->m_coordinatorRef != reference()){ 05692 jam(); 05693 releaseCreateTableOp(signal,createTabPtr); 05694 } 05695 } 05696 05697 void 05698 Dbdict::createTab_drop(Signal* signal, CreateTabReq * req){ 05699 jam(); 05700 05701 const Uint32 key = req->senderData; 05702 05703 CreateTableRecordPtr createTabPtr; 05704 ndbrequire(c_opCreateTable.find(createTabPtr, key)); 05705 05706 TableRecordPtr tabPtr; 05707 c_tableRecordPool.getPtr(tabPtr, createTabPtr.p->m_tablePtrI); 05708 tabPtr.p->tabState = TableRecord::DROPPING; 05709 05710 DropTableRecordPtr dropTabPtr; 05711 ndbrequire(c_opDropTable.seize(dropTabPtr)); 05712 05713 dropTabPtr.p->key = key; 05714 c_opDropTable.add(dropTabPtr); 05715 05716 dropTabPtr.p->m_errorCode = 0; 05717 dropTabPtr.p->m_request.tableId = createTabPtr.p->m_tablePtrI; 05718 dropTabPtr.p->m_requestType = DropTabReq::CreateTabDrop; 05719 dropTabPtr.p->m_coordinatorRef = createTabPtr.p->m_coordinatorRef; 05720 dropTabPtr.p->m_participantData.m_gsn = GSN_DROP_TAB_REQ; 05721 05722 dropTabPtr.p->m_participantData.m_block = 0; 05723 dropTabPtr.p->m_participantData.m_callback.m_callbackData = req->senderData; 05724 dropTabPtr.p->m_participantData.m_callback.m_callbackFunction = 05725 safe_cast(&Dbdict::createTab_dropComplete); 05726 dropTab_nextStep(signal, dropTabPtr); 05727 05728 if (tabPtr.p->m_tablespace_id != RNIL) 05729 { 05730 FilegroupPtr ptr; 05731 ndbrequire(c_filegroup_hash.find(ptr, tabPtr.p->m_tablespace_id)); 05732 decrease_ref_count(ptr.p->m_obj_ptr_i); 05733 } 05734 } 05735 05736 void 05737 Dbdict::createTab_dropComplete(Signal* signal, 05738 Uint32 callbackData, 05739 Uint32 returnCode){ 05740 jam(); 05741 05742 CreateTableRecordPtr createTabPtr; 05743 ndbrequire(c_opCreateTable.find(createTabPtr, callbackData)); 05744 05745 DropTableRecordPtr dropTabPtr; 05746 ndbrequire(c_opDropTable.find(dropTabPtr, callbackData)); 05747 05748 TableRecordPtr tabPtr; 05749 c_tableRecordPool.getPtr(tabPtr, createTabPtr.p->m_tablePtrI); 05750 05751 releaseTableObject(tabPtr.i); 05752 05753 XSchemaFile * xsf = &c_schemaFile[c_schemaRecord.schemaPage != 0]; 05754 SchemaFile::TableEntry * tableEntry = getTableEntry(xsf, tabPtr.i); 05755 tableEntry->m_tableState = SchemaFile::DROP_TABLE_COMMITTED; 05756 05757 //@todo check error 05758 //@todo check master failed 05759 05760 CreateTabConf * const conf = (CreateTabConf*)signal->getDataPtr(); 05761 conf->senderRef = reference(); 05762 conf->senderData = createTabPtr.p->key; 05763 sendSignal(createTabPtr.p->m_coordinatorRef, GSN_CREATE_TAB_CONF, 05764 signal, CreateTabConf::SignalLength, JBB); 05765 05766 if(createTabPtr.p->m_coordinatorRef != reference()){ 05767 jam(); 05768 releaseCreateTableOp(signal,createTabPtr); 05769 } 05770 05771 c_opDropTable.release(dropTabPtr); 05772 } 05773 05774 void 05775 Dbdict::alterTab_activate(Signal* signal, CreateTableRecordPtr createTabPtr, 05776 Callback * c){ 05777 05778 createTabPtr.p->m_callback = * c; 05779 05780 signal->theData[0] = createTabPtr.p->key; 05781 signal->theData[1] = reference(); 05782 signal->theData[2] = createTabPtr.p->m_tablePtrI; 05783 sendSignal(DBDIH_REF, GSN_TAB_COMMITREQ, signal, 3, JBB); 05784 } 05785 05786 void 05787 Dbdict::execTC_SCHVERCONF(Signal* signal){ 05788 jamEntry(); 05789 05790 CreateTableRecordPtr createTabPtr; 05791 ndbrequire(c_opCreateTable.find(createTabPtr, signal->theData[1])); 05792 05793 execute(signal, createTabPtr.p->m_callback, 0); 05794 } 05795 05796 #define tabRequire(cond, error) \ 05797 if (!(cond)) { \ 05798 jam(); \ 05799 parseP->errorCode = error; parseP->errorLine = __LINE__; \ 05800 parseP->errorKey = it.getKey(); \ 05801 return; \ 05802 }//if 05803 05804 // handleAddTableFailure(signal, __LINE__, allocatedTable); 05805 05806 Dbdict::DictObject * 05807 Dbdict::get_object(const char * name, Uint32 len, Uint32 hash){ 05808 DictObject key; 05809 key.m_key.m_name_ptr = name; 05810 key.m_key.m_name_len = len; 05811 key.m_key.m_pool = &c_rope_pool; 05812 key.m_name.m_hash = hash; 05813 Ptr<DictObject> old_ptr; 05814 c_obj_hash.find(old_ptr, key); 05815 return old_ptr.p; 05816 } 05817 05818 void 05819 Dbdict::release_object(Uint32 obj_ptr_i, DictObject* obj_ptr_p){ 05820 Rope name(c_rope_pool, obj_ptr_p->m_name); 05821 name.erase(); 05822 05823 Ptr<DictObject> ptr = { obj_ptr_p, obj_ptr_i }; 05824 c_obj_hash.release(ptr); 05825 } 05826 05827 void 05828 Dbdict::increase_ref_count(Uint32 obj_ptr_i) 05829 { 05830 DictObject* ptr = c_obj_pool.getPtr(obj_ptr_i); 05831 ptr->m_ref_count++; 05832 } 05833 05834 void 05835 Dbdict::decrease_ref_count(Uint32 obj_ptr_i) 05836 { 05837 DictObject* ptr = c_obj_pool.getPtr(obj_ptr_i); 05838 ndbrequire(ptr->m_ref_count); 05839 ptr->m_ref_count--; 05840 } 05841 05842 void Dbdict::handleTabInfoInit(SimpleProperties::Reader & it, 05843 ParseDictTabInfoRecord * parseP, 05844 bool checkExist) 05845 { 05846 /* ---------------------------------------------------------------- */ 05847 // We always start by handling table name since this must be the first 05848 // item in the list. Through the table name we can derive if it is a 05849 // correct name, a new name or an already existing table. 05850 /* ---------------------------------------------------------------- */ 05851 05852 it.first(); 05853 05854 SimpleProperties::UnpackStatus status; 05855 c_tableDesc.init(); 05856 status = SimpleProperties::unpack(it, &c_tableDesc, 05857 DictTabInfo::TableMapping, 05858 DictTabInfo::TableMappingSize, 05859 true, true); 05860 05861 if(status != SimpleProperties::Break){ 05862 parseP->errorCode = CreateTableRef::InvalidFormat; 05863 parseP->status = status; 05864 parseP->errorKey = it.getKey(); 05865 parseP->errorLine = __LINE__; 05866 return; 05867 } 05868 05869 if(parseP->requestType == DictTabInfo::AlterTableFromAPI) 05870 { 05871 ndbrequire(!checkExist); 05872 } 05873 if(!checkExist) 05874 { 05875 ndbrequire(parseP->requestType == DictTabInfo::AlterTableFromAPI); 05876 } 05877 05878 /* ---------------------------------------------------------------- */ 05879 // Verify that table name is an allowed table name. 05880 // TODO 05881 /* ---------------------------------------------------------------- */ 05882 const Uint32 tableNameLength = strlen(c_tableDesc.TableName) + 1; 05883 const Uint32 name_hash = Rope::hash(c_tableDesc.TableName, tableNameLength); 05884 05885 if(checkExist){ 05886 jam(); 05887 tabRequire(get_object(c_tableDesc.TableName, tableNameLength) == 0, 05888 CreateTableRef::TableAlreadyExist); 05889 } 05890 05891 TableRecordPtr tablePtr; 05892 switch (parseP->requestType) { 05893 case DictTabInfo::CreateTableFromAPI: { 05894 jam(); 05895 } 05896 case DictTabInfo::AlterTableFromAPI:{ 05897 jam(); 05898 tablePtr.i = getFreeTableRecord(c_tableDesc.PrimaryTableId); 05899 /* ---------------------------------------------------------------- */ 05900 // Check if no free tables existed. 05901 /* ---------------------------------------------------------------- */ 05902 tabRequire(tablePtr.i != RNIL, CreateTableRef::NoMoreTableRecords); 05903 05904 c_tableRecordPool.getPtr(tablePtr); 05905 break; 05906 } 05907 case DictTabInfo::AddTableFromDict: 05908 case DictTabInfo::ReadTableFromDiskSR: 05909 case DictTabInfo::GetTabInfoConf: 05910 { 05911 /* ---------------------------------------------------------------- */ 05912 // Get table id and check that table doesn't already exist 05913 /* ---------------------------------------------------------------- */ 05914 tablePtr.i = c_tableDesc.TableId; 05915 05916 if (parseP->requestType == DictTabInfo::ReadTableFromDiskSR) { 05917 ndbrequire(tablePtr.i == c_restartRecord.activeTable); 05918 }//if 05919 if (parseP->requestType == DictTabInfo::GetTabInfoConf) { 05920 ndbrequire(tablePtr.i == c_restartRecord.activeTable); 05921 }//if 05922 05923 c_tableRecordPool.getPtr(tablePtr); 05924 ndbrequire(tablePtr.p->tabState == TableRecord::NOT_DEFINED); 05925 05926 //Uint32 oldTableVersion = tablePtr.p->tableVersion; 05927 initialiseTableRecord(tablePtr); 05928 if (parseP->requestType == DictTabInfo::AddTableFromDict) { 05929 jam(); 05930 tablePtr.p->tabState = TableRecord::DEFINING; 05931 }//if 05932 05933 /* ---------------------------------------------------------------- */ 05934 // Set table version 05935 /* ---------------------------------------------------------------- */ 05936 Uint32 tableVersion = c_tableDesc.TableVersion; 05937 tablePtr.p->tableVersion = tableVersion; 05938 05939 break; 05940 } 05941 default: 05942 ndbrequire(false); 05943 break; 05944 }//switch 05945 parseP->tablePtr = tablePtr; 05946 05947 { 05948 Rope name(c_rope_pool, tablePtr.p->tableName); 05949 tabRequire(name.assign(c_tableDesc.TableName, tableNameLength, name_hash), 05950 CreateTableRef::OutOfStringBuffer); 05951 } 05952 05953 Ptr<DictObject> obj_ptr; 05954 if (parseP->requestType != DictTabInfo::AlterTableFromAPI) { 05955 jam(); 05956 ndbrequire(c_obj_hash.seize(obj_ptr)); 05957 obj_ptr.p->m_id = tablePtr.i; 05958 obj_ptr.p->m_type = c_tableDesc.TableType; 05959 obj_ptr.p->m_name = tablePtr.p->tableName; 05960 obj_ptr.p->m_ref_count = 0; 05961 c_obj_hash.add(obj_ptr); 05962 tablePtr.p->m_obj_ptr_i = obj_ptr.i; 05963 05964 #ifdef VM_TRACE 05965 ndbout_c("Dbdict: name=%s,id=%u,obj_ptr_i=%d", 05966 c_tableDesc.TableName, tablePtr.i, tablePtr.p->m_obj_ptr_i); 05967 #endif 05968 } 05969 05970 tablePtr.p->noOfAttributes = c_tableDesc.NoOfAttributes; 05971 tablePtr.p->m_bits |= 05972 (c_tableDesc.TableLoggedFlag ? TableRecord::TR_Logged : 0); 05973 tablePtr.p->m_bits |= 05974 (c_tableDesc.RowChecksumFlag ? TableRecord::TR_RowChecksum : 0); 05975 tablePtr.p->m_bits |= 05976 (c_tableDesc.RowGCIFlag ? TableRecord::TR_RowGCI : 0); 05977 tablePtr.p->minLoadFactor = c_tableDesc.MinLoadFactor; 05978 tablePtr.p->maxLoadFactor = c_tableDesc.MaxLoadFactor; 05979 tablePtr.p->fragmentType = (DictTabInfo::FragmentType)c_tableDesc.FragmentType; 05980 tablePtr.p->tableType = (DictTabInfo::TableType)c_tableDesc.TableType; 05981 tablePtr.p->kValue = c_tableDesc.TableKValue; 05982 tablePtr.p->fragmentCount = c_tableDesc.FragmentCount; 05983 tablePtr.p->m_tablespace_id = c_tableDesc.TablespaceId; 05984 tablePtr.p->maxRowsLow = c_tableDesc.MaxRowsLow; 05985 tablePtr.p->maxRowsHigh = c_tableDesc.MaxRowsHigh; 05986 tablePtr.p->minRowsLow = c_tableDesc.MinRowsLow; 05987 tablePtr.p->minRowsHigh = c_tableDesc.MinRowsHigh; 05988 tablePtr.p->defaultNoPartFlag = c_tableDesc.DefaultNoPartFlag; 05989 tablePtr.p->linearHashFlag = c_tableDesc.LinearHashFlag; 05990 05991 Uint64 maxRows = 05992 (((Uint64)tablePtr.p->maxRowsHigh) << 32) + tablePtr.p->maxRowsLow; 05993 Uint64 minRows = 05994 (((Uint64)tablePtr.p->minRowsHigh) << 32) + tablePtr.p->minRowsLow; 05995 05996 { 05997 Rope frm(c_rope_pool, tablePtr.p->frmData); 05998 tabRequire(frm.assign(c_tableDesc.FrmData, c_tableDesc.FrmLen), 05999 CreateTableRef::OutOfStringBuffer); 06000 Rope range(c_rope_pool, tablePtr.p->rangeData); 06001 tabRequire(range.assign(c_tableDesc.RangeListData, 06002 c_tableDesc.RangeListDataLen), 06003 CreateTableRef::OutOfStringBuffer); 06004 Rope fd(c_rope_pool, tablePtr.p->ngData); 06005 tabRequire(fd.assign((const char*)c_tableDesc.FragmentData, 06006 c_tableDesc.FragmentDataLen), 06007 CreateTableRef::OutOfStringBuffer); 06008 Rope ts(c_rope_pool, tablePtr.p->tsData); 06009 tabRequire(ts.assign((const char*)c_tableDesc.TablespaceData, 06010 c_tableDesc.TablespaceDataLen), 06011 CreateTableRef::OutOfStringBuffer); 06012 } 06013 06014 c_fragDataLen = c_tableDesc.FragmentDataLen; 06015 memcpy(c_fragData, c_tableDesc.FragmentData, 06016 c_tableDesc.FragmentDataLen); 06017 06018 if(c_tableDesc.PrimaryTableId != RNIL) { 06019 06020 tablePtr.p->primaryTableId = c_tableDesc.PrimaryTableId; 06021 tablePtr.p->indexState = (TableRecord::IndexState)c_tableDesc.IndexState; 06022 tablePtr.p->insertTriggerId = c_tableDesc.InsertTriggerId; 06023 tablePtr.p->updateTriggerId = c_tableDesc.UpdateTriggerId; 06024 tablePtr.p->deleteTriggerId = c_tableDesc.DeleteTriggerId; 06025 tablePtr.p->customTriggerId = c_tableDesc.CustomTriggerId; 06026 } else { 06027 tablePtr.p->primaryTableId = RNIL; 06028 tablePtr.p->indexState = TableRecord::IS_UNDEFINED; 06029 tablePtr.p->insertTriggerId = RNIL; 06030 tablePtr.p->updateTriggerId = RNIL; 06031 tablePtr.p->deleteTriggerId = RNIL; 06032 tablePtr.p->customTriggerId = RNIL; 06033 } 06034 tablePtr.p->buildTriggerId = RNIL; 06035 tablePtr.p->indexLocal = 0; 06036 06037 handleTabInfo(it, parseP, c_tableDesc); 06038 06039 if(parseP->errorCode != 0) 06040 { 06044 releaseTableObject(tablePtr.i, checkExist); 06045 return; 06046 } 06047 06048 if (checkExist && tablePtr.p->m_tablespace_id != RNIL) 06049 { 06053 FilegroupPtr ptr; 06054 ndbrequire(c_filegroup_hash.find(ptr, tablePtr.p->m_tablespace_id)); 06055 increase_ref_count(ptr.p->m_obj_ptr_i); 06056 } 06057 }//handleTabInfoInit() 06058 06059 void Dbdict::handleTabInfo(SimpleProperties::Reader & it, 06060 ParseDictTabInfoRecord * parseP, 06061 DictTabInfo::Table &tableDesc) 06062 { 06063 TableRecordPtr tablePtr = parseP->tablePtr; 06064 06065 SimpleProperties::UnpackStatus status; 06066 06067 Uint32 keyCount = 0; 06068 Uint32 keyLength = 0; 06069 Uint32 attrCount = tablePtr.p->noOfAttributes; 06070 Uint32 nullCount = 0; 06071 Uint32 nullBits = 0; 06072 Uint32 noOfCharsets = 0; 06073 Uint16 charsets[128]; 06074 Uint32 recordLength = 0; 06075 AttributeRecordPtr attrPtr; 06076 c_attributeRecordHash.removeAll(); 06077 06078 LocalDLFifoList<AttributeRecord> list(c_attributeRecordPool, 06079 tablePtr.p->m_attributes); 06080 06081 Uint32 counts[] = {0,0,0,0,0}; 06082 06083 for(Uint32 i = 0; i<attrCount; i++){ 06087 DictTabInfo::Attribute attrDesc; attrDesc.init(); 06088 status = SimpleProperties::unpack(it, &attrDesc, 06089 DictTabInfo::AttributeMapping, 06090 DictTabInfo::AttributeMappingSize, 06091 true, true); 06092 06093 if(status != SimpleProperties::Break){ 06094 parseP->errorCode = CreateTableRef::InvalidFormat; 06095 parseP->status = status; 06096 parseP->errorKey = it.getKey(); 06097 parseP->errorLine = __LINE__; 06098 return; 06099 } 06100 06104 const size_t len = strlen(attrDesc.AttributeName)+1; 06105 const Uint32 name_hash = Rope::hash(attrDesc.AttributeName, len); 06106 { 06107 AttributeRecord key; 06108 key.m_key.m_name_ptr = attrDesc.AttributeName; 06109 key.m_key.m_name_len = len; 06110 key.attributeName.m_hash = name_hash; 06111 key.m_key.m_pool = &c_rope_pool; 06112 Ptr<AttributeRecord> old_ptr; 06113 c_attributeRecordHash.find(old_ptr, key); 06114 06115 if(old_ptr.i != RNIL){ 06116 parseP->errorCode = CreateTableRef::AttributeNameTwice; 06117 return; 06118 } 06119 } 06120 06121 list.seize(attrPtr); 06122 if(attrPtr.i == RNIL){ 06123 jam(); 06124 parseP->errorCode = CreateTableRef::NoMoreAttributeRecords; 06125 return; 06126 } 06127 06128 new (attrPtr.p) AttributeRecord(); 06129 attrPtr.p->attributeDescriptor = 0x00012255; //Default value 06130 attrPtr.p->tupleKey = 0; 06131 06135 { 06136 Rope name(c_rope_pool, attrPtr.p->attributeName); 06137 if (!name.assign(attrDesc.AttributeName, len, name_hash)) 06138 { 06139 jam(); 06140 parseP->errorCode = CreateTableRef::OutOfStringBuffer; 06141 parseP->errorLine = __LINE__; 06142 return; 06143 } 06144 } 06145 attrPtr.p->attributeId = i; 06146 //attrPtr.p->attributeId = attrDesc.AttributeId; 06147 attrPtr.p->tupleKey = (keyCount + 1) * attrDesc.AttributeKeyFlag; 06148 06149 attrPtr.p->extPrecision = attrDesc.AttributeExtPrecision; 06150 attrPtr.p->extScale = attrDesc.AttributeExtScale; 06151 attrPtr.p->extLength = attrDesc.AttributeExtLength; 06152 // charset in upper half of precision 06153 unsigned csNumber = (attrPtr.p->extPrecision >> 16); 06154 if (csNumber != 0) { 06155 /* 06156 * A new charset is first accessed here on this node. 06157 * TODO use separate thread (e.g. via NDBFS) if need to load from file 06158 */ 06159 CHARSET_INFO* cs = get_charset(csNumber, MYF(0)); 06160 if (cs == NULL) { 06161 parseP->errorCode = CreateTableRef::InvalidCharset; 06162 parseP->errorLine = __LINE__; 06163 return; 06164 } 06165 // XXX should be done somewhere in mysql 06166 all_charsets[cs->number] = cs; 06167 unsigned i = 0; 06168 while (i < noOfCharsets) { 06169 if (charsets[i] == csNumber) 06170 break; 06171 i++; 06172 } 06173 if (i == noOfCharsets) { 06174 noOfCharsets++; 06175 if (noOfCharsets > sizeof(charsets)/sizeof(charsets[0])) { 06176 parseP->errorCode = CreateTableRef::InvalidFormat; 06177 parseP->errorLine = __LINE__; 06178 return; 06179 } 06180 charsets[i] = csNumber; 06181 } 06182 } 06183 06184 // compute attribute size and array size 06185 bool translateOk = attrDesc.translateExtType(); 06186 tabRequire(translateOk, CreateTableRef::Inconsistency); 06187 06188 if(attrDesc.AttributeArraySize > 65535){ 06189 parseP->errorCode = CreateTableRef::ArraySizeTooBig; 06190 parseP->status = status; 06191 parseP->errorKey = it.getKey(); 06192 parseP->errorLine = __LINE__; 06193 return; 06194 } 06195 06196 // XXX old test option, remove 06197 if(!attrDesc.AttributeKeyFlag && 06198 tablePtr.i > 1 && 06199 !tablePtr.p->isIndex()) 06200 { 06201 //attrDesc.AttributeStorageType= NDB_STORAGETYPE_DISK; 06202 } 06203 06204 Uint32 desc = 0; 06205 AttributeDescriptor::setType(desc, attrDesc.AttributeExtType); 06206 AttributeDescriptor::setSize(desc, attrDesc.AttributeSize); 06207 AttributeDescriptor::setArraySize(desc, attrDesc.AttributeArraySize); 06208 AttributeDescriptor::setArrayType(desc, attrDesc.AttributeArrayType); 06209 AttributeDescriptor::setNullable(desc, attrDesc.AttributeNullableFlag); 06210 AttributeDescriptor::setDKey(desc, attrDesc.AttributeDKey); 06211 AttributeDescriptor::setPrimaryKey(desc, attrDesc.AttributeKeyFlag); 06212 AttributeDescriptor::setDiskBased(desc, attrDesc.AttributeStorageType == NDB_STORAGETYPE_DISK); 06213 attrPtr.p->attributeDescriptor = desc; 06214 attrPtr.p->autoIncrement = attrDesc.AttributeAutoIncrement; 06215 { 06216 Rope defaultValue(c_rope_pool, attrPtr.p->defaultValue); 06217 defaultValue.assign(attrDesc.AttributeDefaultValue); 06218 } 06219 06220 keyCount += attrDesc.AttributeKeyFlag; 06221 nullCount += attrDesc.AttributeNullableFlag; 06222 06223 const Uint32 aSz = (1 << attrDesc.AttributeSize); 06224 Uint32 sz; 06225 if(aSz != 1) 06226 { 06227 sz = ((aSz * attrDesc.AttributeArraySize) + 31) >> 5; 06228 } 06229 else 06230 { 06231 sz = 0; 06232 nullBits += attrDesc.AttributeArraySize; 06233 } 06234 06235 if(attrDesc.AttributeArraySize == 0) 06236 { 06237 parseP->errorCode = CreateTableRef::InvalidArraySize; 06238 parseP->status = status; 06239 parseP->errorKey = it.getKey(); 06240 parseP->errorLine = __LINE__; 06241 return; 06242 } 06243 06244 recordLength += sz; 06245 if(attrDesc.AttributeKeyFlag){ 06246 keyLength += sz; 06247 06248 if(attrDesc.AttributeNullableFlag){ 06249 parseP->errorCode = CreateTableRef::NullablePrimaryKey; 06250 parseP->status = status; 06251 parseP->errorKey = it.getKey(); 06252 parseP->errorLine = __LINE__; 06253 return; 06254 } 06255 } 06256 06257 c_attributeRecordHash.add(attrPtr); 06258 06259 int a= AttributeDescriptor::getDiskBased(desc); 06260 int b= AttributeDescriptor::getArrayType(desc); 06261 Uint32 pos= 2*(a ? 1 : 0) + (b == NDB_ARRAYTYPE_FIXED ? 0 : 1); 06262 counts[pos+1]++; 06263 06264 if(b != NDB_ARRAYTYPE_FIXED && sz == 0) 06265 { 06266 parseP->errorCode = CreateTableRef::VarsizeBitfieldNotSupported; 06267 parseP->status = status; 06268 parseP->errorKey = it.getKey(); 06269 parseP->errorLine = __LINE__; 06270 return; 06271 } 06272 06273 if(!it.next()) 06274 break; 06275 06276 if(it.getKey() != DictTabInfo::AttributeName) 06277 break; 06278 }//while 06279 06280 tablePtr.p->noOfPrimkey = keyCount; 06281 tablePtr.p->noOfNullAttr = nullCount; 06282 tablePtr.p->noOfCharsets = noOfCharsets; 06283 tablePtr.p->tupKeyLength = keyLength; 06284 tablePtr.p->noOfNullBits = nullCount + nullBits; 06285 06286 tabRequire(recordLength<= MAX_TUPLE_SIZE_IN_WORDS, 06287 CreateTableRef::RecordTooBig); 06288 tabRequire(keyLength <= MAX_KEY_SIZE_IN_WORDS, 06289 CreateTableRef::InvalidPrimaryKeySize); 06290 tabRequire(keyLength > 0, 06291 CreateTableRef::InvalidPrimaryKeySize); 06292 06293 if(tablePtr.p->m_tablespace_id != RNIL || counts[3] || counts[4]) 06294 { 06295 FilegroupPtr tablespacePtr; 06296 if(!c_filegroup_hash.find(tablespacePtr, tablePtr.p->m_tablespace_id)) 06297 { 06298 tabRequire(false, CreateTableRef::InvalidTablespace); 06299 } 06300 06301 if(tablespacePtr.p->m_type != DictTabInfo::Tablespace) 06302 { 06303 tabRequire(false, CreateTableRef::NotATablespace); 06304 } 06305 06306 if(tablespacePtr.p->m_version != tableDesc.TablespaceVersion) 06307 { 06308 tabRequire(false, CreateTableRef::InvalidTablespaceVersion); 06309 } 06310 } 06311 }//handleTabInfo() 06312 06313 06314 /* ---------------------------------------------------------------- */ 06315 // DICTTABCONF is sent when participants have received all DICTTABINFO 06316 // and successfully handled it. 06317 // Also sent to self (DICT master) when index table creation ready. 06318 /* ---------------------------------------------------------------- */ 06319 void Dbdict::execCREATE_TABLE_CONF(Signal* signal) 06320 { 06321 jamEntry(); 06322 ndbrequire(signal->getNoOfSections() == 0); 06323 06324 CreateTableConf * const conf = (CreateTableConf *)signal->getDataPtr(); 06325 // assume part of create index operation 06326 OpCreateIndexPtr opPtr; 06327 c_opCreateIndex.find(opPtr, conf->senderData); 06328 ndbrequire(! opPtr.isNull()); 06329 opPtr.p->m_request.setIndexId(conf->tableId); 06330 opPtr.p->m_request.setIndexVersion(conf->tableVersion); 06331 createIndex_fromCreateTable(signal, opPtr); 06332 }//execCREATE_TABLE_CONF() 06333 06334 void Dbdict::execCREATE_TABLE_REF(Signal* signal) 06335 { 06336 jamEntry(); 06337 06338 CreateTableRef * const ref = (CreateTableRef *)signal->getDataPtr(); 06339 // assume part of create index operation 06340 OpCreateIndexPtr opPtr; 06341 c_opCreateIndex.find(opPtr, ref->senderData); 06342 ndbrequire(! opPtr.isNull()); 06343 opPtr.p->setError(ref); 06344 createIndex_fromCreateTable(signal, opPtr); 06345 }//execCREATE_TABLE_REF() 06346 06347 /* ---------------------------------------------------------------- */ 06348 // New global checkpoint created. 06349 /* ---------------------------------------------------------------- */ 06350 void Dbdict::execWAIT_GCP_CONF(Signal* signal) 06351 { 06352 #if 0 06353 TableRecordPtr tablePtr; 06354 jamEntry(); 06355 WaitGCPConf* const conf = (WaitGCPConf*)&signal->theData[0]; 06356 c_tableRecordPool.getPtr(tablePtr, c_connRecord.connTableId); 06357 tablePtr.p->gciTableCreated = conf->gcp; 06358 sendUpdateSchemaState(signal, 06359 tablePtr.i, 06360 SchemaFile::TABLE_ADD_COMMITTED, 06361 c_connRecord.noOfPagesForTable, 06362 conf->gcp); 06363 #endif 06364 }//execWAIT_GCP_CONF() 06365 06366 /* ---------------------------------------------------------------- */ 06367 // Refused new global checkpoint. 06368 /* ---------------------------------------------------------------- */ 06369 void Dbdict::execWAIT_GCP_REF(Signal* signal) 06370 { 06371 jamEntry(); 06372 WaitGCPRef* const ref = (WaitGCPRef*)&signal->theData[0]; 06373 /* ---------------------------------------------------------------- */ 06374 // Error Handling code needed 06375 /* ---------------------------------------------------------------- */ 06376 char buf[32]; 06377 BaseString::snprintf(buf, sizeof(buf), "WAIT_GCP_REF ErrorCode=%d", 06378 ref->errorCode); 06379 progError(__LINE__, NDBD_EXIT_NDBREQUIRE, buf); 06380 }//execWAIT_GCP_REF() 06381 06382 06383 /* **************************************************************** */ 06384 /* ---------------------------------------------------------------- */ 06385 /* MODULE: DROP TABLE -------------------- */ 06386 /* ---------------------------------------------------------------- */ 06387 /* */ 06388 /* This module contains the code used to drop a table. */ 06389 /* ---------------------------------------------------------------- */ 06390 /* **************************************************************** */ 06391 void 06392 Dbdict::execDROP_TABLE_REQ(Signal* signal){ 06393 jamEntry(); 06394 DropTableReq* req = (DropTableReq*)signal->getDataPtr(); 06395 06396 TableRecordPtr tablePtr; 06397 c_tableRecordPool.getPtr(tablePtr, req->tableId, false); 06398 if(tablePtr.isNull()){ 06399 jam(); 06400 dropTableRef(signal, req, DropTableRef::NoSuchTable); 06401 return; 06402 } 06403 06404 if(getOwnNodeId() != c_masterNodeId){ 06405 jam(); 06406 dropTableRef(signal, req, DropTableRef::NotMaster); 06407 return; 06408 } 06409 06410 if(c_blockState == BS_NODE_RESTART){ 06411 jam(); 06412 dropTableRef(signal, req, DropTableRef::BusyWithNR); 06413 return; 06414 } 06415 06416 if(c_blockState != BS_IDLE){ 06417 jam(); 06418 dropTableRef(signal, req, DropTableRef::Busy); 06419 return; 06420 } 06421 06422 const TableRecord::TabState tabState = tablePtr.p->tabState; 06423 bool ok = false; 06424 switch(tabState){ 06425 case TableRecord::NOT_DEFINED: 06426 case TableRecord::REORG_TABLE_PREPARED: 06427 case TableRecord::DEFINING: 06428 case TableRecord::CHECKED: 06429 jam(); 06430 dropTableRef(signal, req, DropTableRef::NoSuchTable); 06431 return; 06432 case TableRecord::DEFINED: 06433 ok = true; 06434 jam(); 06435 break; 06436 case TableRecord::PREPARE_DROPPING: 06437 case TableRecord::DROPPING: 06438 jam(); 06439 dropTableRef(signal, req, DropTableRef::DropInProgress); 06440 return; 06441 case TableRecord::BACKUP_ONGOING: 06442 jam(); 06443 dropTableRef(signal, req, DropTableRef::BackupInProgress); 06444 return; 06445 } 06446 ndbrequire(ok); 06447 06448 if(tablePtr.p->tableVersion != req->tableVersion){ 06449 jam(); 06450 dropTableRef(signal, req, DropTableRef::InvalidTableVersion); 06451 return; 06452 } 06453 06457 DropTableRecordPtr dropTabPtr; 06458 c_opDropTable.seize(dropTabPtr); 06459 06460 if(dropTabPtr.isNull()){ 06461 jam(); 06462 dropTableRef(signal, req, DropTableRef::NoDropTableRecordAvailable); 06463 return; 06464 } 06465 06466 c_blockState = BS_BUSY; 06467 06468 dropTabPtr.p->key = ++c_opRecordSequence; 06469 c_opDropTable.add(dropTabPtr); 06470 06471 dropTabPtr.p->m_request = * req; 06472 dropTabPtr.p->m_errorCode = 0; 06473 dropTabPtr.p->m_requestType = DropTabReq::OnlineDropTab; 06474 dropTabPtr.p->m_coordinatorRef = reference(); 06475 dropTabPtr.p->m_coordinatorData.m_gsn = GSN_PREP_DROP_TAB_REQ; 06476 dropTabPtr.p->m_coordinatorData.m_block = 0; 06477 06478 Mutex mutex(signal, c_mutexMgr, dropTabPtr.p->m_define_backup_mutex); 06479 Callback c = { safe_cast(&Dbdict::dropTable_backup_mutex_locked), 06480 dropTabPtr.p->key}; 06481 06482 ndbrequire(mutex.lock(c)); 06483 06484 } 06485 06486 void 06487 Dbdict::dropTable_backup_mutex_locked(Signal* signal, 06488 Uint32 callbackData, 06489 Uint32 retValue){ 06490 jamEntry(); 06491 06492 ndbrequire(retValue == 0); 06493 06494 DropTableRecordPtr dropTabPtr; 06495 ndbrequire(c_opDropTable.find(dropTabPtr, callbackData)); 06496 06497 TableRecordPtr tablePtr; 06498 c_tableRecordPool.getPtr(tablePtr, dropTabPtr.p->m_request.tableId, true); 06499 06500 Mutex mutex(signal, c_mutexMgr, dropTabPtr.p->m_define_backup_mutex); 06501 mutex.unlock(); // ignore response 06502 06503 if(tablePtr.p->tabState == TableRecord::BACKUP_ONGOING) 06504 { 06505 jam(); 06506 dropTableRef(signal, &dropTabPtr.p->m_request, 06507 DropTableRef::BackupInProgress); 06508 06509 c_blockState = BS_IDLE; 06510 c_opDropTable.release(dropTabPtr); 06511 } 06512 else 06513 { 06514 jam(); 06515 tablePtr.p->tabState = TableRecord::PREPARE_DROPPING; 06516 prepDropTab_nextStep(signal, dropTabPtr); 06517 } 06518 } 06519 06520 void 06521 Dbdict::dropTableRef(Signal * signal, 06522 DropTableReq * req, DropTableRef::ErrorCode errCode){ 06523 06524 Uint32 tableId = req->tableId; 06525 Uint32 tabVersion = req->tableVersion; 06526 Uint32 senderData = req->senderData; 06527 Uint32 senderRef = req->senderRef; 06528 06529 DropTableRef * ref = (DropTableRef*)signal->getDataPtrSend(); 06530 ref->tableId = tableId; 06531 ref->tableVersion = tabVersion; 06532 ref->senderData = senderData; 06533 ref->senderRef = reference(); 06534 ref->errorCode = errCode; 06535 ref->masterNodeId = c_masterNodeId; 06536 sendSignal(senderRef, GSN_DROP_TABLE_REF, signal, 06537 DropTableRef::SignalLength, JBB); 06538 } 06539 06540 void 06541 Dbdict::prepDropTab_nextStep(Signal* signal, DropTableRecordPtr dropTabPtr){ 06542 06546 ndbrequire(dropTabPtr.p->m_errorCode == 0); 06547 06548 Uint32 block = 0; 06549 switch(dropTabPtr.p->m_coordinatorData.m_block){ 06550 case 0: 06551 jam(); 06552 block = dropTabPtr.p->m_coordinatorData.m_block = DBDICT; 06553 break; 06554 case DBDICT: 06555 jam(); 06556 block = dropTabPtr.p->m_coordinatorData.m_block = DBLQH; 06557 break; 06558 case DBLQH: 06559 jam(); 06560 block = dropTabPtr.p->m_coordinatorData.m_block = DBTC; 06561 break; 06562 case DBTC: 06563 jam(); 06564 block = dropTabPtr.p->m_coordinatorData.m_block = DBDIH; 06565 break; 06566 case DBDIH: 06567 jam(); 06568 prepDropTab_complete(signal, dropTabPtr); 06569 return; 06570 default: 06571 ndbrequire(false); 06572 } 06573 06574 PrepDropTabReq * prep = (PrepDropTabReq*)signal->getDataPtrSend(); 06575 prep->senderRef = reference(); 06576 prep->senderData = dropTabPtr.p->key; 06577 prep->tableId = dropTabPtr.p->m_request.tableId; 06578 prep->requestType = dropTabPtr.p->m_requestType; 06579 06580 dropTabPtr.p->m_coordinatorData.m_signalCounter = c_aliveNodes; 06581 NodeReceiverGroup rg(block, c_aliveNodes); 06582 sendSignal(rg, GSN_PREP_DROP_TAB_REQ, signal, 06583 PrepDropTabReq::SignalLength, JBB); 06584 06585 #if 0 06586 for (Uint32 i = 1; i < MAX_NDB_NODES; i++){ 06587 if(c_aliveNodes.get(i)){ 06588 jam(); 06589 BlockReference ref = numberToRef(block, i); 06590 06591 dropTabPtr.p->m_coordinatorData.m_signalCounter.setWaitingFor(i); 06592 } 06593 } 06594 #endif 06595 } 06596 06597 void 06598 Dbdict::execPREP_DROP_TAB_CONF(Signal * signal){ 06599 jamEntry(); 06600 06601 PrepDropTabConf * prep = (PrepDropTabConf*)signal->getDataPtr(); 06602 06603 DropTableRecordPtr dropTabPtr; 06604 ndbrequire(c_opDropTable.find(dropTabPtr, prep->senderData)); 06605 06606 ndbrequire(dropTabPtr.p->m_coordinatorRef == reference()); 06607 ndbrequire(dropTabPtr.p->m_request.tableId == prep->tableId); 06608 ndbrequire(dropTabPtr.p->m_coordinatorData.m_gsn == GSN_PREP_DROP_TAB_REQ); 06609 06610 Uint32 nodeId = refToNode(prep->senderRef); 06611 dropTabPtr.p->m_coordinatorData.m_signalCounter.clearWaitingFor(nodeId); 06612 06613 if(!dropTabPtr.p->m_coordinatorData.m_signalCounter.done()){ 06614 jam(); 06615 return; 06616 } 06617 prepDropTab_nextStep(signal, dropTabPtr); 06618 } 06619 06620 void 06621 Dbdict::execPREP_DROP_TAB_REF(Signal* signal){ 06622 jamEntry(); 06623 06624 PrepDropTabRef * prep = (PrepDropTabRef*)signal->getDataPtr(); 06625 06626 DropTableRecordPtr dropTabPtr; 06627 ndbrequire(c_opDropTable.find(dropTabPtr, prep->senderData)); 06628 06629 ndbrequire(dropTabPtr.p->m_coordinatorRef == reference()); 06630 ndbrequire(dropTabPtr.p->m_request.tableId == prep->tableId); 06631 ndbrequire(dropTabPtr.p->m_coordinatorData.m_gsn == GSN_PREP_DROP_TAB_REQ); 06632 06633 Uint32 nodeId = refToNode(prep->senderRef); 06634 dropTabPtr.p->m_coordinatorData.m_signalCounter.clearWaitingFor(nodeId); 06635 06636 Uint32 block = refToBlock(prep->senderRef); 06637 if((prep->errorCode == PrepDropTabRef::NoSuchTable && block == DBLQH) || 06638 (prep->errorCode == PrepDropTabRef::NF_FakeErrorREF)){ 06639 jam(); 06645 } else { 06646 dropTabPtr.p->setErrorCode((Uint32)prep->errorCode); 06647 } 06648 06649 if(!dropTabPtr.p->m_coordinatorData.m_signalCounter.done()){ 06650 jam(); 06651 return; 06652 } 06653 prepDropTab_nextStep(signal, dropTabPtr); 06654 } 06655 06656 void 06657 Dbdict::prepDropTab_complete(Signal* signal, DropTableRecordPtr dropTabPtr){ 06658 jam(); 06659 06660 dropTabPtr.p->m_coordinatorData.m_gsn = GSN_DROP_TAB_REQ; 06661 dropTabPtr.p->m_coordinatorData.m_block = DBDICT; 06662 06663 DropTabReq * req = (DropTabReq*)signal->getDataPtrSend(); 06664 req->senderRef = reference(); 06665 req->senderData = dropTabPtr.p->key; 06666 req->tableId = dropTabPtr.p->m_request.tableId; 06667 req->requestType = dropTabPtr.p->m_requestType; 06668 06669 dropTabPtr.p->m_coordinatorData.m_signalCounter = c_aliveNodes; 06670 NodeReceiverGroup rg(DBDICT, c_aliveNodes); 06671 sendSignal(rg, GSN_DROP_TAB_REQ, signal, 06672 DropTabReq::SignalLength, JBB); 06673 } 06674 06675 void 06676 Dbdict::execDROP_TAB_REF(Signal* signal){ 06677 jamEntry(); 06678 06679 DropTabRef * const req = (DropTabRef*)signal->getDataPtr(); 06680 06681 Uint32 block = refToBlock(req->senderRef); 06682 ndbrequire(req->errorCode == DropTabRef::NF_FakeErrorREF || 06683 (req->errorCode == DropTabRef::NoSuchTable && 06684 (block == DBTUP || block == DBACC || block == DBLQH))); 06685 06686 if(block != DBDICT){ 06687 jam(); 06688 ndbrequire(refToNode(req->senderRef) == getOwnNodeId()); 06689 dropTab_localDROP_TAB_CONF(signal); 06690 return; 06691 } 06692 ndbrequire(false); 06693 } 06694 06695 void 06696 Dbdict::execDROP_TAB_CONF(Signal* signal){ 06697 jamEntry(); 06698 06699 DropTabConf * const req = (DropTabConf*)signal->getDataPtr(); 06700 06701 if(refToBlock(req->senderRef) != DBDICT){ 06702 jam(); 06703 ndbrequire(refToNode(req->senderRef) == getOwnNodeId()); 06704 dropTab_localDROP_TAB_CONF(signal); 06705 return; 06706 } 06707 06708 DropTableRecordPtr dropTabPtr; 06709 ndbrequire(c_opDropTable.find(dropTabPtr, req->senderData)); 06710 06711 ndbrequire(dropTabPtr.p->m_coordinatorRef == reference()); 06712 ndbrequire(dropTabPtr.p->m_request.tableId == req->tableId); 06713 ndbrequire(dropTabPtr.p->m_coordinatorData.m_gsn == GSN_DROP_TAB_REQ); 06714 06715 Uint32 nodeId = refToNode(req->senderRef); 06716 dropTabPtr.p->m_coordinatorData.m_signalCounter.clearWaitingFor(nodeId); 06717 06718 if(!dropTabPtr.p->m_coordinatorData.m_signalCounter.done()){ 06719 jam(); 06720 return; 06721 } 06722 06723 DropTableConf* conf = (DropTableConf*)signal->getDataPtrSend(); 06724 conf->senderRef = reference(); 06725 conf->senderData = dropTabPtr.p->m_request.senderData; 06726 conf->tableId = dropTabPtr.p->m_request.tableId; 06727 conf->tableVersion = dropTabPtr.p->m_request.tableVersion; 06728 Uint32 ref = dropTabPtr.p->m_request.senderRef; 06729 sendSignal(ref, GSN_DROP_TABLE_CONF, signal, 06730 DropTableConf::SignalLength, JBB); 06731 06732 c_opDropTable.release(dropTabPtr); 06733 c_blockState = BS_IDLE; 06734 } 06735 06739 void 06740 Dbdict::execPREP_DROP_TAB_REQ(Signal* signal){ 06741 jamEntry(); 06742 PrepDropTabReq * prep = (PrepDropTabReq*)signal->getDataPtrSend(); 06743 06744 DropTableRecordPtr dropTabPtr; 06745 if(prep->senderRef == reference()){ 06746 jam(); 06747 ndbrequire(c_opDropTable.find(dropTabPtr, prep->senderData)); 06748 ndbrequire(dropTabPtr.p->m_requestType == prep->requestType); 06749 } else { 06750 jam(); 06751 c_opDropTable.seize(dropTabPtr); 06752 if(!dropTabPtr.isNull()){ 06753 dropTabPtr.p->key = prep->senderData; 06754 c_opDropTable.add(dropTabPtr); 06755 } 06756 } 06757 06758 ndbrequire(!dropTabPtr.isNull()); 06759 06760 dropTabPtr.p->m_errorCode = 0; 06761 dropTabPtr.p->m_request.tableId = prep->tableId; 06762 dropTabPtr.p->m_requestType = prep->requestType; 06763 dropTabPtr.p->m_coordinatorRef = prep->senderRef; 06764 dropTabPtr.p->m_participantData.m_gsn = GSN_PREP_DROP_TAB_REQ; 06765 06766 TableRecordPtr tablePtr; 06767 c_tableRecordPool.getPtr(tablePtr, prep->tableId); 06768 tablePtr.p->tabState = TableRecord::PREPARE_DROPPING; 06769 06773 XSchemaFile * xsf = &c_schemaFile[c_schemaRecord.schemaPage != 0]; 06774 SchemaFile::TableEntry * tableEntry = getTableEntry(xsf, tablePtr.i); 06775 SchemaFile::TableState tabState = 06776 (SchemaFile::TableState)tableEntry->m_tableState; 06777 ndbrequire(tabState == SchemaFile::TABLE_ADD_COMMITTED || 06778 tabState == SchemaFile::ALTER_TABLE_COMMITTED); 06779 tableEntry->m_tableState = SchemaFile::DROP_TABLE_STARTED; 06780 computeChecksum(xsf, tablePtr.i / NDB_SF_PAGE_ENTRIES); 06781 06782 ndbrequire(c_writeSchemaRecord.inUse == false); 06783 c_writeSchemaRecord.inUse = true; 06784 06785 c_writeSchemaRecord.pageId = c_schemaRecord.schemaPage; 06786 c_writeSchemaRecord.newFile = false; 06787 c_writeSchemaRecord.firstPage = tablePtr.i / NDB_SF_PAGE_ENTRIES; 06788 c_writeSchemaRecord.noOfPages = 1; 06789 c_writeSchemaRecord.m_callback.m_callbackData = dropTabPtr.p->key; 06790 c_writeSchemaRecord.m_callback.m_callbackFunction = 06791 safe_cast(&Dbdict::prepDropTab_writeSchemaConf); 06792 startWriteSchemaFile(signal); 06793 } 06794 06795 void 06796 Dbdict::prepDropTab_writeSchemaConf(Signal* signal, 06797 Uint32 dropTabPtrI, 06798 Uint32 returnCode){ 06799 jam(); 06800 06801 DropTableRecordPtr dropTabPtr; 06802 ndbrequire(c_opDropTable.find(dropTabPtr, dropTabPtrI)); 06803 06804 ndbrequire(dropTabPtr.p->m_participantData.m_gsn == GSN_PREP_DROP_TAB_REQ); 06805 06812 PrepDropTabConf * prep = (PrepDropTabConf*)signal->getDataPtr(); 06813 prep->senderRef = reference(); 06814 prep->senderData = dropTabPtrI; 06815 prep->tableId = dropTabPtr.p->m_request.tableId; 06816 06817 dropTabPtr.p->m_participantData.m_gsn = GSN_PREP_DROP_TAB_CONF; 06818 sendSignal(dropTabPtr.p->m_coordinatorRef, GSN_PREP_DROP_TAB_CONF, signal, 06819 PrepDropTabConf::SignalLength, JBB); 06820 } 06821 06822 void 06823 Dbdict::execDROP_TAB_REQ(Signal* signal){ 06824 jamEntry(); 06825 DropTabReq * req = (DropTabReq*)signal->getDataPtrSend(); 06826 06827 DropTableRecordPtr dropTabPtr; 06828 ndbrequire(c_opDropTable.find(dropTabPtr, req->senderData)); 06829 06830 ndbrequire(dropTabPtr.p->m_participantData.m_gsn == GSN_PREP_DROP_TAB_CONF); 06831 dropTabPtr.p->m_participantData.m_gsn = GSN_DROP_TAB_REQ; 06832 06833 ndbrequire(dropTabPtr.p->m_requestType == req->requestType); 06834 06835 TableRecordPtr tablePtr; 06836 c_tableRecordPool.getPtr(tablePtr, dropTabPtr.p->m_request.tableId); 06837 tablePtr.p->tabState = TableRecord::DROPPING; 06838 06839 dropTabPtr.p->m_participantData.m_block = 0; 06840 dropTabPtr.p->m_participantData.m_callback.m_callbackData = dropTabPtr.p->key; 06841 dropTabPtr.p->m_participantData.m_callback.m_callbackFunction = 06842 safe_cast(&Dbdict::dropTab_complete); 06843 dropTab_nextStep(signal, dropTabPtr); 06844 06845 if (tablePtr.p->m_tablespace_id != RNIL) 06846 { 06847 FilegroupPtr ptr; 06848 ndbrequire(c_filegroup_hash.find(ptr, tablePtr.p->m_tablespace_id)); 06849 decrease_ref_count(ptr.p->m_obj_ptr_i); 06850 } 06851 } 06852 06853 #include <DebuggerNames.hpp> 06854 06855 void 06856 Dbdict::dropTab_nextStep(Signal* signal, DropTableRecordPtr dropTabPtr){ 06857 06861 ndbrequire(dropTabPtr.p->m_errorCode == 0); 06862 06863 TableRecordPtr tablePtr; 06864 c_tableRecordPool.getPtr(tablePtr, dropTabPtr.p->m_request.tableId); 06865 06866 Uint32 block = 0; 06867 switch(dropTabPtr.p->m_participantData.m_block){ 06868 case 0: 06869 jam(); 06870 block = DBTC; 06871 break; 06872 case DBTC: 06873 jam(); 06874 if (tablePtr.p->isTable() || tablePtr.p->isHashIndex()) 06875 block = DBACC; 06876 if (tablePtr.p->isOrderedIndex()) 06877 block = DBTUP; 06878 break; 06879 case DBACC: 06880 jam(); 06881 block = DBTUP; 06882 break; 06883 case DBTUP: 06884 jam(); 06885 if (tablePtr.p->isTable() || tablePtr.p->isHashIndex()) 06886 block = DBLQH; 06887 if (tablePtr.p->isOrderedIndex()) 06888 block = DBTUX; 06889 break; 06890 case DBTUX: 06891 jam(); 06892 block = DBLQH; 06893 break; 06894 case DBLQH: 06895 jam(); 06896 block = DBDIH; 06897 break; 06898 case DBDIH: 06899 jam(); 06900 execute(signal, dropTabPtr.p->m_participantData.m_callback, 0); 06901 return; 06902 } 06903 ndbrequire(block != 0); 06904 dropTabPtr.p->m_participantData.m_block = block; 06905 06906 DropTabReq * req = (DropTabReq*)signal->getDataPtrSend(); 06907 req->senderRef = reference(); 06908 req->senderData = dropTabPtr.p->key; 06909 req->tableId = dropTabPtr.p->m_request.tableId; 06910 req->requestType = dropTabPtr.p->m_requestType; 06911 06912 const Uint32 nodeId = getOwnNodeId(); 06913 dropTabPtr.p->m_participantData.m_signalCounter.clearWaitingFor(); 06914 dropTabPtr.p->m_participantData.m_signalCounter.setWaitingFor(nodeId); 06915

