1
/* Copyright (C) 2003 MySQL AB
3
This program is free software; you can redistribute it and/or modify
4
it under the terms of the GNU General Public License as published by
5
the Free Software Foundation; either version 2 of the License, or
6
(at your option) any later version.
8
This program is distributed in the hope that it will be useful,
9
but WITHOUT ANY WARRANTY; without even the implied warranty of
10
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
GNU General Public License for more details.
13
You should have received a copy of the GNU General Public License
14
along with this program; if not, write to the Free Software
15
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
17
#include <ndb_global.h>
23
#include <ndb_limits.h>
25
#include <Properties.hpp>
26
#include <Configuration.hpp>
27
#include <SectionReader.hpp>
28
#include <SimpleProperties.hpp>
29
#include <AttributeHeader.hpp>
30
#include <KeyDescriptor.hpp>
31
#include <signaldata/DictSchemaInfo.hpp>
32
#include <signaldata/DictTabInfo.hpp>
33
#include <signaldata/DropTabFile.hpp>
35
#include <signaldata/EventReport.hpp>
36
#include <signaldata/FsCloseReq.hpp>
37
#include <signaldata/FsConf.hpp>
38
#include <signaldata/FsOpenReq.hpp>
39
#include <signaldata/FsReadWriteReq.hpp>
40
#include <signaldata/FsRef.hpp>
41
#include <signaldata/GetTabInfo.hpp>
42
#include <signaldata/GetTableId.hpp>
43
#include <signaldata/HotSpareRep.hpp>
44
#include <signaldata/NFCompleteRep.hpp>
45
#include <signaldata/NodeFailRep.hpp>
46
#include <signaldata/ReadNodesConf.hpp>
47
#include <signaldata/RelTabMem.hpp>
48
#include <signaldata/WaitGCP.hpp>
49
#include <signaldata/ListTables.hpp>
51
#include <signaldata/CreateTrig.hpp>
52
#include <signaldata/AlterTrig.hpp>
53
#include <signaldata/DropTrig.hpp>
54
#include <signaldata/CreateIndx.hpp>
55
#include <signaldata/DropIndx.hpp>
56
#include <signaldata/BuildIndx.hpp>
58
#include <signaldata/CreateEvnt.hpp>
59
#include <signaldata/UtilPrepare.hpp>
60
#include <signaldata/UtilExecute.hpp>
61
#include <signaldata/UtilRelease.hpp>
62
#include <signaldata/SumaImpl.hpp>
63
#include <GrepError.hpp>
64
//#include <signaldata/DropEvnt.hpp>
66
#include <signaldata/LqhFrag.hpp>
68
#include <signaldata/DiAddTab.hpp>
69
#include <signaldata/DihStartTab.hpp>
71
#include <signaldata/DropTable.hpp>
72
#include <signaldata/DropTab.hpp>
73
#include <signaldata/PrepDropTab.hpp>
75
#include <signaldata/CreateTable.hpp>
76
#include <signaldata/AlterTable.hpp>
77
#include <signaldata/AlterTab.hpp>
78
#include <signaldata/CreateFragmentation.hpp>
79
#include <signaldata/CreateTab.hpp>
81
#include <signaldata/ApiBroadcast.hpp>
83
#define ZNOT_FOUND 626
84
#define ZALREADYEXIST 630
86
//#define EVENT_PH2_DEBUG
87
//#define EVENT_PH3_DEBUG
91
// ndbout_c("Event debug trace: File: %s Line: %u", __FILE__, __LINE__)
93
#define DIV(x,y) (((x)+(y)-1)/(y))
94
#include <ndb_version.h>
98
alter_table_inc_schema_version(Uint32 old)
100
return (old & 0x00FFFFFF) + ((old + 0x1000000) & 0xFF000000);
105
alter_table_dec_schema_version(Uint32 old)
107
return (old & 0x00FFFFFF) + ((old - 0x1000000) & 0xFF000000);
112
create_table_inc_schema_version(Uint32 old)
114
return (old + 0x00000001) & 0x00FFFFFF;
117
/* **************************************************************** */
118
/* ---------------------------------------------------------------- */
119
/* MODULE: GENERAL MODULE -------------------------------- */
120
/* ---------------------------------------------------------------- */
122
/* This module contains general stuff. Mostly debug signals and */
123
/* general signals that go into a specific module after checking a */
124
/* state variable. Also general subroutines used by many. */
125
/* ---------------------------------------------------------------- */
126
/* **************************************************************** */
128
/* ---------------------------------------------------------------- */
129
// This signal is used to dump states of various variables in the
131
/* ---------------------------------------------------------------- */
133
Dbdict::execDUMP_STATE_ORD(Signal* signal)
138
if(signal->theData[0] == 1222){
139
const Uint32 tab = signal->theData[1];
140
PrepDropTabReq* req = (PrepDropTabReq*)signal->getDataPtr();
141
req->senderRef = reference();
142
req->senderData = 1222;
144
sendSignal(DBLQH_REF, GSN_PREP_DROP_TAB_REQ, signal,
145
PrepDropTabReq::SignalLength, JBB);
148
if(signal->theData[0] == 1223){
149
const Uint32 tab = signal->theData[1];
150
PrepDropTabReq* req = (PrepDropTabReq*)signal->getDataPtr();
151
req->senderRef = reference();
152
req->senderData = 1222;
154
sendSignal(DBTC_REF, GSN_PREP_DROP_TAB_REQ, signal,
155
PrepDropTabReq::SignalLength, JBB);
158
if(signal->theData[0] == 1224){
159
const Uint32 tab = signal->theData[1];
160
PrepDropTabReq* req = (PrepDropTabReq*)signal->getDataPtr();
161
req->senderRef = reference();
162
req->senderData = 1222;
164
sendSignal(DBDIH_REF, GSN_PREP_DROP_TAB_REQ, signal,
165
PrepDropTabReq::SignalLength, JBB);
168
if(signal->theData[0] == 1225){
169
const Uint32 tab = signal->theData[1];
170
const Uint32 ver = signal->theData[2];
171
TableRecordPtr tabRecPtr;
172
c_tableRecordPool.getPtr(tabRecPtr, tab);
173
DropTableReq * req = (DropTableReq*)signal->getDataPtr();
174
req->senderData = 1225;
175
req->senderRef = numberToRef(1,1);
177
req->tableVersion = tabRecPtr.p->tableVersion + ver;
178
sendSignal(DBDICT_REF, GSN_DROP_TABLE_REQ, signal,
179
DropTableReq::SignalLength, JBB);
184
}//Dbdict::execDUMP_STATE_ORD()
186
/* ---------------------------------------------------------------- */
187
/* ---------------------------------------------------------------- */
188
// CONTINUEB is used when a real-time break is needed for long
190
/* ---------------------------------------------------------------- */
191
/* ---------------------------------------------------------------- */
192
void Dbdict::execCONTINUEB(Signal* signal)
195
switch (signal->theData[0]) {
196
case ZPACK_TABLE_INTO_PAGES :
198
packTableIntoPages(signal, signal->theData[1], signal->theData[2]);
201
case ZSEND_GET_TAB_RESPONSE :
203
sendGetTabResponse(signal);
206
case ZDICT_LOCK_POLL:
208
checkDictLockQueue(signal, true);
218
/* ---------------------------------------------------------------- */
219
/* ---------------------------------------------------------------- */
220
// Routine to handle pack table into pages.
221
/* ---------------------------------------------------------------- */
222
/* ---------------------------------------------------------------- */
224
void Dbdict::packTableIntoPages(Signal* signal, Uint32 tableId, Uint32 pageId)
227
PageRecordPtr pagePtr;
228
TableRecordPtr tablePtr;
229
c_pageRecordArray.getPtr(pagePtr, pageId);
231
memset(&pagePtr.p->word[0], 0, 4 * ZPAGE_HEADER_SIZE);
232
c_tableRecordPool.getPtr(tablePtr, tableId);
233
LinearWriter w(&pagePtr.p->word[ZPAGE_HEADER_SIZE],
234
8 * ZSIZE_OF_PAGES_IN_WORDS);
237
packTableIntoPagesImpl(w, tablePtr, signal);
239
Uint32 wordsOfTable = w.getWordsUsed();
241
DIV(wordsOfTable + ZPAGE_HEADER_SIZE, ZSIZE_OF_PAGES_IN_WORDS);
242
pagePtr.p->word[ZPOS_CHECKSUM] =
243
computeChecksum(&pagePtr.p->word[0], pagesUsed * ZSIZE_OF_PAGES_IN_WORDS);
245
switch (c_packTable.m_state) {
246
case PackTable::PTS_IDLE:
247
case PackTable::PTS_ADD_TABLE_MASTER:
248
case PackTable::PTS_ADD_TABLE_SLAVE:
249
case PackTable::PTS_RESTART:
252
case PackTable::PTS_GET_TAB:
254
c_retrieveRecord.retrievedNoOfPages = pagesUsed;
255
c_retrieveRecord.retrievedNoOfWords = wordsOfTable;
256
sendGetTabResponse(signal);
262
}//packTableIntoPages()
265
Dbdict::packTableIntoPagesImpl(SimpleProperties::Writer & w,
266
TableRecordPtr tablePtr,
269
w.add(DictTabInfo::TableName, tablePtr.p->tableName);
270
w.add(DictTabInfo::TableId, tablePtr.i);
271
#ifdef HAVE_TABLE_REORG
272
w.add(DictTabInfo::SecondTableId, tablePtr.p->secondTable);
274
w.add(DictTabInfo::SecondTableId, (Uint32)0);
276
w.add(DictTabInfo::TableVersion, tablePtr.p->tableVersion);
277
w.add(DictTabInfo::NoOfKeyAttr, tablePtr.p->noOfPrimkey);
278
w.add(DictTabInfo::NoOfAttributes, tablePtr.p->noOfAttributes);
279
w.add(DictTabInfo::NoOfNullable, tablePtr.p->noOfNullAttr);
280
w.add(DictTabInfo::NoOfVariable, (Uint32)0);
281
w.add(DictTabInfo::KeyLength, tablePtr.p->tupKeyLength);
283
w.add(DictTabInfo::TableLoggedFlag, tablePtr.p->storedTable);
284
w.add(DictTabInfo::MinLoadFactor, tablePtr.p->minLoadFactor);
285
w.add(DictTabInfo::MaxLoadFactor, tablePtr.p->maxLoadFactor);
286
w.add(DictTabInfo::TableKValue, tablePtr.p->kValue);
287
w.add(DictTabInfo::FragmentTypeVal, tablePtr.p->fragmentType);
288
w.add(DictTabInfo::TableTypeVal, tablePtr.p->tableType);
289
w.add(DictTabInfo::MaxRowsLow, tablePtr.p->maxRowsLow);
290
w.add(DictTabInfo::MaxRowsHigh, tablePtr.p->maxRowsHigh);
291
w.add(DictTabInfo::MinRowsLow, tablePtr.p->minRowsLow);
292
w.add(DictTabInfo::MinRowsHigh, tablePtr.p->minRowsHigh);
296
w.add(DictTabInfo::FragmentCount, tablePtr.p->fragmentCount);
300
Uint32 * theData = signal->getDataPtrSend();
301
CreateFragmentationReq * const req = (CreateFragmentationReq*)theData;
303
req->senderData = RNIL;
304
req->fragmentationType = tablePtr.p->fragmentType;
305
req->noOfFragments = 0;
306
req->fragmentNode = 0;
307
req->primaryTableId = tablePtr.i;
308
EXECUTE_DIRECT(DBDIH, GSN_CREATE_FRAGMENTATION_REQ, signal,
309
CreateFragmentationReq::SignalLength);
310
if(signal->theData[0] == 0)
312
Uint16 *data = (Uint16*)&signal->theData[25];
313
Uint32 count = 2 + data[0] * data[1];
314
w.add(DictTabInfo::FragmentDataLen, 2*count);
315
w.add(DictTabInfo::FragmentData, data, 2*count);
319
if (tablePtr.p->primaryTableId != RNIL){
320
TableRecordPtr primTab;
321
c_tableRecordPool.getPtr(primTab, tablePtr.p->primaryTableId);
322
w.add(DictTabInfo::PrimaryTable, primTab.p->tableName);
323
w.add(DictTabInfo::PrimaryTableId, tablePtr.p->primaryTableId);
324
w.add(DictTabInfo::IndexState, tablePtr.p->indexState);
325
w.add(DictTabInfo::InsertTriggerId, tablePtr.p->insertTriggerId);
326
w.add(DictTabInfo::UpdateTriggerId, tablePtr.p->updateTriggerId);
327
w.add(DictTabInfo::DeleteTriggerId, tablePtr.p->deleteTriggerId);
328
w.add(DictTabInfo::CustomTriggerId, tablePtr.p->customTriggerId);
330
w.add(DictTabInfo::FrmLen, tablePtr.p->frmLen);
331
w.add(DictTabInfo::FrmData, tablePtr.p->frmData, tablePtr.p->frmLen);
333
Uint32 nextAttribute = tablePtr.p->firstAttribute;
334
AttributeRecordPtr attrPtr;
337
c_attributeRecordPool.getPtr(attrPtr, nextAttribute);
339
w.add(DictTabInfo::AttributeName, attrPtr.p->attributeName);
340
w.add(DictTabInfo::AttributeId, attrPtr.p->attributeId);
341
w.add(DictTabInfo::AttributeKeyFlag, attrPtr.p->tupleKey > 0);
343
const Uint32 desc = attrPtr.p->attributeDescriptor;
344
const Uint32 attrType = AttributeDescriptor::getType(desc);
345
const Uint32 attrSize = AttributeDescriptor::getSize(desc);
346
const Uint32 arraySize = AttributeDescriptor::getArraySize(desc);
347
const Uint32 nullable = AttributeDescriptor::getNullable(desc);
348
const Uint32 DKey = AttributeDescriptor::getDKey(desc);
350
// AttributeType deprecated
351
w.add(DictTabInfo::AttributeSize, attrSize);
352
w.add(DictTabInfo::AttributeArraySize, arraySize);
353
w.add(DictTabInfo::AttributeNullableFlag, nullable);
354
w.add(DictTabInfo::AttributeDKey, DKey);
355
w.add(DictTabInfo::AttributeExtType, attrType);
356
w.add(DictTabInfo::AttributeExtPrecision, attrPtr.p->extPrecision);
357
w.add(DictTabInfo::AttributeExtScale, attrPtr.p->extScale);
358
w.add(DictTabInfo::AttributeExtLength, attrPtr.p->extLength);
359
w.add(DictTabInfo::AttributeAutoIncrement,
360
(Uint32)attrPtr.p->autoIncrement);
361
w.add(DictTabInfo::AttributeDefaultValue, attrPtr.p->defaultValue);
363
w.add(DictTabInfo::AttributeEnd, 1);
364
nextAttribute = attrPtr.p->nextAttrInTable;
365
} while (nextAttribute != RNIL);
367
w.add(DictTabInfo::TableEnd, 1);
370
/* ---------------------------------------------------------------- */
371
/* ---------------------------------------------------------------- */
372
// The routines to handle responses from file system.
373
/* ---------------------------------------------------------------- */
374
/* ---------------------------------------------------------------- */
376
/* ---------------------------------------------------------------- */
377
// A file was successfully closed.
378
/* ---------------------------------------------------------------- */
379
void Dbdict::execFSCLOSECONF(Signal* signal)
381
FsConnectRecordPtr fsPtr;
382
FsConf * const fsConf = (FsConf *)&signal->theData[0];
384
c_fsConnectRecordPool.getPtr(fsPtr, fsConf->userPointer);
385
switch (fsPtr.p->fsState) {
386
case FsConnectRecord::CLOSE_WRITE_SCHEMA:
388
closeWriteSchemaConf(signal, fsPtr);
390
case FsConnectRecord::CLOSE_READ_SCHEMA:
392
closeReadSchemaConf(signal, fsPtr);
394
case FsConnectRecord::CLOSE_READ_TAB_FILE:
396
closeReadTableConf(signal, fsPtr);
398
case FsConnectRecord::CLOSE_WRITE_TAB_FILE:
400
closeWriteTableConf(signal, fsPtr);
402
case FsConnectRecord::OPEN_READ_SCHEMA2:
403
openSchemaFile(signal, 1, fsPtr.i, false, false);
406
jamLine((fsPtr.p->fsState & 0xFFF));
413
/* ---------------------------------------------------------------- */
414
// A file was successfully opened.
415
/* ---------------------------------------------------------------- */
416
void Dbdict::execFSOPENCONF(Signal* signal)
418
FsConnectRecordPtr fsPtr;
420
FsConf * const fsConf = (FsConf *)&signal->theData[0];
421
c_fsConnectRecordPool.getPtr(fsPtr, fsConf->userPointer);
423
Uint32 filePointer = fsConf->filePointer;
424
fsPtr.p->filePtr = filePointer;
425
switch (fsPtr.p->fsState) {
426
case FsConnectRecord::OPEN_WRITE_SCHEMA:
428
fsPtr.p->fsState = FsConnectRecord::WRITE_SCHEMA;
429
writeSchemaFile(signal, filePointer, fsPtr.i);
431
case FsConnectRecord::OPEN_READ_SCHEMA1:
433
fsPtr.p->fsState = FsConnectRecord::READ_SCHEMA1;
434
readSchemaFile(signal, filePointer, fsPtr.i);
436
case FsConnectRecord::OPEN_READ_SCHEMA2:
438
fsPtr.p->fsState = FsConnectRecord::READ_SCHEMA2;
439
readSchemaFile(signal, filePointer, fsPtr.i);
441
case FsConnectRecord::OPEN_READ_TAB_FILE1:
443
fsPtr.p->fsState = FsConnectRecord::READ_TAB_FILE1;
444
readTableFile(signal, filePointer, fsPtr.i);
446
case FsConnectRecord::OPEN_READ_TAB_FILE2:
448
fsPtr.p->fsState = FsConnectRecord::READ_TAB_FILE2;
449
readTableFile(signal, filePointer, fsPtr.i);
451
case FsConnectRecord::OPEN_WRITE_TAB_FILE:
453
fsPtr.p->fsState = FsConnectRecord::WRITE_TAB_FILE;
454
writeTableFile(signal, filePointer, fsPtr.i);
457
jamLine((fsPtr.p->fsState & 0xFFF));
463
/* ---------------------------------------------------------------- */
464
// An open file was refused.
465
/* ---------------------------------------------------------------- */
466
void Dbdict::execFSOPENREF(Signal* signal)
469
FsRef * const fsRef = (FsRef *)&signal->theData[0];
470
FsConnectRecordPtr fsPtr;
471
c_fsConnectRecordPool.getPtr(fsPtr, fsRef->userPointer);
472
switch (fsPtr.p->fsState) {
473
case FsConnectRecord::OPEN_READ_SCHEMA1:
475
openReadSchemaRef(signal, fsPtr);
477
case FsConnectRecord::OPEN_READ_TAB_FILE1:
479
openReadTableRef(signal, fsPtr);
486
sprintf(msg, "File system open failed during FsConnectRecord state %d", (Uint32)fsPtr.p->fsState);
487
fsRefError(signal,__LINE__,msg);
491
/* ---------------------------------------------------------------- */
492
// A file was successfully read.
493
/* ---------------------------------------------------------------- */
494
void Dbdict::execFSREADCONF(Signal* signal)
497
FsConf * const fsConf = (FsConf *)&signal->theData[0];
498
FsConnectRecordPtr fsPtr;
499
c_fsConnectRecordPool.getPtr(fsPtr, fsConf->userPointer);
500
switch (fsPtr.p->fsState) {
501
case FsConnectRecord::READ_SCHEMA1:
502
case FsConnectRecord::READ_SCHEMA2:
503
readSchemaConf(signal ,fsPtr);
505
case FsConnectRecord::READ_TAB_FILE1:
506
case FsConnectRecord::READ_TAB_FILE2:
508
readTableConf(signal ,fsPtr);
511
jamLine((fsPtr.p->fsState & 0xFFF));
517
/* ---------------------------------------------------------------- */
518
// A read file was refused.
519
/* ---------------------------------------------------------------- */
520
void Dbdict::execFSREADREF(Signal* signal)
523
FsRef * const fsRef = (FsRef *)&signal->theData[0];
524
FsConnectRecordPtr fsPtr;
525
c_fsConnectRecordPool.getPtr(fsPtr, fsRef->userPointer);
526
switch (fsPtr.p->fsState) {
527
case FsConnectRecord::READ_SCHEMA1:
529
readSchemaRef(signal, fsPtr);
531
case FsConnectRecord::READ_TAB_FILE1:
533
readTableRef(signal, fsPtr);
540
sprintf(msg, "File system read failed during FsConnectRecord state %d", (Uint32)fsPtr.p->fsState);
541
fsRefError(signal,__LINE__,msg);
545
/* ---------------------------------------------------------------- */
546
// A file was successfully written.
547
/* ---------------------------------------------------------------- */
548
void Dbdict::execFSWRITECONF(Signal* signal)
550
FsConf * const fsConf = (FsConf *)&signal->theData[0];
551
FsConnectRecordPtr fsPtr;
553
c_fsConnectRecordPool.getPtr(fsPtr, fsConf->userPointer);
554
switch (fsPtr.p->fsState) {
555
case FsConnectRecord::WRITE_TAB_FILE:
556
writeTableConf(signal, fsPtr);
558
case FsConnectRecord::WRITE_SCHEMA:
560
writeSchemaConf(signal, fsPtr);
563
jamLine((fsPtr.p->fsState & 0xFFF));
570
/* ---------------------------------------------------------------- */
571
// Routines to handle Read/Write of Table Files
572
/* ---------------------------------------------------------------- */
574
Dbdict::writeTableFile(Signal* signal, Uint32 tableId,
575
SegmentedSectionPtr tabInfoPtr, Callback* callback){
577
ndbrequire(c_writeTableRecord.tableWriteState == WriteTableRecord::IDLE);
579
Uint32 sz = tabInfoPtr.sz + ZPAGE_HEADER_SIZE;
581
c_writeTableRecord.noOfPages = DIV(sz, ZSIZE_OF_PAGES_IN_WORDS);
582
c_writeTableRecord.tableWriteState = WriteTableRecord::TWR_CALLBACK;
583
c_writeTableRecord.m_callback = * callback;
585
c_writeTableRecord.pageId = 0;
586
ndbrequire(c_writeTableRecord.noOfPages < 8);
588
PageRecordPtr pageRecPtr;
589
c_pageRecordArray.getPtr(pageRecPtr, c_writeTableRecord.pageId);
590
copy(&pageRecPtr.p->word[ZPAGE_HEADER_SIZE], tabInfoPtr);
592
memset(&pageRecPtr.p->word[0], 0, 4 * ZPAGE_HEADER_SIZE);
593
pageRecPtr.p->word[ZPOS_CHECKSUM] =
594
computeChecksum(&pageRecPtr.p->word[0],
595
c_writeTableRecord.noOfPages * ZSIZE_OF_PAGES_IN_WORDS);
597
startWriteTableFile(signal, tableId);
601
void Dbdict::startWriteTableFile(Signal* signal, Uint32 tableId)
603
FsConnectRecordPtr fsPtr;
604
c_writeTableRecord.tableId = tableId;
605
c_fsConnectRecordPool.getPtr(fsPtr, getFsConnRecord());
606
fsPtr.p->fsState = FsConnectRecord::OPEN_WRITE_TAB_FILE;
607
openTableFile(signal, 0, fsPtr.i, tableId, true);
608
c_writeTableRecord.noOfTableFilesHandled = 0;
609
}//Dbdict::startWriteTableFile()
611
void Dbdict::openTableFile(Signal* signal,
617
TableRecordPtr tablePtr;
618
FsOpenReq * const fsOpenReq = (FsOpenReq *)&signal->theData[0];
619
c_tableRecordPool.getPtr(tablePtr, tableId);
621
fsOpenReq->userReference = reference();
622
fsOpenReq->userPointer = fsConPtr;
625
fsOpenReq->fileFlags =
626
FsOpenReq::OM_WRITEONLY |
627
FsOpenReq::OM_TRUNCATE |
628
FsOpenReq::OM_CREATE |
632
fsOpenReq->fileFlags = FsOpenReq::OM_READONLY;
635
fsOpenReq->fileNumber[3] = 0; // Initialise before byte changes
636
FsOpenReq::setVersion(fsOpenReq->fileNumber, 1);
637
FsOpenReq::setSuffix(fsOpenReq->fileNumber, FsOpenReq::S_TABLELIST);
638
FsOpenReq::v1_setDisk(fsOpenReq->fileNumber, (fileNo + 1));
639
FsOpenReq::v1_setTable(fsOpenReq->fileNumber, tableId);
640
FsOpenReq::v1_setFragment(fsOpenReq->fileNumber, (Uint32)-1);
641
FsOpenReq::v1_setS(fsOpenReq->fileNumber, tablePtr.p->tableVersion);
642
FsOpenReq::v1_setP(fsOpenReq->fileNumber, 255);
643
/* ---------------------------------------------------------------- */
644
// File name : D1/DBDICT/T0/S1.TableList
645
// D1 means Disk 1 (set by fileNo + 1)
646
// T0 means table id = 0
647
// S1 means tableVersion 1
648
// TableList indicates that this is a file for a table description.
649
/* ---------------------------------------------------------------- */
650
sendSignal(NDBFS_REF, GSN_FSOPENREQ, signal, FsOpenReq::SignalLength, JBA);
653
void Dbdict::writeTableFile(Signal* signal, Uint32 filePtr, Uint32 fsConPtr)
655
FsReadWriteReq * const fsRWReq = (FsReadWriteReq *)&signal->theData[0];
657
fsRWReq->filePointer = filePtr;
658
fsRWReq->userReference = reference();
659
fsRWReq->userPointer = fsConPtr;
660
fsRWReq->operationFlag = 0; // Initialise before bit changes
661
FsReadWriteReq::setSyncFlag(fsRWReq->operationFlag, 1);
662
FsReadWriteReq::setFormatFlag(fsRWReq->operationFlag,
663
FsReadWriteReq::fsFormatArrayOfPages);
664
fsRWReq->varIndex = ZBAT_TABLE_FILE;
665
fsRWReq->numberOfPages = c_writeTableRecord.noOfPages;
666
fsRWReq->data.arrayOfPages.varIndex = c_writeTableRecord.pageId;
667
fsRWReq->data.arrayOfPages.fileOffset = 0; // Write to file page 0
668
sendSignal(NDBFS_REF, GSN_FSWRITEREQ, signal, 8, JBA);
671
void Dbdict::writeTableConf(Signal* signal,
672
FsConnectRecordPtr fsPtr)
674
fsPtr.p->fsState = FsConnectRecord::CLOSE_WRITE_TAB_FILE;
675
closeFile(signal, fsPtr.p->filePtr, fsPtr.i);
677
}//Dbdict::writeTableConf()
679
void Dbdict::closeWriteTableConf(Signal* signal,
680
FsConnectRecordPtr fsPtr)
682
c_writeTableRecord.noOfTableFilesHandled++;
683
if (c_writeTableRecord.noOfTableFilesHandled < 2) {
685
fsPtr.p->fsState = FsConnectRecord::OPEN_WRITE_TAB_FILE;
686
openTableFile(signal, 1, fsPtr.i, c_writeTableRecord.tableId, true);
689
ndbrequire(c_writeTableRecord.noOfTableFilesHandled == 2);
690
c_fsConnectRecordPool.release(fsPtr);
691
WriteTableRecord::TableWriteState state = c_writeTableRecord.tableWriteState;
692
c_writeTableRecord.tableWriteState = WriteTableRecord::IDLE;
694
case WriteTableRecord::IDLE:
695
case WriteTableRecord::WRITE_ADD_TABLE_MASTER :
696
case WriteTableRecord::WRITE_ADD_TABLE_SLAVE :
697
case WriteTableRecord::WRITE_RESTART_FROM_MASTER :
698
case WriteTableRecord::WRITE_RESTART_FROM_OWN :
701
case WriteTableRecord::TWR_CALLBACK:
703
execute(signal, c_writeTableRecord.m_callback, 0);
707
}//Dbdict::closeWriteTableConf()
709
void Dbdict::startReadTableFile(Signal* signal, Uint32 tableId)
711
//globalSignalLoggers.log(number(), "startReadTableFile");
712
ndbrequire(!c_readTableRecord.inUse);
714
FsConnectRecordPtr fsPtr;
715
c_fsConnectRecordPool.getPtr(fsPtr, getFsConnRecord());
716
c_readTableRecord.inUse = true;
717
c_readTableRecord.tableId = tableId;
718
fsPtr.p->fsState = FsConnectRecord::OPEN_READ_TAB_FILE1;
719
openTableFile(signal, 0, fsPtr.i, tableId, false);
720
}//Dbdict::startReadTableFile()
722
void Dbdict::openReadTableRef(Signal* signal,
723
FsConnectRecordPtr fsPtr)
725
fsPtr.p->fsState = FsConnectRecord::OPEN_READ_TAB_FILE2;
726
openTableFile(signal, 1, fsPtr.i, c_readTableRecord.tableId, false);
728
}//Dbdict::openReadTableConf()
730
void Dbdict::readTableFile(Signal* signal, Uint32 filePtr, Uint32 fsConPtr)
732
FsReadWriteReq * const fsRWReq = (FsReadWriteReq *)&signal->theData[0];
734
fsRWReq->filePointer = filePtr;
735
fsRWReq->userReference = reference();
736
fsRWReq->userPointer = fsConPtr;
737
fsRWReq->operationFlag = 0; // Initialise before bit changes
738
FsReadWriteReq::setSyncFlag(fsRWReq->operationFlag, 0);
739
FsReadWriteReq::setFormatFlag(fsRWReq->operationFlag,
740
FsReadWriteReq::fsFormatArrayOfPages);
741
fsRWReq->varIndex = ZBAT_TABLE_FILE;
742
fsRWReq->numberOfPages = c_readTableRecord.noOfPages;
743
fsRWReq->data.arrayOfPages.varIndex = c_readTableRecord.pageId;
744
fsRWReq->data.arrayOfPages.fileOffset = 0; // Write to file page 0
745
sendSignal(NDBFS_REF, GSN_FSREADREQ, signal, 8, JBA);
748
void Dbdict::readTableConf(Signal* signal,
749
FsConnectRecordPtr fsPtr)
751
/* ---------------------------------------------------------------- */
752
// Verify the data read from disk
753
/* ---------------------------------------------------------------- */
755
if (fsPtr.p->fsState == FsConnectRecord::READ_TAB_FILE1) {
763
PageRecordPtr tmpPagePtr;
764
c_pageRecordArray.getPtr(tmpPagePtr, c_readTableRecord.pageId);
765
Uint32 sz = c_readTableRecord.noOfPages * ZSIZE_OF_PAGES_IN_WORDS;
766
Uint32 chk = computeChecksum((const Uint32*)tmpPagePtr.p, sz);
768
ndbrequire((chk == 0) || !crashInd);
771
ndbrequire(fsPtr.p->fsState == FsConnectRecord::READ_TAB_FILE1);
772
readTableRef(signal, fsPtr);
776
fsPtr.p->fsState = FsConnectRecord::CLOSE_READ_TAB_FILE;
777
closeFile(signal, fsPtr.p->filePtr, fsPtr.i);
779
}//Dbdict::readTableConf()
781
void Dbdict::readTableRef(Signal* signal,
782
FsConnectRecordPtr fsPtr)
784
fsPtr.p->fsState = FsConnectRecord::OPEN_READ_TAB_FILE2;
785
openTableFile(signal, 1, fsPtr.i, c_readTableRecord.tableId, false);
787
}//Dbdict::readTableRef()
789
void Dbdict::closeReadTableConf(Signal* signal,
790
FsConnectRecordPtr fsPtr)
792
c_fsConnectRecordPool.release(fsPtr);
793
c_readTableRecord.inUse = false;
795
execute(signal, c_readTableRecord.m_callback, 0);
797
}//Dbdict::closeReadTableConf()
799
/* ---------------------------------------------------------------- */
800
// Routines to handle Read/Write of Schema Files
801
/* ---------------------------------------------------------------- */
803
Dbdict::updateSchemaState(Signal* signal, Uint32 tableId,
804
SchemaFile::TableEntry* te, Callback* callback){
807
ndbrequire(tableId < c_tableRecordPool.getSize());
808
XSchemaFile * xsf = &c_schemaFile[c_schemaRecord.schemaPage != 0];
809
SchemaFile::TableEntry * tableEntry = getTableEntry(xsf, tableId);
811
SchemaFile::TableState newState =
812
(SchemaFile::TableState)te->m_tableState;
813
SchemaFile::TableState oldState =
814
(SchemaFile::TableState)tableEntry->m_tableState;
816
Uint32 newVersion = te->m_tableVersion;
817
Uint32 oldVersion = tableEntry->m_tableVersion;
821
case SchemaFile::ADD_STARTED:
824
ndbrequire(create_table_inc_schema_version(oldVersion) == newVersion);
825
ndbrequire(oldState == SchemaFile::INIT ||
826
oldState == SchemaFile::DROP_TABLE_COMMITTED);
828
case SchemaFile::TABLE_ADD_COMMITTED:
831
ndbrequire(newVersion == oldVersion);
832
ndbrequire(oldState == SchemaFile::ADD_STARTED);
834
case SchemaFile::ALTER_TABLE_COMMITTED:
837
ndbrequire(alter_table_inc_schema_version(oldVersion) == newVersion);
838
ndbrequire(oldState == SchemaFile::TABLE_ADD_COMMITTED ||
839
oldState == SchemaFile::ALTER_TABLE_COMMITTED);
841
case SchemaFile::DROP_TABLE_STARTED:
843
case SchemaFile::DROP_TABLE_COMMITTED:
848
case SchemaFile::INIT:
851
ndbrequire((oldState == SchemaFile::ADD_STARTED));
856
computeChecksum(xsf, tableId / NDB_SF_PAGE_ENTRIES);
858
ndbrequire(c_writeSchemaRecord.inUse == false);
859
c_writeSchemaRecord.inUse = true;
861
c_writeSchemaRecord.pageId = c_schemaRecord.schemaPage;
862
c_writeSchemaRecord.newFile = false;
863
c_writeSchemaRecord.firstPage = tableId / NDB_SF_PAGE_ENTRIES;
864
c_writeSchemaRecord.noOfPages = 1;
865
c_writeSchemaRecord.m_callback = * callback;
867
startWriteSchemaFile(signal);
870
void Dbdict::startWriteSchemaFile(Signal* signal)
872
FsConnectRecordPtr fsPtr;
873
c_fsConnectRecordPool.getPtr(fsPtr, getFsConnRecord());
874
fsPtr.p->fsState = FsConnectRecord::OPEN_WRITE_SCHEMA;
875
openSchemaFile(signal, 0, fsPtr.i, true, c_writeSchemaRecord.newFile);
876
c_writeSchemaRecord.noOfSchemaFilesHandled = 0;
877
}//Dbdict::startWriteSchemaFile()
879
void Dbdict::openSchemaFile(Signal* signal,
885
FsOpenReq * const fsOpenReq = (FsOpenReq *)&signal->theData[0];
886
fsOpenReq->userReference = reference();
887
fsOpenReq->userPointer = fsConPtr;
890
fsOpenReq->fileFlags =
891
FsOpenReq::OM_WRITEONLY |
894
fsOpenReq->fileFlags |=
895
FsOpenReq::OM_TRUNCATE |
896
FsOpenReq::OM_CREATE;
899
fsOpenReq->fileFlags = FsOpenReq::OM_READONLY;
901
fsOpenReq->fileNumber[3] = 0; // Initialise before byte changes
902
FsOpenReq::setVersion(fsOpenReq->fileNumber, 1);
903
FsOpenReq::setSuffix(fsOpenReq->fileNumber, FsOpenReq::S_SCHEMALOG);
904
FsOpenReq::v1_setDisk(fsOpenReq->fileNumber, (fileNo + 1));
905
FsOpenReq::v1_setTable(fsOpenReq->fileNumber, (Uint32)-1);
906
FsOpenReq::v1_setFragment(fsOpenReq->fileNumber, (Uint32)-1);
907
FsOpenReq::v1_setS(fsOpenReq->fileNumber, (Uint32)-1);
908
FsOpenReq::v1_setP(fsOpenReq->fileNumber, 0);
909
/* ---------------------------------------------------------------- */
910
// File name : D1/DBDICT/P0.SchemaLog
911
// D1 means Disk 1 (set by fileNo + 1). Writes to both D1 and D2
912
// SchemaLog indicates that this is a file giving a list of current tables.
913
/* ---------------------------------------------------------------- */
914
sendSignal(NDBFS_REF, GSN_FSOPENREQ, signal, FsOpenReq::SignalLength, JBA);
917
void Dbdict::writeSchemaFile(Signal* signal, Uint32 filePtr, Uint32 fsConPtr)
919
FsReadWriteReq * const fsRWReq = (FsReadWriteReq *)&signal->theData[0];
921
// check write record
922
WriteSchemaRecord & wr = c_writeSchemaRecord;
923
ndbrequire(wr.pageId == (wr.pageId != 0) * NDB_SF_MAX_PAGES);
924
ndbrequire(wr.noOfPages != 0);
925
ndbrequire(wr.firstPage + wr.noOfPages <= NDB_SF_MAX_PAGES);
927
fsRWReq->filePointer = filePtr;
928
fsRWReq->userReference = reference();
929
fsRWReq->userPointer = fsConPtr;
930
fsRWReq->operationFlag = 0; // Initialise before bit changes
931
FsReadWriteReq::setSyncFlag(fsRWReq->operationFlag, 1);
932
FsReadWriteReq::setFormatFlag(fsRWReq->operationFlag,
933
FsReadWriteReq::fsFormatArrayOfPages);
934
fsRWReq->varIndex = ZBAT_SCHEMA_FILE;
935
fsRWReq->numberOfPages = wr.noOfPages;
936
// Write from memory page
937
fsRWReq->data.arrayOfPages.varIndex = wr.pageId + wr.firstPage;
938
fsRWReq->data.arrayOfPages.fileOffset = wr.firstPage;
939
sendSignal(NDBFS_REF, GSN_FSWRITEREQ, signal, 8, JBA);
942
void Dbdict::writeSchemaConf(Signal* signal,
943
FsConnectRecordPtr fsPtr)
945
fsPtr.p->fsState = FsConnectRecord::CLOSE_WRITE_SCHEMA;
946
closeFile(signal, fsPtr.p->filePtr, fsPtr.i);
948
}//Dbdict::writeSchemaConf()
950
void Dbdict::closeFile(Signal* signal, Uint32 filePtr, Uint32 fsConPtr)
952
FsCloseReq * const fsCloseReq = (FsCloseReq *)&signal->theData[0];
953
fsCloseReq->filePointer = filePtr;
954
fsCloseReq->userReference = reference();
955
fsCloseReq->userPointer = fsConPtr;
956
FsCloseReq::setRemoveFileFlag(fsCloseReq->fileFlag, false);
957
sendSignal(NDBFS_REF, GSN_FSCLOSEREQ, signal, FsCloseReq::SignalLength, JBA);
961
void Dbdict::closeWriteSchemaConf(Signal* signal,
962
FsConnectRecordPtr fsPtr)
964
c_writeSchemaRecord.noOfSchemaFilesHandled++;
965
if (c_writeSchemaRecord.noOfSchemaFilesHandled < 2) {
967
fsPtr.p->fsState = FsConnectRecord::OPEN_WRITE_SCHEMA;
968
openSchemaFile(signal, 1, fsPtr.i, true, c_writeSchemaRecord.newFile);
971
ndbrequire(c_writeSchemaRecord.noOfSchemaFilesHandled == 2);
973
c_fsConnectRecordPool.release(fsPtr);
975
c_writeSchemaRecord.inUse = false;
976
execute(signal, c_writeSchemaRecord.m_callback, 0);
978
}//Dbdict::closeWriteSchemaConf()
980
void Dbdict::startReadSchemaFile(Signal* signal)
982
//globalSignalLoggers.log(number(), "startReadSchemaFile");
983
FsConnectRecordPtr fsPtr;
984
c_fsConnectRecordPool.getPtr(fsPtr, getFsConnRecord());
985
fsPtr.p->fsState = FsConnectRecord::OPEN_READ_SCHEMA1;
986
openSchemaFile(signal, 0, fsPtr.i, false, false);
987
}//Dbdict::startReadSchemaFile()
989
void Dbdict::openReadSchemaRef(Signal* signal,
990
FsConnectRecordPtr fsPtr)
992
fsPtr.p->fsState = FsConnectRecord::OPEN_READ_SCHEMA2;
993
openSchemaFile(signal, 1, fsPtr.i, false, false);
994
}//Dbdict::openReadSchemaRef()
996
void Dbdict::readSchemaFile(Signal* signal, Uint32 filePtr, Uint32 fsConPtr)
998
FsReadWriteReq * const fsRWReq = (FsReadWriteReq *)&signal->theData[0];
1000
// check read record
1001
ReadSchemaRecord & rr = c_readSchemaRecord;
1002
ndbrequire(rr.pageId == (rr.pageId != 0) * NDB_SF_MAX_PAGES);
1003
ndbrequire(rr.noOfPages != 0);
1004
ndbrequire(rr.firstPage + rr.noOfPages <= NDB_SF_MAX_PAGES);
1006
fsRWReq->filePointer = filePtr;
1007
fsRWReq->userReference = reference();
1008
fsRWReq->userPointer = fsConPtr;
1009
fsRWReq->operationFlag = 0; // Initialise before bit changes
1010
FsReadWriteReq::setSyncFlag(fsRWReq->operationFlag, 0);
1011
FsReadWriteReq::setFormatFlag(fsRWReq->operationFlag,
1012
FsReadWriteReq::fsFormatArrayOfPages);
1013
fsRWReq->varIndex = ZBAT_SCHEMA_FILE;
1014
fsRWReq->numberOfPages = rr.noOfPages;
1015
fsRWReq->data.arrayOfPages.varIndex = rr.pageId + rr.firstPage;
1016
fsRWReq->data.arrayOfPages.fileOffset = rr.firstPage;
1017
sendSignal(NDBFS_REF, GSN_FSREADREQ, signal, 8, JBA);
1020
void Dbdict::readSchemaConf(Signal* signal,
1021
FsConnectRecordPtr fsPtr)
1023
/* ---------------------------------------------------------------- */
1024
// Verify the data read from disk
1025
/* ---------------------------------------------------------------- */
1027
if (fsPtr.p->fsState == FsConnectRecord::READ_SCHEMA1) {
1035
ReadSchemaRecord & rr = c_readSchemaRecord;
1036
XSchemaFile * xsf = &c_schemaFile[rr.pageId != 0];
1038
if (rr.schemaReadState == ReadSchemaRecord::INITIAL_READ_HEAD) {
1040
ndbrequire(rr.firstPage == 0);
1041
SchemaFile * sf = &xsf->schemaPage[0];
1043
if (sf->NdbVersion < NDB_SF_VERSION_5_0_6) {
1045
const Uint32 pageSize_old = 32 * 1024;
1046
noOfPages = pageSize_old / NDB_SF_PAGE_SIZE - 1;
1048
noOfPages = sf->FileSize / NDB_SF_PAGE_SIZE - 1;
1050
rr.schemaReadState = ReadSchemaRecord::INITIAL_READ;
1051
if (noOfPages != 0) {
1053
rr.noOfPages = noOfPages;
1054
readSchemaFile(signal, fsPtr.p->filePtr, fsPtr.i);
1059
SchemaFile * sf0 = &xsf->schemaPage[0];
1060
xsf->noOfPages = sf0->FileSize / NDB_SF_PAGE_SIZE;
1062
if (sf0->NdbVersion < NDB_SF_VERSION_5_0_6 &&
1063
! convertSchemaFileTo_5_0_6(xsf)) {
1065
ndbrequire(! crashInd);
1066
ndbrequire(fsPtr.p->fsState == FsConnectRecord::READ_SCHEMA1);
1067
readSchemaRef(signal, fsPtr);
1071
for (Uint32 n = 0; n < xsf->noOfPages; n++) {
1072
SchemaFile * sf = &xsf->schemaPage[n];
1074
memcmp(sf->Magic, NDB_SF_MAGIC, sizeof(sf->Magic)) == 0 &&
1075
sf->FileSize != 0 &&
1076
sf->FileSize % NDB_SF_PAGE_SIZE == 0 &&
1077
sf->FileSize == sf0->FileSize &&
1078
sf->PageNumber == n &&
1079
computeChecksum((Uint32*)sf, NDB_SF_PAGE_SIZE_IN_WORDS) == 0;
1080
ndbrequire(ok || !crashInd);
1083
ndbrequire(fsPtr.p->fsState == FsConnectRecord::READ_SCHEMA1);
1084
readSchemaRef(signal, fsPtr);
1089
fsPtr.p->fsState = FsConnectRecord::CLOSE_READ_SCHEMA;
1090
closeFile(signal, fsPtr.p->filePtr, fsPtr.i);
1092
}//Dbdict::readSchemaConf()
1094
void Dbdict::readSchemaRef(Signal* signal,
1095
FsConnectRecordPtr fsPtr)
1098
* First close corrupt file
1100
fsPtr.p->fsState = FsConnectRecord::OPEN_READ_SCHEMA2;
1101
closeFile(signal, fsPtr.p->filePtr, fsPtr.i);
1105
void Dbdict::closeReadSchemaConf(Signal* signal,
1106
FsConnectRecordPtr fsPtr)
1108
c_fsConnectRecordPool.release(fsPtr);
1109
ReadSchemaRecord::SchemaReadState state = c_readSchemaRecord.schemaReadState;
1110
c_readSchemaRecord.schemaReadState = ReadSchemaRecord::IDLE;
1113
case ReadSchemaRecord::INITIAL_READ :
1116
// write back both copies
1118
ndbrequire(c_writeSchemaRecord.inUse == false);
1119
XSchemaFile * xsf = &c_schemaFile[c_schemaRecord.oldSchemaPage != 0 ];
1121
(c_tableRecordPool.getSize() + NDB_SF_PAGE_ENTRIES - 1) /
1122
NDB_SF_PAGE_ENTRIES;
1123
resizeSchemaFile(xsf, noOfPages);
1125
c_writeSchemaRecord.inUse = true;
1126
c_writeSchemaRecord.pageId = c_schemaRecord.oldSchemaPage;
1127
c_writeSchemaRecord.newFile = true;
1128
c_writeSchemaRecord.firstPage = 0;
1129
c_writeSchemaRecord.noOfPages = xsf->noOfPages;
1131
c_writeSchemaRecord.m_callback.m_callbackFunction =
1132
safe_cast(&Dbdict::initSchemaFile_conf);
1134
startWriteSchemaFile(signal);
1143
}//Dbdict::closeReadSchemaConf()
1146
Dbdict::convertSchemaFileTo_5_0_6(XSchemaFile * xsf)
1148
const Uint32 pageSize_old = 32 * 1024;
1149
Uint32 page_old[pageSize_old >> 2];
1150
SchemaFile * sf_old = (SchemaFile *)page_old;
1152
if (xsf->noOfPages * NDB_SF_PAGE_SIZE != pageSize_old)
1154
SchemaFile * sf0 = &xsf->schemaPage[0];
1155
memcpy(sf_old, sf0, pageSize_old);
1157
// init max number new pages needed
1158
xsf->noOfPages = (sf_old->NoOfTableEntries + NDB_SF_PAGE_ENTRIES - 1) /
1159
NDB_SF_PAGE_ENTRIES;
1160
initSchemaFile(xsf, 0, xsf->noOfPages, true);
1162
Uint32 noOfPages = 1;
1164
for (n = 0; n < xsf->noOfPages; n++) {
1166
for (i = 0; i < NDB_SF_PAGE_ENTRIES; i++) {
1167
j = n * NDB_SF_PAGE_ENTRIES + i;
1168
if (j >= sf_old->NoOfTableEntries)
1170
const SchemaFile::TableEntry_old & te_old = sf_old->TableEntries_old[j];
1171
if (te_old.m_tableState == SchemaFile::INIT ||
1172
te_old.m_tableState == SchemaFile::DROP_TABLE_COMMITTED ||
1173
te_old.m_noOfPages == 0)
1175
SchemaFile * sf = &xsf->schemaPage[n];
1176
SchemaFile::TableEntry & te = sf->TableEntries[i];
1177
te.m_tableState = te_old.m_tableState;
1178
te.m_tableVersion = te_old.m_tableVersion;
1179
te.m_tableType = te_old.m_tableType;
1180
te.m_info_words = te_old.m_noOfPages * ZSIZE_OF_PAGES_IN_WORDS -
1182
te.m_gcp = te_old.m_gcp;
1187
xsf->noOfPages = noOfPages;
1188
initSchemaFile(xsf, 0, xsf->noOfPages, false);
1193
/* **************************************************************** */
1194
/* ---------------------------------------------------------------- */
1195
/* MODULE: INITIALISATION MODULE ------------------------- */
1196
/* ---------------------------------------------------------------- */
1198
/* This module contains initialisation of data at start/restart. */
1199
/* ---------------------------------------------------------------- */
1200
/* **************************************************************** */
1202
Dbdict::Dbdict(const class Configuration & conf):
1203
SimulatedBlock(DBDICT, conf),
1204
c_tableRecordHash(c_tableRecordPool),
1205
c_attributeRecordHash(c_attributeRecordPool),
1206
c_triggerRecordHash(c_triggerRecordPool),
1207
c_opCreateTable(c_opRecordPool),
1208
c_opDropTable(c_opRecordPool),
1209
c_opCreateIndex(c_opRecordPool),
1210
c_opDropIndex(c_opRecordPool),
1211
c_opAlterIndex(c_opRecordPool),
1212
c_opBuildIndex(c_opRecordPool),
1213
c_opCreateTrigger(c_opRecordPool),
1214
c_opDropTrigger(c_opRecordPool),
1215
c_opAlterTrigger(c_opRecordPool),
1216
c_opRecordSequence(0),
1217
c_dictLockQueue(c_dictLockPool),
1218
c_dictLockPoll(false)
1220
BLOCK_CONSTRUCTOR(Dbdict);
1222
const ndb_mgm_configuration_iterator * p = conf.getOwnConfigIterator();
1225
ndb_mgm_get_int_parameter(p, CFG_DB_NO_TRIGGERS, &c_maxNoOfTriggers);
1227
addRecSignal(GSN_DUMP_STATE_ORD, &Dbdict::execDUMP_STATE_ORD);
1228
addRecSignal(GSN_GET_TABINFOREQ, &Dbdict::execGET_TABINFOREQ);
1229
addRecSignal(GSN_GET_TABLEID_REQ, &Dbdict::execGET_TABLEDID_REQ);
1230
addRecSignal(GSN_GET_TABINFO_CONF, &Dbdict::execGET_TABINFO_CONF);
1231
addRecSignal(GSN_CONTINUEB, &Dbdict::execCONTINUEB);
1233
addRecSignal(GSN_CREATE_TABLE_REQ, &Dbdict::execCREATE_TABLE_REQ);
1234
addRecSignal(GSN_CREATE_TAB_REQ, &Dbdict::execCREATE_TAB_REQ);
1235
addRecSignal(GSN_CREATE_TAB_REF, &Dbdict::execCREATE_TAB_REF);
1236
addRecSignal(GSN_CREATE_TAB_CONF, &Dbdict::execCREATE_TAB_CONF);
1237
addRecSignal(GSN_CREATE_FRAGMENTATION_REF, &Dbdict::execCREATE_FRAGMENTATION_REF);
1238
addRecSignal(GSN_CREATE_FRAGMENTATION_CONF, &Dbdict::execCREATE_FRAGMENTATION_CONF);
1239
addRecSignal(GSN_DIADDTABCONF, &Dbdict::execDIADDTABCONF);
1240
addRecSignal(GSN_DIADDTABREF, &Dbdict::execDIADDTABREF);
1241
addRecSignal(GSN_ADD_FRAGREQ, &Dbdict::execADD_FRAGREQ);
1242
addRecSignal(GSN_TAB_COMMITCONF, &Dbdict::execTAB_COMMITCONF);
1243
addRecSignal(GSN_TAB_COMMITREF, &Dbdict::execTAB_COMMITREF);
1244
addRecSignal(GSN_ALTER_TABLE_REQ, &Dbdict::execALTER_TABLE_REQ);
1245
addRecSignal(GSN_ALTER_TAB_REQ, &Dbdict::execALTER_TAB_REQ);
1246
addRecSignal(GSN_ALTER_TAB_REF, &Dbdict::execALTER_TAB_REF);
1247
addRecSignal(GSN_ALTER_TAB_CONF, &Dbdict::execALTER_TAB_CONF);
1250
addRecSignal(GSN_CREATE_INDX_REQ, &Dbdict::execCREATE_INDX_REQ);
1251
addRecSignal(GSN_CREATE_INDX_CONF, &Dbdict::execCREATE_INDX_CONF);
1252
addRecSignal(GSN_CREATE_INDX_REF, &Dbdict::execCREATE_INDX_REF);
1254
addRecSignal(GSN_ALTER_INDX_REQ, &Dbdict::execALTER_INDX_REQ);
1255
addRecSignal(GSN_ALTER_INDX_CONF, &Dbdict::execALTER_INDX_CONF);
1256
addRecSignal(GSN_ALTER_INDX_REF, &Dbdict::execALTER_INDX_REF);
1258
addRecSignal(GSN_CREATE_TABLE_CONF, &Dbdict::execCREATE_TABLE_CONF);
1259
addRecSignal(GSN_CREATE_TABLE_REF, &Dbdict::execCREATE_TABLE_REF);
1261
addRecSignal(GSN_DROP_INDX_REQ, &Dbdict::execDROP_INDX_REQ);
1262
addRecSignal(GSN_DROP_INDX_CONF, &Dbdict::execDROP_INDX_CONF);
1263
addRecSignal(GSN_DROP_INDX_REF, &Dbdict::execDROP_INDX_REF);
1265
addRecSignal(GSN_DROP_TABLE_CONF, &Dbdict::execDROP_TABLE_CONF);
1266
addRecSignal(GSN_DROP_TABLE_REF, &Dbdict::execDROP_TABLE_REF);
1268
addRecSignal(GSN_BUILDINDXREQ, &Dbdict::execBUILDINDXREQ);
1269
addRecSignal(GSN_BUILDINDXCONF, &Dbdict::execBUILDINDXCONF);
1270
addRecSignal(GSN_BUILDINDXREF, &Dbdict::execBUILDINDXREF);
1273
addRecSignal(GSN_CREATE_TRIG_REQ, &Dbdict::execCREATE_TRIG_REQ);
1274
addRecSignal(GSN_CREATE_TRIG_CONF, &Dbdict::execCREATE_TRIG_CONF);
1275
addRecSignal(GSN_CREATE_TRIG_REF, &Dbdict::execCREATE_TRIG_REF);
1276
addRecSignal(GSN_ALTER_TRIG_REQ, &Dbdict::execALTER_TRIG_REQ);
1277
addRecSignal(GSN_ALTER_TRIG_CONF, &Dbdict::execALTER_TRIG_CONF);
1278
addRecSignal(GSN_ALTER_TRIG_REF, &Dbdict::execALTER_TRIG_REF);
1279
addRecSignal(GSN_DROP_TRIG_REQ, &Dbdict::execDROP_TRIG_REQ);
1280
addRecSignal(GSN_DROP_TRIG_CONF, &Dbdict::execDROP_TRIG_CONF);
1281
addRecSignal(GSN_DROP_TRIG_REF, &Dbdict::execDROP_TRIG_REF);
1284
addRecSignal(GSN_HOT_SPAREREP, &Dbdict::execHOT_SPAREREP);
1285
addRecSignal(GSN_GET_SCHEMA_INFOREQ, &Dbdict::execGET_SCHEMA_INFOREQ);
1286
addRecSignal(GSN_SCHEMA_INFO, &Dbdict::execSCHEMA_INFO);
1287
addRecSignal(GSN_SCHEMA_INFOCONF, &Dbdict::execSCHEMA_INFOCONF);
1288
addRecSignal(GSN_DICTSTARTREQ, &Dbdict::execDICTSTARTREQ);
1289
addRecSignal(GSN_READ_NODESCONF, &Dbdict::execREAD_NODESCONF);
1290
addRecSignal(GSN_FSOPENCONF, &Dbdict::execFSOPENCONF);
1291
addRecSignal(GSN_FSOPENREF, &Dbdict::execFSOPENREF, true);
1292
addRecSignal(GSN_FSCLOSECONF, &Dbdict::execFSCLOSECONF);
1293
addRecSignal(GSN_FSWRITECONF, &Dbdict::execFSWRITECONF);
1294
addRecSignal(GSN_FSREADCONF, &Dbdict::execFSREADCONF);
1295
addRecSignal(GSN_FSREADREF, &Dbdict::execFSREADREF, true);
1296
addRecSignal(GSN_LQHFRAGCONF, &Dbdict::execLQHFRAGCONF);
1297
addRecSignal(GSN_LQHADDATTCONF, &Dbdict::execLQHADDATTCONF);
1298
addRecSignal(GSN_LQHADDATTREF, &Dbdict::execLQHADDATTREF);
1299
addRecSignal(GSN_LQHFRAGREF, &Dbdict::execLQHFRAGREF);
1300
addRecSignal(GSN_NDB_STTOR, &Dbdict::execNDB_STTOR);
1301
addRecSignal(GSN_READ_CONFIG_REQ, &Dbdict::execREAD_CONFIG_REQ, true);
1302
addRecSignal(GSN_STTOR, &Dbdict::execSTTOR);
1303
addRecSignal(GSN_TC_SCHVERCONF, &Dbdict::execTC_SCHVERCONF);
1304
addRecSignal(GSN_NODE_FAILREP, &Dbdict::execNODE_FAILREP);
1305
addRecSignal(GSN_INCL_NODEREQ, &Dbdict::execINCL_NODEREQ);
1306
addRecSignal(GSN_API_FAILREQ, &Dbdict::execAPI_FAILREQ);
1308
addRecSignal(GSN_WAIT_GCP_REF, &Dbdict::execWAIT_GCP_REF);
1309
addRecSignal(GSN_WAIT_GCP_CONF, &Dbdict::execWAIT_GCP_CONF);
1311
addRecSignal(GSN_LIST_TABLES_REQ, &Dbdict::execLIST_TABLES_REQ);
1313
addRecSignal(GSN_DROP_TABLE_REQ, &Dbdict::execDROP_TABLE_REQ);
1315
addRecSignal(GSN_PREP_DROP_TAB_REQ, &Dbdict::execPREP_DROP_TAB_REQ);
1316
addRecSignal(GSN_PREP_DROP_TAB_REF, &Dbdict::execPREP_DROP_TAB_REF);
1317
addRecSignal(GSN_PREP_DROP_TAB_CONF, &Dbdict::execPREP_DROP_TAB_CONF);
1319
addRecSignal(GSN_DROP_TAB_REQ, &Dbdict::execDROP_TAB_REQ);
1320
addRecSignal(GSN_DROP_TAB_REF, &Dbdict::execDROP_TAB_REF);
1321
addRecSignal(GSN_DROP_TAB_CONF, &Dbdict::execDROP_TAB_CONF);
1323
addRecSignal(GSN_BACKUP_FRAGMENT_REQ, &Dbdict::execBACKUP_FRAGMENT_REQ);
1325
addRecSignal(GSN_DICT_LOCK_REQ, &Dbdict::execDICT_LOCK_REQ);
1326
addRecSignal(GSN_DICT_UNLOCK_ORD, &Dbdict::execDICT_UNLOCK_ORD);
1331
}//Dbdict::~Dbdict()
1333
BLOCK_FUNCTIONS(Dbdict)
1335
void Dbdict::initCommonData()
1337
/* ---------------------------------------------------------------- */
1338
// Initialise all common variables.
1339
/* ---------------------------------------------------------------- */
1340
initRetrieveRecord(0, 0, 0);
1342
initRestartRecord();
1343
initSendSchemaRecord();
1344
initReadTableRecord();
1345
initWriteTableRecord();
1346
initReadSchemaRecord();
1347
initWriteSchemaRecord();
1349
c_masterNodeId = ZNIL;
1351
c_noNodesFailed = 0;
1353
c_blockState = BS_IDLE;
1354
c_packTable.m_state = PackTable::PTS_IDLE;
1356
c_restartType = 255; //Ensure not used restartType
1357
c_tabinfoReceived = 0;
1358
c_initialStart = false;
1359
c_systemRestart = false;
1360
c_initialNodeRestart = false;
1361
c_nodeRestart = false;
1362
}//Dbdict::initCommonData()
1364
void Dbdict::initRecords()
1369
initTriggerRecords();
1370
}//Dbdict::initRecords()
1372
void Dbdict::initSendSchemaRecord()
1374
c_sendSchemaRecord.noOfWords = (Uint32)-1;
1375
c_sendSchemaRecord.pageId = RNIL;
1376
c_sendSchemaRecord.noOfWordsCurrentlySent = 0;
1377
c_sendSchemaRecord.noOfSignalsSentSinceDelay = 0;
1378
c_sendSchemaRecord.inUse = false;
1379
//c_sendSchemaRecord.sendSchemaState = SendSchemaRecord::IDLE;
1380
}//initSendSchemaRecord()
1382
void Dbdict::initReadTableRecord()
1384
c_readTableRecord.noOfPages = (Uint32)-1;
1385
c_readTableRecord.pageId = RNIL;
1386
c_readTableRecord.tableId = ZNIL;
1387
c_readTableRecord.inUse = false;
1388
}//initReadTableRecord()
1390
void Dbdict::initWriteTableRecord()
1392
c_writeTableRecord.noOfPages = (Uint32)-1;
1393
c_writeTableRecord.pageId = RNIL;
1394
c_writeTableRecord.noOfTableFilesHandled = 3;
1395
c_writeTableRecord.tableId = ZNIL;
1396
c_writeTableRecord.tableWriteState = WriteTableRecord::IDLE;
1397
}//initWriteTableRecord()
1399
void Dbdict::initReadSchemaRecord()
1401
c_readSchemaRecord.pageId = RNIL;
1402
c_readSchemaRecord.schemaReadState = ReadSchemaRecord::IDLE;
1403
}//initReadSchemaRecord()
1405
void Dbdict::initWriteSchemaRecord()
1407
c_writeSchemaRecord.inUse = false;
1408
c_writeSchemaRecord.pageId = RNIL;
1409
c_writeSchemaRecord.noOfSchemaFilesHandled = 3;
1410
}//initWriteSchemaRecord()
1412
void Dbdict::initRetrieveRecord(Signal* signal, Uint32 i, Uint32 returnCode)
1414
c_retrieveRecord.busyState = false;
1415
c_retrieveRecord.blockRef = 0;
1416
c_retrieveRecord.m_senderData = RNIL;
1417
c_retrieveRecord.tableId = RNIL;
1418
c_retrieveRecord.currentSent = 0;
1419
c_retrieveRecord.retrievedNoOfPages = 0;
1420
c_retrieveRecord.retrievedNoOfWords = 0;
1421
c_retrieveRecord.m_useLongSig = false;
1422
}//initRetrieveRecord()
1424
void Dbdict::initSchemaRecord()
1426
c_schemaRecord.schemaPage = RNIL;
1427
c_schemaRecord.oldSchemaPage = RNIL;
1428
}//Dbdict::initSchemaRecord()
1430
void Dbdict::initRestartRecord()
1432
c_restartRecord.gciToRestart = 0;
1433
c_restartRecord.activeTable = ZNIL;
1434
}//Dbdict::initRestartRecord()
1436
void Dbdict::initNodeRecords()
1439
for (unsigned i = 1; i < MAX_NODES; i++) {
1440
NodeRecordPtr nodePtr;
1441
c_nodes.getPtr(nodePtr, i);
1442
nodePtr.p->hotSpare = false;
1443
nodePtr.p->nodeState = NodeRecord::API_NODE;
1445
}//Dbdict::initNodeRecords()
1447
void Dbdict::initPageRecords()
1449
c_retrieveRecord.retrievePage = ZMAX_PAGES_OF_TABLE_DEFINITION;
1450
ndbrequire(ZNUMBER_OF_PAGES >= (ZMAX_PAGES_OF_TABLE_DEFINITION + 1));
1451
c_schemaRecord.schemaPage = 0;
1452
c_schemaRecord.oldSchemaPage = NDB_SF_MAX_PAGES;
1453
}//Dbdict::initPageRecords()
1455
void Dbdict::initTableRecords()
1457
TableRecordPtr tablePtr;
1460
refresh_watch_dog();
1461
c_tableRecordPool.seize(tablePtr);
1462
if (tablePtr.i == RNIL) {
1466
initialiseTableRecord(tablePtr);
1468
}//Dbdict::initTableRecords()
1470
void Dbdict::initialiseTableRecord(TableRecordPtr tablePtr)
1472
tablePtr.p->activePage = RNIL;
1473
tablePtr.p->filePtr[0] = RNIL;
1474
tablePtr.p->filePtr[1] = RNIL;
1475
tablePtr.p->firstAttribute = RNIL;
1476
tablePtr.p->firstPage = RNIL;
1477
tablePtr.p->lastAttribute = RNIL;
1478
tablePtr.p->tableId = tablePtr.i;
1479
tablePtr.p->tableVersion = (Uint32)-1;
1480
tablePtr.p->tabState = TableRecord::NOT_DEFINED;
1481
tablePtr.p->tabReturnState = TableRecord::TRS_IDLE;
1482
tablePtr.p->fragmentType = DictTabInfo::AllNodesSmallTable;
1483
memset(tablePtr.p->tableName, 0, sizeof(tablePtr.p->tableName));
1484
tablePtr.p->gciTableCreated = 0;
1485
tablePtr.p->noOfAttributes = ZNIL;
1486
tablePtr.p->noOfNullAttr = 0;
1487
tablePtr.p->frmLen = 0;
1488
memset(tablePtr.p->frmData, 0, sizeof(tablePtr.p->frmData));
1490
tablePtr.p->lh3PageIndexBits = 0;
1491
tablePtr.p->lh3DistrBits = 0;
1492
tablePtr.p->lh3PageBits = 6;
1494
tablePtr.p->kValue = 6;
1495
tablePtr.p->localKeyLen = 1;
1496
tablePtr.p->maxLoadFactor = 80;
1497
tablePtr.p->minLoadFactor = 70;
1498
tablePtr.p->noOfPrimkey = 1;
1499
tablePtr.p->tupKeyLength = 1;
1500
tablePtr.p->maxRowsLow = 0;
1501
tablePtr.p->maxRowsHigh = 0;
1502
tablePtr.p->minRowsLow = 0;
1503
tablePtr.p->minRowsHigh = 0;
1504
tablePtr.p->storedTable = true;
1505
tablePtr.p->tableType = DictTabInfo::UserTable;
1506
tablePtr.p->primaryTableId = RNIL;
1507
// volatile elements
1508
tablePtr.p->indexState = TableRecord::IS_UNDEFINED;
1509
tablePtr.p->insertTriggerId = RNIL;
1510
tablePtr.p->updateTriggerId = RNIL;
1511
tablePtr.p->deleteTriggerId = RNIL;
1512
tablePtr.p->customTriggerId = RNIL;
1513
tablePtr.p->buildTriggerId = RNIL;
1514
tablePtr.p->indexLocal = 0;
1515
}//Dbdict::initialiseTableRecord()
1517
void Dbdict::initTriggerRecords()
1519
TriggerRecordPtr triggerPtr;
1522
refresh_watch_dog();
1523
c_triggerRecordPool.seize(triggerPtr);
1524
if (triggerPtr.i == RNIL) {
1528
initialiseTriggerRecord(triggerPtr);
1532
void Dbdict::initialiseTriggerRecord(TriggerRecordPtr triggerPtr)
1534
triggerPtr.p->triggerState = TriggerRecord::TS_NOT_DEFINED;
1535
triggerPtr.p->triggerLocal = 0;
1536
memset(triggerPtr.p->triggerName, 0, sizeof(triggerPtr.p->triggerName));
1537
triggerPtr.p->triggerId = RNIL;
1538
triggerPtr.p->tableId = RNIL;
1539
triggerPtr.p->triggerType = (TriggerType::Value)~0;
1540
triggerPtr.p->triggerActionTime = (TriggerActionTime::Value)~0;
1541
triggerPtr.p->triggerEvent = (TriggerEvent::Value)~0;
1542
triggerPtr.p->monitorReplicas = false;
1543
triggerPtr.p->monitorAllAttributes = false;
1544
triggerPtr.p->attributeMask.clear();
1545
triggerPtr.p->indexId = RNIL;
1548
Uint32 Dbdict::getFsConnRecord()
1550
FsConnectRecordPtr fsPtr;
1551
c_fsConnectRecordPool.seize(fsPtr);
1552
ndbrequire(fsPtr.i != RNIL);
1553
fsPtr.p->filePtr = (Uint32)-1;
1554
fsPtr.p->ownerPtr = RNIL;
1555
fsPtr.p->fsState = FsConnectRecord::IDLE;
1557
}//Dbdict::getFsConnRecord()
1559
Uint32 Dbdict::getFreeTableRecord(Uint32 primaryTableId)
1561
Uint32 minId = (primaryTableId == RNIL ? 0 : primaryTableId + 1);
1562
TableRecordPtr tablePtr;
1563
TableRecordPtr firstTablePtr;
1564
bool firstFound = false;
1565
Uint32 tabSize = c_tableRecordPool.getSize();
1566
for (tablePtr.i = minId; tablePtr.i < tabSize ; tablePtr.i++) {
1568
c_tableRecordPool.getPtr(tablePtr);
1569
if (tablePtr.p->tabState == TableRecord::NOT_DEFINED) {
1571
initialiseTableRecord(tablePtr);
1572
tablePtr.p->tabState = TableRecord::DEFINING;
1574
firstTablePtr.i = tablePtr.i;
1575
firstTablePtr.p = tablePtr.p;
1583
#ifdef HAVE_TABLE_REORG
1584
bool secondFound = false;
1585
for (tablePtr.i = firstTablePtr.i + 1; tablePtr.i < tabSize ; tablePtr.i++) {
1587
c_tableRecordPool.getPtr(tablePtr);
1588
if (tablePtr.p->tabState == TableRecord::NOT_DEFINED) {
1590
initialiseTableRecord(tablePtr);
1591
tablePtr.p->tabState = TableRecord::REORG_TABLE_PREPARED;
1592
tablePtr.p->secondTable = firstTablePtr.i;
1593
firstTablePtr.p->secondTable = tablePtr.i;
1600
firstTablePtr.p->tabState = TableRecord::NOT_DEFINED;
1604
return firstTablePtr.i;
1605
}//Dbdict::getFreeTableRecord()
1607
Uint32 Dbdict::getFreeTriggerRecord()
1609
const Uint32 size = c_triggerRecordPool.getSize();
1610
TriggerRecordPtr triggerPtr;
1611
for (triggerPtr.i = 0; triggerPtr.i < size; triggerPtr.i++) {
1613
c_triggerRecordPool.getPtr(triggerPtr);
1614
if (triggerPtr.p->triggerState == TriggerRecord::TS_NOT_DEFINED) {
1616
initialiseTriggerRecord(triggerPtr);
1617
return triggerPtr.i;
1624
Dbdict::getNewAttributeRecord(TableRecordPtr tablePtr,
1625
AttributeRecordPtr & attrPtr)
1627
c_attributeRecordPool.seize(attrPtr);
1628
if(attrPtr.i == RNIL){
1632
memset(attrPtr.p->attributeName, 0, sizeof(attrPtr.p->attributeName));
1633
attrPtr.p->attributeDescriptor = 0x00012255; //Default value
1634
attrPtr.p->attributeId = ZNIL;
1635
attrPtr.p->nextAttrInTable = RNIL;
1636
attrPtr.p->tupleKey = 0;
1637
memset(attrPtr.p->defaultValue, 0, sizeof(attrPtr.p->defaultValue));
1639
/* ---------------------------------------------------------------- */
1640
// A free attribute record has been acquired. We will now link it
1641
// to the table record.
1642
/* ---------------------------------------------------------------- */
1643
if (tablePtr.p->lastAttribute == RNIL) {
1645
tablePtr.p->firstAttribute = attrPtr.i;
1648
AttributeRecordPtr lastAttrPtr;
1649
c_attributeRecordPool.getPtr(lastAttrPtr, tablePtr.p->lastAttribute);
1650
lastAttrPtr.p->nextAttrInTable = attrPtr.i;
1652
tablePtr.p->lastAttribute = attrPtr.i;
1654
}//Dbdict::getNewAttributeRecord()
1656
/* **************************************************************** */
1657
/* ---------------------------------------------------------------- */
1658
/* MODULE: START/RESTART HANDLING ------------------------ */
1659
/* ---------------------------------------------------------------- */
1661
/* This module contains the code that is common for all */
1662
/* start/restart types. */
1663
/* ---------------------------------------------------------------- */
1664
/* **************************************************************** */
1666
/* ---------------------------------------------------------------- */
1667
// This is sent as the first signal during start/restart.
1668
/* ---------------------------------------------------------------- */
1669
void Dbdict::execSTTOR(Signal* signal)
1672
c_startPhase = signal->theData[1];
1673
switch (c_startPhase) {
1677
c_restartType = signal->theData[7]; /* valid if 3 */
1678
ndbrequire(c_restartType == NodeState::ST_INITIAL_START ||
1679
c_restartType == NodeState::ST_SYSTEM_RESTART ||
1680
c_restartType == NodeState::ST_INITIAL_NODE_RESTART ||
1681
c_restartType == NodeState::ST_NODE_RESTART);
1684
sendSTTORRY(signal);
1687
void Dbdict::sendSTTORRY(Signal* signal)
1689
signal->theData[0] = 0; /* garbage SIGNAL KEY */
1690
signal->theData[1] = 0; /* garbage SIGNAL VERSION NUMBER */
1691
signal->theData[2] = 0; /* garbage */
1692
signal->theData[3] = 1; /* first wanted start phase */
1693
signal->theData[4] = 3; /* get type of start */
1694
signal->theData[5] = ZNOMOREPHASES;
1695
sendSignal(NDBCNTR_REF, GSN_STTORRY, signal, 6, JBB);
1698
/* ---------------------------------------------------------------- */
1699
// We receive information about sizes of records.
1700
/* ---------------------------------------------------------------- */
1701
void Dbdict::execREAD_CONFIG_REQ(Signal* signal)
1703
const ReadConfigReq * req = (ReadConfigReq*)signal->getDataPtr();
1704
Uint32 ref = req->senderRef;
1705
Uint32 senderData = req->senderData;
1706
ndbrequire(req->noOfParameters == 0);
1710
const ndb_mgm_configuration_iterator * p =
1711
theConfiguration.getOwnConfigIterator();
1714
Uint32 attributesize, tablerecSize;
1715
ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_DICT_ATTRIBUTE,&attributesize));
1716
ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_DICT_TABLE, &tablerecSize));
1718
c_attributeRecordPool.setSize(attributesize);
1719
c_attributeRecordHash.setSize(64);
1720
c_fsConnectRecordPool.setSize(ZFS_CONNECT_SIZE);
1721
c_nodes.setSize(MAX_NODES);
1722
c_pageRecordArray.setSize(ZNUMBER_OF_PAGES);
1723
c_schemaPageRecordArray.setSize(2 * NDB_SF_MAX_PAGES);
1724
c_tableRecordPool.setSize(tablerecSize);
1725
c_tableRecordHash.setSize(tablerecSize);
1726
g_key_descriptor_pool.setSize(tablerecSize);
1727
c_triggerRecordPool.setSize(c_maxNoOfTriggers);
1728
c_triggerRecordHash.setSize(c_maxNoOfTriggers);
1729
c_opRecordPool.setSize(256); // XXX need config params
1730
c_opCreateTable.setSize(8);
1731
c_opDropTable.setSize(8);
1732
c_opCreateIndex.setSize(8);
1733
c_opDropIndex.setSize(8);
1734
c_opAlterIndex.setSize(8);
1735
c_opBuildIndex.setSize(8);
1736
c_opCreateTrigger.setSize(8);
1737
c_opDropTrigger.setSize(8);
1738
c_opAlterTrigger.setSize(8);
1740
c_dictLockPool.setSize(32);
1742
// Initialize schema file copies
1743
c_schemaFile[0].schemaPage =
1744
(SchemaFile*)c_schemaPageRecordArray.getPtr(0 * NDB_SF_MAX_PAGES);
1745
c_schemaFile[0].noOfPages = 0;
1746
c_schemaFile[1].schemaPage =
1747
(SchemaFile*)c_schemaPageRecordArray.getPtr(1 * NDB_SF_MAX_PAGES);
1748
c_schemaFile[1].noOfPages = 0;
1750
// Initialize BAT for interface to file system
1751
NewVARIABLE* bat = allocateBat(2);
1752
bat[0].WA = &c_schemaPageRecordArray.getPtr(0)->word[0];
1753
bat[0].nrr = 2 * NDB_SF_MAX_PAGES;
1754
bat[0].ClusterSize = NDB_SF_PAGE_SIZE;
1755
bat[0].bits.q = NDB_SF_PAGE_SIZE_IN_WORDS_LOG2;
1756
bat[0].bits.v = 5; // 32 bits per element
1757
bat[1].WA = &c_pageRecordArray.getPtr(0)->word[0];
1758
bat[1].nrr = ZNUMBER_OF_PAGES;
1759
bat[1].ClusterSize = ZSIZE_OF_PAGES_IN_WORDS * 4;
1760
bat[1].bits.q = ZLOG_SIZE_OF_PAGES_IN_WORDS; // 2**13 = 8192 elements
1761
bat[1].bits.v = 5; // 32 bits per element
1766
ReadConfigConf * conf = (ReadConfigConf*)signal->getDataPtrSend();
1767
conf->senderRef = reference();
1768
conf->senderData = senderData;
1769
sendSignal(ref, GSN_READ_CONFIG_CONF, signal,
1770
ReadConfigConf::SignalLength, JBB);
1771
}//execSIZEALT_REP()
1773
/* ---------------------------------------------------------------- */
1774
// Start phase signals sent by CNTR. We reply with NDB_STTORRY when
1775
// we completed this phase.
1776
/* ---------------------------------------------------------------- */
1777
void Dbdict::execNDB_STTOR(Signal* signal)
1780
c_startPhase = signal->theData[2];
1781
const Uint32 restartType = signal->theData[3];
1782
if (restartType == NodeState::ST_INITIAL_START) {
1784
c_initialStart = true;
1785
} else if (restartType == NodeState::ST_SYSTEM_RESTART) {
1787
c_systemRestart = true;
1788
} else if (restartType == NodeState::ST_INITIAL_NODE_RESTART) {
1790
c_initialNodeRestart = true;
1791
} else if (restartType == NodeState::ST_NODE_RESTART) {
1793
c_nodeRestart = true;
1797
switch (c_startPhase) {
1800
initSchemaFile(signal);
1804
signal->theData[0] = reference();
1805
sendSignal(NDBCNTR_REF, GSN_READ_NODESREQ, signal, 1, JBB);
1809
c_initialStart = false;
1810
c_systemRestart = false;
1811
c_initialNodeRestart = false;
1812
c_nodeRestart = false;
1813
sendNDB_STTORRY(signal);
1816
// uses c_restartType
1817
if(restartType == NodeState::ST_SYSTEM_RESTART &&
1818
c_masterNodeId == getOwnNodeId()){
1819
rebuildIndexes(signal, 0);
1822
sendNDB_STTORRY(signal);
1826
sendNDB_STTORRY(signal);
1831
void Dbdict::sendNDB_STTORRY(Signal* signal)
1833
signal->theData[0] = reference();
1834
sendSignal(NDBCNTR_REF, GSN_NDB_STTORRY, signal, 1, JBB);
1836
}//sendNDB_STTORRY()
1838
/* ---------------------------------------------------------------- */
1839
// We receive the information about which nodes that are up and down.
1840
/* ---------------------------------------------------------------- */
1841
void Dbdict::execREAD_NODESCONF(Signal* signal)
1845
ReadNodesConf * const readNodes = (ReadNodesConf *)&signal->theData[0];
1846
c_numberNode = readNodes->noOfNodes;
1847
c_masterNodeId = readNodes->masterNodeId;
1849
c_noNodesFailed = 0;
1850
c_aliveNodes.clear();
1851
for (unsigned i = 1; i < MAX_NDB_NODES; i++) {
1853
NodeRecordPtr nodePtr;
1854
c_nodes.getPtr(nodePtr, i);
1856
if (NodeBitmask::get(readNodes->allNodes, i)) {
1858
nodePtr.p->nodeState = NodeRecord::NDB_NODE_ALIVE;
1859
if (NodeBitmask::get(readNodes->inactiveNodes, i)) {
1861
/**-------------------------------------------------------------------
1863
* THIS NODE IS DEFINED IN THE CLUSTER BUT IS NOT ALIVE CURRENTLY.
1864
* WE ADD THE NODE TO THE SET OF FAILED NODES AND ALSO SET THE
1865
* BLOCKSTATE TO BUSY TO AVOID ADDING TABLES WHILE NOT ALL NODES ARE
1867
*------------------------------------------------------------------*/
1868
nodePtr.p->nodeState = NodeRecord::NDB_NODE_DEAD;
1871
c_aliveNodes.set(i);
1875
sendNDB_STTORRY(signal);
1876
}//execREAD_NODESCONF()
1878
/* ---------------------------------------------------------------- */
1879
// HOT_SPAREREP informs DBDICT about which nodes that have become
1881
/* ---------------------------------------------------------------- */
1882
void Dbdict::execHOT_SPAREREP(Signal* signal)
1884
Uint32 hotSpareNodes = 0;
1886
HotSpareRep * const hotSpare = (HotSpareRep*)&signal->theData[0];
1887
for (unsigned i = 1; i < MAX_NDB_NODES; i++) {
1888
if (NodeBitmask::get(hotSpare->theHotSpareNodes, i)) {
1889
NodeRecordPtr nodePtr;
1890
c_nodes.getPtr(nodePtr, i);
1891
nodePtr.p->hotSpare = true;
1895
ndbrequire(hotSpareNodes == hotSpare->noHotSpareNodes);
1896
c_noHotSpareNodes = hotSpareNodes;
1898
}//execHOT_SPAREREP()
1900
void Dbdict::initSchemaFile(Signal* signal)
1902
XSchemaFile * xsf = &c_schemaFile[c_schemaRecord.schemaPage != 0];
1903
xsf->noOfPages = (c_tableRecordPool.getSize() + NDB_SF_PAGE_ENTRIES - 1)
1904
/ NDB_SF_PAGE_ENTRIES;
1905
initSchemaFile(xsf, 0, xsf->noOfPages, true);
1906
// init alt copy too for INR
1907
XSchemaFile * oldxsf = &c_schemaFile[c_schemaRecord.oldSchemaPage != 0];
1908
oldxsf->noOfPages = xsf->noOfPages;
1909
memcpy(&oldxsf->schemaPage[0], &xsf->schemaPage[0], xsf->schemaPage[0].FileSize);
1911
if (c_initialStart || c_initialNodeRestart) {
1913
ndbrequire(c_writeSchemaRecord.inUse == false);
1914
c_writeSchemaRecord.inUse = true;
1915
c_writeSchemaRecord.pageId = c_schemaRecord.schemaPage;
1916
c_writeSchemaRecord.newFile = true;
1917
c_writeSchemaRecord.firstPage = 0;
1918
c_writeSchemaRecord.noOfPages = xsf->noOfPages;
1920
c_writeSchemaRecord.m_callback.m_callbackFunction =
1921
safe_cast(&Dbdict::initSchemaFile_conf);
1923
startWriteSchemaFile(signal);
1924
} else if (c_systemRestart || c_nodeRestart) {
1926
ndbrequire(c_readSchemaRecord.schemaReadState == ReadSchemaRecord::IDLE);
1927
c_readSchemaRecord.pageId = c_schemaRecord.oldSchemaPage;
1928
c_readSchemaRecord.firstPage = 0;
1929
c_readSchemaRecord.noOfPages = 1;
1930
c_readSchemaRecord.schemaReadState = ReadSchemaRecord::INITIAL_READ_HEAD;
1931
startReadSchemaFile(signal);
1935
}//Dbdict::initSchemaFile()
1938
Dbdict::initSchemaFile_conf(Signal* signal, Uint32 callbackData, Uint32 rv){
1940
sendNDB_STTORRY(signal);
1944
Dbdict::activateIndexes(Signal* signal, Uint32 i)
1946
AlterIndxReq* req = (AlterIndxReq*)signal->getDataPtrSend();
1947
TableRecordPtr tablePtr;
1948
for (; i < c_tableRecordPool.getSize(); i++) {
1950
c_tableRecordPool.getPtr(tablePtr);
1951
if (tablePtr.p->tabState != TableRecord::DEFINED)
1953
if (! tablePtr.p->isIndex())
1956
req->setUserRef(reference());
1957
req->setConnectionPtr(i);
1958
req->setTableId(tablePtr.p->primaryTableId);
1959
req->setIndexId(tablePtr.i);
1960
req->setIndexVersion(tablePtr.p->tableVersion);
1961
req->setOnline(true);
1962
if (c_restartType == NodeState::ST_SYSTEM_RESTART) {
1963
if (c_masterNodeId != getOwnNodeId())
1965
// from file index state is not defined currently
1966
req->setRequestType(AlterIndxReq::RT_SYSTEMRESTART);
1967
req->addRequestFlag((Uint32)RequestFlag::RF_NOBUILD);
1970
c_restartType == NodeState::ST_NODE_RESTART ||
1971
c_restartType == NodeState::ST_INITIAL_NODE_RESTART) {
1972
// from master index must be online
1973
if (tablePtr.p->indexState != TableRecord::IS_ONLINE)
1975
req->setRequestType(AlterIndxReq::RT_NODERESTART);
1976
// activate locally, rebuild not needed
1977
req->addRequestFlag((Uint32)RequestFlag::RF_LOCAL);
1978
req->addRequestFlag((Uint32)RequestFlag::RF_NOBUILD);
1982
sendSignal(reference(), GSN_ALTER_INDX_REQ,
1983
signal, AlterIndxReq::SignalLength, JBB);
1986
signal->theData[0] = reference();
1987
sendSignal(c_restartRecord.returnBlockRef, GSN_DICTSTARTCONF,
1992
Dbdict::rebuildIndexes(Signal* signal, Uint32 i){
1993
BuildIndxReq* const req = (BuildIndxReq*)signal->getDataPtrSend();
1995
TableRecordPtr indexPtr;
1996
for (; i < c_tableRecordPool.getSize(); i++) {
1998
c_tableRecordPool.getPtr(indexPtr);
1999
if (indexPtr.p->tabState != TableRecord::DEFINED)
2001
if (! indexPtr.p->isIndex())
2006
req->setUserRef(reference());
2007
req->setConnectionPtr(i);
2008
req->setRequestType(BuildIndxReq::RT_SYSTEMRESTART);
2009
req->setBuildId(0); // not used
2010
req->setBuildKey(0); // not used
2011
req->setIndexType(indexPtr.p->tableType);
2012
req->setIndexId(indexPtr.i);
2013
req->setTableId(indexPtr.p->primaryTableId);
2014
req->setParallelism(16);
2016
// from file index state is not defined currently
2017
if (indexPtr.p->storedTable) {
2018
// rebuild not needed
2019
req->addRequestFlag((Uint32)RequestFlag::RF_NOBUILD);
2023
sendSignal(reference(), GSN_BUILDINDXREQ,
2024
signal, BuildIndxReq::SignalLength, JBB);
2027
sendNDB_STTORRY(signal);
2031
/* **************************************************************** */
2032
/* ---------------------------------------------------------------- */
2033
/* MODULE: SYSTEM RESTART MODULE ------------------------- */
2034
/* ---------------------------------------------------------------- */
2036
/* This module contains code specific for system restart */
2037
/* ---------------------------------------------------------------- */
2038
/* **************************************************************** */
2040
/* ---------------------------------------------------------------- */
2041
// DIH asks DICT to read in table data from disk during system
2042
// restart. DIH also asks DICT to send information about which
2043
// tables that should be started as part of this system restart.
2044
// DICT will also activate the tables in TC as part of this process.
2045
/* ---------------------------------------------------------------- */
2046
void Dbdict::execDICTSTARTREQ(Signal* signal)
2049
c_restartRecord.gciToRestart = signal->theData[0];
2050
c_restartRecord.returnBlockRef = signal->theData[1];
2051
if (c_nodeRestart || c_initialNodeRestart) {
2054
CRASH_INSERTION(6000);
2056
BlockReference dictRef = calcDictBlockRef(c_masterNodeId);
2057
signal->theData[0] = getOwnNodeId();
2058
sendSignal(dictRef, GSN_GET_SCHEMA_INFOREQ, signal, 1, JBB);
2061
ndbrequire(c_systemRestart);
2062
ndbrequire(c_masterNodeId == getOwnNodeId());
2064
c_schemaRecord.m_callback.m_callbackData = 0;
2065
c_schemaRecord.m_callback.m_callbackFunction =
2066
safe_cast(&Dbdict::masterRestart_checkSchemaStatusComplete);
2068
c_restartRecord.activeTable = 0;
2069
c_schemaRecord.schemaPage = c_schemaRecord.oldSchemaPage; // ugly
2070
checkSchemaStatus(signal);
2071
}//execDICTSTARTREQ()
2074
Dbdict::masterRestart_checkSchemaStatusComplete(Signal* signal,
2075
Uint32 callbackData,
2078
c_schemaRecord.schemaPage = 0; // ugly
2079
XSchemaFile * oldxsf = &c_schemaFile[c_schemaRecord.oldSchemaPage != 0];
2080
ndbrequire(oldxsf->noOfPages != 0);
2082
LinearSectionPtr ptr[3];
2083
ptr[0].p = (Uint32*)&oldxsf->schemaPage[0];
2084
ptr[0].sz = oldxsf->noOfPages * NDB_SF_PAGE_SIZE_IN_WORDS;
2086
c_sendSchemaRecord.m_SCHEMAINFO_Counter = c_aliveNodes;
2087
NodeReceiverGroup rg(DBDICT, c_aliveNodes);
2089
rg.m_nodes.clear(getOwnNodeId());
2090
Callback c = { 0, 0 };
2091
sendFragmentedSignal(rg,
2094
1, //SchemaInfo::SignalLength,
2100
XSchemaFile * newxsf = &c_schemaFile[c_schemaRecord.schemaPage != 0];
2101
newxsf->noOfPages = oldxsf->noOfPages;
2102
memcpy(&newxsf->schemaPage[0], &oldxsf->schemaPage[0],
2103
oldxsf->noOfPages * NDB_SF_PAGE_SIZE);
2105
signal->theData[0] = getOwnNodeId();
2106
sendSignal(reference(), GSN_SCHEMA_INFOCONF, signal, 1, JBB);
2110
Dbdict::execGET_SCHEMA_INFOREQ(Signal* signal){
2112
const Uint32 ref = signal->getSendersBlockRef();
2113
//const Uint32 senderData = signal->theData[0];
2115
ndbrequire(c_sendSchemaRecord.inUse == false);
2116
c_sendSchemaRecord.inUse = true;
2118
LinearSectionPtr ptr[3];
2120
XSchemaFile * xsf = &c_schemaFile[c_schemaRecord.schemaPage != 0];
2121
ndbrequire(xsf->noOfPages != 0);
2123
ptr[0].p = (Uint32*)&xsf->schemaPage[0];
2124
ptr[0].sz = xsf->noOfPages * NDB_SF_PAGE_SIZE_IN_WORDS;
2126
Callback c = { safe_cast(&Dbdict::sendSchemaComplete), 0 };
2127
sendFragmentedSignal(ref,
2130
1, //GetSchemaInfoConf::SignalLength,
2135
}//Dbdict::execGET_SCHEMA_INFOREQ()
2138
Dbdict::sendSchemaComplete(Signal * signal,
2139
Uint32 callbackData,
2141
ndbrequire(c_sendSchemaRecord.inUse == true);
2142
c_sendSchemaRecord.inUse = false;
2147
/* ---------------------------------------------------------------- */
2148
// We receive the schema info from master as part of all restarts
2149
// except the initial start where no tables exists.
2150
/* ---------------------------------------------------------------- */
2151
void Dbdict::execSCHEMA_INFO(Signal* signal)
2154
if(!assembleFragments(signal)){
2159
if(getNodeState().getNodeRestartInProgress()){
2160
CRASH_INSERTION(6001);
2163
SegmentedSectionPtr schemaDataPtr;
2164
signal->getSection(schemaDataPtr, 0);
2166
XSchemaFile * xsf = &c_schemaFile[c_schemaRecord.schemaPage != 0];
2167
ndbrequire(schemaDataPtr.sz % NDB_SF_PAGE_SIZE_IN_WORDS == 0);
2168
xsf->noOfPages = schemaDataPtr.sz / NDB_SF_PAGE_SIZE_IN_WORDS;
2169
copy((Uint32*)&xsf->schemaPage[0], schemaDataPtr);
2170
releaseSections(signal);
2172
SchemaFile * sf0 = &xsf->schemaPage[0];
2173
if (sf0->NdbVersion < NDB_SF_VERSION_5_0_6) {
2174
bool ok = convertSchemaFileTo_5_0_6(xsf);
2178
validateChecksum(xsf);
2180
XSchemaFile * oldxsf = &c_schemaFile[c_schemaRecord.oldSchemaPage != 0];
2181
resizeSchemaFile(xsf, oldxsf->noOfPages);
2183
ndbrequire(signal->getSendersBlockRef() != reference());
2185
/* ---------------------------------------------------------------- */
2186
// Synchronise our view on data with other nodes in the cluster.
2187
// This is an important part of restart handling where we will handle
2188
// cases where the table have been added but only partially, where
2189
// tables have been deleted but not completed the deletion yet and
2190
// other scenarios needing synchronisation.
2191
/* ---------------------------------------------------------------- */
2192
c_schemaRecord.m_callback.m_callbackData = 0;
2193
c_schemaRecord.m_callback.m_callbackFunction =
2194
safe_cast(&Dbdict::restart_checkSchemaStatusComplete);
2195
c_restartRecord.activeTable = 0;
2196
checkSchemaStatus(signal);
2197
}//execSCHEMA_INFO()
2200
Dbdict::restart_checkSchemaStatusComplete(Signal * signal,
2201
Uint32 callbackData,
2204
ndbrequire(c_writeSchemaRecord.inUse == false);
2205
c_writeSchemaRecord.inUse = true;
2206
XSchemaFile * xsf = &c_schemaFile[c_schemaRecord.schemaPage != 0];
2207
c_writeSchemaRecord.pageId = c_schemaRecord.schemaPage;
2208
c_writeSchemaRecord.newFile = true;
2209
c_writeSchemaRecord.firstPage = 0;
2210
c_writeSchemaRecord.noOfPages = xsf->noOfPages;
2211
c_writeSchemaRecord.m_callback.m_callbackData = 0;
2212
c_writeSchemaRecord.m_callback.m_callbackFunction =
2213
safe_cast(&Dbdict::restart_writeSchemaConf);
2215
startWriteSchemaFile(signal);
2219
Dbdict::restart_writeSchemaConf(Signal * signal,
2220
Uint32 callbackData,
2223
if(c_systemRestart){
2225
signal->theData[0] = getOwnNodeId();
2226
sendSignal(calcDictBlockRef(c_masterNodeId), GSN_SCHEMA_INFOCONF,
2231
ndbrequire(c_nodeRestart || c_initialNodeRestart);
2232
c_blockState = BS_IDLE;
2233
activateIndexes(signal, 0);
2237
void Dbdict::execSCHEMA_INFOCONF(Signal* signal)
2240
ndbrequire(signal->getNoOfSections() == 0);
2242
/* ---------------------------------------------------------------- */
2243
// This signal is received in the master as part of system restart
2244
// from all nodes (including the master) after they have synchronised
2245
// their data with the master node's schema information.
2246
/* ---------------------------------------------------------------- */
2247
const Uint32 nodeId = signal->theData[0];
2248
c_sendSchemaRecord.m_SCHEMAINFO_Counter.clearWaitingFor(nodeId);
2250
if (!c_sendSchemaRecord.m_SCHEMAINFO_Counter.done()){
2254
activateIndexes(signal, 0);
2255
}//execSCHEMA_INFOCONF()
2257
void Dbdict::checkSchemaStatus(Signal* signal)
2259
XSchemaFile * newxsf = &c_schemaFile[c_schemaRecord.schemaPage != 0];
2260
XSchemaFile * oldxsf = &c_schemaFile[c_schemaRecord.oldSchemaPage != 0];
2261
ndbrequire(newxsf->noOfPages == oldxsf->noOfPages);
2262
const Uint32 noOfEntries = newxsf->noOfPages * NDB_SF_PAGE_ENTRIES;
2264
for (; c_restartRecord.activeTable < noOfEntries;
2265
c_restartRecord.activeTable++) {
2268
Uint32 tableId = c_restartRecord.activeTable;
2269
SchemaFile::TableEntry *newEntry = getTableEntry(newxsf, tableId);
2270
SchemaFile::TableEntry *oldEntry = getTableEntry(oldxsf, tableId);
2271
SchemaFile::TableState schemaState =
2272
(SchemaFile::TableState)newEntry->m_tableState;
2273
SchemaFile::TableState oldSchemaState =
2274
(SchemaFile::TableState)oldEntry->m_tableState;
2276
if (c_restartRecord.activeTable >= c_tableRecordPool.getSize()) {
2278
ndbrequire(schemaState == SchemaFile::INIT);
2279
ndbrequire(oldSchemaState == SchemaFile::INIT);
2283
switch(schemaState){
2284
case SchemaFile::INIT:{
2287
switch(oldSchemaState) {
2288
case SchemaFile::INIT:
2290
case SchemaFile::DROP_TABLE_COMMITTED:
2296
case SchemaFile::ADD_STARTED:
2298
case SchemaFile::TABLE_ADD_COMMITTED:
2300
case SchemaFile::DROP_TABLE_STARTED:
2302
case SchemaFile::ALTER_TABLE_COMMITTED:
2306
newEntry->m_tableState = SchemaFile::INIT;
2307
restartDropTab(signal, tableId);
2313
case SchemaFile::ADD_STARTED:{
2316
switch(oldSchemaState) {
2317
case SchemaFile::INIT:
2319
case SchemaFile::DROP_TABLE_COMMITTED:
2323
case SchemaFile::ADD_STARTED:
2325
case SchemaFile::DROP_TABLE_STARTED:
2327
case SchemaFile::TABLE_ADD_COMMITTED:
2329
case SchemaFile::ALTER_TABLE_COMMITTED:
2332
//------------------------------------------------------------------
2333
// Add Table was started but not completed. Will be dropped in all
2334
// nodes. Update schema information (restore table version).
2335
//------------------------------------------------------------------
2336
newEntry->m_tableState = SchemaFile::INIT;
2337
restartDropTab(signal, tableId);
2343
case SchemaFile::TABLE_ADD_COMMITTED:{
2346
switch(oldSchemaState) {
2347
case SchemaFile::INIT:
2349
case SchemaFile::ADD_STARTED:
2351
case SchemaFile::DROP_TABLE_STARTED:
2353
case SchemaFile::DROP_TABLE_COMMITTED:
2356
//------------------------------------------------------------------
2357
// Table was added in the master node but not in our node. We can
2358
// retrieve the table definition from the master.
2359
//------------------------------------------------------------------
2360
restartCreateTab(signal, tableId, oldEntry, false);
2363
case SchemaFile::TABLE_ADD_COMMITTED:
2365
case SchemaFile::ALTER_TABLE_COMMITTED:
2368
//------------------------------------------------------------------
2369
// Table was added in both our node and the master node. We can
2370
// retrieve the table definition from our own disk.
2371
//------------------------------------------------------------------
2372
if(* newEntry == * oldEntry){
2375
TableRecordPtr tablePtr;
2376
c_tableRecordPool.getPtr(tablePtr, tableId);
2377
tablePtr.p->tableVersion = oldEntry->m_tableVersion;
2378
tablePtr.p->tableType = (DictTabInfo::TableType)oldEntry->m_tableType;
2380
// On NR get index from master because index state is not on file
2381
const bool file = c_systemRestart || tablePtr.p->isTable();
2382
restartCreateTab(signal, tableId, oldEntry, file);
2386
//------------------------------------------------------------------
2387
// Must be a new version of the table if anything differs. Both table
2388
// version and global checkpoint must be different.
2389
// This should not happen for the master node. This can happen after
2390
// drop table followed by add table or after change table.
2391
// Not supported in this version.
2392
//------------------------------------------------------------------
2393
ndbrequire(c_masterNodeId != getOwnNodeId());
2394
ndbrequire(newEntry->m_tableVersion != oldEntry->m_tableVersion);
2397
restartCreateTab(signal, tableId, oldEntry, false);
2404
case SchemaFile::DROP_TABLE_STARTED:
2406
case SchemaFile::DROP_TABLE_COMMITTED:{
2409
switch(oldSchemaState){
2410
case SchemaFile::INIT:
2412
case SchemaFile::DROP_TABLE_COMMITTED:
2416
case SchemaFile::ADD_STARTED:
2418
case SchemaFile::TABLE_ADD_COMMITTED:
2420
case SchemaFile::DROP_TABLE_STARTED:
2422
case SchemaFile::ALTER_TABLE_COMMITTED:
2424
newEntry->m_tableState = SchemaFile::INIT;
2425
restartDropTab(signal, tableId);
2431
case SchemaFile::ALTER_TABLE_COMMITTED: {
2434
switch(oldSchemaState) {
2435
case SchemaFile::INIT:
2437
case SchemaFile::ADD_STARTED:
2439
case SchemaFile::DROP_TABLE_STARTED:
2441
case SchemaFile::DROP_TABLE_COMMITTED:
2443
case SchemaFile::TABLE_ADD_COMMITTED:
2446
//------------------------------------------------------------------
2447
// Table was altered in the master node but not in our node. We can
2448
// retrieve the altered table definition from the master.
2449
//------------------------------------------------------------------
2450
restartCreateTab(signal, tableId, oldEntry, false);
2453
case SchemaFile::ALTER_TABLE_COMMITTED:
2457
//------------------------------------------------------------------
2458
// Table was altered in both our node and the master node. We can
2459
// retrieve the table definition from our own disk.
2460
//------------------------------------------------------------------
2461
TableRecordPtr tablePtr;
2462
c_tableRecordPool.getPtr(tablePtr, tableId);
2463
tablePtr.p->tableVersion = oldEntry->m_tableVersion;
2464
tablePtr.p->tableType = (DictTabInfo::TableType)oldEntry->m_tableType;
2466
// On NR get index from master because index state is not on file
2467
const bool file = (* newEntry == * oldEntry) &&
2468
(c_systemRestart || tablePtr.p->isTable());
2469
restartCreateTab(signal, tableId, oldEntry, file);
2479
execute(signal, c_schemaRecord.m_callback, 0);
2480
}//checkSchemaStatus()
2483
Dbdict::restartCreateTab(Signal* signal, Uint32 tableId,
2484
const SchemaFile::TableEntry * te, bool file){
2487
CreateTableRecordPtr createTabPtr;
2488
c_opCreateTable.seize(createTabPtr);
2489
ndbrequire(!createTabPtr.isNull());
2491
createTabPtr.p->key = ++c_opRecordSequence;
2492
c_opCreateTable.add(createTabPtr);
2494
createTabPtr.p->m_errorCode = 0;
2495
createTabPtr.p->m_tablePtrI = tableId;
2496
createTabPtr.p->m_coordinatorRef = reference();
2497
createTabPtr.p->m_senderRef = 0;
2498
createTabPtr.p->m_senderData = RNIL;
2499
createTabPtr.p->m_tabInfoPtrI = RNIL;
2500
createTabPtr.p->m_dihAddFragPtr = RNIL;
2502
if(file && !ERROR_INSERTED(6002)){
2505
c_readTableRecord.noOfPages =
2506
DIV(te->m_info_words + ZPAGE_HEADER_SIZE, ZSIZE_OF_PAGES_IN_WORDS);
2507
c_readTableRecord.pageId = 0;
2508
c_readTableRecord.m_callback.m_callbackData = createTabPtr.p->key;
2509
c_readTableRecord.m_callback.m_callbackFunction =
2510
safe_cast(&Dbdict::restartCreateTab_readTableConf);
2512
startReadTableFile(signal, tableId);
2516
ndbrequire(c_masterNodeId != getOwnNodeId());
2521
GetTabInfoReq * const req = (GetTabInfoReq *)&signal->theData[0];
2522
req->senderRef = reference();
2523
req->senderData = createTabPtr.p->key;
2524
req->requestType = GetTabInfoReq::RequestById |
2525
GetTabInfoReq::LongSignalConf;
2526
req->tableId = tableId;
2527
sendSignal(calcDictBlockRef(c_masterNodeId), GSN_GET_TABINFOREQ, signal,
2528
GetTabInfoReq::SignalLength, JBB);
2530
if(ERROR_INSERTED(6002)){
2531
NdbSleep_MilliSleep(10);
2532
CRASH_INSERTION(6002);
2538
Dbdict::restartCreateTab_readTableConf(Signal* signal,
2539
Uint32 callbackData,
2543
PageRecordPtr pageRecPtr;
2544
c_pageRecordArray.getPtr(pageRecPtr, c_readTableRecord.pageId);
2546
ParseDictTabInfoRecord parseRecord;
2547
parseRecord.requestType = DictTabInfo::GetTabInfoConf;
2548
parseRecord.errorCode = 0;
2550
Uint32 sz = c_readTableRecord.noOfPages * ZSIZE_OF_PAGES_IN_WORDS;
2551
SimplePropertiesLinearReader r(&pageRecPtr.p->word[0], sz);
2552
handleTabInfoInit(r, &parseRecord);
2553
if (parseRecord.errorCode != 0)
2556
BaseString::snprintf(buf, sizeof(buf),
2557
"Unable to restart, fail while creating table %d"
2558
" error: %d. Most likely change of configuration",
2559
c_readTableRecord.tableId,
2560
parseRecord.errorCode);
2562
NDBD_EXIT_INVALID_CONFIG,
2564
ndbrequire(parseRecord.errorCode == 0);
2567
/* ---------------------------------------------------------------- */
2568
// We have read the table description from disk as part of system restart.
2569
// We will also write it back again to ensure that both copies are ok.
2570
/* ---------------------------------------------------------------- */
2571
ndbrequire(c_writeTableRecord.tableWriteState == WriteTableRecord::IDLE);
2572
c_writeTableRecord.noOfPages = c_readTableRecord.noOfPages;
2573
c_writeTableRecord.pageId = c_readTableRecord.pageId;
2574
c_writeTableRecord.tableWriteState = WriteTableRecord::TWR_CALLBACK;
2575
c_writeTableRecord.m_callback.m_callbackData = callbackData;
2576
c_writeTableRecord.m_callback.m_callbackFunction =
2577
safe_cast(&Dbdict::restartCreateTab_writeTableConf);
2578
startWriteTableFile(signal, c_readTableRecord.tableId);
2582
Dbdict::execGET_TABINFO_CONF(Signal* signal){
2585
if(!assembleFragments(signal)){
2590
GetTabInfoConf * const conf = (GetTabInfoConf*)signal->getDataPtr();
2592
const Uint32 tableId = conf->tableId;
2593
const Uint32 senderData = conf->senderData;
2595
SegmentedSectionPtr tabInfoPtr;
2596
signal->getSection(tabInfoPtr, GetTabInfoConf::DICT_TAB_INFO);
2598
CreateTableRecordPtr createTabPtr;
2599
ndbrequire(c_opCreateTable.find(createTabPtr, senderData));
2600
ndbrequire(!createTabPtr.isNull());
2601
ndbrequire(createTabPtr.p->m_tablePtrI == tableId);
2604
* Put data into table record
2606
ParseDictTabInfoRecord parseRecord;
2607
parseRecord.requestType = DictTabInfo::GetTabInfoConf;
2608
parseRecord.errorCode = 0;
2610
SimplePropertiesSectionReader r(tabInfoPtr, getSectionSegmentPool());
2611
handleTabInfoInit(r, &parseRecord);
2612
ndbrequire(parseRecord.errorCode == 0);
2615
callback.m_callbackData = createTabPtr.p->key;
2616
callback.m_callbackFunction =
2617
safe_cast(&Dbdict::restartCreateTab_writeTableConf);
2619
signal->header.m_noOfSections = 0;
2620
writeTableFile(signal, createTabPtr.p->m_tablePtrI, tabInfoPtr, &callback);
2621
signal->setSection(tabInfoPtr, 0);
2622
releaseSections(signal);
2626
Dbdict::restartCreateTab_writeTableConf(Signal* signal,
2627
Uint32 callbackData,
2631
CreateTableRecordPtr createTabPtr;
2632
ndbrequire(c_opCreateTable.find(createTabPtr, callbackData));
2635
callback.m_callbackData = callbackData;
2636
callback.m_callbackFunction =
2637
safe_cast(&Dbdict::restartCreateTab_dihComplete);
2639
SegmentedSectionPtr fragDataPtr;
2641
fragDataPtr.setNull();
2642
createTab_dih(signal, createTabPtr, fragDataPtr, &callback);
2646
Dbdict::restartCreateTab_dihComplete(Signal* signal,
2647
Uint32 callbackData,
2651
CreateTableRecordPtr createTabPtr;
2652
ndbrequire(c_opCreateTable.find(createTabPtr, callbackData));
2655
ndbrequire(createTabPtr.p->m_errorCode == 0);
2658
callback.m_callbackData = callbackData;
2659
callback.m_callbackFunction =
2660
safe_cast(&Dbdict::restartCreateTab_activateComplete);
2662
alterTab_activate(signal, createTabPtr, &callback);
2666
Dbdict::restartCreateTab_activateComplete(Signal* signal,
2667
Uint32 callbackData,
2671
CreateTableRecordPtr createTabPtr;
2672
ndbrequire(c_opCreateTable.find(createTabPtr, callbackData));
2674
TableRecordPtr tabPtr;
2675
c_tableRecordPool.getPtr(tabPtr, createTabPtr.p->m_tablePtrI);
2676
tabPtr.p->tabState = TableRecord::DEFINED;
2678
c_opCreateTable.release(createTabPtr);
2680
c_restartRecord.activeTable++;
2681
checkSchemaStatus(signal);
2685
Dbdict::restartDropTab(Signal* signal, Uint32 tableId){
2687
const Uint32 key = ++c_opRecordSequence;
2689
DropTableRecordPtr dropTabPtr;
2690
ndbrequire(c_opDropTable.seize(dropTabPtr));
2692
dropTabPtr.p->key = key;
2693
c_opDropTable.add(dropTabPtr);
2695
dropTabPtr.p->m_errorCode = 0;
2696
dropTabPtr.p->m_request.tableId = tableId;
2697
dropTabPtr.p->m_coordinatorRef = 0;
2698
dropTabPtr.p->m_requestType = DropTabReq::RestartDropTab;
2699
dropTabPtr.p->m_participantData.m_gsn = GSN_DROP_TAB_REQ;
2702
dropTabPtr.p->m_participantData.m_block = 0;
2703
dropTabPtr.p->m_participantData.m_callback.m_callbackData = key;
2704
dropTabPtr.p->m_participantData.m_callback.m_callbackFunction =
2705
safe_cast(&Dbdict::restartDropTab_complete);
2706
dropTab_nextStep(signal, dropTabPtr);
2710
Dbdict::restartDropTab_complete(Signal* signal,
2711
Uint32 callbackData,
2715
DropTableRecordPtr dropTabPtr;
2716
ndbrequire(c_opDropTable.find(dropTabPtr, callbackData));
2720
c_opDropTable.release(dropTabPtr);
2722
c_restartRecord.activeTable++;
2723
checkSchemaStatus(signal);
2726
/* **************************************************************** */
2727
/* ---------------------------------------------------------------- */
2728
/* MODULE: NODE FAILURE HANDLING ------------------------- */
2729
/* ---------------------------------------------------------------- */
2731
/* This module contains the code that is used when nodes */
2732
/* (kernel/api) fails. */
2733
/* ---------------------------------------------------------------- */
2734
/* **************************************************************** */
2736
/* ---------------------------------------------------------------- */
2737
// We receive a report of an API that failed.
2738
/* ---------------------------------------------------------------- */
2739
void Dbdict::execAPI_FAILREQ(Signal* signal)
2742
Uint32 failedApiNode = signal->theData[0];
2743
BlockReference retRef = signal->theData[1];
2746
Uint32 userNode = refToNode(c_connRecord.userBlockRef);
2747
if (userNode == failedApiNode) {
2749
c_connRecord.userBlockRef = (Uint32)-1;
2753
signal->theData[0] = failedApiNode;
2754
signal->theData[1] = reference();
2755
sendSignal(retRef, GSN_API_FAILCONF, signal, 2, JBB);
2756
}//execAPI_FAILREQ()
2758
/* ---------------------------------------------------------------- */
2759
// We receive a report of one or more node failures of kernel nodes.
2760
/* ---------------------------------------------------------------- */
2761
void Dbdict::execNODE_FAILREP(Signal* signal)
2764
NodeFailRep * const nodeFail = (NodeFailRep *)&signal->theData[0];
2766
c_failureNr = nodeFail->failNo;
2767
const Uint32 numberOfFailedNodes = nodeFail->noOfNodes;
2768
const bool masterFailed = (c_masterNodeId != nodeFail->masterNodeId);
2769
c_masterNodeId = nodeFail->masterNodeId;
2771
c_noNodesFailed += numberOfFailedNodes;
2772
Uint32 theFailedNodes[NodeBitmask::Size];
2773
memcpy(theFailedNodes, nodeFail->theNodes, sizeof(theFailedNodes));
2775
c_counterMgr.execNODE_FAILREP(signal);
2778
switch(c_blockState){
2782
if(c_opRecordPool.getSize() != c_opRecordPool.getNoOfFree()){
2784
c_blockState = BS_NODE_FAILURE;
2794
case BS_NODE_FAILURE:
2796
c_blockState = BS_NODE_FAILURE;
2799
case BS_NODE_RESTART:
2806
for(unsigned i = 1; i < MAX_NDB_NODES; i++) {
2808
if(NodeBitmask::get(theFailedNodes, i)) {
2810
NodeRecordPtr nodePtr;
2811
c_nodes.getPtr(nodePtr, i);
2813
nodePtr.p->nodeState = NodeRecord::NDB_NODE_DEAD;
2814
NFCompleteRep * const nfCompRep = (NFCompleteRep *)&signal->theData[0];
2815
nfCompRep->blockNo = DBDICT;
2816
nfCompRep->nodeId = getOwnNodeId();
2817
nfCompRep->failedNodeId = nodePtr.i;
2818
sendSignal(DBDIH_REF, GSN_NF_COMPLETEREP, signal,
2819
NFCompleteRep::SignalLength, JBB);
2821
c_aliveNodes.clear(i);
2826
* NODE_FAILREP guarantees that no "in flight" signal from
2827
* a dead node is accepted, and also that the job buffer contains
2828
* no such (un-executed) signals. Therefore no DICT_UNLOCK_ORD
2829
* from a dead node (leading to master crash) is possible after
2830
* this clean-up removes the lock record.
2832
removeStaleDictLocks(signal, theFailedNodes);
2834
}//execNODE_FAILREP()
2837
/* **************************************************************** */
2838
/* ---------------------------------------------------------------- */
2839
/* MODULE: NODE START HANDLING --------------------------- */
2840
/* ---------------------------------------------------------------- */
2842
/* This module contains the code that is used when kernel nodes */
2844
/* ---------------------------------------------------------------- */
2845
/* **************************************************************** */
2847
/* ---------------------------------------------------------------- */
2848
// Include a starting node in list of nodes to be part of adding
2849
// and dropping tables.
2850
/* ---------------------------------------------------------------- */
2851
void Dbdict::execINCL_NODEREQ(Signal* signal)
2854
NodeRecordPtr nodePtr;
2855
BlockReference retRef = signal->theData[0];
2856
nodePtr.i = signal->theData[1];
2858
ndbrequire(c_noNodesFailed > 0);
2861
c_nodes.getPtr(nodePtr);
2862
ndbrequire(nodePtr.p->nodeState == NodeRecord::NDB_NODE_DEAD);
2863
nodePtr.p->nodeState = NodeRecord::NDB_NODE_ALIVE;
2864
signal->theData[0] = reference();
2865
sendSignal(retRef, GSN_INCL_NODECONF, signal, 1, JBB);
2867
c_aliveNodes.set(nodePtr.i);
2868
}//execINCL_NODEREQ()
2870
/* **************************************************************** */
2871
/* ---------------------------------------------------------------- */
2872
/* MODULE: ADD TABLE HANDLING ---------------------------- */
2873
/* ---------------------------------------------------------------- */
2875
/* This module contains the code that is used when adding a table. */
2876
/* ---------------------------------------------------------------- */
2877
/* **************************************************************** */
2879
/* ---------------------------------------------------------------- */
2880
// This signal receives information about a table from either:
2881
// API, Ndbcntr or from other DICT.
2882
/* ---------------------------------------------------------------- */
2884
Dbdict::execCREATE_TABLE_REQ(Signal* signal){
2886
if(!assembleFragments(signal)){
2890
CreateTableReq* const req = (CreateTableReq*)signal->getDataPtr();
2891
const Uint32 senderRef = req->senderRef;
2892
const Uint32 senderData = req->senderData;
2894
ParseDictTabInfoRecord parseRecord;
2896
if(getOwnNodeId() != c_masterNodeId){
2898
parseRecord.errorCode = CreateTableRef::NotMaster;
2902
if (c_blockState == BS_NODE_RESTART){
2904
parseRecord.errorCode = CreateTableRef::BusyWithNR;
2908
if (c_blockState != BS_IDLE){
2910
parseRecord.errorCode = CreateTableRef::Busy;
2914
CreateTableRecordPtr createTabPtr;
2915
c_opCreateTable.seize(createTabPtr);
2917
if(createTabPtr.isNull()){
2919
parseRecord.errorCode = CreateTableRef::Busy;
2923
parseRecord.requestType = DictTabInfo::CreateTableFromAPI;
2924
parseRecord.errorCode = 0;
2926
SegmentedSectionPtr ptr;
2927
signal->getSection(ptr, CreateTableReq::DICT_TAB_INFO);
2928
SimplePropertiesSectionReader r(ptr, getSectionSegmentPool());
2930
handleTabInfoInit(r, &parseRecord);
2931
releaseSections(signal);
2933
if(parseRecord.errorCode != 0){
2935
c_opCreateTable.release(createTabPtr);
2939
createTabPtr.p->key = ++c_opRecordSequence;
2940
c_opCreateTable.add(createTabPtr);
2941
createTabPtr.p->m_errorCode = 0;
2942
createTabPtr.p->m_senderRef = senderRef;
2943
createTabPtr.p->m_senderData = senderData;
2944
createTabPtr.p->m_tablePtrI = parseRecord.tablePtr.i;
2945
createTabPtr.p->m_coordinatorRef = reference();
2946
createTabPtr.p->m_fragmentsPtrI = RNIL;
2947
createTabPtr.p->m_dihAddFragPtr = RNIL;
2949
Uint32 * theData = signal->getDataPtrSend();
2950
CreateFragmentationReq * const req = (CreateFragmentationReq*)theData;
2951
req->senderRef = reference();
2952
req->senderData = createTabPtr.p->key;
2953
req->fragmentationType = parseRecord.tablePtr.p->fragmentType;
2954
req->noOfFragments = 0;
2955
req->fragmentNode = 0;
2956
req->primaryTableId = RNIL;
2957
if (parseRecord.tablePtr.p->isOrderedIndex()) {
2958
// ordered index has same fragmentation as the table
2959
const Uint32 primaryTableId = parseRecord.tablePtr.p->primaryTableId;
2960
TableRecordPtr primaryTablePtr;
2961
c_tableRecordPool.getPtr(primaryTablePtr, primaryTableId);
2962
// fragmentationType must be consistent
2963
req->fragmentationType = primaryTablePtr.p->fragmentType;
2964
req->primaryTableId = primaryTableId;
2966
sendSignal(DBDIH_REF, GSN_CREATE_FRAGMENTATION_REQ, signal,
2967
CreateFragmentationReq::SignalLength, JBB);
2969
c_blockState = BS_CREATE_TAB;
2974
* Something went wrong
2976
releaseSections(signal);
2978
CreateTableRef * ref = (CreateTableRef*)signal->getDataPtrSend();
2979
ref->senderData = senderData;
2980
ref->senderRef = reference();
2981
ref->masterNodeId = c_masterNodeId;
2982
ref->errorCode = parseRecord.errorCode;
2983
ref->errorLine = parseRecord.errorLine;
2984
ref->errorKey = parseRecord.errorKey;
2985
ref->status = parseRecord.status;
2986
sendSignal(senderRef, GSN_CREATE_TABLE_REF, signal,
2987
CreateTableRef::SignalLength, JBB);
2991
Dbdict::execBACKUP_FRAGMENT_REQ(Signal* signal)
2994
Uint32 tableId = signal->theData[0];
2995
Uint32 lock = signal->theData[1];
2997
TableRecordPtr tablePtr;
2998
c_tableRecordPool.getPtr(tablePtr, tableId, true);
3002
ndbrequire(tablePtr.p->tabState == TableRecord::DEFINED);
3003
tablePtr.p->tabState = TableRecord::BACKUP_ONGOING;
3005
else if(tablePtr.p->tabState == TableRecord::BACKUP_ONGOING)
3007
tablePtr.p->tabState = TableRecord::DEFINED;
3012
Dbdict::check_ndb_versions() const
3015
Uint32 version = getNodeInfo(getOwnNodeId()).m_version;
3016
while((node = c_aliveNodes.find(node + 1)) != BitmaskImpl::NotFound)
3018
if(getNodeInfo(node).m_version != version)
3027
Dbdict::execALTER_TABLE_REQ(Signal* signal)
3029
// Received by master
3031
if(!assembleFragments(signal)){
3034
AlterTableReq* const req = (AlterTableReq*)signal->getDataPtr();
3035
const Uint32 senderRef = req->senderRef;
3036
const Uint32 senderData = req->senderData;
3037
const Uint32 changeMask = req->changeMask;
3038
const Uint32 tableId = req->tableId;
3039
const Uint32 tableVersion = req->tableVersion;
3040
ParseDictTabInfoRecord* aParseRecord;
3042
// Get table definition
3043
TableRecordPtr tablePtr;
3044
c_tableRecordPool.getPtr(tablePtr, tableId, false);
3045
if(tablePtr.isNull()){
3047
alterTableRef(signal, req, AlterTableRef::NoSuchTable);
3051
if(getOwnNodeId() != c_masterNodeId){
3053
alterTableRef(signal, req, AlterTableRef::NotMaster);
3057
if(c_blockState == BS_NODE_RESTART){
3059
alterTableRef(signal, req, AlterTableRef::BusyWithNR);
3063
if(c_blockState != BS_IDLE){
3065
alterTableRef(signal, req, AlterTableRef::Busy);
3069
if (!check_ndb_versions())
3072
alterTableRef(signal, req, AlterTableRef::IncompatibleVersions);
3076
const TableRecord::TabState tabState = tablePtr.p->tabState;
3079
case TableRecord::NOT_DEFINED:
3080
case TableRecord::REORG_TABLE_PREPARED:
3081
case TableRecord::DEFINING:
3082
case TableRecord::CHECKED:
3084
alterTableRef(signal, req, AlterTableRef::NoSuchTable);
3086
case TableRecord::DEFINED:
3090
case TableRecord::BACKUP_ONGOING:
3092
alterTableRef(signal, req, AlterTableRef::BackupInProgress);
3094
case TableRecord::PREPARE_DROPPING:
3095
case TableRecord::DROPPING:
3097
alterTableRef(signal, req, AlterTableRef::DropInProgress);
3102
if(tablePtr.p->tableVersion != tableVersion){
3104
alterTableRef(signal, req, AlterTableRef::InvalidTableVersion);
3107
// Parse new table defintion
3108
ParseDictTabInfoRecord parseRecord;
3109
aParseRecord = &parseRecord;
3111
CreateTableRecordPtr alterTabPtr; // Reuse create table records
3112
c_opCreateTable.seize(alterTabPtr);
3114
if(alterTabPtr.isNull()){
3116
alterTableRef(signal, req, AlterTableRef::Busy);
3120
alterTabPtr.p->m_changeMask = changeMask;
3121
parseRecord.requestType = DictTabInfo::AlterTableFromAPI;
3122
parseRecord.errorCode = 0;
3124
SegmentedSectionPtr ptr;
3125
signal->getSection(ptr, AlterTableReq::DICT_TAB_INFO);
3126
SimplePropertiesSectionReader r(ptr, getSectionSegmentPool());
3128
handleTabInfoInit(r, &parseRecord, false); // Will not save info
3130
if(parseRecord.errorCode != 0){
3132
c_opCreateTable.release(alterTabPtr);
3133
alterTableRef(signal, req,
3134
(AlterTableRef::ErrorCode) parseRecord.errorCode,
3139
releaseSections(signal);
3140
alterTabPtr.p->key = ++c_opRecordSequence;
3141
c_opCreateTable.add(alterTabPtr);
3142
ndbrequire(c_opCreateTable.find(alterTabPtr, alterTabPtr.p->key));
3143
alterTabPtr.p->m_errorCode = 0;
3144
alterTabPtr.p->m_senderRef = senderRef;
3145
alterTabPtr.p->m_senderData = senderData;
3146
alterTabPtr.p->m_tablePtrI = parseRecord.tablePtr.i;
3147
alterTabPtr.p->m_alterTableFailed = false;
3148
alterTabPtr.p->m_coordinatorRef = reference();
3149
alterTabPtr.p->m_fragmentsPtrI = RNIL;
3150
alterTabPtr.p->m_dihAddFragPtr = RNIL;
3151
alterTabPtr.p->m_alterTableId = tablePtr.p->tableId;
3153
// Send prepare request to all alive nodes
3154
SimplePropertiesSectionWriter w(getSectionSegmentPool());
3155
packTableIntoPagesImpl(w, parseRecord.tablePtr);
3157
SegmentedSectionPtr tabInfoPtr;
3158
w.getPtr(tabInfoPtr);
3160
alterTabPtr.p->m_tabInfoPtrI = tabInfoPtr.i;
3162
// Alter table on all nodes
3163
c_blockState = BS_BUSY;
3165
Mutex mutex(signal, c_mutexMgr, alterTabPtr.p->m_startLcpMutex);
3166
Callback c = { safe_cast(&Dbdict::alterTable_backup_mutex_locked),
3167
alterTabPtr.p->key };
3169
ndbrequire(mutex.lock(c));
3173
Dbdict::alterTable_backup_mutex_locked(Signal* signal,
3174
Uint32 callbackData,
3179
ndbrequire(retValue == 0);
3181
CreateTableRecordPtr alterTabPtr;
3182
ndbrequire(c_opCreateTable.find(alterTabPtr, callbackData));
3184
TableRecordPtr tablePtr;
3185
c_tableRecordPool.getPtr(tablePtr, alterTabPtr.p->m_alterTableId, true);
3187
Mutex mutex(signal, c_mutexMgr, alterTabPtr.p->m_startLcpMutex);
3188
mutex.unlock(); // ignore response
3190
SegmentedSectionPtr tabInfoPtr;
3191
getSection(tabInfoPtr, alterTabPtr.p->m_tabInfoPtrI);
3192
signal->setSection(tabInfoPtr, AlterTabReq::DICT_TAB_INFO);
3194
alterTabPtr.p->m_tabInfoPtrI = RNIL;
3196
if(tablePtr.p->tabState == TableRecord::BACKUP_ONGOING)
3199
AlterTableReq* req = (AlterTableReq*)signal->getDataPtr();
3200
req->senderData = alterTabPtr.p->m_senderData;
3201
req->senderRef = alterTabPtr.p->m_senderRef;
3202
alterTableRef(signal, req, AlterTableRef::BackupInProgress);
3204
c_tableRecordPool.getPtr(tablePtr, alterTabPtr.p->m_tablePtrI);
3205
releaseTableObject(tablePtr.i, false);
3207
c_opCreateTable.release(alterTabPtr);
3208
c_blockState = BS_IDLE;
3212
NodeReceiverGroup rg(DBDICT, c_aliveNodes);
3213
alterTabPtr.p->m_coordinatorData.m_gsn = GSN_ALTER_TAB_REQ;
3214
SafeCounter safeCounter(c_counterMgr,
3215
alterTabPtr.p->m_coordinatorData.m_counter);
3216
safeCounter.init<AlterTabRef>(rg, alterTabPtr.p->key);
3218
AlterTabReq * const lreq = (AlterTabReq*)signal->getDataPtrSend();
3219
lreq->senderRef = reference();
3220
lreq->senderData = alterTabPtr.p->key;
3221
lreq->clientRef = alterTabPtr.p->m_senderRef;
3222
lreq->clientData = alterTabPtr.p->m_senderData;
3223
lreq->changeMask = alterTabPtr.p->m_changeMask;
3224
lreq->tableId = tablePtr.p->tableId;
3225
lreq->tableVersion = alter_table_inc_schema_version(tablePtr.p->tableVersion);
3226
lreq->gci = tablePtr.p->gciTableCreated;
3227
lreq->requestType = AlterTabReq::AlterTablePrepare;
3229
sendFragmentedSignal(rg, GSN_ALTER_TAB_REQ, signal,
3230
AlterTabReq::SignalLength, JBB);
3233
void Dbdict::alterTableRef(Signal * signal,
3234
AlterTableReq * req,
3235
AlterTableRef::ErrorCode errCode,
3236
ParseDictTabInfoRecord* parseRecord)
3239
releaseSections(signal);
3240
AlterTableRef * ref = (AlterTableRef*)signal->getDataPtrSend();
3241
Uint32 senderRef = req->senderRef;
3242
ref->senderData = req->senderData;
3243
ref->senderRef = reference();
3244
ref->masterNodeId = c_masterNodeId;
3246
ref->errorCode = parseRecord->errorCode;
3247
ref->errorLine = parseRecord->errorLine;
3248
ref->errorKey = parseRecord->errorKey;
3249
ref->status = parseRecord->status;
3252
ref->errorCode = errCode;
3257
sendSignal(senderRef, GSN_ALTER_TABLE_REF, signal,
3258
AlterTableRef::SignalLength, JBB);
3262
Dbdict::execALTER_TAB_REQ(Signal * signal)
3264
// Received in all nodes to handle change locally
3267
if(!assembleFragments(signal)){
3270
AlterTabReq* const req = (AlterTabReq*)signal->getDataPtr();
3271
const Uint32 senderRef = req->senderRef;
3272
const Uint32 senderData = req->senderData;
3273
const Uint32 changeMask = req->changeMask;
3274
const Uint32 tableId = req->tableId;
3275
const Uint32 tableVersion = req->tableVersion;
3276
const Uint32 gci = req->gci;
3277
AlterTabReq::RequestType requestType =
3278
(AlterTabReq::RequestType) req->requestType;
3280
SegmentedSectionPtr tabInfoPtr;
3281
signal->getSection(tabInfoPtr, AlterTabReq::DICT_TAB_INFO);
3283
CreateTableRecordPtr alterTabPtr; // Reuse create table records
3285
if (senderRef != reference()) {
3287
c_blockState = BS_BUSY;
3289
if ((requestType == AlterTabReq::AlterTablePrepare)
3290
&& (senderRef != reference())) {
3292
c_opCreateTable.seize(alterTabPtr);
3293
if(!alterTabPtr.isNull())
3294
alterTabPtr.p->m_changeMask = changeMask;
3298
ndbrequire(c_opCreateTable.find(alterTabPtr, senderData));
3300
if(alterTabPtr.isNull()){
3302
alterTabRef(signal, req, AlterTableRef::Busy);
3306
if (!check_ndb_versions())
3309
alterTabRef(signal, req, AlterTableRef::IncompatibleVersions);
3313
alterTabPtr.p->m_alterTableId = tableId;
3314
alterTabPtr.p->m_coordinatorRef = senderRef;
3316
// Get table definition
3317
TableRecordPtr tablePtr;
3318
c_tableRecordPool.getPtr(tablePtr, tableId, false);
3319
if(tablePtr.isNull()){
3321
alterTabRef(signal, req, AlterTableRef::NoSuchTable);
3325
switch(requestType) {
3326
case(AlterTabReq::AlterTablePrepare): {
3327
ParseDictTabInfoRecord* aParseRecord;
3329
const TableRecord::TabState tabState = tablePtr.p->tabState;
3332
case TableRecord::NOT_DEFINED:
3333
case TableRecord::REORG_TABLE_PREPARED:
3334
case TableRecord::DEFINING:
3335
case TableRecord::CHECKED:
3337
alterTabRef(signal, req, AlterTableRef::NoSuchTable);
3339
case TableRecord::DEFINED:
3343
case TableRecord::PREPARE_DROPPING:
3344
case TableRecord::DROPPING:
3346
alterTabRef(signal, req, AlterTableRef::DropInProgress);
3348
case TableRecord::BACKUP_ONGOING:
3350
alterTabRef(signal, req, AlterTableRef::BackupInProgress);
3355
if(alter_table_inc_schema_version(tablePtr.p->tableVersion) != tableVersion){
3357
alterTabRef(signal, req, AlterTableRef::InvalidTableVersion);
3360
TableRecordPtr newTablePtr;
3361
if (senderRef != reference()) {
3363
// Parse altered table defintion
3364
ParseDictTabInfoRecord parseRecord;
3365
aParseRecord = &parseRecord;
3367
parseRecord.requestType = DictTabInfo::AlterTableFromAPI;
3368
parseRecord.errorCode = 0;
3370
SimplePropertiesSectionReader r(tabInfoPtr, getSectionSegmentPool());
3372
handleTabInfoInit(r, &parseRecord, false); // Will not save info
3374
if(parseRecord.errorCode != 0){
3376
c_opCreateTable.release(alterTabPtr);
3377
alterTabRef(signal, req,
3378
(AlterTableRef::ErrorCode) parseRecord.errorCode,
3382
alterTabPtr.p->key = senderData;
3383
c_opCreateTable.add(alterTabPtr);
3384
alterTabPtr.p->m_errorCode = 0;
3385
alterTabPtr.p->m_senderRef = senderRef;
3386
alterTabPtr.p->m_senderData = senderData;
3387
alterTabPtr.p->m_tablePtrI = parseRecord.tablePtr.i;
3388
alterTabPtr.p->m_fragmentsPtrI = RNIL;
3389
alterTabPtr.p->m_dihAddFragPtr = RNIL;
3390
newTablePtr = parseRecord.tablePtr;
3391
newTablePtr.p->tableVersion = tableVersion;
3393
else { // (req->senderRef == reference())
3395
c_tableRecordPool.getPtr(newTablePtr, alterTabPtr.p->m_tablePtrI);
3396
newTablePtr.p->tableVersion = tableVersion;
3398
if (handleAlterTab(req, alterTabPtr.p, tablePtr, newTablePtr) == -1) {
3400
c_opCreateTable.release(alterTabPtr);
3401
alterTabRef(signal, req, AlterTableRef::UnsupportedChange);
3404
releaseSections(signal);
3405
// Propagate alter table to other local blocks
3406
AlterTabReq * req = (AlterTabReq*)signal->getDataPtrSend();
3407
req->senderRef = reference();
3408
req->senderData = senderData;
3409
req->changeMask = changeMask;
3410
req->tableId = tableId;
3411
req->tableVersion = tableVersion;
3413
req->requestType = requestType;
3414
sendSignal(DBLQH_REF, GSN_ALTER_TAB_REQ, signal,
3415
AlterTabReq::SignalLength, JBB);
3418
case(AlterTabReq::AlterTableCommit): {
3420
// Write schema for altered table to disk
3421
SegmentedSectionPtr tabInfoPtr;
3422
signal->getSection(tabInfoPtr, AlterTabReq::DICT_TAB_INFO);
3423
alterTabPtr.p->m_tabInfoPtrI = tabInfoPtr.i;
3425
signal->header.m_noOfSections = 0;
3427
// Update table record
3428
tablePtr.p->packedSize = tabInfoPtr.sz;
3429
tablePtr.p->tableVersion = tableVersion;
3430
tablePtr.p->gciTableCreated = gci;
3432
SchemaFile::TableEntry tabEntry;
3433
tabEntry.m_tableVersion = tableVersion;
3434
tabEntry.m_tableType = tablePtr.p->tableType;
3435
tabEntry.m_tableState = SchemaFile::ALTER_TABLE_COMMITTED;
3436
tabEntry.m_gcp = gci;
3437
tabEntry.m_info_words = tabInfoPtr.sz;
3438
memset(tabEntry.m_unused, 0, sizeof(tabEntry.m_unused));
3441
callback.m_callbackData = senderData;
3442
callback.m_callbackFunction =
3443
safe_cast(&Dbdict::alterTab_writeSchemaConf);
3445
updateSchemaState(signal, tableId, &tabEntry, &callback);
3448
case(AlterTabReq::AlterTableRevert): {
3450
// Revert failed alter table
3451
revertAlterTable(signal, changeMask, tableId, alterTabPtr.p);
3452
// Acknowledge the reverted alter table
3453
AlterTabConf * conf = (AlterTabConf*)signal->getDataPtrSend();
3454
conf->senderRef = reference();
3455
conf->senderData = senderData;
3456
conf->changeMask = changeMask;
3457
conf->tableId = tableId;
3458
conf->tableVersion = tableVersion;
3460
conf->requestType = requestType;
3461
sendSignal(senderRef, GSN_ALTER_TAB_CONF, signal,
3462
AlterTabConf::SignalLength, JBB);
3465
default: ndbrequire(false);
3469
void Dbdict::alterTabRef(Signal * signal,
3471
AlterTableRef::ErrorCode errCode,
3472
ParseDictTabInfoRecord* parseRecord)
3475
releaseSections(signal);
3476
AlterTabRef * ref = (AlterTabRef*)signal->getDataPtrSend();
3477
Uint32 senderRef = req->senderRef;
3478
ref->senderData = req->senderData;
3479
ref->senderRef = reference();
3482
ref->errorCode = parseRecord->errorCode;
3483
ref->errorLine = parseRecord->errorLine;
3484
ref->errorKey = parseRecord->errorKey;
3485
ref->errorStatus = parseRecord->status;
3489
ref->errorCode = errCode;
3492
ref->errorStatus = 0;
3494
sendSignal(senderRef, GSN_ALTER_TAB_REF, signal,
3495
AlterTabRef::SignalLength, JBB);
3497
c_blockState = BS_IDLE;
3500
void Dbdict::execALTER_TAB_REF(Signal * signal){
3503
AlterTabRef * ref = (AlterTabRef*)signal->getDataPtr();
3505
Uint32 senderRef = ref->senderRef;
3506
Uint32 senderData = ref->senderData;
3507
Uint32 errorCode = ref->errorCode;
3508
Uint32 errorLine = ref->errorLine;
3509
Uint32 errorKey = ref->errorKey;
3510
Uint32 errorStatus = ref->errorStatus;
3511
AlterTabReq::RequestType requestType =
3512
(AlterTabReq::RequestType) ref->requestType;
3513
CreateTableRecordPtr alterTabPtr;
3514
ndbrequire(c_opCreateTable.find(alterTabPtr, senderData));
3515
Uint32 changeMask = alterTabPtr.p->m_changeMask;
3516
SafeCounter safeCounter(c_counterMgr, alterTabPtr.p->m_coordinatorData.m_counter);
3517
safeCounter.clearWaitingFor(refToNode(senderRef));
3518
switch (requestType) {
3519
case(AlterTabReq::AlterTablePrepare): {
3520
if (safeCounter.done()) {
3522
// Send revert request to all alive nodes
3523
TableRecordPtr tablePtr;
3524
c_tableRecordPool.getPtr(tablePtr, alterTabPtr.p->m_alterTableId);
3525
Uint32 tableId = tablePtr.p->tableId;
3526
Uint32 tableVersion = tablePtr.p->tableVersion;
3527
Uint32 gci = tablePtr.p->gciTableCreated;
3528
SimplePropertiesSectionWriter w(getSectionSegmentPool());
3529
packTableIntoPagesImpl(w, tablePtr);
3530
SegmentedSectionPtr spDataPtr;
3531
w.getPtr(spDataPtr);
3532
signal->setSection(spDataPtr, AlterTabReq::DICT_TAB_INFO);
3534
NodeReceiverGroup rg(DBDICT, c_aliveNodes);
3535
alterTabPtr.p->m_coordinatorData.m_gsn = GSN_ALTER_TAB_REQ;
3536
safeCounter.init<AlterTabRef>(rg, alterTabPtr.p->key);
3538
AlterTabReq * const lreq = (AlterTabReq*)signal->getDataPtrSend();
3539
lreq->senderRef = reference();
3540
lreq->senderData = alterTabPtr.p->key;
3541
lreq->clientRef = alterTabPtr.p->m_senderRef;
3542
lreq->clientData = alterTabPtr.p->m_senderData;
3543
lreq->changeMask = changeMask;
3544
lreq->tableId = tableId;
3545
lreq->tableVersion = tableVersion;
3547
lreq->requestType = AlterTabReq::AlterTableRevert;
3549
sendSignal(rg, GSN_ALTER_TAB_REQ, signal,
3550
AlterTabReq::SignalLength, JBB);
3554
alterTabPtr.p->m_alterTableFailed = true;
3558
case(AlterTabReq::AlterTableCommit):
3560
case(AlterTabReq::AlterTableRevert): {
3561
AlterTableRef * apiRef = (AlterTableRef*)signal->getDataPtrSend();
3563
apiRef->senderData = senderData;
3564
apiRef->senderRef = reference();
3565
apiRef->masterNodeId = c_masterNodeId;
3566
apiRef->errorCode = errorCode;
3567
apiRef->errorLine = errorLine;
3568
apiRef->errorKey = errorKey;
3569
apiRef->status = errorStatus;
3570
if (safeCounter.done()) {
3572
sendSignal(senderRef, GSN_ALTER_TABLE_REF, signal,
3573
AlterTableRef::SignalLength, JBB);
3574
c_blockState = BS_IDLE;
3578
alterTabPtr.p->m_alterTableFailed = true;
3579
alterTabPtr.p->m_alterTableRef = *apiRef;
3583
default: ndbrequire(false);
3588
Dbdict::execALTER_TAB_CONF(Signal * signal){
3590
AlterTabConf * const conf = (AlterTabConf*)signal->getDataPtr();
3591
Uint32 senderRef = conf->senderRef;
3592
Uint32 senderData = conf->senderData;
3593
Uint32 changeMask = conf->changeMask;
3594
Uint32 tableId = conf->tableId;
3595
Uint32 tableVersion = conf->tableVersion;
3596
Uint32 gci = conf->gci;
3597
AlterTabReq::RequestType requestType =
3598
(AlterTabReq::RequestType) conf->requestType;
3599
CreateTableRecordPtr alterTabPtr;
3600
ndbrequire(c_opCreateTable.find(alterTabPtr, senderData));
3602
switch (requestType) {
3603
case(AlterTabReq::AlterTablePrepare): {
3604
switch(refToBlock(signal->getSendersBlockRef())) {
3607
AlterTabReq * req = (AlterTabReq*)signal->getDataPtrSend();
3608
req->senderRef = reference();
3609
req->senderData = senderData;
3610
req->changeMask = changeMask;
3611
req->tableId = tableId;
3612
req->tableVersion = tableVersion;
3614
req->requestType = requestType;
3615
sendSignal(DBDIH_REF, GSN_ALTER_TAB_REQ, signal,
3616
AlterTabReq::SignalLength, JBB);
3621
AlterTabReq * req = (AlterTabReq*)signal->getDataPtrSend();
3622
req->senderRef = reference();
3623
req->senderData = senderData;
3624
req->changeMask = changeMask;
3625
req->tableId = tableId;
3626
req->tableVersion = tableVersion;
3628
req->requestType = requestType;
3629
sendSignal(DBTC_REF, GSN_ALTER_TAB_REQ, signal,
3630
AlterTabReq::SignalLength, JBB);
3635
// Participant is done with prepare phase, send conf to coordinator
3636
AlterTabConf * conf = (AlterTabConf*)signal->getDataPtrSend();
3637
conf->senderRef = reference();
3638
conf->senderData = senderData;
3639
conf->changeMask = changeMask;
3640
conf->tableId = tableId;
3641
conf->tableVersion = tableVersion;
3643
conf->requestType = requestType;
3644
sendSignal(alterTabPtr.p->m_coordinatorRef, GSN_ALTER_TAB_CONF, signal,
3645
AlterTabConf::SignalLength, JBB);
3651
SafeCounter safeCounter(c_counterMgr, alterTabPtr.p->m_coordinatorData.m_counter);
3652
safeCounter.clearWaitingFor(refToNode(senderRef));
3653
if (safeCounter.done()) {
3655
// We have received all local confirmations
3656
if (alterTabPtr.p->m_alterTableFailed) {
3658
// Send revert request to all alive nodes
3659
TableRecordPtr tablePtr;
3660
c_tableRecordPool.getPtr(tablePtr, alterTabPtr.p->m_alterTableId);
3661
Uint32 tableId = tablePtr.p->tableId;
3662
Uint32 tableVersion = tablePtr.p->tableVersion;
3663
Uint32 gci = tablePtr.p->gciTableCreated;
3664
SimplePropertiesSectionWriter w(getSectionSegmentPool());
3665
packTableIntoPagesImpl(w, tablePtr);
3666
SegmentedSectionPtr spDataPtr;
3667
w.getPtr(spDataPtr);
3668
signal->setSection(spDataPtr, AlterTabReq::DICT_TAB_INFO);
3670
NodeReceiverGroup rg(DBDICT, c_aliveNodes);
3671
alterTabPtr.p->m_coordinatorData.m_gsn = GSN_ALTER_TAB_REQ;
3672
safeCounter.init<AlterTabRef>(rg, alterTabPtr.p->key);
3674
AlterTabReq * const lreq = (AlterTabReq*)signal->getDataPtrSend();
3675
lreq->senderRef = reference();
3676
lreq->senderData = alterTabPtr.p->key;
3677
lreq->clientRef = alterTabPtr.p->m_senderRef;
3678
lreq->clientData = alterTabPtr.p->m_senderData;
3679
lreq->changeMask = changeMask;
3680
lreq->tableId = tableId;
3681
lreq->tableVersion = tableVersion;
3683
lreq->requestType = AlterTabReq::AlterTableRevert;
3685
sendSignal(rg, GSN_ALTER_TAB_REQ, signal,
3686
AlterTabReq::SignalLength, JBB);
3690
// Send commit request to all alive nodes
3691
TableRecordPtr tablePtr;
3692
c_tableRecordPool.getPtr(tablePtr, tableId);
3693
SimplePropertiesSectionWriter w(getSectionSegmentPool());
3694
packTableIntoPagesImpl(w, tablePtr);
3695
SegmentedSectionPtr spDataPtr;
3696
w.getPtr(spDataPtr);
3697
signal->setSection(spDataPtr, AlterTabReq::DICT_TAB_INFO);
3699
NodeReceiverGroup rg(DBDICT, c_aliveNodes);
3700
alterTabPtr.p->m_coordinatorData.m_gsn = GSN_ALTER_TAB_REQ;
3701
safeCounter.init<AlterTabRef>(rg, alterTabPtr.p->key);
3703
AlterTabReq * const lreq = (AlterTabReq*)signal->getDataPtrSend();
3704
lreq->senderRef = reference();
3705
lreq->senderData = alterTabPtr.p->key;
3706
lreq->clientRef = alterTabPtr.p->m_senderRef;
3707
lreq->clientData = alterTabPtr.p->m_senderData;
3708
lreq->changeMask = changeMask;
3709
lreq->tableId = tableId;
3710
lreq->tableVersion = tableVersion;
3712
lreq->requestType = AlterTabReq::AlterTableCommit;
3714
sendFragmentedSignal(rg, GSN_ALTER_TAB_REQ, signal,
3715
AlterTabReq::SignalLength, JBB);
3719
// (!safeCounter.done())
3724
case(AlterTabReq::AlterTableRevert):
3726
case(AlterTabReq::AlterTableCommit): {
3727
SafeCounter safeCounter(c_counterMgr, alterTabPtr.p->m_coordinatorData.m_counter);
3728
safeCounter.clearWaitingFor(refToNode(senderRef));
3729
if (safeCounter.done()) {
3731
// We have received all local confirmations
3732
releaseSections(signal);
3733
if (alterTabPtr.p->m_alterTableFailed) {
3735
AlterTableRef * apiRef =
3736
(AlterTableRef*)signal->getDataPtrSend();
3737
*apiRef = alterTabPtr.p->m_alterTableRef;
3738
sendSignal(alterTabPtr.p->m_senderRef, GSN_ALTER_TABLE_REF, signal,
3739
AlterTableRef::SignalLength, JBB);
3743
// Alter table completed, inform API
3744
AlterTableConf * const apiConf =
3745
(AlterTableConf*)signal->getDataPtrSend();
3746
apiConf->senderRef = reference();
3747
apiConf->senderData = alterTabPtr.p->m_senderData;
3748
apiConf->tableId = tableId;
3749
apiConf->tableVersion = tableVersion;
3751
//@todo check api failed
3752
sendSignal(alterTabPtr.p->m_senderRef, GSN_ALTER_TABLE_CONF, signal,
3753
AlterTableConf::SignalLength, JBB);
3756
// Release resources
3757
TableRecordPtr tabPtr;
3758
c_tableRecordPool.getPtr(tabPtr, alterTabPtr.p->m_tablePtrI);
3759
releaseTableObject(tabPtr.i, false);
3760
c_opCreateTable.release(alterTabPtr);
3761
c_blockState = BS_IDLE;
3764
// (!safeCounter.done())
3769
default: ndbrequire(false);
3775
void Dbdict::printTables()
3777
DLHashTable<TableRecord>::Iterator iter;
3778
bool moreTables = c_tableRecordHash.first(iter);
3779
printf("TABLES IN DICT:\n");
3780
while (moreTables) {
3781
TableRecordPtr tablePtr = iter.curr;
3782
printf("%s ", tablePtr.p->tableName);
3783
moreTables = c_tableRecordHash.next(iter);
3788
int Dbdict::handleAlterTab(AlterTabReq * req,
3789
CreateTableRecord * alterTabPtrP,
3790
TableRecordPtr origTablePtr,
3791
TableRecordPtr newTablePtr)
3793
Uint32 changeMask = req->changeMask;
3795
if (AlterTableReq::getNameFlag(changeMask)) {
3798
// Remove from hashtable
3801
ndbrequire(c_tableRecordHash.find(tmp, *origTablePtr.p));
3803
c_tableRecordHash.remove(origTablePtr);
3804
strcpy(alterTabPtrP->previousTableName, origTablePtr.p->tableName);
3805
strcpy(origTablePtr.p->tableName, newTablePtr.p->tableName);
3806
// Set new schema version
3807
origTablePtr.p->tableVersion = newTablePtr.p->tableVersion;
3810
ndbrequire(!c_tableRecordHash.find(tmp, *origTablePtr.p));
3812
c_tableRecordHash.add(origTablePtr);
3820
void Dbdict::revertAlterTable(Signal * signal,
3823
CreateTableRecord * alterTabPtrP)
3825
if (AlterTableReq::getNameFlag(changeMask)) {
3828
// Restore previous name
3829
TableRecordPtr tablePtr;
3830
c_tableRecordPool.getPtr(tablePtr, tableId);
3831
// Remove from hashtable
3834
ndbrequire(c_tableRecordHash.find(tmp, * tablePtr.p));
3836
c_tableRecordHash.remove(tablePtr);
3838
strcpy(tablePtr.p->tableName, alterTabPtrP->previousTableName);
3839
// Revert schema version
3840
tablePtr.p->tableVersion = alter_table_dec_schema_version(tablePtr.p->tableVersion);
3843
ndbrequire(!c_tableRecordHash.find(tmp, * tablePtr.p));
3845
c_tableRecordHash.add(tablePtr);
3854
Dbdict::alterTab_writeSchemaConf(Signal* signal,
3855
Uint32 callbackData,
3859
Uint32 key = callbackData;
3860
CreateTableRecordPtr alterTabPtr;
3861
ndbrequire(c_opCreateTable.find(alterTabPtr, key));
3862
Uint32 tableId = alterTabPtr.p->m_alterTableId;
3865
callback.m_callbackData = alterTabPtr.p->key;
3866
callback.m_callbackFunction =
3867
safe_cast(&Dbdict::alterTab_writeTableConf);
3869
SegmentedSectionPtr tabInfoPtr;
3870
getSection(tabInfoPtr, alterTabPtr.p->m_tabInfoPtrI);
3872
writeTableFile(signal, tableId, tabInfoPtr, &callback);
3874
signal->setSection(tabInfoPtr, 0);
3875
releaseSections(signal);
3879
Dbdict::alterTab_writeTableConf(Signal* signal,
3880
Uint32 callbackData,
3884
CreateTableRecordPtr alterTabPtr;
3885
ndbrequire(c_opCreateTable.find(alterTabPtr, callbackData));
3886
Uint32 coordinatorRef = alterTabPtr.p->m_coordinatorRef;
3887
TableRecordPtr tabPtr;
3888
c_tableRecordPool.getPtr(tabPtr, alterTabPtr.p->m_alterTableId);
3890
// Alter table commit request handled successfully
3891
AlterTabConf * conf = (AlterTabConf*)signal->getDataPtrSend();
3892
conf->senderRef = reference();
3893
conf->senderData = callbackData;
3894
conf->tableId = tabPtr.p->tableId;
3895
conf->tableVersion = tabPtr.p->tableVersion;
3896
conf->gci = tabPtr.p->gciTableCreated;
3897
conf->requestType = AlterTabReq::AlterTableCommit;
3898
sendSignal(coordinatorRef, GSN_ALTER_TAB_CONF, signal,
3899
AlterTabConf::SignalLength, JBB);
3903
ApiBroadcastRep* api= (ApiBroadcastRep*)signal->getDataPtrSend();
3904
api->gsn = GSN_ALTER_TABLE_REP;
3905
api->minVersion = MAKE_VERSION(4,1,15);
3907
AlterTableRep* rep = (AlterTableRep*)api->theData;
3908
rep->tableId = tabPtr.p->tableId;
3909
rep->tableVersion = alter_table_dec_schema_version(tabPtr.p->tableVersion);
3910
rep->changeType = AlterTableRep::CT_ALTERED;
3912
LinearSectionPtr ptr[3];
3913
ptr[0].p = (Uint32*)alterTabPtr.p->previousTableName;
3914
ptr[0].sz = (sizeof(alterTabPtr.p->previousTableName) + 3) >> 2;
3916
sendSignal(QMGR_REF, GSN_API_BROADCAST_REP, signal,
3917
ApiBroadcastRep::SignalLength + AlterTableRep::SignalLength,
3921
if(coordinatorRef != reference()) {
3923
// Release resources
3924
c_tableRecordPool.getPtr(tabPtr, alterTabPtr.p->m_tablePtrI);
3925
releaseTableObject(tabPtr.i, false);
3926
c_opCreateTable.release(alterTabPtr);
3927
c_blockState = BS_IDLE;
3932
Dbdict::execCREATE_FRAGMENTATION_REF(Signal * signal){
3934
const Uint32 * theData = signal->getDataPtr();
3935
CreateFragmentationRef * const ref = (CreateFragmentationRef*)theData;
3941
Dbdict::execCREATE_FRAGMENTATION_CONF(Signal* signal){
3943
const Uint32 * theData = signal->getDataPtr();
3944
CreateFragmentationConf * const conf = (CreateFragmentationConf*)theData;
3946
CreateTableRecordPtr createTabPtr;
3947
ndbrequire(c_opCreateTable.find(createTabPtr, conf->senderData));
3949
ndbrequire(signal->getNoOfSections() == 1);
3951
SegmentedSectionPtr fragDataPtr;
3952
signal->getSection(fragDataPtr, CreateFragmentationConf::FRAGMENTS);
3953
signal->header.m_noOfSections = 0;
3958
TableRecordPtr tabPtr;
3959
c_tableRecordPool.getPtr(tabPtr, createTabPtr.p->m_tablePtrI);
3962
* Save fragment count
3964
tabPtr.p->fragmentCount = conf->noOfFragments;
3967
* Update table version
3969
XSchemaFile * xsf = &c_schemaFile[c_schemaRecord.schemaPage != 0];
3970
SchemaFile::TableEntry * tabEntry = getTableEntry(xsf, tabPtr.i);
3972
tabPtr.p->tableVersion = create_table_inc_schema_version(tabEntry->m_tableVersion);
3977
SimplePropertiesSectionWriter w(getSectionSegmentPool());
3978
packTableIntoPagesImpl(w, tabPtr);
3980
SegmentedSectionPtr spDataPtr;
3981
w.getPtr(spDataPtr);
3983
signal->setSection(spDataPtr, CreateTabReq::DICT_TAB_INFO);
3984
signal->setSection(fragDataPtr, CreateTabReq::FRAGMENTATION);
3986
NodeReceiverGroup rg(DBDICT, c_aliveNodes);
3987
SafeCounter tmp(c_counterMgr, createTabPtr.p->m_coordinatorData.m_counter);
3988
createTabPtr.p->m_coordinatorData.m_gsn = GSN_CREATE_TAB_REQ;
3989
createTabPtr.p->m_coordinatorData.m_requestType = CreateTabReq::CreateTablePrepare;
3990
tmp.init<CreateTabRef>(rg, GSN_CREATE_TAB_REF, createTabPtr.p->key);
3992
CreateTabReq * const req = (CreateTabReq*)theData;
3993
req->senderRef = reference();
3994
req->senderData = createTabPtr.p->key;
3995
req->clientRef = createTabPtr.p->m_senderRef;
3996
req->clientData = createTabPtr.p->m_senderData;
3997
req->requestType = CreateTabReq::CreateTablePrepare;
4000
req->tableId = tabPtr.i;
4001
req->tableVersion = create_table_inc_schema_version(tabEntry->m_tableVersion);
4003
sendFragmentedSignal(rg, GSN_CREATE_TAB_REQ, signal,
4004
CreateTabReq::SignalLength, JBB);
4010
Dbdict::execCREATE_TAB_REF(Signal* signal){
4013
CreateTabRef * const ref = (CreateTabRef*)signal->getDataPtr();
4015
CreateTableRecordPtr createTabPtr;
4016
ndbrequire(c_opCreateTable.find(createTabPtr, ref->senderData));
4018
ndbrequire(createTabPtr.p->m_coordinatorRef == reference());
4019
ndbrequire(createTabPtr.p->m_coordinatorData.m_gsn == GSN_CREATE_TAB_REQ);
4021
if(ref->errorCode != CreateTabRef::NF_FakeErrorREF){
4022
createTabPtr.p->setErrorCode(ref->errorCode);
4024
createTab_reply(signal, createTabPtr, refToNode(ref->senderRef));
4028
Dbdict::execCREATE_TAB_CONF(Signal* signal){
4031
ndbrequire(signal->getNoOfSections() == 0);
4033
CreateTabConf * const conf = (CreateTabConf*)signal->getDataPtr();
4035
CreateTableRecordPtr createTabPtr;
4036
ndbrequire(c_opCreateTable.find(createTabPtr, conf->senderData));
4038
ndbrequire(createTabPtr.p->m_coordinatorRef == reference());
4039
ndbrequire(createTabPtr.p->m_coordinatorData.m_gsn == GSN_CREATE_TAB_REQ);
4041
createTab_reply(signal, createTabPtr, refToNode(conf->senderRef));
4045
Dbdict::createTab_reply(Signal* signal,
4046
CreateTableRecordPtr createTabPtr,
4050
SafeCounter tmp(c_counterMgr, createTabPtr.p->m_coordinatorData.m_counter);
4051
if(!tmp.clearWaitingFor(nodeId)){
4056
switch(createTabPtr.p->m_coordinatorData.m_requestType){
4057
case CreateTabReq::CreateTablePrepare:{
4059
if(createTabPtr.p->m_errorCode != 0){
4062
* Failed to prepare on atleast one node -> abort on all
4064
NodeReceiverGroup rg(DBDICT, c_aliveNodes);
4065
createTabPtr.p->m_coordinatorData.m_gsn = GSN_CREATE_TAB_REQ;
4066
createTabPtr.p->m_coordinatorData.m_requestType = CreateTabReq::CreateTableDrop;
4067
ndbrequire(tmp.init<CreateTabRef>(rg, createTabPtr.p->key));
4069
CreateTabReq * const req = (CreateTabReq*)signal->getDataPtrSend();
4070
req->senderRef = reference();
4071
req->senderData = createTabPtr.p->key;
4072
req->requestType = CreateTabReq::CreateTableDrop;
4074
sendSignal(rg, GSN_CREATE_TAB_REQ, signal,
4075
CreateTabReq::SignalLength, JBB);
4080
* Lock mutex before commiting table
4082
Mutex mutex(signal, c_mutexMgr, createTabPtr.p->m_startLcpMutex);
4083
Callback c = { safe_cast(&Dbdict::createTab_startLcpMutex_locked),
4084
createTabPtr.p->key};
4086
ndbrequire(mutex.lock(c));
4089
case CreateTabReq::CreateTableCommit:{
4091
ndbrequire(createTabPtr.p->m_errorCode == 0);
4094
* Unlock mutex before commiting table
4096
Mutex mutex(signal, c_mutexMgr, createTabPtr.p->m_startLcpMutex);
4097
Callback c = { safe_cast(&Dbdict::createTab_startLcpMutex_unlocked),
4098
createTabPtr.p->key};
4102
case CreateTabReq::CreateTableDrop:{
4104
CreateTableRef * const ref = (CreateTableRef*)signal->getDataPtr();
4105
ref->senderRef = reference();
4106
ref->senderData = createTabPtr.p->m_senderData;
4107
ref->errorCode = createTabPtr.p->m_errorCode;
4108
ref->masterNodeId = c_masterNodeId;
4113
//@todo check api failed
4114
sendSignal(createTabPtr.p->m_senderRef, GSN_CREATE_TABLE_REF, signal,
4115
CreateTableRef::SignalLength, JBB);
4116
c_opCreateTable.release(createTabPtr);
4117
c_blockState = BS_IDLE;
4125
Dbdict::createTab_startLcpMutex_locked(Signal* signal,
4126
Uint32 callbackData,
4130
ndbrequire(retValue == 0);
4132
CreateTableRecordPtr createTabPtr;
4133
ndbrequire(c_opCreateTable.find(createTabPtr, callbackData));
4135
NodeReceiverGroup rg(DBDICT, c_aliveNodes);
4136
createTabPtr.p->m_coordinatorData.m_gsn = GSN_CREATE_TAB_REQ;
4137
createTabPtr.p->m_coordinatorData.m_requestType = CreateTabReq::CreateTableCommit;
4138
SafeCounter tmp(c_counterMgr, createTabPtr.p->m_coordinatorData.m_counter);
4139
tmp.init<CreateTabRef>(rg, GSN_CREATE_TAB_REF, createTabPtr.p->key);
4141
CreateTabReq * const req = (CreateTabReq*)signal->getDataPtrSend();
4142
req->senderRef = reference();
4143
req->senderData = createTabPtr.p->key;
4144
req->requestType = CreateTabReq::CreateTableCommit;
4146
sendSignal(rg, GSN_CREATE_TAB_REQ, signal,
4147
CreateTabReq::SignalLength, JBB);
4151
Dbdict::createTab_startLcpMutex_unlocked(Signal* signal,
4152
Uint32 callbackData,
4156
ndbrequire(retValue == 0);
4158
CreateTableRecordPtr createTabPtr;
4159
ndbrequire(c_opCreateTable.find(createTabPtr, callbackData));
4161
createTabPtr.p->m_startLcpMutex.release(c_mutexMgr);
4163
TableRecordPtr tabPtr;
4164
c_tableRecordPool.getPtr(tabPtr, createTabPtr.p->m_tablePtrI);
4166
CreateTableConf * const conf = (CreateTableConf*)signal->getDataPtr();
4167
conf->senderRef = reference();
4168
conf->senderData = createTabPtr.p->m_senderData;
4169
conf->tableId = createTabPtr.p->m_tablePtrI;
4170
conf->tableVersion = tabPtr.p->tableVersion;
4172
//@todo check api failed
4173
sendSignal(createTabPtr.p->m_senderRef, GSN_CREATE_TABLE_CONF, signal,
4174
CreateTableConf::SignalLength, JBB);
4175
c_opCreateTable.release(createTabPtr);
4176
c_blockState = BS_IDLE;
4180
/***********************************************************
4181
* CreateTable participant code
4182
**********************************************************/
4184
Dbdict::execCREATE_TAB_REQ(Signal* signal){
4187
if(!assembleFragments(signal)){
4192
CreateTabReq * const req = (CreateTabReq*)signal->getDataPtr();
4194
CreateTabReq::RequestType rt = (CreateTabReq::RequestType)req->requestType;
4196
case CreateTabReq::CreateTablePrepare:
4197
CRASH_INSERTION2(6003, getOwnNodeId() != c_masterNodeId);
4198
createTab_prepare(signal, req);
4200
case CreateTabReq::CreateTableCommit:
4201
CRASH_INSERTION2(6004, getOwnNodeId() != c_masterNodeId);
4202
createTab_commit(signal, req);
4204
case CreateTabReq::CreateTableDrop:
4205
CRASH_INSERTION2(6005, getOwnNodeId() != c_masterNodeId);
4206
createTab_drop(signal, req);
4213
Dbdict::createTab_prepare(Signal* signal, CreateTabReq * req){
4215
const Uint32 gci = req->gci;
4216
const Uint32 tableId = req->tableId;
4217
const Uint32 tableVersion = req->tableVersion;
4219
SegmentedSectionPtr tabInfoPtr;
4220
signal->getSection(tabInfoPtr, CreateTabReq::DICT_TAB_INFO);
4222
CreateTableRecordPtr createTabPtr;
4223
if(req->senderRef == reference()){
4225
ndbrequire(c_opCreateTable.find(createTabPtr, req->senderData));
4228
c_opCreateTable.seize(createTabPtr);
4230
ndbrequire(!createTabPtr.isNull());
4232
createTabPtr.p->key = req->senderData;
4233
c_opCreateTable.add(createTabPtr);
4234
createTabPtr.p->m_errorCode = 0;
4235
createTabPtr.p->m_tablePtrI = tableId;
4236
createTabPtr.p->m_coordinatorRef = req->senderRef;
4237
createTabPtr.p->m_senderRef = req->clientRef;
4238
createTabPtr.p->m_senderData = req->clientData;
4239
createTabPtr.p->m_dihAddFragPtr = RNIL;
4242
* Put data into table record
4244
ParseDictTabInfoRecord parseRecord;
4245
parseRecord.requestType = DictTabInfo::AddTableFromDict;
4246
parseRecord.errorCode = 0;
4248
SimplePropertiesSectionReader r(tabInfoPtr, getSectionSegmentPool());
4250
handleTabInfoInit(r, &parseRecord);
4252
ndbrequire(parseRecord.errorCode == 0);
4255
ndbrequire(!createTabPtr.isNull());
4257
SegmentedSectionPtr fragPtr;
4258
signal->getSection(fragPtr, CreateTabReq::FRAGMENTATION);
4260
createTabPtr.p->m_tabInfoPtrI = tabInfoPtr.i;
4261
createTabPtr.p->m_fragmentsPtrI = fragPtr.i;
4263
signal->header.m_noOfSections = 0;
4265
TableRecordPtr tabPtr;
4266
c_tableRecordPool.getPtr(tabPtr, tableId);
4267
tabPtr.p->packedSize = tabInfoPtr.sz;
4268
tabPtr.p->tableVersion = tableVersion;
4269
tabPtr.p->gciTableCreated = gci;
4271
SchemaFile::TableEntry tabEntry;
4272
tabEntry.m_tableVersion = tableVersion;
4273
tabEntry.m_tableType = tabPtr.p->tableType;
4274
tabEntry.m_tableState = SchemaFile::ADD_STARTED;
4275
tabEntry.m_gcp = gci;
4276
tabEntry.m_info_words = tabInfoPtr.sz;
4277
memset(tabEntry.m_unused, 0, sizeof(tabEntry.m_unused));
4280
callback.m_callbackData = createTabPtr.p->key;
4281
callback.m_callbackFunction =
4282
safe_cast(&Dbdict::createTab_writeSchemaConf1);
4284
updateSchemaState(signal, tableId, &tabEntry, &callback);
4287
void getSection(SegmentedSectionPtr & ptr, Uint32 i);
4290
Dbdict::createTab_writeSchemaConf1(Signal* signal,
4291
Uint32 callbackData,
4295
CreateTableRecordPtr createTabPtr;
4296
ndbrequire(c_opCreateTable.find(createTabPtr, callbackData));
4299
callback.m_callbackData = createTabPtr.p->key;
4300
callback.m_callbackFunction =
4301
safe_cast(&Dbdict::createTab_writeTableConf);
4303
SegmentedSectionPtr tabInfoPtr;
4304
getSection(tabInfoPtr, createTabPtr.p->m_tabInfoPtrI);
4305
writeTableFile(signal, createTabPtr.p->m_tablePtrI, tabInfoPtr, &callback);
4307
createTabPtr.p->m_tabInfoPtrI = RNIL;
4308
signal->setSection(tabInfoPtr, 0);
4309
releaseSections(signal);
4313
Dbdict::createTab_writeTableConf(Signal* signal,
4314
Uint32 callbackData,
4318
CreateTableRecordPtr createTabPtr;
4319
ndbrequire(c_opCreateTable.find(createTabPtr, callbackData));
4321
SegmentedSectionPtr fragDataPtr;
4322
getSection(fragDataPtr, createTabPtr.p->m_fragmentsPtrI);
4325
callback.m_callbackData = callbackData;
4326
callback.m_callbackFunction =
4327
safe_cast(&Dbdict::createTab_dihComplete);
4329
createTab_dih(signal, createTabPtr, fragDataPtr, &callback);
4333
Dbdict::createTab_dih(Signal* signal,
4334
CreateTableRecordPtr createTabPtr,
4335
SegmentedSectionPtr fragDataPtr,
4339
createTabPtr.p->m_callback = * c;
4341
TableRecordPtr tabPtr;
4342
c_tableRecordPool.getPtr(tabPtr, createTabPtr.p->m_tablePtrI);
4344
DiAddTabReq * req = (DiAddTabReq*)signal->getDataPtrSend();
4345
req->connectPtr = createTabPtr.p->key;
4346
req->tableId = tabPtr.i;
4347
req->fragType = tabPtr.p->fragmentType;
4348
req->kValue = tabPtr.p->kValue;
4349
req->noOfReplicas = 0;
4350
req->storedTable = tabPtr.p->storedTable;
4351
req->tableType = tabPtr.p->tableType;
4352
req->schemaVersion = tabPtr.p->tableVersion;
4353
req->primaryTableId = tabPtr.p->primaryTableId;
4355
if(!fragDataPtr.isNull()){
4356
signal->setSection(fragDataPtr, DiAddTabReq::FRAGMENTATION);
4359
sendSignal(DBDIH_REF, GSN_DIADDTABREQ, signal,
4360
DiAddTabReq::SignalLength, JBB);
4363
* Create KeyDescriptor
4365
KeyDescriptor* desc= g_key_descriptor_pool.getPtr(tabPtr.i);
4366
new (desc) KeyDescriptor();
4369
Uint32 tAttr = tabPtr.p->firstAttribute;
4370
while (tAttr != RNIL)
4373
AttributeRecord* aRec = c_attributeRecordPool.getPtr(tAttr);
4376
desc->noOfKeyAttr ++;
4377
desc->keyAttr[key].attributeDescriptor = aRec->attributeDescriptor;
4379
Uint32 csNumber = (aRec->extPrecision >> 16);
4382
desc->keyAttr[key].charsetInfo = all_charsets[csNumber];
4383
ndbrequire(all_charsets[csNumber]);
4384
desc->hasCharAttr = 1;
4388
desc->keyAttr[key].charsetInfo = 0;
4390
if(AttributeDescriptor::getDKey(aRec->attributeDescriptor))
4392
desc->noOfDistrKeys ++;
4396
tAttr = aRec->nextAttrInTable;
4398
ndbrequire(key == tabPtr.p->noOfPrimkey);
4403
calcLHbits(Uint32 * lhPageBits, Uint32 * lhDistrBits,
4404
Uint32 fid, Uint32 totalFragments)
4406
Uint32 distrBits = 0;
4407
Uint32 pageBits = 0;
4410
while (tmp < totalFragments) {
4415
#ifdef ndb_classical_lhdistrbits
4416
if (tmp != totalFragments) {
4418
if ((fid >= (totalFragments - tmp)) && (fid < (tmp - 1))) {
4423
* lhPageBits = pageBits;
4424
* lhDistrBits = distrBits;
4430
Dbdict::execADD_FRAGREQ(Signal* signal) {
4433
AddFragReq * const req = (AddFragReq*)signal->getDataPtr();
4435
Uint32 dihPtr = req->dihPtr;
4436
Uint32 senderData = req->senderData;
4437
Uint32 tableId = req->tableId;
4438
Uint32 fragId = req->fragmentId;
4439
Uint32 node = req->nodeId;
4440
Uint32 lcpNo = req->nextLCP;
4441
Uint32 fragCount = req->totalFragments;
4442
Uint32 requestInfo = req->requestInfo;
4443
Uint32 startGci = req->startGci;
4445
ndbrequire(node == getOwnNodeId());
4447
CreateTableRecordPtr createTabPtr;
4448
ndbrequire(c_opCreateTable.find(createTabPtr, senderData));
4450
createTabPtr.p->m_dihAddFragPtr = dihPtr;
4452
TableRecordPtr tabPtr;
4453
c_tableRecordPool.getPtr(tabPtr, tableId);
4456
tabPtr.p->gciTableCreated = (startGci > tabPtr.p->gciTableCreated ? startGci:
4457
startGci > tabPtr.p->gciTableCreated);
4463
Uint32 lhDistrBits = 0;
4464
Uint32 lhPageBits = 0;
4465
::calcLHbits(&lhPageBits, &lhDistrBits, fragId, fragCount);
4467
Uint64 maxRows = tabPtr.p->maxRowsLow +
4468
(((Uint64)tabPtr.p->maxRowsHigh) << 32);
4469
Uint64 minRows = tabPtr.p->minRowsLow +
4470
(((Uint64)tabPtr.p->minRowsHigh) << 32);
4471
maxRows = (maxRows + fragCount - 1) / fragCount;
4472
minRows = (minRows + fragCount - 1) / fragCount;
4475
LqhFragReq* req = (LqhFragReq*)signal->getDataPtrSend();
4476
req->senderData = senderData;
4477
req->senderRef = reference();
4478
req->fragmentId = fragId;
4479
req->requestInfo = requestInfo;
4480
req->tableId = tableId;
4481
req->localKeyLength = tabPtr.p->localKeyLen;
4482
req->maxLoadFactor = tabPtr.p->maxLoadFactor;
4483
req->minLoadFactor = tabPtr.p->minLoadFactor;
4484
req->kValue = tabPtr.p->kValue;
4485
req->lh3DistrBits = 0; //lhDistrBits;
4486
req->lh3PageBits = 0; //lhPageBits;
4487
req->noOfAttributes = tabPtr.p->noOfAttributes;
4488
req->noOfNullAttributes = tabPtr.p->noOfNullBits;
4489
req->maxRowsLow = maxRows & 0xFFFFFFFF;
4490
req->maxRowsHigh = maxRows >> 32;
4491
req->minRowsLow = minRows & 0xFFFFFFFF;
4492
req->minRowsHigh = minRows >> 32;
4493
req->schemaVersion = tabPtr.p->tableVersion;
4494
Uint32 keyLen = tabPtr.p->tupKeyLength;
4495
req->keyLength = keyLen; // wl-2066 no more "long keys"
4496
req->nextLCP = lcpNo;
4498
req->noOfKeyAttr = tabPtr.p->noOfPrimkey;
4499
req->noOfNewAttr = 0;
4500
req->noOfCharsets = tabPtr.p->noOfCharsets;
4501
req->checksumIndicator = 1;
4502
req->noOfAttributeGroups = 1;
4503
req->GCPIndicator = 0;
4504
req->startGci = startGci;
4505
req->tableType = tabPtr.p->tableType;
4506
req->primaryTableId = tabPtr.p->primaryTableId;
4507
sendSignal(DBLQH_REF, GSN_LQHFRAGREQ, signal,
4508
LqhFragReq::SignalLength, JBB);
4513
Dbdict::execLQHFRAGREF(Signal * signal){
4515
LqhFragRef * const ref = (LqhFragRef*)signal->getDataPtr();
4517
CreateTableRecordPtr createTabPtr;
4518
ndbrequire(c_opCreateTable.find(createTabPtr, ref->senderData));
4520
createTabPtr.p->setErrorCode(ref->errorCode);
4523
AddFragRef * const ref = (AddFragRef*)signal->getDataPtr();
4524
ref->dihPtr = createTabPtr.p->m_dihAddFragPtr;
4525
sendSignal(DBDIH_REF, GSN_ADD_FRAGREF, signal,
4526
AddFragRef::SignalLength, JBB);
4531
Dbdict::execLQHFRAGCONF(Signal * signal){
4533
LqhFragConf * const conf = (LqhFragConf*)signal->getDataPtr();
4535
CreateTableRecordPtr createTabPtr;
4536
ndbrequire(c_opCreateTable.find(createTabPtr, conf->senderData));
4538
createTabPtr.p->m_lqhFragPtr = conf->lqhFragPtr;
4540
TableRecordPtr tabPtr;
4541
c_tableRecordPool.getPtr(tabPtr, createTabPtr.p->m_tablePtrI);
4542
sendLQHADDATTRREQ(signal, createTabPtr, tabPtr.p->firstAttribute);
4546
Dbdict::sendLQHADDATTRREQ(Signal* signal,
4547
CreateTableRecordPtr createTabPtr,
4548
Uint32 attributePtrI){
4550
TableRecordPtr tabPtr;
4551
c_tableRecordPool.getPtr(tabPtr, createTabPtr.p->m_tablePtrI);
4552
LqhAddAttrReq * const req = (LqhAddAttrReq*)signal->getDataPtrSend();
4554
for(i = 0; i<LqhAddAttrReq::MAX_ATTRIBUTES && attributePtrI != RNIL; i++){
4556
AttributeRecordPtr attrPtr;
4557
c_attributeRecordPool.getPtr(attrPtr, attributePtrI);
4558
LqhAddAttrReq::Entry& entry = req->attributes[i];
4559
entry.attrId = attrPtr.p->attributeId;
4560
entry.attrDescriptor = attrPtr.p->attributeDescriptor;
4561
entry.extTypeInfo = 0;
4562
// charset number passed to TUP, TUX in upper half
4563
entry.extTypeInfo |= (attrPtr.p->extPrecision & ~0xFFFF);
4564
if (tabPtr.p->isIndex()) {
4565
Uint32 primaryAttrId;
4566
if (attrPtr.p->nextAttrInTable != RNIL) {
4567
getIndexAttr(tabPtr, attributePtrI, &primaryAttrId);
4569
primaryAttrId = ZNIL;
4570
if (tabPtr.p->isOrderedIndex())
4571
entry.attrId = 0; // attribute goes to TUP
4573
entry.attrId |= (primaryAttrId << 16);
4575
attributePtrI = attrPtr.p->nextAttrInTable;
4577
req->lqhFragPtr = createTabPtr.p->m_lqhFragPtr;
4578
req->senderData = createTabPtr.p->key;
4579
req->senderAttrPtr = attributePtrI;
4580
req->noOfAttributes = i;
4582
sendSignal(DBLQH_REF, GSN_LQHADDATTREQ, signal,
4583
LqhAddAttrReq::HeaderLength + LqhAddAttrReq::EntryLength * i, JBB);
4587
Dbdict::execLQHADDATTREF(Signal * signal){
4589
LqhAddAttrRef * const ref = (LqhAddAttrRef*)signal->getDataPtr();
4591
CreateTableRecordPtr createTabPtr;
4592
ndbrequire(c_opCreateTable.find(createTabPtr, ref->senderData));
4594
createTabPtr.p->setErrorCode(ref->errorCode);
4597
AddFragRef * const ref = (AddFragRef*)signal->getDataPtr();
4598
ref->dihPtr = createTabPtr.p->m_dihAddFragPtr;
4599
sendSignal(DBDIH_REF, GSN_ADD_FRAGREF, signal,
4600
AddFragRef::SignalLength, JBB);
4606
Dbdict::execLQHADDATTCONF(Signal * signal){
4608
LqhAddAttrConf * const conf = (LqhAddAttrConf*)signal->getDataPtr();
4610
CreateTableRecordPtr createTabPtr;
4611
ndbrequire(c_opCreateTable.find(createTabPtr, conf->senderData));
4613
const Uint32 fragId = conf->fragId;
4614
const Uint32 nextAttrPtr = conf->senderAttrPtr;
4615
if(nextAttrPtr != RNIL){
4617
sendLQHADDATTRREQ(signal, createTabPtr, nextAttrPtr);
4622
AddFragConf * const conf = (AddFragConf*)signal->getDataPtr();
4623
conf->dihPtr = createTabPtr.p->m_dihAddFragPtr;
4624
conf->fragId = fragId;
4625
sendSignal(DBDIH_REF, GSN_ADD_FRAGCONF, signal,
4626
AddFragConf::SignalLength, JBB);
4631
Dbdict::execDIADDTABREF(Signal* signal){
4634
DiAddTabRef * const ref = (DiAddTabRef*)signal->getDataPtr();
4636
CreateTableRecordPtr createTabPtr;
4637
ndbrequire(c_opCreateTable.find(createTabPtr, ref->senderData));
4639
createTabPtr.p->setErrorCode(ref->errorCode);
4640
execute(signal, createTabPtr.p->m_callback, 0);
4644
Dbdict::execDIADDTABCONF(Signal* signal){
4647
DiAddTabConf * const conf = (DiAddTabConf*)signal->getDataPtr();
4649
CreateTableRecordPtr createTabPtr;
4650
ndbrequire(c_opCreateTable.find(createTabPtr, conf->senderData));
4652
signal->theData[0] = createTabPtr.p->key;
4653
signal->theData[1] = reference();
4654
signal->theData[2] = createTabPtr.p->m_tablePtrI;
4656
if(createTabPtr.p->m_dihAddFragPtr != RNIL){
4660
* We did perform at least one LQHFRAGREQ
4662
sendSignal(DBLQH_REF, GSN_TAB_COMMITREQ, signal, 3, JBB);
4666
* No local fragment (i.e. no LQHFRAGREQ)
4668
execute(signal, createTabPtr.p->m_callback, 0);
4670
//sendSignal(DBDIH_REF, GSN_TAB_COMMITREQ, signal, 3, JBB);
4675
Dbdict::execTAB_COMMITREF(Signal* signal) {
4678
}//execTAB_COMMITREF()
4681
Dbdict::execTAB_COMMITCONF(Signal* signal){
4684
CreateTableRecordPtr createTabPtr;
4685
ndbrequire(c_opCreateTable.find(createTabPtr, signal->theData[0]));
4687
if(refToBlock(signal->getSendersBlockRef()) == DBLQH){
4689
execute(signal, createTabPtr.p->m_callback, 0);
4693
if(refToBlock(signal->getSendersBlockRef()) == DBDIH){
4694
TableRecordPtr tabPtr;
4695
c_tableRecordPool.getPtr(tabPtr, createTabPtr.p->m_tablePtrI);
4697
signal->theData[0] = tabPtr.i;
4698
signal->theData[1] = tabPtr.p->tableVersion;
4699
signal->theData[2] = (Uint32)tabPtr.p->storedTable;
4700
signal->theData[3] = reference();
4701
signal->theData[4] = (Uint32)tabPtr.p->tableType;
4702
signal->theData[5] = createTabPtr.p->key;
4703
signal->theData[6] = (Uint32)tabPtr.p->noOfPrimkey;
4705
sendSignal(DBTC_REF, GSN_TC_SCHVERREQ, signal, 7, JBB);
4713
Dbdict::createTab_dihComplete(Signal* signal,
4714
Uint32 callbackData,
4718
CreateTableRecordPtr createTabPtr;
4719
ndbrequire(c_opCreateTable.find(createTabPtr, callbackData));
4721
//@todo check for master failed
4723
if(createTabPtr.p->m_errorCode == 0){
4726
CreateTabConf * const conf = (CreateTabConf*)signal->getDataPtr();
4727
conf->senderRef = reference();
4728
conf->senderData = createTabPtr.p->key;
4729
sendSignal(createTabPtr.p->m_coordinatorRef, GSN_CREATE_TAB_CONF,
4730
signal, CreateTabConf::SignalLength, JBB);
4734
CreateTabRef * const ref = (CreateTabRef*)signal->getDataPtr();
4735
ref->senderRef = reference();
4736
ref->senderData = createTabPtr.p->key;
4737
ref->errorCode = createTabPtr.p->m_errorCode;
4740
ref->errorStatus = 0;
4742
sendSignal(createTabPtr.p->m_coordinatorRef, GSN_CREATE_TAB_REF,
4743
signal, CreateTabRef::SignalLength, JBB);
4747
Dbdict::createTab_commit(Signal * signal, CreateTabReq * req){
4750
CreateTableRecordPtr createTabPtr;
4751
ndbrequire(c_opCreateTable.find(createTabPtr, req->senderData));
4753
TableRecordPtr tabPtr;
4754
c_tableRecordPool.getPtr(tabPtr, createTabPtr.p->m_tablePtrI);
4756
SchemaFile::TableEntry tabEntry;
4757
tabEntry.m_tableVersion = tabPtr.p->tableVersion;
4758
tabEntry.m_tableType = tabPtr.p->tableType;
4759
tabEntry.m_tableState = SchemaFile::TABLE_ADD_COMMITTED;
4760
tabEntry.m_gcp = tabPtr.p->gciTableCreated;
4761
tabEntry.m_info_words = tabPtr.p->packedSize;
4762
memset(tabEntry.m_unused, 0, sizeof(tabEntry.m_unused));
4765
callback.m_callbackData = createTabPtr.p->key;
4766
callback.m_callbackFunction =
4767
safe_cast(&Dbdict::createTab_writeSchemaConf2);
4769
updateSchemaState(signal, tabPtr.i, &tabEntry, &callback);
4773
Dbdict::createTab_writeSchemaConf2(Signal* signal,
4774
Uint32 callbackData,
4778
CreateTableRecordPtr createTabPtr;
4779
ndbrequire(c_opCreateTable.find(createTabPtr, callbackData));
4782
c.m_callbackData = callbackData;
4783
c.m_callbackFunction = safe_cast(&Dbdict::createTab_alterComplete);
4784
alterTab_activate(signal, createTabPtr, &c);
4788
Dbdict::createTab_alterComplete(Signal* signal,
4789
Uint32 callbackData,
4793
CreateTableRecordPtr createTabPtr;
4794
ndbrequire(c_opCreateTable.find(createTabPtr, callbackData));
4796
TableRecordPtr tabPtr;
4797
c_tableRecordPool.getPtr(tabPtr, createTabPtr.p->m_tablePtrI);
4798
tabPtr.p->tabState = TableRecord::DEFINED;
4801
//@todo check master failed
4803
CreateTabConf * const conf = (CreateTabConf*)signal->getDataPtr();
4804
conf->senderRef = reference();
4805
conf->senderData = createTabPtr.p->key;
4806
sendSignal(createTabPtr.p->m_coordinatorRef, GSN_CREATE_TAB_CONF,
4807
signal, CreateTabConf::SignalLength, JBB);
4809
if(createTabPtr.p->m_coordinatorRef != reference()){
4811
c_opCreateTable.release(createTabPtr);
4816
Dbdict::createTab_drop(Signal* signal, CreateTabReq * req){
4819
const Uint32 key = req->senderData;
4821
CreateTableRecordPtr createTabPtr;
4822
ndbrequire(c_opCreateTable.find(createTabPtr, key));
4824
TableRecordPtr tabPtr;
4825
c_tableRecordPool.getPtr(tabPtr, createTabPtr.p->m_tablePtrI);
4826
tabPtr.p->tabState = TableRecord::DROPPING;
4828
DropTableRecordPtr dropTabPtr;
4829
ndbrequire(c_opDropTable.seize(dropTabPtr));
4831
dropTabPtr.p->key = key;
4832
c_opDropTable.add(dropTabPtr);
4834
dropTabPtr.p->m_errorCode = 0;
4835
dropTabPtr.p->m_request.tableId = createTabPtr.p->m_tablePtrI;
4836
dropTabPtr.p->m_requestType = DropTabReq::CreateTabDrop;
4837
dropTabPtr.p->m_coordinatorRef = createTabPtr.p->m_coordinatorRef;
4838
dropTabPtr.p->m_participantData.m_gsn = GSN_DROP_TAB_REQ;
4840
dropTabPtr.p->m_participantData.m_block = 0;
4841
dropTabPtr.p->m_participantData.m_callback.m_callbackData = req->senderData;
4842
dropTabPtr.p->m_participantData.m_callback.m_callbackFunction =
4843
safe_cast(&Dbdict::createTab_dropComplete);
4844
dropTab_nextStep(signal, dropTabPtr);
4848
Dbdict::createTab_dropComplete(Signal* signal,
4849
Uint32 callbackData,
4853
CreateTableRecordPtr createTabPtr;
4854
ndbrequire(c_opCreateTable.find(createTabPtr, callbackData));
4856
DropTableRecordPtr dropTabPtr;
4857
ndbrequire(c_opDropTable.find(dropTabPtr, callbackData));
4859
TableRecordPtr tabPtr;
4860
c_tableRecordPool.getPtr(tabPtr, createTabPtr.p->m_tablePtrI);
4862
releaseTableObject(tabPtr.i);
4864
XSchemaFile * xsf = &c_schemaFile[c_schemaRecord.schemaPage != 0];
4865
SchemaFile::TableEntry * tableEntry = getTableEntry(xsf, tabPtr.i);
4866
tableEntry->m_tableState = SchemaFile::DROP_TABLE_COMMITTED;
4869
//@todo check master failed
4871
CreateTabConf * const conf = (CreateTabConf*)signal->getDataPtr();
4872
conf->senderRef = reference();
4873
conf->senderData = createTabPtr.p->key;
4874
sendSignal(createTabPtr.p->m_coordinatorRef, GSN_CREATE_TAB_CONF,
4875
signal, CreateTabConf::SignalLength, JBB);
4877
if(createTabPtr.p->m_coordinatorRef != reference()){
4879
c_opCreateTable.release(createTabPtr);
4882
c_opDropTable.release(dropTabPtr);
4886
Dbdict::alterTab_activate(Signal* signal, CreateTableRecordPtr createTabPtr,
4889
createTabPtr.p->m_callback = * c;
4891
signal->theData[0] = createTabPtr.p->key;
4892
signal->theData[1] = reference();
4893
signal->theData[2] = createTabPtr.p->m_tablePtrI;
4894
sendSignal(DBDIH_REF, GSN_TAB_COMMITREQ, signal, 3, JBB);
4898
Dbdict::execTC_SCHVERCONF(Signal* signal){
4901
CreateTableRecordPtr createTabPtr;
4902
ndbrequire(c_opCreateTable.find(createTabPtr, signal->theData[1]));
4904
execute(signal, createTabPtr.p->m_callback, 0);
4907
#define tabRequire(cond, error) \
4910
parseP->errorCode = error; parseP->errorLine = __LINE__; \
4911
parseP->errorKey = it.getKey(); \
4915
// handleAddTableFailure(signal, __LINE__, allocatedTable);
4917
void Dbdict::handleTabInfoInit(SimpleProperties::Reader & it,
4918
ParseDictTabInfoRecord * parseP,
4921
/* ---------------------------------------------------------------- */
4922
// We always start by handling table name since this must be the first
4923
// item in the list. Through the table name we can derive if it is a
4924
// correct name, a new name or an already existing table.
4925
/* ---------------------------------------------------------------- */
4929
SimpleProperties::UnpackStatus status;
4930
DictTabInfo::Table tableDesc; tableDesc.init();
4931
status = SimpleProperties::unpack(it, &tableDesc,
4932
DictTabInfo::TableMapping,
4933
DictTabInfo::TableMappingSize,
4936
if(status != SimpleProperties::Break){
4937
parseP->errorCode = CreateTableRef::InvalidFormat;
4938
parseP->status = status;
4939
parseP->errorKey = it.getKey();
4940
parseP->errorLine = __LINE__;
4944
if(parseP->requestType == DictTabInfo::AlterTableFromAPI)
4946
ndbrequire(!checkExist);
4950
ndbrequire(parseP->requestType == DictTabInfo::AlterTableFromAPI);
4953
/* ---------------------------------------------------------------- */
4954
// Verify that table name is an allowed table name.
4956
/* ---------------------------------------------------------------- */
4957
const Uint32 tableNameLength = strlen(tableDesc.TableName) + 1;
4959
TableRecord keyRecord;
4960
tabRequire(tableNameLength <= sizeof(keyRecord.tableName),
4961
CreateTableRef::TableNameTooLong);
4962
strcpy(keyRecord.tableName, tableDesc.TableName);
4964
TableRecordPtr tablePtr;
4965
c_tableRecordHash.find(tablePtr, keyRecord);
4969
/* ---------------------------------------------------------------- */
4970
// Check if table already existed.
4971
/* ---------------------------------------------------------------- */
4972
tabRequire(tablePtr.i == RNIL, CreateTableRef::TableAlreadyExist);
4975
switch (parseP->requestType) {
4976
case DictTabInfo::CreateTableFromAPI: {
4979
case DictTabInfo::AlterTableFromAPI:{
4981
tablePtr.i = getFreeTableRecord(tableDesc.PrimaryTableId);
4982
/* ---------------------------------------------------------------- */
4983
// Check if no free tables existed.
4984
/* ---------------------------------------------------------------- */
4985
tabRequire(tablePtr.i != RNIL, CreateTableRef::NoMoreTableRecords);
4987
c_tableRecordPool.getPtr(tablePtr);
4990
case DictTabInfo::AddTableFromDict:
4991
case DictTabInfo::ReadTableFromDiskSR:
4992
case DictTabInfo::GetTabInfoConf:
4994
/* ---------------------------------------------------------------- */
4995
// Get table id and check that table doesn't already exist
4996
/* ---------------------------------------------------------------- */
4997
tablePtr.i = tableDesc.TableId;
4999
if (parseP->requestType == DictTabInfo::ReadTableFromDiskSR) {
5000
ndbrequire(tablePtr.i == c_restartRecord.activeTable);
5002
if (parseP->requestType == DictTabInfo::GetTabInfoConf) {
5003
ndbrequire(tablePtr.i == c_restartRecord.activeTable);
5006
c_tableRecordPool.getPtr(tablePtr);
5007
ndbrequire(tablePtr.p->tabState == TableRecord::NOT_DEFINED);
5009
//Uint32 oldTableVersion = tablePtr.p->tableVersion;
5010
initialiseTableRecord(tablePtr);
5011
if (parseP->requestType == DictTabInfo::AddTableFromDict) {
5013
tablePtr.p->tabState = TableRecord::DEFINING;
5015
#ifdef HAVE_TABLE_REORG
5016
/* ---------------------------------------------------------------- */
5017
// Get id of second table id and check that table doesn't already exist
5018
// and set up links between first and second table.
5019
/* ---------------------------------------------------------------- */
5020
TableRecordPtr secondTablePtr;
5021
secondTablePtr.i = tableDesc.SecondTableId;
5022
c_tableRecordPool.getPtr(secondTablePtr);
5023
ndbrequire(secondTablePtr.p->tabState == TableRecord::NOT_DEFINED);
5025
initialiseTableRecord(secondTablePtr);
5026
secondTablePtr.p->tabState = TableRecord::REORG_TABLE_PREPARED;
5027
secondTablePtr.p->secondTable = tablePtr.i;
5028
tablePtr.p->secondTable = secondTablePtr.i;
5030
/* ---------------------------------------------------------------- */
5031
// Set table version
5032
/* ---------------------------------------------------------------- */
5033
Uint32 tableVersion = tableDesc.TableVersion;
5034
tablePtr.p->tableVersion = tableVersion;
5042
parseP->tablePtr = tablePtr;
5044
strcpy(tablePtr.p->tableName, keyRecord.tableName);
5045
if (parseP->requestType != DictTabInfo::AlterTableFromAPI) {
5048
ndbout_c("Dbdict: name=%s,id=%u", tablePtr.p->tableName, tablePtr.i);
5050
ndbrequire(!c_tableRecordHash.find(tmp, * tablePtr.p));
5052
c_tableRecordHash.add(tablePtr);
5055
//tablePtr.p->noOfPrimkey = tableDesc.NoOfKeyAttr;
5056
//tablePtr.p->noOfNullAttr = tableDesc.NoOfNullable;
5057
//tablePtr.p->tupKeyLength = tableDesc.KeyLength;
5058
tablePtr.p->noOfAttributes = tableDesc.NoOfAttributes;
5059
tablePtr.p->storedTable = tableDesc.TableLoggedFlag;
5060
tablePtr.p->minLoadFactor = tableDesc.MinLoadFactor;
5061
tablePtr.p->maxLoadFactor = tableDesc.MaxLoadFactor;
5062
tablePtr.p->fragmentType = (DictTabInfo::FragmentType)tableDesc.FragmentType;
5063
tablePtr.p->tableType = (DictTabInfo::TableType)tableDesc.TableType;
5064
tablePtr.p->kValue = tableDesc.TableKValue;
5065
tablePtr.p->fragmentCount = tableDesc.FragmentCount;
5066
tablePtr.p->maxRowsLow = tableDesc.MaxRowsLow;
5067
tablePtr.p->maxRowsHigh = tableDesc.MaxRowsHigh;
5068
tablePtr.p->minRowsLow = tableDesc.MinRowsLow;
5069
tablePtr.p->minRowsHigh = tableDesc.MinRowsHigh;
5072
(((Uint64)tablePtr.p->maxRowsHigh) << 32) + tablePtr.p->maxRowsLow;
5074
(((Uint64)tablePtr.p->minRowsHigh) << 32) + tablePtr.p->minRowsLow;
5076
tablePtr.p->frmLen = tableDesc.FrmLen;
5077
memcpy(tablePtr.p->frmData, tableDesc.FrmData, tableDesc.FrmLen);
5079
if(tableDesc.PrimaryTableId != RNIL) {
5081
tablePtr.p->primaryTableId = tableDesc.PrimaryTableId;
5082
tablePtr.p->indexState = (TableRecord::IndexState)tableDesc.IndexState;
5083
tablePtr.p->insertTriggerId = tableDesc.InsertTriggerId;
5084
tablePtr.p->updateTriggerId = tableDesc.UpdateTriggerId;
5085
tablePtr.p->deleteTriggerId = tableDesc.DeleteTriggerId;
5086
tablePtr.p->customTriggerId = tableDesc.CustomTriggerId;
5088
tablePtr.p->primaryTableId = RNIL;
5089
tablePtr.p->indexState = TableRecord::IS_UNDEFINED;
5090
tablePtr.p->insertTriggerId = RNIL;
5091
tablePtr.p->updateTriggerId = RNIL;
5092
tablePtr.p->deleteTriggerId = RNIL;
5093
tablePtr.p->customTriggerId = RNIL;
5095
tablePtr.p->buildTriggerId = RNIL;
5096
tablePtr.p->indexLocal = 0;
5098
handleTabInfo(it, parseP);
5100
if(parseP->errorCode != 0)
5105
releaseTableObject(tablePtr.i, checkExist);
5107
}//handleTabInfoInit()
5109
void Dbdict::handleTabInfo(SimpleProperties::Reader & it,
5110
ParseDictTabInfoRecord * parseP)
5112
TableRecordPtr tablePtr = parseP->tablePtr;
5114
SimpleProperties::UnpackStatus status;
5116
Uint32 keyCount = 0;
5117
Uint32 keyLength = 0;
5118
Uint32 attrCount = tablePtr.p->noOfAttributes;
5119
Uint32 nullCount = 0;
5120
Uint32 nullBits = 0;
5121
Uint32 noOfCharsets = 0;
5122
Uint16 charsets[128];
5123
Uint32 recordLength = 0;
5124
AttributeRecordPtr attrPtr;
5125
c_attributeRecordHash.removeAll();
5127
for(Uint32 i = 0; i<attrCount; i++){
5131
DictTabInfo::Attribute attrDesc; attrDesc.init();
5132
status = SimpleProperties::unpack(it, &attrDesc,
5133
DictTabInfo::AttributeMapping,
5134
DictTabInfo::AttributeMappingSize,
5136
if(status != SimpleProperties::Break){
5137
parseP->errorCode = CreateTableRef::InvalidFormat;
5138
parseP->status = status;
5139
parseP->errorKey = it.getKey();
5140
parseP->errorLine = __LINE__;
5145
* Check that attribute is not defined twice
5147
AttributeRecord tmpAttr;
5149
strcpy(tmpAttr.attributeName, attrDesc.AttributeName);
5151
AttributeRecordPtr attrPtr;
5152
c_attributeRecordHash.find(attrPtr, tmpAttr);
5154
if(attrPtr.i != RNIL){
5155
parseP->errorCode = CreateTableRef::AttributeNameTwice;
5160
if(!getNewAttributeRecord(tablePtr, attrPtr)){
5162
parseP->errorCode = CreateTableRef::NoMoreAttributeRecords;
5167
* TmpAttrib to Attribute mapping
5169
strcpy(attrPtr.p->attributeName, attrDesc.AttributeName);
5170
attrPtr.p->attributeId = attrDesc.AttributeId;
5171
attrPtr.p->tupleKey = (keyCount + 1) * attrDesc.AttributeKeyFlag;
5173
attrPtr.p->extPrecision = attrDesc.AttributeExtPrecision;
5174
attrPtr.p->extScale = attrDesc.AttributeExtScale;
5175
attrPtr.p->extLength = attrDesc.AttributeExtLength;
5176
// charset in upper half of precision
5177
unsigned csNumber = (attrPtr.p->extPrecision >> 16);
5178
if (csNumber != 0) {
5180
* A new charset is first accessed here on this node.
5181
* TODO use separate thread (e.g. via NDBFS) if need to load from file
5183
CHARSET_INFO* cs = get_charset(csNumber, MYF(0));
5185
parseP->errorCode = CreateTableRef::InvalidCharset;
5186
parseP->errorLine = __LINE__;
5189
// XXX should be done somewhere in mysql
5190
all_charsets[cs->number] = cs;
5192
while (i < noOfCharsets) {
5193
if (charsets[i] == csNumber)
5197
if (i == noOfCharsets) {
5199
if (noOfCharsets > sizeof(charsets)/sizeof(charsets[0])) {
5200
parseP->errorCode = CreateTableRef::InvalidFormat;
5201
parseP->errorLine = __LINE__;
5204
charsets[i] = csNumber;
5208
// compute attribute size and array size
5209
bool translateOk = attrDesc.translateExtType();
5210
tabRequire(translateOk, CreateTableRef::Inconsistency);
5212
if(attrDesc.AttributeArraySize > 65535){
5213
parseP->errorCode = CreateTableRef::ArraySizeTooBig;
5214
parseP->status = status;
5215
parseP->errorKey = it.getKey();
5216
parseP->errorLine = __LINE__;
5221
AttributeDescriptor::setType(desc, attrDesc.AttributeExtType);
5222
AttributeDescriptor::setSize(desc, attrDesc.AttributeSize);
5223
AttributeDescriptor::setArray(desc, attrDesc.AttributeArraySize);
5224
AttributeDescriptor::setNullable(desc, attrDesc.AttributeNullableFlag);
5225
AttributeDescriptor::setDKey(desc, attrDesc.AttributeDKey);
5226
AttributeDescriptor::setPrimaryKey(desc, attrDesc.AttributeKeyFlag);
5227
attrPtr.p->attributeDescriptor = desc;
5228
attrPtr.p->autoIncrement = attrDesc.AttributeAutoIncrement;
5229
strcpy(attrPtr.p->defaultValue, attrDesc.AttributeDefaultValue);
5231
tabRequire(attrDesc.AttributeId == i, CreateTableRef::InvalidFormat);
5234
keyCount += attrDesc.AttributeKeyFlag;
5235
nullCount += attrDesc.AttributeNullableFlag;
5237
const Uint32 aSz = (1 << attrDesc.AttributeSize);
5241
sz = ((aSz * attrDesc.AttributeArraySize) + 31) >> 5;
5246
nullBits += attrDesc.AttributeArraySize;
5249
if(attrDesc.AttributeArraySize == 0)
5251
parseP->errorCode = CreateTableRef::InvalidArraySize;
5252
parseP->status = status;
5253
parseP->errorKey = it.getKey();
5254
parseP->errorLine = __LINE__;
5259
if(attrDesc.AttributeKeyFlag){
5262
if(attrDesc.AttributeNullableFlag){
5263
parseP->errorCode = CreateTableRef::NullablePrimaryKey;
5264
parseP->status = status;
5265
parseP->errorKey = it.getKey();
5266
parseP->errorLine = __LINE__;
5271
if (parseP->requestType != DictTabInfo::AlterTableFromAPI)
5272
c_attributeRecordHash.add(attrPtr);
5277
if(it.getKey() != DictTabInfo::AttributeName)
5281
tablePtr.p->noOfPrimkey = keyCount;
5282
tablePtr.p->noOfNullAttr = nullCount;
5283
tablePtr.p->noOfCharsets = noOfCharsets;
5284
tablePtr.p->tupKeyLength = keyLength;
5285
tablePtr.p->noOfNullBits = nullCount + nullBits;
5287
tabRequire(recordLength<= MAX_TUPLE_SIZE_IN_WORDS,
5288
CreateTableRef::RecordTooBig);
5289
tabRequire(keyLength <= MAX_KEY_SIZE_IN_WORDS,
5290
CreateTableRef::InvalidPrimaryKeySize);
5291
tabRequire(keyLength > 0,
5292
CreateTableRef::InvalidPrimaryKeySize);
5297
/* ---------------------------------------------------------------- */
5298
// DICTTABCONF is sent when participants have received all DICTTABINFO
5299
// and successfully handled it.
5300
// Also sent to self (DICT master) when index table creation ready.
5301
/* ---------------------------------------------------------------- */
5302
void Dbdict::execCREATE_TABLE_CONF(Signal* signal)
5305
ndbrequire(signal->getNoOfSections() == 0);
5307
CreateTableConf * const conf = (CreateTableConf *)signal->getDataPtr();
5308
// assume part of create index operation
5309
OpCreateIndexPtr opPtr;
5310
c_opCreateIndex.find(opPtr, conf->senderData);
5311
ndbrequire(! opPtr.isNull());
5312
opPtr.p->m_request.setIndexId(conf->tableId);
5313
opPtr.p->m_request.setIndexVersion(conf->tableVersion);
5314
createIndex_fromCreateTable(signal, opPtr);
5315
}//execCREATE_TABLE_CONF()
5317
void Dbdict::execCREATE_TABLE_REF(Signal* signal)
5321
CreateTableRef * const ref = (CreateTableRef *)signal->getDataPtr();
5322
// assume part of create index operation
5323
OpCreateIndexPtr opPtr;
5324
c_opCreateIndex.find(opPtr, ref->senderData);
5325
ndbrequire(! opPtr.isNull());
5326
opPtr.p->setError(ref);
5327
createIndex_fromCreateTable(signal, opPtr);
5328
}//execCREATE_TABLE_REF()
5330
/* ---------------------------------------------------------------- */
5331
// New global checkpoint created.
5332
/* ---------------------------------------------------------------- */
5333
void Dbdict::execWAIT_GCP_CONF(Signal* signal)
5336
TableRecordPtr tablePtr;
5338
WaitGCPConf* const conf = (WaitGCPConf*)&signal->theData[0];
5339
c_tableRecordPool.getPtr(tablePtr, c_connRecord.connTableId);
5340
tablePtr.p->gciTableCreated = conf->gcp;
5341
sendUpdateSchemaState(signal,
5343
SchemaFile::TABLE_ADD_COMMITTED,
5344
c_connRecord.noOfPagesForTable,
5347
}//execWAIT_GCP_CONF()
5349
/* ---------------------------------------------------------------- */
5350
// Refused new global checkpoint.
5351
/* ---------------------------------------------------------------- */
5352
void Dbdict::execWAIT_GCP_REF(Signal* signal)
5355
WaitGCPRef* const ref = (WaitGCPRef*)&signal->theData[0];
5356
/* ---------------------------------------------------------------- */
5357
// Error Handling code needed
5358
/* ---------------------------------------------------------------- */
5360
BaseString::snprintf(buf, sizeof(buf), "WAIT_GCP_REF ErrorCode=%d",
5362
progError(__LINE__, NDBD_EXIT_NDBREQUIRE, buf);
5363
}//execWAIT_GCP_REF()
5366
/* **************************************************************** */
5367
/* ---------------------------------------------------------------- */
5368
/* MODULE: DROP TABLE -------------------- */
5369
/* ---------------------------------------------------------------- */
5371
/* This module contains the code used to drop a table. */
5372
/* ---------------------------------------------------------------- */
5373
/* **************************************************************** */
5375
Dbdict::execDROP_TABLE_REQ(Signal* signal){
5377
DropTableReq* req = (DropTableReq*)signal->getDataPtr();
5379
TableRecordPtr tablePtr;
5380
c_tableRecordPool.getPtr(tablePtr, req->tableId, false);
5381
if(tablePtr.isNull()){
5383
dropTableRef(signal, req, DropTableRef::NoSuchTable);
5387
if(getOwnNodeId() != c_masterNodeId){
5389
dropTableRef(signal, req, DropTableRef::NotMaster);
5393
if(c_blockState == BS_NODE_RESTART){
5395
dropTableRef(signal, req, DropTableRef::BusyWithNR);
5399
if(c_blockState != BS_IDLE){
5401
dropTableRef(signal, req, DropTableRef::Busy);
5405
const TableRecord::TabState tabState = tablePtr.p->tabState;
5408
case TableRecord::NOT_DEFINED:
5409
case TableRecord::REORG_TABLE_PREPARED:
5410
case TableRecord::DEFINING:
5411
case TableRecord::CHECKED:
5413
dropTableRef(signal, req, DropTableRef::NoSuchTable);
5415
case TableRecord::DEFINED:
5419
case TableRecord::PREPARE_DROPPING:
5420
case TableRecord::DROPPING:
5422
dropTableRef(signal, req, DropTableRef::DropInProgress);
5424
case TableRecord::BACKUP_ONGOING:
5426
dropTableRef(signal, req, DropTableRef::BackupInProgress);
5431
if(tablePtr.p->tableVersion != req->tableVersion){
5433
dropTableRef(signal, req, DropTableRef::InvalidTableVersion);
5440
DropTableRecordPtr dropTabPtr;
5441
c_opDropTable.seize(dropTabPtr);
5443
if(dropTabPtr.isNull()){
5445
dropTableRef(signal, req, DropTableRef::NoDropTableRecordAvailable);
5449
c_blockState = BS_BUSY;
5451
dropTabPtr.p->key = ++c_opRecordSequence;
5452
c_opDropTable.add(dropTabPtr);
5454
dropTabPtr.p->m_request = * req;
5455
dropTabPtr.p->m_errorCode = 0;
5456
dropTabPtr.p->m_requestType = DropTabReq::OnlineDropTab;
5457
dropTabPtr.p->m_coordinatorRef = reference();
5458
dropTabPtr.p->m_coordinatorData.m_gsn = GSN_PREP_DROP_TAB_REQ;
5459
dropTabPtr.p->m_coordinatorData.m_block = 0;
5461
Mutex mutex(signal, c_mutexMgr, dropTabPtr.p->m_define_backup_mutex);
5462
Callback c = { safe_cast(&Dbdict::dropTable_backup_mutex_locked),
5465
ndbrequire(mutex.lock(c));
5470
Dbdict::dropTable_backup_mutex_locked(Signal* signal,
5471
Uint32 callbackData,
5475
ndbrequire(retValue == 0);
5477
DropTableRecordPtr dropTabPtr;
5478
ndbrequire(c_opDropTable.find(dropTabPtr, callbackData));
5480
TableRecordPtr tablePtr;
5481
c_tableRecordPool.getPtr(tablePtr, dropTabPtr.p->m_request.tableId, true);
5483
Mutex mutex(signal, c_mutexMgr, dropTabPtr.p->m_define_backup_mutex);
5484
mutex.unlock(); // ignore response
5486
if(tablePtr.p->tabState == TableRecord::BACKUP_ONGOING)
5489
dropTableRef(signal, &dropTabPtr.p->m_request,
5490
DropTableRef::BackupInProgress);
5492
c_blockState = BS_IDLE;
5493
c_opDropTable.release(dropTabPtr);
5498
tablePtr.p->tabState = TableRecord::PREPARE_DROPPING;
5499
prepDropTab_nextStep(signal, dropTabPtr);
5504
Dbdict::dropTableRef(Signal * signal,
5505
DropTableReq * req, DropTableRef::ErrorCode errCode){
5507
Uint32 tableId = req->tableId;
5508
Uint32 tabVersion = req->tableVersion;
5509
Uint32 senderData = req->senderData;
5510
Uint32 senderRef = req->senderRef;
5512
DropTableRef * ref = (DropTableRef*)signal->getDataPtrSend();
5513
ref->tableId = tableId;
5514
ref->tableVersion = tabVersion;
5515
ref->senderData = senderData;
5516
ref->senderRef = reference();
5517
ref->errorCode = errCode;
5518
ref->masterNodeId = c_masterNodeId;
5519
sendSignal(senderRef, GSN_DROP_TABLE_REF, signal,
5520
DropTableRef::SignalLength, JBB);
5524
Dbdict::prepDropTab_nextStep(Signal* signal, DropTableRecordPtr dropTabPtr){
5527
* No errors currently allowed
5529
ndbrequire(dropTabPtr.p->m_errorCode == 0);
5532
switch(dropTabPtr.p->m_coordinatorData.m_block){
5535
block = dropTabPtr.p->m_coordinatorData.m_block = DBDICT;
5539
block = dropTabPtr.p->m_coordinatorData.m_block = DBLQH;
5543
block = dropTabPtr.p->m_coordinatorData.m_block = DBTC;
5547
block = dropTabPtr.p->m_coordinatorData.m_block = DBDIH;
5551
prepDropTab_complete(signal, dropTabPtr);
5557
PrepDropTabReq * prep = (PrepDropTabReq*)signal->getDataPtrSend();
5558
prep->senderRef = reference();
5559
prep->senderData = dropTabPtr.p->key;
5560
prep->tableId = dropTabPtr.p->m_request.tableId;
5561
prep->requestType = dropTabPtr.p->m_requestType;
5563
dropTabPtr.p->m_coordinatorData.m_signalCounter = c_aliveNodes;
5564
NodeReceiverGroup rg(block, c_aliveNodes);
5565
sendSignal(rg, GSN_PREP_DROP_TAB_REQ, signal,
5566
PrepDropTabReq::SignalLength, JBB);
5569
for (Uint32 i = 1; i < MAX_NDB_NODES; i++){
5570
if(c_aliveNodes.get(i)){
5572
BlockReference ref = numberToRef(block, i);
5574
dropTabPtr.p->m_coordinatorData.m_signalCounter.setWaitingFor(i);
5581
Dbdict::execPREP_DROP_TAB_CONF(Signal * signal){
5584
PrepDropTabConf * prep = (PrepDropTabConf*)signal->getDataPtr();
5586
DropTableRecordPtr dropTabPtr;
5587
ndbrequire(c_opDropTable.find(dropTabPtr, prep->senderData));
5589
ndbrequire(dropTabPtr.p->m_coordinatorRef == reference());
5590
ndbrequire(dropTabPtr.p->m_request.tableId == prep->tableId);
5591
ndbrequire(dropTabPtr.p->m_coordinatorData.m_gsn == GSN_PREP_DROP_TAB_REQ);
5593
Uint32 nodeId = refToNode(prep->senderRef);
5594
dropTabPtr.p->m_coordinatorData.m_signalCounter.clearWaitingFor(nodeId);
5596
if(!dropTabPtr.p->m_coordinatorData.m_signalCounter.done()){
5600
prepDropTab_nextStep(signal, dropTabPtr);
5604
Dbdict::execPREP_DROP_TAB_REF(Signal* signal){
5607
PrepDropTabRef * prep = (PrepDropTabRef*)signal->getDataPtr();
5609
DropTableRecordPtr dropTabPtr;
5610
ndbrequire(c_opDropTable.find(dropTabPtr, prep->senderData));
5612
ndbrequire(dropTabPtr.p->m_coordinatorRef == reference());
5613
ndbrequire(dropTabPtr.p->m_request.tableId == prep->tableId);
5614
ndbrequire(dropTabPtr.p->m_coordinatorData.m_gsn == GSN_PREP_DROP_TAB_REQ);
5616
Uint32 nodeId = refToNode(prep->senderRef);
5617
dropTabPtr.p->m_coordinatorData.m_signalCounter.clearWaitingFor(nodeId);
5619
Uint32 block = refToBlock(prep->senderRef);
5620
if((prep->errorCode == PrepDropTabRef::NoSuchTable && block == DBLQH) ||
5621
(prep->errorCode == PrepDropTabRef::NF_FakeErrorREF)){
5625
* 1) no such table and LQH, it might not exists in different LQH's
5626
* 2) node failure...
5629
dropTabPtr.p->setErrorCode((Uint32)prep->errorCode);
5632
if(!dropTabPtr.p->m_coordinatorData.m_signalCounter.done()){
5636
prepDropTab_nextStep(signal, dropTabPtr);
5640
Dbdict::prepDropTab_complete(Signal* signal, DropTableRecordPtr dropTabPtr){
5643
dropTabPtr.p->m_coordinatorData.m_gsn = GSN_DROP_TAB_REQ;
5644
dropTabPtr.p->m_coordinatorData.m_block = DBDICT;
5646
DropTabReq * req = (DropTabReq*)signal->getDataPtrSend();
5647
req->senderRef = reference();
5648
req->senderData = dropTabPtr.p->key;
5649
req->tableId = dropTabPtr.p->m_request.tableId;
5650
req->requestType = dropTabPtr.p->m_requestType;
5652
dropTabPtr.p->m_coordinatorData.m_signalCounter = c_aliveNodes;
5653
NodeReceiverGroup rg(DBDICT, c_aliveNodes);
5654
sendSignal(rg, GSN_DROP_TAB_REQ, signal,
5655
DropTabReq::SignalLength, JBB);
5659
Dbdict::execDROP_TAB_REF(Signal* signal){
5662
DropTabRef * const req = (DropTabRef*)signal->getDataPtr();
5664
Uint32 block = refToBlock(req->senderRef);
5665
ndbrequire(req->errorCode == DropTabRef::NF_FakeErrorREF ||
5666
(req->errorCode == DropTabRef::NoSuchTable &&
5667
(block == DBTUP || block == DBACC || block == DBLQH)));
5669
if(block != DBDICT){
5671
ndbrequire(refToNode(req->senderRef) == getOwnNodeId());
5672
dropTab_localDROP_TAB_CONF(signal);
5679
Dbdict::execDROP_TAB_CONF(Signal* signal){
5682
DropTabConf * const req = (DropTabConf*)signal->getDataPtr();
5684
if(refToBlock(req->senderRef) != DBDICT){
5686
ndbrequire(refToNode(req->senderRef) == getOwnNodeId());
5687
dropTab_localDROP_TAB_CONF(signal);
5691
DropTableRecordPtr dropTabPtr;
5692
ndbrequire(c_opDropTable.find(dropTabPtr, req->senderData));
5694
ndbrequire(dropTabPtr.p->m_coordinatorRef == reference());
5695
ndbrequire(dropTabPtr.p->m_request.tableId == req->tableId);
5696
ndbrequire(dropTabPtr.p->m_coordinatorData.m_gsn == GSN_DROP_TAB_REQ);
5698
Uint32 nodeId = refToNode(req->senderRef);
5699
dropTabPtr.p->m_coordinatorData.m_signalCounter.clearWaitingFor(nodeId);
5701
if(!dropTabPtr.p->m_coordinatorData.m_signalCounter.done()){
5706
DropTableConf* conf = (DropTableConf*)signal->getDataPtrSend();
5707
conf->senderRef = reference();
5708
conf->senderData = dropTabPtr.p->m_request.senderData;
5709
conf->tableId = dropTabPtr.p->m_request.tableId;
5710
conf->tableVersion = dropTabPtr.p->m_request.tableVersion;
5712
Uint32 ref = dropTabPtr.p->m_request.senderRef;
5713
sendSignal(ref, GSN_DROP_TABLE_CONF, signal,
5714
DropTableConf::SignalLength, JBB);
5716
c_opDropTable.release(dropTabPtr);
5717
c_blockState = BS_IDLE;
5721
* DROP TABLE PARTICIPANT CODE
5724
Dbdict::execPREP_DROP_TAB_REQ(Signal* signal){
5726
PrepDropTabReq * prep = (PrepDropTabReq*)signal->getDataPtrSend();
5728
DropTableRecordPtr dropTabPtr;
5729
if(prep->senderRef == reference()){
5731
ndbrequire(c_opDropTable.find(dropTabPtr, prep->senderData));
5732
ndbrequire(dropTabPtr.p->m_requestType == prep->requestType);
5735
c_opDropTable.seize(dropTabPtr);
5736
if(!dropTabPtr.isNull()){
5737
dropTabPtr.p->key = prep->senderData;
5738
c_opDropTable.add(dropTabPtr);
5742
ndbrequire(!dropTabPtr.isNull());
5744
dropTabPtr.p->m_errorCode = 0;
5745
dropTabPtr.p->m_request.tableId = prep->tableId;
5746
dropTabPtr.p->m_requestType = prep->requestType;
5747
dropTabPtr.p->m_coordinatorRef = prep->senderRef;
5748
dropTabPtr.p->m_participantData.m_gsn = GSN_PREP_DROP_TAB_REQ;
5750
TableRecordPtr tablePtr;
5751
c_tableRecordPool.getPtr(tablePtr, prep->tableId);
5752
tablePtr.p->tabState = TableRecord::PREPARE_DROPPING;
5757
XSchemaFile * xsf = &c_schemaFile[c_schemaRecord.schemaPage != 0];
5758
SchemaFile::TableEntry * tableEntry = getTableEntry(xsf, tablePtr.i);
5759
SchemaFile::TableState tabState =
5760
(SchemaFile::TableState)tableEntry->m_tableState;
5761
ndbrequire(tabState == SchemaFile::TABLE_ADD_COMMITTED ||
5762
tabState == SchemaFile::ALTER_TABLE_COMMITTED);
5763
tableEntry->m_tableState = SchemaFile::DROP_TABLE_STARTED;
5764
computeChecksum(xsf, tablePtr.i / NDB_SF_PAGE_ENTRIES);
5766
ndbrequire(c_writeSchemaRecord.inUse == false);
5767
c_writeSchemaRecord.inUse = true;
5769
c_writeSchemaRecord.pageId = c_schemaRecord.schemaPage;
5770
c_writeSchemaRecord.newFile = false;
5771
c_writeSchemaRecord.firstPage = tablePtr.i / NDB_SF_PAGE_ENTRIES;
5772
c_writeSchemaRecord.noOfPages = 1;
5773
c_writeSchemaRecord.m_callback.m_callbackData = dropTabPtr.p->key;
5774
c_writeSchemaRecord.m_callback.m_callbackFunction =
5775
safe_cast(&Dbdict::prepDropTab_writeSchemaConf);
5776
startWriteSchemaFile(signal);
5780
Dbdict::prepDropTab_writeSchemaConf(Signal* signal,
5785
DropTableRecordPtr dropTabPtr;
5786
ndbrequire(c_opDropTable.find(dropTabPtr, dropTabPtrI));
5788
ndbrequire(dropTabPtr.p->m_participantData.m_gsn == GSN_PREP_DROP_TAB_REQ);
5791
* There probably should be node fail handlign here
5793
* To check that coordinator hasn't died
5796
PrepDropTabConf * prep = (PrepDropTabConf*)signal->getDataPtr();
5797
prep->senderRef = reference();
5798
prep->senderData = dropTabPtrI;
5799
prep->tableId = dropTabPtr.p->m_request.tableId;
5801
dropTabPtr.p->m_participantData.m_gsn = GSN_PREP_DROP_TAB_CONF;
5802
sendSignal(dropTabPtr.p->m_coordinatorRef, GSN_PREP_DROP_TAB_CONF, signal,
5803
PrepDropTabConf::SignalLength, JBB);
5807
Dbdict::execDROP_TAB_REQ(Signal* signal){
5809
DropTabReq * req = (DropTabReq*)signal->getDataPtrSend();
5811
DropTableRecordPtr dropTabPtr;
5812
ndbrequire(c_opDropTable.find(dropTabPtr, req->senderData));
5814
ndbrequire(dropTabPtr.p->m_participantData.m_gsn == GSN_PREP_DROP_TAB_CONF);
5815
dropTabPtr.p->m_participantData.m_gsn = GSN_DROP_TAB_REQ;
5817
ndbrequire(dropTabPtr.p->m_requestType == req->requestType);
5819
TableRecordPtr tablePtr;
5820
c_tableRecordPool.getPtr(tablePtr, dropTabPtr.p->m_request.tableId);
5821
tablePtr.p->tabState = TableRecord::DROPPING;
5823
dropTabPtr.p->m_participantData.m_block = 0;
5824
dropTabPtr.p->m_participantData.m_callback.m_callbackData = dropTabPtr.p->key;
5825
dropTabPtr.p->m_participantData.m_callback.m_callbackFunction =
5826
safe_cast(&Dbdict::dropTab_complete);
5827
dropTab_nextStep(signal, dropTabPtr);
5830
#include <DebuggerNames.hpp>
5833
Dbdict::dropTab_nextStep(Signal* signal, DropTableRecordPtr dropTabPtr){
5836
* No errors currently allowed
5838
ndbrequire(dropTabPtr.p->m_errorCode == 0);
5840
TableRecordPtr tablePtr;
5841
c_tableRecordPool.getPtr(tablePtr, dropTabPtr.p->m_request.tableId);
5844
switch(dropTabPtr.p->m_participantData.m_block){
5851
if (tablePtr.p->isTable() || tablePtr.p->isHashIndex())
5853
if (tablePtr.p->isOrderedIndex())
5862
if (tablePtr.p->isTable() || tablePtr.p->isHashIndex())
5864
if (tablePtr.p->isOrderedIndex())
5877
execute(signal, dropTabPtr.p->m_participantData.m_callback, 0);
5880
ndbrequire(block != 0);
5881
dropTabPtr.p->m_participantData.m_block = block;
5883
DropTabReq * req = (DropTabReq*)signal->getDataPtrSend();
5884
req->senderRef = reference();
5885
req->senderData = dropTabPtr.p->key;
5886
req->tableId = dropTabPtr.p->m_request.tableId;
5887
req->requestType = dropTabPtr.p->m_requestType;
5889
const Uint32 nodeId = getOwnNodeId();
5890
dropTabPtr.p->m_participantData.m_signalCounter.clearWaitingFor();
5891
dropTabPtr.p->m_participantData.m_signalCounter.setWaitingFor(nodeId);
5892
BlockReference ref = numberToRef(block, 0);
5893
sendSignal(ref, GSN_DROP_TAB_REQ, signal, DropTabReq::SignalLength, JBB);
5897
Dbdict::dropTab_localDROP_TAB_CONF(Signal* signal){
5900
DropTabConf * conf = (DropTabConf*)signal->getDataPtr();
5902
DropTableRecordPtr dropTabPtr;
5903
ndbrequire(c_opDropTable.find(dropTabPtr, conf->senderData));
5905
ndbrequire(dropTabPtr.p->m_request.tableId == conf->tableId);
5906
ndbrequire(dropTabPtr.p->m_participantData.m_gsn == GSN_DROP_TAB_REQ);
5908
Uint32 nodeId = refToNode(conf->senderRef);
5909
dropTabPtr.p->m_participantData.m_signalCounter.clearWaitingFor(nodeId);
5911
if(!dropTabPtr.p->m_participantData.m_signalCounter.done()){
5916
dropTab_nextStep(signal, dropTabPtr);
5920
Dbdict::dropTab_complete(Signal* signal,
5925
DropTableRecordPtr dropTabPtr;
5926
ndbrequire(c_opDropTable.find(dropTabPtr, dropTabPtrI));
5928
Uint32 tableId = dropTabPtr.p->m_request.tableId;
5931
* Write to schema file
5933
XSchemaFile * xsf = &c_schemaFile[c_schemaRecord.schemaPage != 0];
5934
SchemaFile::TableEntry * tableEntry = getTableEntry(xsf, tableId);
5935
SchemaFile::TableState tabState =
5936
(SchemaFile::TableState)tableEntry->m_tableState;
5937
ndbrequire(tabState == SchemaFile::DROP_TABLE_STARTED);
5938
tableEntry->m_tableState = SchemaFile::DROP_TABLE_COMMITTED;
5939
computeChecksum(xsf, tableId / NDB_SF_PAGE_ENTRIES);
5941
ndbrequire(c_writeSchemaRecord.inUse == false);
5942
c_writeSchemaRecord.inUse = true;
5944
c_writeSchemaRecord.pageId = c_schemaRecord.schemaPage;
5945
c_writeSchemaRecord.firstPage = tableId / NDB_SF_PAGE_ENTRIES;
5946
c_writeSchemaRecord.noOfPages = 1;
5947
c_writeSchemaRecord.m_callback.m_callbackData = dropTabPtr.p->key;
5948
c_writeSchemaRecord.m_callback.m_callbackFunction =
5949
safe_cast(&Dbdict::dropTab_writeSchemaConf);
5950
startWriteSchemaFile(signal);
5954
Dbdict::dropTab_writeSchemaConf(Signal* signal,
5959
DropTableRecordPtr dropTabPtr;
5960
ndbrequire(c_opDropTable.find(dropTabPtr, dropTabPtrI));
5962
ndbrequire(dropTabPtr.p->m_participantData.m_gsn == GSN_DROP_TAB_REQ);
5964
dropTabPtr.p->m_participantData.m_gsn = GSN_DROP_TAB_CONF;
5966
releaseTableObject(dropTabPtr.p->m_request.tableId);
5968
DropTabConf * conf = (DropTabConf*)signal->getDataPtr();
5969
conf->senderRef = reference();
5970
conf->senderData = dropTabPtrI;
5971
conf->tableId = dropTabPtr.p->m_request.tableId;
5973
dropTabPtr.p->m_participantData.m_gsn = GSN_DROP_TAB_CONF;
5974
sendSignal(dropTabPtr.p->m_coordinatorRef, GSN_DROP_TAB_CONF, signal,
5975
DropTabConf::SignalLength, JBB);
5977
if(dropTabPtr.p->m_coordinatorRef != reference()){
5978
c_opDropTable.release(dropTabPtr);
5982
void Dbdict::releaseTableObject(Uint32 tableId, bool removeFromHash)
5984
TableRecordPtr tablePtr;
5985
AttributeRecordPtr attrPtr;
5986
c_tableRecordPool.getPtr(tablePtr, tableId);
5991
ndbrequire(c_tableRecordHash.find(tmp, * tablePtr.p));
5993
c_tableRecordHash.remove(tablePtr);
5995
tablePtr.p->tabState = TableRecord::NOT_DEFINED;
5997
Uint32 nextAttrRecord = tablePtr.p->firstAttribute;
5998
while (nextAttrRecord != RNIL) {
6000
/* ---------------------------------------------------------------- */
6001
// Release all attribute records
6002
/* ---------------------------------------------------------------- */
6003
c_attributeRecordPool.getPtr(attrPtr, nextAttrRecord);
6004
nextAttrRecord = attrPtr.p->nextAttrInTable;
6005
c_attributeRecordPool.release(attrPtr);
6007
#ifdef HAVE_TABLE_REORG
6008
Uint32 secondTableId = tablePtr.p->secondTable;
6009
initialiseTableRecord(tablePtr);
6010
c_tableRecordPool.getPtr(tablePtr, secondTableId);
6011
initialiseTableRecord(tablePtr);
6014
}//releaseTableObject()
6017
* DICT receives these on index create and drop.
6019
void Dbdict::execDROP_TABLE_CONF(Signal* signal)
6022
ndbrequire(signal->getNoOfSections() == 0);
6024
DropTableConf * const conf = (DropTableConf *)signal->getDataPtr();
6025
// assume part of drop index operation
6026
OpDropIndexPtr opPtr;
6027
c_opDropIndex.find(opPtr, conf->senderData);
6028
ndbrequire(! opPtr.isNull());
6029
ndbrequire(opPtr.p->m_request.getIndexId() == conf->tableId);
6030
ndbrequire(opPtr.p->m_request.getIndexVersion() == conf->tableVersion);
6031
dropIndex_fromDropTable(signal, opPtr);
6034
void Dbdict::execDROP_TABLE_REF(Signal* signal)
6038
DropTableRef * const ref = (DropTableRef *)signal->getDataPtr();
6039
// assume part of drop index operation
6040
OpDropIndexPtr opPtr;
6041
c_opDropIndex.find(opPtr, ref->senderData);
6042
ndbrequire(! opPtr.isNull());
6043
opPtr.p->setError(ref);
6044
opPtr.p->m_errorLine = __LINE__;
6045
dropIndex_fromDropTable(signal, opPtr);
6048
/* **************************************************************** */
6049
/* ---------------------------------------------------------------- */
6050
/* MODULE: EXTERNAL INTERFACE TO DATA -------------------- */
6051
/* ---------------------------------------------------------------- */
6053
/* This module contains the code that is used by other modules to. */
6054
/* access the data within DBDICT. */
6055
/* ---------------------------------------------------------------- */
6056
/* **************************************************************** */
6058
void Dbdict::execGET_TABLEDID_REQ(Signal * signal)
6061
ndbrequire(signal->getNoOfSections() == 1);
6062
GetTableIdReq const * req = (GetTableIdReq *)signal->getDataPtr();
6063
Uint32 senderData = req->senderData;
6064
Uint32 senderRef = req->senderRef;
6065
Uint32 len = req->len;
6067
if(len>MAX_TAB_NAME_SIZE)
6070
sendGET_TABLEID_REF((Signal*)signal,
6071
(GetTableIdReq *)req,
6072
GetTableIdRef::TableNameTooLong);
6076
char tableName[MAX_TAB_NAME_SIZE];
6077
TableRecord keyRecord;
6078
SegmentedSectionPtr ssPtr;
6079
signal->getSection(ssPtr,GetTableIdReq::TABLE_NAME);
6080
copy((Uint32*)tableName, ssPtr);
6081
strcpy(keyRecord.tableName, tableName);
6082
releaseSections(signal);
6084
if(len > sizeof(keyRecord.tableName)){
6086
sendGET_TABLEID_REF((Signal*)signal,
6087
(GetTableIdReq *)req,
6088
GetTableIdRef::TableNameTooLong);
6092
TableRecordPtr tablePtr;
6093
if(!c_tableRecordHash.find(tablePtr, keyRecord)) {
6095
sendGET_TABLEID_REF((Signal*)signal,
6096
(GetTableIdReq *)req,
6097
GetTableIdRef::TableNotDefined);
6100
GetTableIdConf * conf = (GetTableIdConf *)req;
6101
conf->tableId = tablePtr.p->tableId;
6102
conf->schemaVersion = tablePtr.p->tableVersion;
6103
conf->senderData = senderData;
6104
sendSignal(senderRef, GSN_GET_TABLEID_CONF, signal,
6105
GetTableIdConf::SignalLength, JBB);
6110
void Dbdict::sendGET_TABLEID_REF(Signal* signal,
6111
GetTableIdReq * req,
6112
GetTableIdRef::ErrorCode errorCode)
6114
GetTableIdRef * const ref = (GetTableIdRef *)req;
6116
* The format of GetTabInfo Req/Ref is the same
6118
BlockReference retRef = req->senderRef;
6119
ref->err = errorCode;
6120
sendSignal(retRef, GSN_GET_TABLEID_REF, signal,
6121
GetTableIdRef::SignalLength, JBB);
6122
}//sendGET_TABINFOREF()
6124
/* ---------------------------------------------------------------- */
6125
// Get a full table description.
6126
/* ---------------------------------------------------------------- */
6127
void Dbdict::execGET_TABINFOREQ(Signal* signal)
6130
if(!assembleFragments(signal))
6135
GetTabInfoReq * const req = (GetTabInfoReq *)&signal->theData[0];
6138
* If I get a GET_TABINFO_REQ from myself
6139
* it's is a one from the time queue
6141
bool fromTimeQueue = (signal->senderBlockRef() == reference());
6143
if (c_retrieveRecord.busyState && fromTimeQueue == true) {
6146
sendSignalWithDelay(reference(), GSN_GET_TABINFOREQ, signal, 30,
6151
const Uint32 MAX_WAITERS = 5;
6153
if(c_retrieveRecord.busyState && fromTimeQueue == false){
6155
if(c_retrieveRecord.noOfWaiters < MAX_WAITERS){
6157
c_retrieveRecord.noOfWaiters++;
6159
sendSignalWithDelay(reference(), GSN_GET_TABINFOREQ, signal, 30,
6164
sendGET_TABINFOREF(signal, req, GetTabInfoRef::Busy);
6170
c_retrieveRecord.noOfWaiters--;
6173
const bool useLongSig = (req->requestType & GetTabInfoReq::LongSignalConf);
6174
const Uint32 reqType = req->requestType & (~GetTabInfoReq::LongSignalConf);
6176
TableRecordPtr tablePtr;
6177
if(reqType == GetTabInfoReq::RequestByName){
6179
ndbrequire(signal->getNoOfSections() == 1);
6180
const Uint32 len = req->tableNameLen;
6182
TableRecord keyRecord;
6183
if(len > sizeof(keyRecord.tableName)){
6185
releaseSections(signal);
6186
sendGET_TABINFOREF(signal, req, GetTabInfoRef::TableNameTooLong);
6190
char tableName[MAX_TAB_NAME_SIZE];
6191
SegmentedSectionPtr ssPtr;
6192
signal->getSection(ssPtr,GetTabInfoReq::TABLE_NAME);
6193
SimplePropertiesSectionReader r0(ssPtr, getSectionSegmentPool());
6194
r0.reset(); // undo implicit first()
6195
if(r0.getWords((Uint32*)tableName, ((len + 3)/4)))
6196
memcpy(keyRecord.tableName, tableName, len);
6199
releaseSections(signal);
6200
sendGET_TABINFOREF(signal, req, GetTabInfoRef::TableNotDefined);
6203
releaseSections(signal);
6204
// memcpy(keyRecord.tableName, req->tableName, len);
6205
//ntohS(&keyRecord.tableName[0], len);
6207
c_tableRecordHash.find(tablePtr, keyRecord);
6210
c_tableRecordPool.getPtr(tablePtr, req->tableId, false);
6213
// The table seached for was not found
6214
if(tablePtr.i == RNIL){
6216
sendGET_TABINFOREF(signal, req, GetTabInfoRef::InvalidTableId);
6220
if (! (tablePtr.p->tabState == TableRecord::DEFINED ||
6221
tablePtr.p->tabState == TableRecord::BACKUP_ONGOING)) {
6223
sendGET_TABINFOREF(signal, req, GetTabInfoRef::TableNotDefined);
6227
c_retrieveRecord.busyState = true;
6228
c_retrieveRecord.blockRef = req->senderRef;
6229
c_retrieveRecord.m_senderData = req->senderData;
6230
c_retrieveRecord.tableId = tablePtr.i;
6231
c_retrieveRecord.currentSent = 0;
6232
c_retrieveRecord.m_useLongSig = useLongSig;
6234
c_packTable.m_state = PackTable::PTS_GET_TAB;
6236
signal->theData[0] = ZPACK_TABLE_INTO_PAGES;
6237
signal->theData[1] = tablePtr.i;
6238
signal->theData[2] = c_retrieveRecord.retrievePage;
6239
sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
6240
}//execGET_TABINFOREQ()
6242
void Dbdict::sendGetTabResponse(Signal* signal)
6244
PageRecordPtr pagePtr;
6245
DictTabInfo * const conf = (DictTabInfo *)&signal->theData[0];
6246
conf->senderRef = reference();
6247
conf->senderData = c_retrieveRecord.m_senderData;
6248
conf->requestType = DictTabInfo::GetTabInfoConf;
6249
conf->totalLen = c_retrieveRecord.retrievedNoOfWords;
6251
c_pageRecordArray.getPtr(pagePtr, c_retrieveRecord.retrievePage);
6252
Uint32* pagePointer = (Uint32*)&pagePtr.p->word[0] + ZPAGE_HEADER_SIZE;
6254
if(c_retrieveRecord.m_useLongSig){
6256
GetTabInfoConf* conf = (GetTabInfoConf*)signal->getDataPtr();
6258
conf->tableId = c_retrieveRecord.tableId;
6259
conf->senderData = c_retrieveRecord.m_senderData;
6260
conf->totalLen = c_retrieveRecord.retrievedNoOfWords;
6262
Callback c = { safe_cast(&Dbdict::initRetrieveRecord), 0 };
6263
LinearSectionPtr ptr[3];
6264
ptr[0].p = pagePointer;
6265
ptr[0].sz = c_retrieveRecord.retrievedNoOfWords;
6266
sendFragmentedSignal(c_retrieveRecord.blockRef,
6267
GSN_GET_TABINFO_CONF,
6269
GetTabInfoConf::SignalLength,
6278
}//sendGetTabResponse()
6280
void Dbdict::sendGET_TABINFOREF(Signal* signal,
6281
GetTabInfoReq * req,
6282
GetTabInfoRef::ErrorCode errorCode)
6285
GetTabInfoRef * const ref = (GetTabInfoRef *)&signal->theData[0];
6287
* The format of GetTabInfo Req/Ref is the same
6289
BlockReference retRef = req->senderRef;
6290
ref->errorCode = errorCode;
6292
sendSignal(retRef, GSN_GET_TABINFOREF, signal, signal->length(), JBB);
6293
}//sendGET_TABINFOREF()
6295
Uint32 convertEndian(Uint32 in) {
6296
#ifdef WORDS_BIGENDIAN
6298
ut += ((in >> 24) & 255);
6299
ut += (((in >> 16) & 255) << 8);
6300
ut += (((in >> 8) & 255) << 16);
6301
ut += ((in & 255) << 24);
6308
Dbdict::execLIST_TABLES_REQ(Signal* signal)
6312
ListTablesReq * req = (ListTablesReq*)signal->getDataPtr();
6313
Uint32 senderRef = req->senderRef;
6314
Uint32 senderData = req->senderData;
6316
const Uint32 reqTableId = req->getTableId();
6317
const Uint32 reqTableType = req->getTableType();
6318
const bool reqListNames = req->getListNames();
6319
const bool reqListIndexes = req->getListIndexes();
6321
ListTablesConf * conf = (ListTablesConf *)signal->getDataPtrSend();
6322
conf->senderData = senderData;
6325
for (i = 0; i < c_tableRecordPool.getSize(); i++) {
6326
TableRecordPtr tablePtr;
6327
c_tableRecordPool.getPtr(tablePtr, i);
6329
if (tablePtr.p->tabState == TableRecord::NOT_DEFINED ||
6330
tablePtr.p->tabState == TableRecord::REORG_TABLE_PREPARED)
6334
if ((reqTableType != (Uint32)0) && (reqTableType != (unsigned)tablePtr.p->tableType))
6336
if (reqListIndexes && reqTableId != tablePtr.p->primaryTableId)
6338
conf->tableData[pos] = 0;
6340
conf->setTableId(pos, tablePtr.i);
6342
conf->setTableType(pos, tablePtr.p->tableType);
6344
if (tablePtr.p->isTable()) {
6345
switch (tablePtr.p->tabState) {
6346
case TableRecord::DEFINING:
6347
case TableRecord::CHECKED:
6348
conf->setTableState(pos, DictTabInfo::StateBuilding);
6350
case TableRecord::PREPARE_DROPPING:
6351
case TableRecord::DROPPING:
6352
conf->setTableState(pos, DictTabInfo::StateDropping);
6354
case TableRecord::DEFINED:
6355
conf->setTableState(pos, DictTabInfo::StateOnline);
6357
case TableRecord::BACKUP_ONGOING:
6358
conf->setTableState(pos, DictTabInfo::StateBackup);
6361
conf->setTableState(pos, DictTabInfo::StateBroken);
6365
if (tablePtr.p->isIndex()) {
6366
switch (tablePtr.p->indexState) {
6367
case TableRecord::IS_OFFLINE:
6368
conf->setTableState(pos, DictTabInfo::StateOffline);
6370
case TableRecord::IS_BUILDING:
6371
conf->setTableState(pos, DictTabInfo::StateBuilding);
6373
case TableRecord::IS_DROPPING:
6374
conf->setTableState(pos, DictTabInfo::StateDropping);
6376
case TableRecord::IS_ONLINE:
6377
conf->setTableState(pos, DictTabInfo::StateOnline);
6380
conf->setTableState(pos, DictTabInfo::StateBroken);
6385
if (! tablePtr.p->storedTable) {
6386
conf->setTableStore(pos, DictTabInfo::StoreTemporary);
6388
conf->setTableStore(pos, DictTabInfo::StorePermanent);
6391
if (pos >= ListTablesConf::DataLength) {
6392
sendSignal(senderRef, GSN_LIST_TABLES_CONF, signal,
6393
ListTablesConf::SignalLength, JBB);
6399
const Uint32 size = strlen(tablePtr.p->tableName) + 1;
6400
conf->tableData[pos] = size;
6402
if (pos >= ListTablesConf::DataLength) {
6403
sendSignal(senderRef, GSN_LIST_TABLES_CONF, signal,
6404
ListTablesConf::SignalLength, JBB);
6410
char* p = (char*)&conf->tableData[pos];
6411
for (Uint32 j = 0; j < 4; j++) {
6413
*p++ = tablePtr.p->tableName[k++];
6418
if (pos >= ListTablesConf::DataLength) {
6419
sendSignal(senderRef, GSN_LIST_TABLES_CONF, signal,
6420
ListTablesConf::SignalLength, JBB);
6426
// XXX merge with above somehow
6427
for (i = 0; i < c_triggerRecordPool.getSize(); i++) {
6430
TriggerRecordPtr triggerPtr;
6431
c_triggerRecordPool.getPtr(triggerPtr, i);
6432
if (triggerPtr.p->triggerState == TriggerRecord::TS_NOT_DEFINED)
6434
// constant 10 hardcoded
6435
Uint32 type = 10 + triggerPtr.p->triggerType;
6436
if (reqTableType != 0 && reqTableType != type)
6438
conf->tableData[pos] = 0;
6439
conf->setTableId(pos, triggerPtr.i);
6440
conf->setTableType(pos, type);
6441
switch (triggerPtr.p->triggerState) {
6442
case TriggerRecord::TS_OFFLINE:
6443
conf->setTableState(pos, DictTabInfo::StateOffline);
6445
case TriggerRecord::TS_ONLINE:
6446
conf->setTableState(pos, DictTabInfo::StateOnline);
6449
conf->setTableState(pos, DictTabInfo::StateBroken);
6452
conf->setTableStore(pos, DictTabInfo::StoreTemporary);
6454
if (pos >= ListTablesConf::DataLength) {
6455
sendSignal(senderRef, GSN_LIST_TABLES_CONF, signal,
6456
ListTablesConf::SignalLength, JBB);
6462
const Uint32 size = strlen(triggerPtr.p->triggerName) + 1;
6463
conf->tableData[pos] = size;
6465
if (pos >= ListTablesConf::DataLength) {
6466
sendSignal(senderRef, GSN_LIST_TABLES_CONF, signal,
6467
ListTablesConf::SignalLength, JBB);
6473
char* p = (char*)&conf->tableData[pos];
6474
for (Uint32 j = 0; j < 4; j++) {
6476
*p++ = triggerPtr.p->triggerName[k++];
6481
if (pos >= ListTablesConf::DataLength) {
6482
sendSignal(senderRef, GSN_LIST_TABLES_CONF, signal,
6483
ListTablesConf::SignalLength, JBB);
6489
// last signal must have less than max length
6490
sendSignal(senderRef, GSN_LIST_TABLES_CONF, signal,
6491
ListTablesConf::HeaderLength + pos, JBB);
6495
* MODULE: Create index
6497
* Create index in DICT via create table operation. Then invoke alter
6498
* index opearation to online the index.
6500
* Request type in CREATE_INDX signals:
6502
* RT_USER - from API to DICT master
6503
* RT_DICT_PREPARE - prepare participants
6504
* RT_DICT_COMMIT - commit participants
6505
* RT_TC - create index in TC (part of alter index operation)
6509
Dbdict::execCREATE_INDX_REQ(Signal* signal)
6512
CreateIndxReq* const req = (CreateIndxReq*)signal->getDataPtrSend();
6513
OpCreateIndexPtr opPtr;
6514
const Uint32 senderRef = signal->senderBlockRef();
6515
const CreateIndxReq::RequestType requestType = req->getRequestType();
6516
if (requestType == CreateIndxReq::RT_USER) {
6518
if (! assembleFragments(signal)) {
6522
if (signal->getLength() == CreateIndxReq::SignalLength) {
6524
CreateIndxRef::ErrorCode tmperr = CreateIndxRef::NoError;
6525
if (getOwnNodeId() != c_masterNodeId) {
6527
tmperr = CreateIndxRef::NotMaster;
6528
} else if (c_blockState == BS_NODE_RESTART) {
6530
tmperr = CreateIndxRef::BusyWithNR;
6531
} else if (c_blockState != BS_IDLE) {
6533
tmperr = CreateIndxRef::Busy;
6535
if (tmperr != CreateIndxRef::NoError) {
6536
releaseSections(signal);
6537
OpCreateIndex opBusy;
6540
opPtr.p->m_isMaster = (senderRef == reference());
6542
opPtr.p->m_requestType = CreateIndxReq::RT_DICT_PREPARE;
6543
opPtr.p->m_errorCode = tmperr;
6544
opPtr.p->m_errorLine = __LINE__;
6545
opPtr.p->m_errorNode = c_masterNodeId;
6546
createIndex_sendReply(signal, opPtr, true);
6549
// forward initial request plus operation key to all
6550
req->setOpKey(++c_opRecordSequence);
6551
NodeReceiverGroup rg(DBDICT, c_aliveNodes);
6552
sendSignal(rg, GSN_CREATE_INDX_REQ,
6553
signal, CreateIndxReq::SignalLength + 1, JBB);
6556
// seize operation record
6557
ndbrequire(signal->getLength() == CreateIndxReq::SignalLength + 1);
6558
const Uint32 opKey = req->getOpKey();
6559
OpCreateIndex opBusy;
6560
if (! c_opCreateIndex.seize(opPtr))
6563
opPtr.p->m_coordinatorRef = senderRef;
6564
opPtr.p->m_isMaster = (senderRef == reference());
6565
opPtr.p->key = opKey;
6566
opPtr.p->m_requestType = CreateIndxReq::RT_DICT_PREPARE;
6567
if (opPtr.p == &opBusy) {
6569
opPtr.p->m_errorCode = CreateIndxRef::Busy;
6570
opPtr.p->m_errorLine = __LINE__;
6571
releaseSections(signal);
6572
createIndex_sendReply(signal, opPtr, opPtr.p->m_isMaster);
6575
c_opCreateIndex.add(opPtr);
6576
// save attribute list
6577
SegmentedSectionPtr ssPtr;
6578
signal->getSection(ssPtr, CreateIndxReq::ATTRIBUTE_LIST_SECTION);
6579
SimplePropertiesSectionReader r0(ssPtr, getSectionSegmentPool());
6580
r0.reset(); // undo implicit first()
6581
if (! r0.getWord(&opPtr.p->m_attrList.sz) ||
6582
! r0.getWords(opPtr.p->m_attrList.id, opPtr.p->m_attrList.sz)) {
6584
opPtr.p->m_errorCode = CreateIndxRef::InvalidName;
6585
opPtr.p->m_errorLine = __LINE__;
6586
releaseSections(signal);
6587
createIndex_sendReply(signal, opPtr, opPtr.p->m_isMaster);
6590
// save name and index table properties
6591
signal->getSection(ssPtr, CreateIndxReq::INDEX_NAME_SECTION);
6592
SimplePropertiesSectionReader r1(ssPtr, getSectionSegmentPool());
6593
DictTabInfo::Table tableDesc;
6595
SimpleProperties::UnpackStatus status = SimpleProperties::unpack(
6597
DictTabInfo::TableMapping, DictTabInfo::TableMappingSize,
6599
if (status != SimpleProperties::Eof) {
6600
opPtr.p->m_errorCode = CreateIndxRef::InvalidName;
6601
opPtr.p->m_errorLine = __LINE__;
6602
releaseSections(signal);
6603
createIndex_sendReply(signal, opPtr, opPtr.p->m_isMaster);
6606
memcpy(opPtr.p->m_indexName, tableDesc.TableName, MAX_TAB_NAME_SIZE);
6607
opPtr.p->m_storedIndex = tableDesc.TableLoggedFlag;
6608
releaseSections(signal);
6609
// master expects to hear from all
6610
if (opPtr.p->m_isMaster)
6611
opPtr.p->m_signalCounter = c_aliveNodes;
6612
createIndex_slavePrepare(signal, opPtr);
6613
createIndex_sendReply(signal, opPtr, false);
6616
c_opCreateIndex.find(opPtr, req->getConnectionPtr());
6617
if (! opPtr.isNull()) {
6618
opPtr.p->m_requestType = requestType;
6619
if (requestType == CreateIndxReq::RT_DICT_COMMIT ||
6620
requestType == CreateIndxReq::RT_DICT_ABORT) {
6622
if (requestType == CreateIndxReq::RT_DICT_COMMIT) {
6623
opPtr.p->m_request.setIndexId(req->getIndexId());
6624
opPtr.p->m_request.setIndexVersion(req->getIndexVersion());
6625
createIndex_slaveCommit(signal, opPtr);
6627
createIndex_slaveAbort(signal, opPtr);
6629
createIndex_sendReply(signal, opPtr, false);
6631
if (! opPtr.p->m_isMaster)
6632
c_opCreateIndex.release(opPtr);
6638
releaseSections(signal);
6639
OpCreateIndex opBad;
6642
opPtr.p->m_errorCode = CreateIndxRef::BadRequestType;
6643
opPtr.p->m_errorLine = __LINE__;
6644
createIndex_sendReply(signal, opPtr, true);
6648
Dbdict::execCREATE_INDX_CONF(Signal* signal)
6651
ndbrequire(signal->getNoOfSections() == 0);
6652
CreateIndxConf* conf = (CreateIndxConf*)signal->getDataPtrSend();
6653
createIndex_recvReply(signal, conf, 0);
6657
Dbdict::execCREATE_INDX_REF(Signal* signal)
6660
CreateIndxRef* ref = (CreateIndxRef*)signal->getDataPtrSend();
6661
createIndex_recvReply(signal, ref->getConf(), ref);
6665
Dbdict::createIndex_recvReply(Signal* signal, const CreateIndxConf* conf,
6666
const CreateIndxRef* ref)
6669
const Uint32 senderRef = signal->senderBlockRef();
6670
const CreateIndxReq::RequestType requestType = conf->getRequestType();
6671
const Uint32 key = conf->getConnectionPtr();
6672
if (requestType == CreateIndxReq::RT_TC) {
6674
// part of alter index operation
6675
OpAlterIndexPtr opPtr;
6676
c_opAlterIndex.find(opPtr, key);
6677
ndbrequire(! opPtr.isNull());
6678
opPtr.p->setError(ref);
6679
alterIndex_fromCreateTc(signal, opPtr);
6682
OpCreateIndexPtr opPtr;
6683
c_opCreateIndex.find(opPtr, key);
6684
ndbrequire(! opPtr.isNull());
6685
ndbrequire(opPtr.p->m_isMaster);
6686
ndbrequire(opPtr.p->m_requestType == requestType);
6687
opPtr.p->setError(ref);
6688
opPtr.p->m_signalCounter.clearWaitingFor(refToNode(senderRef));
6689
if (! opPtr.p->m_signalCounter.done()) {
6693
if (requestType == CreateIndxReq::RT_DICT_COMMIT ||
6694
requestType == CreateIndxReq::RT_DICT_ABORT) {
6696
// send reply to user
6697
createIndex_sendReply(signal, opPtr, true);
6698
c_opCreateIndex.release(opPtr);
6701
if (opPtr.p->hasError()) {
6703
opPtr.p->m_requestType = CreateIndxReq::RT_DICT_ABORT;
6704
createIndex_sendSlaveReq(signal, opPtr);
6707
if (requestType == CreateIndxReq::RT_DICT_PREPARE) {
6709
// start index table create
6710
createIndex_toCreateTable(signal, opPtr);
6711
if (opPtr.p->hasError()) {
6713
opPtr.p->m_requestType = CreateIndxReq::RT_DICT_ABORT;
6714
createIndex_sendSlaveReq(signal, opPtr);
6723
Dbdict::createIndex_slavePrepare(Signal* signal, OpCreateIndexPtr opPtr)
6726
if (ERROR_INSERTED(6006) && ! opPtr.p->m_isMaster) {
6732
Dbdict::createIndex_toCreateTable(Signal* signal, OpCreateIndexPtr opPtr)
6734
Uint32 attrid_map[MAX_ATTRIBUTES_IN_INDEX];
6737
const CreateIndxReq* const req = &opPtr.p->m_request;
6738
// signal data writer
6739
Uint32* wbuffer = &c_indexPage.word[0];
6740
LinearWriter w(wbuffer, sizeof(c_indexPage) >> 2);
6742
// get table being indexed
6743
if (! (req->getTableId() < c_tableRecordPool.getSize())) {
6745
opPtr.p->m_errorCode = CreateIndxRef::InvalidPrimaryTable;
6746
opPtr.p->m_errorLine = __LINE__;
6749
TableRecordPtr tablePtr;
6750
c_tableRecordPool.getPtr(tablePtr, req->getTableId());
6751
if (tablePtr.p->tabState != TableRecord::DEFINED &&
6752
tablePtr.p->tabState != TableRecord::BACKUP_ONGOING) {
6754
opPtr.p->m_errorCode = CreateIndxRef::InvalidPrimaryTable;
6755
opPtr.p->m_errorLine = __LINE__;
6758
if (! tablePtr.p->isTable()) {
6760
opPtr.p->m_errorCode = CreateIndxRef::InvalidPrimaryTable;
6761
opPtr.p->m_errorLine = __LINE__;
6764
// compute index table record
6765
TableRecord indexRec;
6766
TableRecordPtr indexPtr;
6767
indexPtr.i = RNIL; // invalid
6768
indexPtr.p = &indexRec;
6769
initialiseTableRecord(indexPtr);
6770
if (req->getIndexType() == DictTabInfo::UniqueHashIndex) {
6771
indexPtr.p->storedTable = opPtr.p->m_storedIndex;
6772
indexPtr.p->fragmentType = tablePtr.p->fragmentType;
6773
} else if (req->getIndexType() == DictTabInfo::OrderedIndex) {
6774
// first version will not supported logging
6775
if (opPtr.p->m_storedIndex) {
6777
opPtr.p->m_errorCode = CreateIndxRef::InvalidIndexType;
6778
opPtr.p->m_errorLine = __LINE__;
6781
indexPtr.p->storedTable = false;
6782
// follows table fragmentation
6783
indexPtr.p->fragmentType = tablePtr.p->fragmentType;
6786
opPtr.p->m_errorCode = CreateIndxRef::InvalidIndexType;
6787
opPtr.p->m_errorLine = __LINE__;
6790
indexPtr.p->tableType = (DictTabInfo::TableType)req->getIndexType();
6791
indexPtr.p->primaryTableId = req->getTableId();
6792
indexPtr.p->noOfAttributes = opPtr.p->m_attrList.sz;
6793
indexPtr.p->tupKeyLength = 0;
6794
if (indexPtr.p->noOfAttributes == 0) {
6796
opPtr.p->m_errorCode = CreateIndxRef::InvalidIndexType;
6797
opPtr.p->m_errorLine = __LINE__;
6800
if (indexPtr.p->isOrderedIndex()) {
6801
// tree node size in words (make configurable later)
6802
indexPtr.p->tupKeyLength = MAX_TTREE_NODE_SIZE;
6807
for (k = 0; k < opPtr.p->m_attrList.sz; k++) {
6809
unsigned current_id= opPtr.p->m_attrList.id[k];
6810
AttributeRecord* aRec= NULL;
6811
Uint32 tAttr= tablePtr.p->firstAttribute;
6812
for (; tAttr != RNIL; tAttr= aRec->nextAttrInTable)
6814
aRec = c_attributeRecordPool.getPtr(tAttr);
6815
if (aRec->attributeId != current_id)
6820
if (tAttr == RNIL) {
6822
opPtr.p->m_errorCode = CreateIndxRef::BadRequestType;
6823
opPtr.p->m_errorLine = __LINE__;
6826
if (mask.get(current_id))
6829
opPtr.p->m_errorCode = CreateIndxRef::DuplicateAttributes;
6830
opPtr.p->m_errorLine = __LINE__;
6833
mask.set(current_id);
6835
const Uint32 a = aRec->attributeDescriptor;
6837
if (indexPtr.p->isHashIndex()) {
6838
const Uint32 s1 = AttributeDescriptor::getSize(a);
6839
const Uint32 s2 = AttributeDescriptor::getArraySize(a);
6840
indexPtr.p->tupKeyLength += ((1 << s1) * s2 + 31) >> 5;
6841
// reorder the attributes according to the tableid order
6842
// for unque indexes
6843
for (; kk > 0 && current_id < attrid_map[kk-1]>>16; kk--)
6844
attrid_map[kk]= attrid_map[kk-1];
6846
attrid_map[kk]= k | (current_id << 16);
6848
indexPtr.p->noOfPrimkey = indexPtr.p->noOfAttributes;
6849
// plus concatenated primary table key attribute
6850
indexPtr.p->noOfAttributes += 1;
6851
indexPtr.p->noOfNullAttr = 0;
6852
// write index table
6853
w.add(DictTabInfo::TableName, opPtr.p->m_indexName);
6854
w.add(DictTabInfo::TableLoggedFlag, indexPtr.p->storedTable);
6855
w.add(DictTabInfo::FragmentTypeVal, indexPtr.p->fragmentType);
6856
w.add(DictTabInfo::TableTypeVal, indexPtr.p->tableType);
6857
w.add(DictTabInfo::PrimaryTable, tablePtr.p->tableName);
6858
w.add(DictTabInfo::PrimaryTableId, tablePtr.i);
6859
w.add(DictTabInfo::NoOfAttributes, indexPtr.p->noOfAttributes);
6860
w.add(DictTabInfo::NoOfKeyAttr, indexPtr.p->noOfPrimkey);
6861
w.add(DictTabInfo::NoOfNullable, indexPtr.p->noOfNullAttr);
6862
w.add(DictTabInfo::KeyLength, indexPtr.p->tupKeyLength);
6863
// write index key attributes
6864
AttributeRecordPtr aRecPtr;
6865
c_attributeRecordPool.getPtr(aRecPtr, tablePtr.p->firstAttribute);
6866
for (k = 0; k < opPtr.p->m_attrList.sz; k++) {
6867
// insert the attributes in the order decided above in attrid_map
6868
// k is new order, current_id is in previous order
6869
// ToDo: make sure "current_id" is stored with the table and
6870
// passed up to NdbDictionary
6871
unsigned current_id= opPtr.p->m_attrList.id[attrid_map[k] & 0xffff];
6873
for (Uint32 tAttr = tablePtr.p->firstAttribute; tAttr != RNIL; ) {
6874
AttributeRecord* aRec = c_attributeRecordPool.getPtr(tAttr);
6875
tAttr = aRec->nextAttrInTable;
6876
if (aRec->attributeId != current_id)
6879
const Uint32 a = aRec->attributeDescriptor;
6880
bool isNullable = AttributeDescriptor::getNullable(a);
6881
Uint32 attrType = AttributeDescriptor::getType(a);
6882
w.add(DictTabInfo::AttributeName, aRec->attributeName);
6883
w.add(DictTabInfo::AttributeId, k);
6884
if (indexPtr.p->isHashIndex()) {
6885
w.add(DictTabInfo::AttributeKeyFlag, (Uint32)true);
6886
w.add(DictTabInfo::AttributeNullableFlag, (Uint32)false);
6888
if (indexPtr.p->isOrderedIndex()) {
6889
w.add(DictTabInfo::AttributeKeyFlag, (Uint32)false);
6890
w.add(DictTabInfo::AttributeNullableFlag, (Uint32)isNullable);
6892
w.add(DictTabInfo::AttributeExtType, attrType);
6893
w.add(DictTabInfo::AttributeExtPrecision, aRec->extPrecision);
6894
w.add(DictTabInfo::AttributeExtScale, aRec->extScale);
6895
w.add(DictTabInfo::AttributeExtLength, aRec->extLength);
6896
w.add(DictTabInfo::AttributeEnd, (Uint32)true);
6899
if (indexPtr.p->isHashIndex()) {
6901
// write concatenated primary table key attribute
6902
w.add(DictTabInfo::AttributeName, "NDB$PK");
6903
w.add(DictTabInfo::AttributeId, opPtr.p->m_attrList.sz);
6904
w.add(DictTabInfo::AttributeKeyFlag, (Uint32)false);
6905
w.add(DictTabInfo::AttributeNullableFlag, (Uint32)false);
6906
w.add(DictTabInfo::AttributeExtType, (Uint32)DictTabInfo::ExtUnsigned);
6907
w.add(DictTabInfo::AttributeExtLength, tablePtr.p->tupKeyLength);
6908
w.add(DictTabInfo::AttributeEnd, (Uint32)true);
6910
if (indexPtr.p->isOrderedIndex()) {
6912
// write index tree node as Uint32 array attribute
6913
w.add(DictTabInfo::AttributeName, "NDB$TNODE");
6914
w.add(DictTabInfo::AttributeId, opPtr.p->m_attrList.sz);
6915
w.add(DictTabInfo::AttributeKeyFlag, (Uint32)true);
6916
w.add(DictTabInfo::AttributeNullableFlag, (Uint32)false);
6917
w.add(DictTabInfo::AttributeExtType, (Uint32)DictTabInfo::ExtUnsigned);
6918
w.add(DictTabInfo::AttributeExtLength, indexPtr.p->tupKeyLength);
6919
w.add(DictTabInfo::AttributeEnd, (Uint32)true);
6922
w.add(DictTabInfo::TableEnd, (Uint32)true);
6924
releaseSections(signal);
6925
// send create index table request
6926
CreateTableReq * const cre = (CreateTableReq*)signal->getDataPtrSend();
6927
cre->senderRef = reference();
6928
cre->senderData = opPtr.p->key;
6929
LinearSectionPtr lsPtr[3];
6930
lsPtr[0].p = wbuffer;
6931
lsPtr[0].sz = w.getWordsUsed();
6932
sendSignal(DBDICT_REF, GSN_CREATE_TABLE_REQ,
6933
signal, CreateTableReq::SignalLength, JBB, lsPtr, 1);
6937
Dbdict::createIndex_fromCreateTable(Signal* signal, OpCreateIndexPtr opPtr)
6940
if (opPtr.p->hasError()) {
6942
opPtr.p->m_requestType = CreateIndxReq::RT_DICT_ABORT;
6943
createIndex_sendSlaveReq(signal, opPtr);
6946
if (! opPtr.p->m_request.getOnline()) {
6948
opPtr.p->m_requestType = CreateIndxReq::RT_DICT_COMMIT;
6949
createIndex_sendSlaveReq(signal, opPtr);
6952
createIndex_toAlterIndex(signal, opPtr);
6956
Dbdict::createIndex_toAlterIndex(Signal* signal, OpCreateIndexPtr opPtr)
6959
AlterIndxReq* const req = (AlterIndxReq*)signal->getDataPtrSend();
6960
req->setUserRef(reference());
6961
req->setConnectionPtr(opPtr.p->key);
6962
req->setRequestType(AlterIndxReq::RT_CREATE_INDEX);
6963
req->addRequestFlag(opPtr.p->m_requestFlag);
6964
req->setTableId(opPtr.p->m_request.getTableId());
6965
req->setIndexId(opPtr.p->m_request.getIndexId());
6966
req->setIndexVersion(opPtr.p->m_request.getIndexVersion());
6967
req->setOnline(true);
6968
sendSignal(reference(), GSN_ALTER_INDX_REQ,
6969
signal, AlterIndxReq::SignalLength, JBB);
6973
Dbdict::createIndex_fromAlterIndex(Signal* signal, OpCreateIndexPtr opPtr)
6976
if (opPtr.p->hasError()) {
6978
opPtr.p->m_requestType = CreateIndxReq::RT_DICT_ABORT;
6979
createIndex_sendSlaveReq(signal, opPtr);
6982
opPtr.p->m_requestType = CreateIndxReq::RT_DICT_COMMIT;
6983
createIndex_sendSlaveReq(signal, opPtr);
6987
Dbdict::createIndex_slaveCommit(Signal* signal, OpCreateIndexPtr opPtr)
6990
const Uint32 indexId = opPtr.p->m_request.getIndexId();
6991
TableRecordPtr indexPtr;
6992
c_tableRecordPool.getPtr(indexPtr, indexId);
6993
if (! opPtr.p->m_request.getOnline()) {
6994
ndbrequire(indexPtr.p->indexState == TableRecord::IS_UNDEFINED);
6995
indexPtr.p->indexState = TableRecord::IS_OFFLINE;
6997
ndbrequire(indexPtr.p->indexState == TableRecord::IS_ONLINE);
7002
Dbdict::createIndex_slaveAbort(Signal* signal, OpCreateIndexPtr opPtr)
7005
CreateIndxReq* const req = &opPtr.p->m_request;
7006
const Uint32 indexId = req->getIndexId();
7007
if (indexId >= c_tableRecordPool.getSize()) {
7011
TableRecordPtr indexPtr;
7012
c_tableRecordPool.getPtr(indexPtr, indexId);
7013
if (! indexPtr.p->isIndex()) {
7017
indexPtr.p->indexState = TableRecord::IS_BROKEN;
7021
Dbdict::createIndex_sendSlaveReq(Signal* signal, OpCreateIndexPtr opPtr)
7024
CreateIndxReq* const req = (CreateIndxReq*)signal->getDataPtrSend();
7025
*req = opPtr.p->m_request;
7026
req->setUserRef(opPtr.p->m_coordinatorRef);
7027
req->setConnectionPtr(opPtr.p->key);
7028
req->setRequestType(opPtr.p->m_requestType);
7029
req->addRequestFlag(opPtr.p->m_requestFlag);
7030
opPtr.p->m_signalCounter = c_aliveNodes;
7031
NodeReceiverGroup rg(DBDICT, c_aliveNodes);
7032
sendSignal(rg, GSN_CREATE_INDX_REQ,
7033
signal, CreateIndxReq::SignalLength, JBB);
7037
Dbdict::createIndex_sendReply(Signal* signal, OpCreateIndexPtr opPtr,
7040
CreateIndxRef* rep = (CreateIndxRef*)signal->getDataPtrSend();
7041
Uint32 gsn = GSN_CREATE_INDX_CONF;
7042
Uint32 length = CreateIndxConf::InternalLength;
7045
sendRef = opPtr.p->hasLastError();
7046
rep->setUserRef(opPtr.p->m_coordinatorRef);
7047
rep->setConnectionPtr(opPtr.p->key);
7048
rep->setRequestType(opPtr.p->m_requestType);
7049
if (opPtr.p->m_requestType == CreateIndxReq::RT_DICT_ABORT)
7052
sendRef = opPtr.p->hasError();
7053
rep->setUserRef(opPtr.p->m_request.getUserRef());
7054
rep->setConnectionPtr(opPtr.p->m_request.getConnectionPtr());
7055
rep->setRequestType(opPtr.p->m_request.getRequestType());
7056
length = CreateIndxConf::SignalLength;
7058
rep->setTableId(opPtr.p->m_request.getTableId());
7059
rep->setIndexId(opPtr.p->m_request.getIndexId());
7060
rep->setIndexVersion(opPtr.p->m_request.getIndexVersion());
7062
if (opPtr.p->m_errorNode == 0)
7063
opPtr.p->m_errorNode = getOwnNodeId();
7064
rep->setErrorCode(opPtr.p->m_errorCode);
7065
rep->setErrorLine(opPtr.p->m_errorLine);
7066
rep->setErrorNode(opPtr.p->m_errorNode);
7067
gsn = GSN_CREATE_INDX_REF;
7068
length = CreateIndxRef::SignalLength;
7070
sendSignal(rep->getUserRef(), gsn, signal, length, JBB);
7074
* MODULE: Drop index.
7076
* Drop index. First alters the index offline (i.e. drops metadata in
7077
* other blocks) and then drops the index table.
7081
Dbdict::execDROP_INDX_REQ(Signal* signal)
7084
DropIndxReq* const req = (DropIndxReq*)signal->getDataPtrSend();
7085
OpDropIndexPtr opPtr;
7087
int err = DropIndxRef::BadRequestType;
7088
const Uint32 senderRef = signal->senderBlockRef();
7089
const DropIndxReq::RequestType requestType = req->getRequestType();
7090
if (requestType == DropIndxReq::RT_USER) {
7092
if (signal->getLength() == DropIndxReq::SignalLength) {
7094
DropIndxRef::ErrorCode tmperr = DropIndxRef::NoError;
7095
if (getOwnNodeId() != c_masterNodeId) {
7097
tmperr = DropIndxRef::NotMaster;
7098
} else if (c_blockState == BS_NODE_RESTART) {
7100
tmperr = DropIndxRef::BusyWithNR;
7101
} else if (c_blockState != BS_IDLE) {
7103
tmperr = DropIndxRef::Busy;
7105
if (tmperr != DropIndxRef::NoError) {
7109
// forward initial request plus operation key to all
7110
Uint32 indexId= req->getIndexId();
7111
Uint32 indexVersion= req->getIndexVersion();
7113
int res = getMetaTablePtr(tmp, indexId, indexVersion);
7115
case MetaData::InvalidArgument:
7116
err = DropIndxRef::IndexNotFound;
7118
case MetaData::TableNotFound:
7119
case MetaData::InvalidTableVersion:
7120
err = DropIndxRef::InvalidIndexVersion;
7124
if (! tmp.p->isIndex()) {
7126
err = DropIndxRef::NotAnIndex;
7130
if (tmp.p->indexState != TableRecord::IS_ONLINE)
7131
req->addRequestFlag(RequestFlag::RF_FORCE);
7133
tmp.p->indexState = TableRecord::IS_DROPPING;
7135
req->setOpKey(++c_opRecordSequence);
7136
NodeReceiverGroup rg(DBDICT, c_aliveNodes);
7137
sendSignal(rg, GSN_DROP_INDX_REQ,
7138
signal, DropIndxReq::SignalLength + 1, JBB);
7141
// seize operation record
7142
ndbrequire(signal->getLength() == DropIndxReq::SignalLength + 1);
7143
const Uint32 opKey = req->getOpKey();
7145
if (! c_opDropIndex.seize(opPtr))
7148
opPtr.p->m_coordinatorRef = senderRef;
7149
opPtr.p->m_isMaster = (senderRef == reference());
7150
opPtr.p->key = opKey;
7151
opPtr.p->m_requestType = DropIndxReq::RT_DICT_PREPARE;
7152
if (opPtr.p == &opBusy) {
7154
opPtr.p->m_errorCode = DropIndxRef::Busy;
7155
opPtr.p->m_errorLine = __LINE__;
7156
dropIndex_sendReply(signal, opPtr, opPtr.p->m_isMaster);
7159
c_opDropIndex.add(opPtr);
7160
// master expects to hear from all
7161
if (opPtr.p->m_isMaster)
7162
opPtr.p->m_signalCounter = c_aliveNodes;
7163
dropIndex_slavePrepare(signal, opPtr);
7164
dropIndex_sendReply(signal, opPtr, false);
7167
c_opDropIndex.find(opPtr, req->getConnectionPtr());
7168
if (! opPtr.isNull()) {
7169
opPtr.p->m_requestType = requestType;
7170
if (requestType == DropIndxReq::RT_DICT_COMMIT ||
7171
requestType == DropIndxReq::RT_DICT_ABORT) {
7173
if (requestType == DropIndxReq::RT_DICT_COMMIT)
7174
dropIndex_slaveCommit(signal, opPtr);
7176
dropIndex_slaveAbort(signal, opPtr);
7177
dropIndex_sendReply(signal, opPtr, false);
7179
if (! opPtr.p->m_isMaster)
7180
c_opDropIndex.release(opPtr);
7190
opPtr.p->m_errorCode = (DropIndxRef::ErrorCode)err;
7191
opPtr.p->m_errorLine = __LINE__;
7192
opPtr.p->m_errorNode = c_masterNodeId;
7193
dropIndex_sendReply(signal, opPtr, true);
7197
Dbdict::execDROP_INDX_CONF(Signal* signal)
7200
DropIndxConf* conf = (DropIndxConf*)signal->getDataPtrSend();
7201
dropIndex_recvReply(signal, conf, 0);
7205
Dbdict::execDROP_INDX_REF(Signal* signal)
7208
DropIndxRef* ref = (DropIndxRef*)signal->getDataPtrSend();
7209
dropIndex_recvReply(signal, ref->getConf(), ref);
7213
Dbdict::dropIndex_recvReply(Signal* signal, const DropIndxConf* conf,
7214
const DropIndxRef* ref)
7217
const Uint32 senderRef = signal->senderBlockRef();
7218
const DropIndxReq::RequestType requestType = conf->getRequestType();
7219
const Uint32 key = conf->getConnectionPtr();
7220
if (requestType == DropIndxReq::RT_TC) {
7222
// part of alter index operation
7223
OpAlterIndexPtr opPtr;
7224
c_opAlterIndex.find(opPtr, key);
7225
ndbrequire(! opPtr.isNull());
7226
opPtr.p->setError(ref);
7227
alterIndex_fromDropTc(signal, opPtr);
7230
OpDropIndexPtr opPtr;
7231
c_opDropIndex.find(opPtr, key);
7232
ndbrequire(! opPtr.isNull());
7233
ndbrequire(opPtr.p->m_isMaster);
7234
ndbrequire(opPtr.p->m_requestType == requestType);
7235
opPtr.p->setError(ref);
7236
opPtr.p->m_signalCounter.clearWaitingFor(refToNode(senderRef));
7237
if (! opPtr.p->m_signalCounter.done()) {
7241
if (requestType == DropIndxReq::RT_DICT_COMMIT ||
7242
requestType == DropIndxReq::RT_DICT_ABORT) {
7244
// send reply to user
7245
dropIndex_sendReply(signal, opPtr, true);
7246
c_opDropIndex.release(opPtr);
7249
if (opPtr.p->hasError()) {
7251
opPtr.p->m_requestType = DropIndxReq::RT_DICT_ABORT;
7252
dropIndex_sendSlaveReq(signal, opPtr);
7255
if (requestType == DropIndxReq::RT_DICT_PREPARE) {
7257
// start alter offline
7258
dropIndex_toAlterIndex(signal, opPtr);
7265
Dbdict::dropIndex_slavePrepare(Signal* signal, OpDropIndexPtr opPtr)
7268
DropIndxReq* const req = &opPtr.p->m_request;
7269
// check index exists
7270
TableRecordPtr indexPtr;
7271
if (! (req->getIndexId() < c_tableRecordPool.getSize())) {
7273
opPtr.p->m_errorCode = DropIndxRef::IndexNotFound;
7274
opPtr.p->m_errorLine = __LINE__;
7277
c_tableRecordPool.getPtr(indexPtr, req->getIndexId());
7278
if (indexPtr.p->tabState != TableRecord::DEFINED) {
7280
opPtr.p->m_errorCode = DropIndxRef::IndexNotFound;
7281
opPtr.p->m_errorLine = __LINE__;
7284
if (! indexPtr.p->isIndex()) {
7286
opPtr.p->m_errorCode = DropIndxRef::NotAnIndex;
7287
opPtr.p->m_errorLine = __LINE__;
7290
// ignore incoming primary table id
7291
req->setTableId(indexPtr.p->primaryTableId);
7295
Dbdict::dropIndex_toAlterIndex(Signal* signal, OpDropIndexPtr opPtr)
7298
AlterIndxReq* const req = (AlterIndxReq*)signal->getDataPtrSend();
7299
req->setUserRef(reference());
7300
req->setConnectionPtr(opPtr.p->key);
7301
req->setRequestType(AlterIndxReq::RT_DROP_INDEX);
7302
req->addRequestFlag(opPtr.p->m_requestFlag);
7303
req->setTableId(opPtr.p->m_request.getTableId());
7304
req->setIndexId(opPtr.p->m_request.getIndexId());
7305
req->setIndexVersion(opPtr.p->m_request.getIndexVersion());
7306
req->setOnline(false);
7307
sendSignal(reference(), GSN_ALTER_INDX_REQ,
7308
signal, AlterIndxReq::SignalLength, JBB);
7312
Dbdict::dropIndex_fromAlterIndex(Signal* signal, OpDropIndexPtr opPtr)
7315
if (opPtr.p->hasError()) {
7317
opPtr.p->m_requestType = DropIndxReq::RT_DICT_ABORT;
7318
dropIndex_sendSlaveReq(signal, opPtr);
7321
dropIndex_toDropTable(signal, opPtr);
7325
Dbdict::dropIndex_toDropTable(Signal* signal, OpDropIndexPtr opPtr)
7328
DropTableReq* const req = (DropTableReq*)signal->getDataPtrSend();
7329
req->senderRef = reference();
7330
req->senderData = opPtr.p->key;
7331
req->tableId = opPtr.p->m_request.getIndexId();
7332
req->tableVersion = opPtr.p->m_request.getIndexVersion();
7333
sendSignal(reference(), GSN_DROP_TABLE_REQ,
7334
signal,DropTableReq::SignalLength, JBB);
7338
Dbdict::dropIndex_fromDropTable(Signal* signal, OpDropIndexPtr opPtr)
7341
if (opPtr.p->hasError()) {
7343
opPtr.p->m_requestType = DropIndxReq::RT_DICT_ABORT;
7344
dropIndex_sendSlaveReq(signal, opPtr);
7347
opPtr.p->m_requestType = DropIndxReq::RT_DICT_COMMIT;
7348
dropIndex_sendSlaveReq(signal, opPtr);
7352
Dbdict::dropIndex_slaveCommit(Signal* signal, OpDropIndexPtr opPtr)
7358
Dbdict::dropIndex_slaveAbort(Signal* signal, OpDropIndexPtr opPtr)
7361
DropIndxReq* const req = &opPtr.p->m_request;
7362
const Uint32 indexId = req->getIndexId();
7363
if (indexId >= c_tableRecordPool.getSize()) {
7367
TableRecordPtr indexPtr;
7368
c_tableRecordPool.getPtr(indexPtr, indexId);
7369
indexPtr.p->indexState = TableRecord::IS_BROKEN;
7373
Dbdict::dropIndex_sendSlaveReq(Signal* signal, OpDropIndexPtr opPtr)
7375
DropIndxReq* const req = (DropIndxReq*)signal->getDataPtrSend();
7376
*req = opPtr.p->m_request;
7377
req->setUserRef(opPtr.p->m_coordinatorRef);
7378
req->setConnectionPtr(opPtr.p->key);
7379
req->setRequestType(opPtr.p->m_requestType);
7380
req->addRequestFlag(opPtr.p->m_requestFlag);
7381
opPtr.p->m_signalCounter = c_aliveNodes;
7382
NodeReceiverGroup rg(DBDICT, c_aliveNodes);
7383
sendSignal(rg, GSN_DROP_INDX_REQ,
7384
signal, DropIndxReq::SignalLength, JBB);
7388
Dbdict::dropIndex_sendReply(Signal* signal, OpDropIndexPtr opPtr,
7391
DropIndxRef* rep = (DropIndxRef*)signal->getDataPtrSend();
7392
Uint32 gsn = GSN_DROP_INDX_CONF;
7393
Uint32 length = DropIndxConf::InternalLength;
7396
sendRef = opPtr.p->hasLastError();
7397
rep->setUserRef(opPtr.p->m_coordinatorRef);
7398
rep->setConnectionPtr(opPtr.p->key);
7399
rep->setRequestType(opPtr.p->m_requestType);
7400
if (opPtr.p->m_requestType == DropIndxReq::RT_DICT_ABORT)
7403
sendRef = opPtr.p->hasError();
7404
rep->setUserRef(opPtr.p->m_request.getUserRef());
7405
rep->setConnectionPtr(opPtr.p->m_request.getConnectionPtr());
7406
rep->setRequestType(opPtr.p->m_request.getRequestType());
7407
length = DropIndxConf::SignalLength;
7409
rep->setTableId(opPtr.p->m_request.getTableId());
7410
rep->setIndexId(opPtr.p->m_request.getIndexId());
7411
rep->setIndexVersion(opPtr.p->m_request.getIndexVersion());
7413
if (opPtr.p->m_errorNode == 0)
7414
opPtr.p->m_errorNode = getOwnNodeId();
7415
rep->setErrorCode(opPtr.p->m_errorCode);
7416
rep->setErrorLine(opPtr.p->m_errorLine);
7417
rep->setErrorNode(opPtr.p->m_errorNode);
7418
gsn = GSN_DROP_INDX_REF;
7419
length = DropIndxRef::SignalLength;
7421
sendSignal(rep->getUserRef(), gsn, signal, length, JBB);
7426
* MODULE: Alter index
7428
* Alter index state. Alter online creates the index in each TC and
7429
* then invokes create trigger and alter trigger protocols to activate
7430
* the 3 triggers. Alter offline does the opposite.
7432
* Request type received in REQ and returned in CONF/REF:
7434
* RT_USER - from API to DICT master
7435
* RT_CREATE_INDEX - part of create index operation
7436
* RT_DROP_INDEX - part of drop index operation
7437
* RT_NODERESTART - node restart, activate locally only
7438
* RT_SYSTEMRESTART - system restart, activate and build if not logged
7439
* RT_DICT_PREPARE - prepare participants
7440
* RT_DICT_TC - to local TC via each participant
7441
* RT_DICT_COMMIT - commit in each participant
7445
Dbdict::execALTER_INDX_REQ(Signal* signal)
7448
AlterIndxReq* const req = (AlterIndxReq*)signal->getDataPtrSend();
7449
OpAlterIndexPtr opPtr;
7450
const Uint32 senderRef = signal->senderBlockRef();
7451
const AlterIndxReq::RequestType requestType = req->getRequestType();
7452
if (requestType == AlterIndxReq::RT_USER ||
7453
requestType == AlterIndxReq::RT_CREATE_INDEX ||
7454
requestType == AlterIndxReq::RT_DROP_INDEX ||
7455
requestType == AlterIndxReq::RT_NODERESTART ||
7456
requestType == AlterIndxReq::RT_SYSTEMRESTART) {
7458
const bool isLocal = req->getRequestFlag() & RequestFlag::RF_LOCAL;
7459
NdbNodeBitmask receiverNodes = c_aliveNodes;
7461
receiverNodes.clear();
7462
receiverNodes.set(getOwnNodeId());
7464
if (signal->getLength() == AlterIndxReq::SignalLength) {
7466
if (! isLocal && getOwnNodeId() != c_masterNodeId) {
7469
releaseSections(signal);
7473
opPtr.p->m_errorCode = AlterIndxRef::NotMaster;
7474
opPtr.p->m_errorLine = __LINE__;
7475
opPtr.p->m_errorNode = c_masterNodeId;
7476
alterIndex_sendReply(signal, opPtr, true);
7479
// forward initial request plus operation key to all
7480
req->setOpKey(++c_opRecordSequence);
7481
NodeReceiverGroup rg(DBDICT, receiverNodes);
7482
sendSignal(rg, GSN_ALTER_INDX_REQ,
7483
signal, AlterIndxReq::SignalLength + 1, JBB);
7486
// seize operation record
7487
ndbrequire(signal->getLength() == AlterIndxReq::SignalLength + 1);
7488
const Uint32 opKey = req->getOpKey();
7489
OpAlterIndex opBusy;
7490
if (! c_opAlterIndex.seize(opPtr))
7493
opPtr.p->m_coordinatorRef = senderRef;
7494
opPtr.p->m_isMaster = (senderRef == reference());
7495
opPtr.p->key = opKey;
7496
opPtr.p->m_requestType = AlterIndxReq::RT_DICT_PREPARE;
7497
if (opPtr.p == &opBusy) {
7499
opPtr.p->m_errorCode = AlterIndxRef::Busy;
7500
opPtr.p->m_errorLine = __LINE__;
7501
alterIndex_sendReply(signal, opPtr, opPtr.p->m_isMaster);
7504
c_opAlterIndex.add(opPtr);
7505
// master expects to hear from all
7506
if (opPtr.p->m_isMaster)
7507
opPtr.p->m_signalCounter = receiverNodes;
7508
// check request in all participants
7509
alterIndex_slavePrepare(signal, opPtr);
7510
alterIndex_sendReply(signal, opPtr, false);
7513
c_opAlterIndex.find(opPtr, req->getConnectionPtr());
7514
if (! opPtr.isNull()) {
7515
opPtr.p->m_requestType = requestType;
7516
if (requestType == AlterIndxReq::RT_DICT_TC) {
7518
if (opPtr.p->m_request.getOnline())
7519
alterIndex_toCreateTc(signal, opPtr);
7521
alterIndex_toDropTc(signal, opPtr);
7524
if (requestType == AlterIndxReq::RT_DICT_COMMIT ||
7525
requestType == AlterIndxReq::RT_DICT_ABORT) {
7527
if (requestType == AlterIndxReq::RT_DICT_COMMIT)
7528
alterIndex_slaveCommit(signal, opPtr);
7530
alterIndex_slaveAbort(signal, opPtr);
7531
alterIndex_sendReply(signal, opPtr, false);
7533
if (! opPtr.p->m_isMaster)
7534
c_opAlterIndex.release(opPtr);
7543
opPtr.p->m_errorCode = AlterIndxRef::BadRequestType;
7544
opPtr.p->m_errorLine = __LINE__;
7545
alterIndex_sendReply(signal, opPtr, true);
7549
Dbdict::execALTER_INDX_CONF(Signal* signal)
7552
ndbrequire(signal->getNoOfSections() == 0);
7553
AlterIndxConf* conf = (AlterIndxConf*)signal->getDataPtrSend();
7554
alterIndex_recvReply(signal, conf, 0);
7558
Dbdict::execALTER_INDX_REF(Signal* signal)
7561
AlterIndxRef* ref = (AlterIndxRef*)signal->getDataPtrSend();
7562
alterIndex_recvReply(signal, ref->getConf(), ref);
7566
Dbdict::alterIndex_recvReply(Signal* signal, const AlterIndxConf* conf,
7567
const AlterIndxRef* ref)
7570
const Uint32 senderRef = signal->senderBlockRef();
7571
const AlterIndxReq::RequestType requestType = conf->getRequestType();
7572
const Uint32 key = conf->getConnectionPtr();
7573
if (requestType == AlterIndxReq::RT_CREATE_INDEX) {
7575
// part of create index operation
7576
OpCreateIndexPtr opPtr;
7577
c_opCreateIndex.find(opPtr, key);
7578
ndbrequire(! opPtr.isNull());
7579
opPtr.p->setError(ref);
7580
createIndex_fromAlterIndex(signal, opPtr);
7583
if (requestType == AlterIndxReq::RT_DROP_INDEX) {
7585
// part of drop index operation
7586
OpDropIndexPtr opPtr;
7587
c_opDropIndex.find(opPtr, key);
7588
ndbrequire(! opPtr.isNull());
7589
opPtr.p->setError(ref);
7590
dropIndex_fromAlterIndex(signal, opPtr);
7593
if (requestType == AlterIndxReq::RT_TC ||
7594
requestType == AlterIndxReq::RT_TUX) {
7596
// part of build index operation
7597
OpBuildIndexPtr opPtr;
7598
c_opBuildIndex.find(opPtr, key);
7599
ndbrequire(! opPtr.isNull());
7600
opPtr.p->setError(ref);
7601
buildIndex_fromOnline(signal, opPtr);
7604
if (requestType == AlterIndxReq::RT_NODERESTART) {
7607
infoEvent("DICT: index %u activated", (unsigned)key);
7609
warningEvent("DICT: index %u activation failed: code=%d line=%d",
7611
ref->getErrorCode(), ref->getErrorLine());
7613
activateIndexes(signal, key + 1);
7616
if (requestType == AlterIndxReq::RT_SYSTEMRESTART) {
7619
infoEvent("DICT: index %u activated done", (unsigned)key);
7621
warningEvent("DICT: index %u activated failed: code=%d line=%d node=%d",
7623
ref->getErrorCode(), ref->getErrorLine(), ref->getErrorNode());
7625
activateIndexes(signal, key + 1);
7628
OpAlterIndexPtr opPtr;
7629
c_opAlterIndex.find(opPtr, key);
7630
ndbrequire(! opPtr.isNull());
7631
ndbrequire(opPtr.p->m_isMaster);
7632
ndbrequire(opPtr.p->m_requestType == requestType);
7633
opPtr.p->setError(ref);
7634
opPtr.p->m_signalCounter.clearWaitingFor(refToNode(senderRef));
7635
if (! opPtr.p->m_signalCounter.done()) {
7639
if (requestType == AlterIndxReq::RT_DICT_COMMIT ||
7640
requestType == AlterIndxReq::RT_DICT_ABORT) {
7642
// send reply to user
7643
alterIndex_sendReply(signal, opPtr, true);
7644
c_opAlterIndex.release(opPtr);
7647
if (opPtr.p->hasError()) {
7649
opPtr.p->m_requestType = AlterIndxReq::RT_DICT_ABORT;
7650
alterIndex_sendSlaveReq(signal, opPtr);
7653
TableRecordPtr indexPtr;
7654
c_tableRecordPool.getPtr(indexPtr, opPtr.p->m_request.getIndexId());
7655
if (indexPtr.p->isHashIndex()) {
7656
if (requestType == AlterIndxReq::RT_DICT_PREPARE) {
7658
if (opPtr.p->m_request.getOnline()) {
7659
opPtr.p->m_requestType = AlterIndxReq::RT_DICT_TC;
7660
alterIndex_sendSlaveReq(signal, opPtr);
7662
// start drop triggers
7663
alterIndex_toDropTrigger(signal, opPtr);
7667
if (requestType == AlterIndxReq::RT_DICT_TC) {
7669
if (opPtr.p->m_request.getOnline()) {
7670
// start create triggers
7671
alterIndex_toCreateTrigger(signal, opPtr);
7673
opPtr.p->m_requestType = AlterIndxReq::RT_DICT_COMMIT;
7674
alterIndex_sendSlaveReq(signal, opPtr);
7679
if (indexPtr.p->isOrderedIndex()) {
7680
if (requestType == AlterIndxReq::RT_DICT_PREPARE) {
7682
if (opPtr.p->m_request.getOnline()) {
7683
// start create triggers
7684
alterIndex_toCreateTrigger(signal, opPtr);
7686
// start drop triggers
7687
alterIndex_toDropTrigger(signal, opPtr);
7696
Dbdict::alterIndex_slavePrepare(Signal* signal, OpAlterIndexPtr opPtr)
7699
const AlterIndxReq* const req = &opPtr.p->m_request;
7700
if (! (req->getIndexId() < c_tableRecordPool.getSize())) {
7702
opPtr.p->m_errorCode = AlterIndxRef::Inconsistency;
7703
opPtr.p->m_errorLine = __LINE__;
7706
TableRecordPtr indexPtr;
7707
c_tableRecordPool.getPtr(indexPtr, req->getIndexId());
7708
if (indexPtr.p->tabState != TableRecord::DEFINED) {
7710
opPtr.p->m_errorCode = AlterIndxRef::IndexNotFound;
7711
opPtr.p->m_errorLine = __LINE__;
7714
if (! indexPtr.p->isIndex()) {
7716
opPtr.p->m_errorCode = AlterIndxRef::NotAnIndex;
7717
opPtr.p->m_errorLine = __LINE__;
7720
if (req->getOnline())
7721
indexPtr.p->indexState = TableRecord::IS_BUILDING;
7723
indexPtr.p->indexState = TableRecord::IS_DROPPING;
7727
Dbdict::alterIndex_toCreateTc(Signal* signal, OpAlterIndexPtr opPtr)
7730
TableRecordPtr indexPtr;
7731
c_tableRecordPool.getPtr(indexPtr, opPtr.p->m_request.getIndexId());
7732
// request to create index in local TC
7733
CreateIndxReq* const req = (CreateIndxReq*)signal->getDataPtrSend();
7734
req->setUserRef(reference());
7735
req->setConnectionPtr(opPtr.p->key);
7736
req->setRequestType(CreateIndxReq::RT_TC);
7737
req->setIndexType(indexPtr.p->tableType);
7738
req->setTableId(indexPtr.p->primaryTableId);
7739
req->setIndexId(indexPtr.i);
7740
req->setOnline(true);
7741
getIndexAttrList(indexPtr, opPtr.p->m_attrList);
7743
LinearSectionPtr lsPtr[3];
7744
lsPtr[0].p = (Uint32*)&opPtr.p->m_attrList;
7745
lsPtr[0].sz = 1 + opPtr.p->m_attrList.sz;
7746
sendSignal(calcTcBlockRef(getOwnNodeId()), GSN_CREATE_INDX_REQ,
7747
signal, CreateIndxReq::SignalLength, JBB, lsPtr, 1);
7751
Dbdict::alterIndex_fromCreateTc(Signal* signal, OpAlterIndexPtr opPtr)
7754
// mark created in local TC
7755
if (! opPtr.p->hasLastError()) {
7756
TableRecordPtr indexPtr;
7757
c_tableRecordPool.getPtr(indexPtr, opPtr.p->m_request.getIndexId());
7758
indexPtr.p->indexLocal |= TableRecord::IL_CREATED_TC;
7760
// forward CONF or REF to master
7761
ndbrequire(opPtr.p->m_requestType == AlterIndxReq::RT_DICT_TC);
7762
alterIndex_sendReply(signal, opPtr, false);
7766
Dbdict::alterIndex_toDropTc(Signal* signal, OpAlterIndexPtr opPtr)
7769
TableRecordPtr indexPtr;
7770
c_tableRecordPool.getPtr(indexPtr, opPtr.p->m_request.getIndexId());
7771
// broken index allowed if force
7772
if (! (indexPtr.p->indexLocal & TableRecord::IL_CREATED_TC)) {
7774
ndbassert(opPtr.p->m_requestFlag & RequestFlag::RF_FORCE);
7775
alterIndex_sendReply(signal, opPtr, false);
7778
// request to drop in local TC
7779
DropIndxReq* const req = (DropIndxReq*)signal->getDataPtrSend();
7780
req->setUserRef(reference());
7781
req->setConnectionPtr(opPtr.p->key);
7782
req->setRequestType(DropIndxReq::RT_TC);
7783
req->setTableId(indexPtr.p->primaryTableId);
7784
req->setIndexId(indexPtr.i);
7785
req->setIndexVersion(indexPtr.p->tableVersion);
7787
sendSignal(calcTcBlockRef(getOwnNodeId()), GSN_DROP_INDX_REQ,
7788
signal, DropIndxReq::SignalLength, JBB);
7792
Dbdict::alterIndex_fromDropTc(Signal* signal, OpAlterIndexPtr opPtr)
7795
ndbrequire(opPtr.p->m_requestType == AlterIndxReq::RT_DICT_TC);
7796
// mark dropped locally
7797
if (! opPtr.p->hasLastError()) {
7798
TableRecordPtr indexPtr;
7799
c_tableRecordPool.getPtr(indexPtr, opPtr.p->m_request.getIndexId());
7800
indexPtr.p->indexLocal &= ~TableRecord::IL_CREATED_TC;
7802
// forward CONF or REF to master
7803
alterIndex_sendReply(signal, opPtr, false);
7807
Dbdict::alterIndex_toCreateTrigger(Signal* signal, OpAlterIndexPtr opPtr)
7810
TableRecordPtr indexPtr;
7811
c_tableRecordPool.getPtr(indexPtr, opPtr.p->m_request.getIndexId());
7812
// start creation of index triggers
7813
CreateTrigReq* const req = (CreateTrigReq*)signal->getDataPtrSend();
7814
req->setUserRef(reference());
7815
req->setConnectionPtr(opPtr.p->key);
7816
req->setRequestType(CreateTrigReq::RT_ALTER_INDEX);
7817
req->addRequestFlag(opPtr.p->m_requestFlag);
7818
req->setTableId(opPtr.p->m_request.getTableId());
7819
req->setIndexId(opPtr.p->m_request.getIndexId());
7820
req->setTriggerId(RNIL);
7821
req->setTriggerActionTime(TriggerActionTime::TA_AFTER);
7822
req->setMonitorAllAttributes(false);
7823
req->setOnline(true); // alter online after create
7824
req->setReceiverRef(0); // implicit for index triggers
7825
getIndexAttrMask(indexPtr, req->getAttributeMask());
7827
char triggerName[MAX_TAB_NAME_SIZE];
7828
Uint32 buffer[2 + ((MAX_TAB_NAME_SIZE + 3) >> 2)]; // SP string
7829
LinearWriter w(buffer, sizeof(buffer) >> 2);
7830
LinearSectionPtr lsPtr[3];
7831
if (indexPtr.p->isHashIndex()) {
7832
req->setTriggerType(TriggerType::SECONDARY_INDEX);
7833
req->setMonitorReplicas(false);
7835
if (opPtr.p->m_requestFlag & RequestFlag::RF_LOCAL)
7836
req->setTriggerId(indexPtr.p->insertTriggerId);
7837
req->setTriggerEvent(TriggerEvent::TE_INSERT);
7838
sprintf(triggerName, "NDB$INDEX_%u_INSERT", opPtr.p->m_request.getIndexId());
7840
w.add(CreateTrigReq::TriggerNameKey, triggerName);
7841
lsPtr[0].p = buffer;
7842
lsPtr[0].sz = w.getWordsUsed();
7843
sendSignal(reference(), GSN_CREATE_TRIG_REQ,
7844
signal, CreateTrigReq::SignalLength, JBB, lsPtr, 1);
7846
if (opPtr.p->m_requestFlag & RequestFlag::RF_LOCAL)
7847
req->setTriggerId(indexPtr.p->updateTriggerId);
7848
req->setTriggerEvent(TriggerEvent::TE_UPDATE);
7849
sprintf(triggerName, "NDB$INDEX_%u_UPDATE", opPtr.p->m_request.getIndexId());
7851
w.add(CreateTrigReq::TriggerNameKey, triggerName);
7852
lsPtr[0].p = buffer;
7853
lsPtr[0].sz = w.getWordsUsed();
7854
sendSignal(reference(), GSN_CREATE_TRIG_REQ,
7855
signal, CreateTrigReq::SignalLength, JBB, lsPtr, 1);
7857
if (opPtr.p->m_requestFlag & RequestFlag::RF_LOCAL)
7858
req->setTriggerId(indexPtr.p->deleteTriggerId);
7859
req->setTriggerEvent(TriggerEvent::TE_DELETE);
7860
sprintf(triggerName, "NDB$INDEX_%u_DELETE", opPtr.p->m_request.getIndexId());
7862
w.add(CreateTrigReq::TriggerNameKey, triggerName);
7863
lsPtr[0].p = buffer;
7864
lsPtr[0].sz = w.getWordsUsed();
7865
sendSignal(reference(), GSN_CREATE_TRIG_REQ,
7866
signal, CreateTrigReq::SignalLength, JBB, lsPtr, 1);
7867
// triggers left to create
7868
opPtr.p->m_triggerCounter = 3;
7871
if (indexPtr.p->isOrderedIndex()) {
7872
req->addRequestFlag(RequestFlag::RF_NOTCTRIGGER);
7873
req->setTriggerType(TriggerType::ORDERED_INDEX);
7874
req->setTriggerActionTime(TriggerActionTime::TA_CUSTOM);
7875
req->setMonitorReplicas(true);
7876
// one trigger for 5 events (insert, update, delete, commit, abort)
7877
if (opPtr.p->m_requestFlag & RequestFlag::RF_LOCAL)
7878
req->setTriggerId(indexPtr.p->customTriggerId);
7879
req->setTriggerEvent(TriggerEvent::TE_CUSTOM);
7880
sprintf(triggerName, "NDB$INDEX_%u_CUSTOM", opPtr.p->m_request.getIndexId());
7882
w.add(CreateTrigReq::TriggerNameKey, triggerName);
7883
lsPtr[0].p = buffer;
7884
lsPtr[0].sz = w.getWordsUsed();
7885
sendSignal(reference(), GSN_CREATE_TRIG_REQ,
7886
signal, CreateTrigReq::SignalLength, JBB, lsPtr, 1);
7887
// triggers left to create
7888
opPtr.p->m_triggerCounter = 1;
7895
Dbdict::alterIndex_fromCreateTrigger(Signal* signal, OpAlterIndexPtr opPtr)
7898
ndbrequire(opPtr.p->m_triggerCounter != 0);
7899
if (--opPtr.p->m_triggerCounter != 0) {
7903
if (opPtr.p->hasError()) {
7905
opPtr.p->m_requestType = AlterIndxReq::RT_DICT_ABORT;
7906
alterIndex_sendSlaveReq(signal, opPtr);
7909
if(opPtr.p->m_requestType != AlterIndxReq::RT_SYSTEMRESTART){
7910
// send build request
7911
alterIndex_toBuildIndex(signal, opPtr);
7916
* During system restart,
7917
* leave index in activated but not build state.
7919
* Build a bit later when REDO has been run
7921
alterIndex_sendReply(signal, opPtr, true);
7925
Dbdict::alterIndex_toDropTrigger(Signal* signal, OpAlterIndexPtr opPtr)
7928
TableRecordPtr indexPtr;
7929
c_tableRecordPool.getPtr(indexPtr, opPtr.p->m_request.getIndexId());
7930
// start drop of index triggers
7931
DropTrigReq* const req = (DropTrigReq*)signal->getDataPtrSend();
7932
req->setUserRef(reference());
7933
req->setConnectionPtr(opPtr.p->key);
7934
req->setRequestType(DropTrigReq::RT_ALTER_INDEX);
7935
req->addRequestFlag(opPtr.p->m_requestFlag);
7936
req->setTableId(opPtr.p->m_request.getTableId());
7937
req->setIndexId(opPtr.p->m_request.getIndexId());
7938
req->setTriggerInfo(0); // not used
7939
opPtr.p->m_triggerCounter = 0;
7940
if (indexPtr.p->isHashIndex()) {
7942
req->setTriggerId(indexPtr.p->insertTriggerId);
7943
sendSignal(reference(), GSN_DROP_TRIG_REQ,
7944
signal, DropTrigReq::SignalLength, JBB);
7945
opPtr.p->m_triggerCounter++;
7947
req->setTriggerId(indexPtr.p->updateTriggerId);
7948
sendSignal(reference(), GSN_DROP_TRIG_REQ,
7949
signal, DropTrigReq::SignalLength, JBB);
7950
opPtr.p->m_triggerCounter++;
7952
req->setTriggerId(indexPtr.p->deleteTriggerId);
7953
sendSignal(reference(), GSN_DROP_TRIG_REQ,
7954
signal, DropTrigReq::SignalLength, JBB);
7955
opPtr.p->m_triggerCounter++;
7957
if (indexPtr.p->buildTriggerId != RNIL) {
7958
req->setTriggerId(indexPtr.p->buildTriggerId);
7959
sendSignal(reference(), GSN_DROP_TRIG_REQ,
7960
signal, DropTrigReq::SignalLength, JBB);
7961
opPtr.p->m_triggerCounter++;
7965
if (indexPtr.p->isOrderedIndex()) {
7967
req->addRequestFlag(RequestFlag::RF_NOTCTRIGGER);
7968
req->setTriggerId(indexPtr.p->customTriggerId);
7969
sendSignal(reference(), GSN_DROP_TRIG_REQ,
7970
signal, DropTrigReq::SignalLength, JBB);
7971
opPtr.p->m_triggerCounter++;
7978
Dbdict::alterIndex_fromDropTrigger(Signal* signal, OpAlterIndexPtr opPtr)
7981
ndbrequire(opPtr.p->m_triggerCounter != 0);
7982
if (--opPtr.p->m_triggerCounter != 0) {
7986
// finally drop index in each TC
7987
TableRecordPtr indexPtr;
7988
c_tableRecordPool.getPtr(indexPtr, opPtr.p->m_request.getIndexId());
7989
const bool isHashIndex = indexPtr.p->isHashIndex();
7990
const bool isOrderedIndex = indexPtr.p->isOrderedIndex();
7991
ndbrequire(isHashIndex != isOrderedIndex); // xor
7993
opPtr.p->m_requestType = AlterIndxReq::RT_DICT_TC;
7995
opPtr.p->m_requestType = AlterIndxReq::RT_DICT_COMMIT;
7996
alterIndex_sendSlaveReq(signal, opPtr);
8000
Dbdict::alterIndex_toBuildIndex(Signal* signal, OpAlterIndexPtr opPtr)
8003
// get index and table records
8004
TableRecordPtr indexPtr;
8005
c_tableRecordPool.getPtr(indexPtr, opPtr.p->m_request.getIndexId());
8006
TableRecordPtr tablePtr;
8007
c_tableRecordPool.getPtr(tablePtr, indexPtr.p->primaryTableId);
8008
// build request to self (short signal)
8009
BuildIndxReq* const req = (BuildIndxReq*)signal->getDataPtrSend();
8010
req->setUserRef(reference());
8011
req->setConnectionPtr(opPtr.p->key);
8012
req->setRequestType(BuildIndxReq::RT_ALTER_INDEX);
8013
req->addRequestFlag(opPtr.p->m_requestFlag);
8014
req->setBuildId(0); // not used
8015
req->setBuildKey(0); // not used
8016
req->setIndexType(indexPtr.p->tableType);
8017
req->setIndexId(indexPtr.i);
8018
req->setTableId(indexPtr.p->primaryTableId);
8019
req->setParallelism(16);
8021
sendSignal(reference(), GSN_BUILDINDXREQ,
8022
signal, BuildIndxReq::SignalLength, JBB);
8026
Dbdict::alterIndex_fromBuildIndex(Signal* signal, OpAlterIndexPtr opPtr)
8029
if (opPtr.p->hasError()) {
8031
opPtr.p->m_requestType = AlterIndxReq::RT_DICT_ABORT;
8032
alterIndex_sendSlaveReq(signal, opPtr);
8035
opPtr.p->m_requestType = AlterIndxReq::RT_DICT_COMMIT;
8036
alterIndex_sendSlaveReq(signal, opPtr);
8040
Dbdict::alterIndex_slaveCommit(Signal* signal, OpAlterIndexPtr opPtr)
8044
TableRecordPtr indexPtr;
8045
c_tableRecordPool.getPtr(indexPtr, opPtr.p->m_request.getIndexId());
8046
indexPtr.p->indexState = TableRecord::IS_ONLINE;
8050
Dbdict::alterIndex_slaveAbort(Signal* signal, OpAlterIndexPtr opPtr)
8053
// find index record
8054
const Uint32 indexId = opPtr.p->m_request.getIndexId();
8055
if (indexId >= c_tableRecordPool.getSize())
8057
TableRecordPtr indexPtr;
8058
c_tableRecordPool.getPtr(indexPtr, indexId);
8059
if (! indexPtr.p->isIndex())
8062
indexPtr.p->indexState = TableRecord::IS_BROKEN;
8066
Dbdict::alterIndex_sendSlaveReq(Signal* signal, OpAlterIndexPtr opPtr)
8068
AlterIndxReq* const req = (AlterIndxReq*)signal->getDataPtrSend();
8069
*req = opPtr.p->m_request;
8070
req->setUserRef(opPtr.p->m_coordinatorRef);
8071
req->setConnectionPtr(opPtr.p->key);
8072
req->setRequestType(opPtr.p->m_requestType);
8073
req->addRequestFlag(opPtr.p->m_requestFlag);
8074
NdbNodeBitmask receiverNodes = c_aliveNodes;
8075
if (opPtr.p->m_requestFlag & RequestFlag::RF_LOCAL) {
8076
receiverNodes.clear();
8077
receiverNodes.set(getOwnNodeId());
8079
opPtr.p->m_signalCounter = receiverNodes;
8080
NodeReceiverGroup rg(DBDICT, receiverNodes);
8081
sendSignal(rg, GSN_ALTER_INDX_REQ,
8082
signal, AlterIndxReq::SignalLength, JBB);
8086
Dbdict::alterIndex_sendReply(Signal* signal, OpAlterIndexPtr opPtr,
8089
AlterIndxRef* rep = (AlterIndxRef*)signal->getDataPtrSend();
8090
Uint32 gsn = GSN_ALTER_INDX_CONF;
8091
Uint32 length = AlterIndxConf::InternalLength;
8094
sendRef = opPtr.p->hasLastError();
8095
rep->setUserRef(opPtr.p->m_coordinatorRef);
8096
rep->setConnectionPtr(opPtr.p->key);
8097
rep->setRequestType(opPtr.p->m_requestType);
8098
if (opPtr.p->m_requestType == AlterIndxReq::RT_DICT_ABORT)
8101
sendRef = opPtr.p->hasError();
8102
rep->setUserRef(opPtr.p->m_request.getUserRef());
8103
rep->setConnectionPtr(opPtr.p->m_request.getConnectionPtr());
8104
rep->setRequestType(opPtr.p->m_request.getRequestType());
8105
length = AlterIndxConf::SignalLength;
8107
rep->setTableId(opPtr.p->m_request.getTableId());
8108
rep->setIndexId(opPtr.p->m_request.getIndexId());
8110
if (opPtr.p->m_errorNode == 0)
8111
opPtr.p->m_errorNode = getOwnNodeId();
8112
rep->setErrorCode(opPtr.p->m_errorCode);
8113
rep->setErrorLine(opPtr.p->m_errorLine);
8114
rep->setErrorNode(opPtr.p->m_errorNode);
8115
gsn = GSN_ALTER_INDX_REF;
8116
length = AlterIndxRef::SignalLength;
8118
sendSignal(rep->getUserRef(), gsn, signal, length, JBB);
8122
* MODULE: Build index
8124
* Build index or all indexes on a table. Request type:
8126
* RT_USER - normal user request, not yet used
8127
* RT_ALTER_INDEX - from alter index
8128
* RT_SYSTEM_RESTART -
8129
* RT_DICT_PREPARE - prepare participants
8130
* RT_DICT_TRIX - to participant on way to local TRIX
8131
* RT_DICT_COMMIT - commit in each participant
8132
* RT_DICT_ABORT - abort
8133
* RT_TRIX - to local TRIX
8137
Dbdict::execBUILDINDXREQ(Signal* signal)
8140
BuildIndxReq* const req = (BuildIndxReq*)signal->getDataPtrSend();
8141
OpBuildIndexPtr opPtr;
8142
const Uint32 senderRef = signal->senderBlockRef();
8143
const BuildIndxReq::RequestType requestType = req->getRequestType();
8144
if (requestType == BuildIndxReq::RT_USER ||
8145
requestType == BuildIndxReq::RT_ALTER_INDEX ||
8146
requestType == BuildIndxReq::RT_SYSTEMRESTART) {
8149
const bool isLocal = req->getRequestFlag() & RequestFlag::RF_LOCAL;
8150
NdbNodeBitmask receiverNodes = c_aliveNodes;
8152
receiverNodes.clear();
8153
receiverNodes.set(getOwnNodeId());
8156
if (signal->getLength() == BuildIndxReq::SignalLength) {
8159
if (!isLocal && getOwnNodeId() != c_masterNodeId) {
8162
releaseSections(signal);
8166
opPtr.p->m_errorCode = BuildIndxRef::NotMaster;
8167
opPtr.p->m_errorLine = __LINE__;
8168
opPtr.p->m_errorNode = c_masterNodeId;
8169
buildIndex_sendReply(signal, opPtr, true);
8172
// forward initial request plus operation key to all
8173
req->setOpKey(++c_opRecordSequence);
8174
NodeReceiverGroup rg(DBDICT, receiverNodes);
8175
sendSignal(rg, GSN_BUILDINDXREQ,
8176
signal, BuildIndxReq::SignalLength + 1, JBB);
8179
// seize operation record
8180
ndbrequire(signal->getLength() == BuildIndxReq::SignalLength + 1);
8181
const Uint32 opKey = req->getOpKey();
8182
OpBuildIndex opBusy;
8183
if (! c_opBuildIndex.seize(opPtr))
8186
opPtr.p->m_coordinatorRef = senderRef;
8187
opPtr.p->m_isMaster = (senderRef == reference());
8188
opPtr.p->key = opKey;
8189
opPtr.p->m_requestType = BuildIndxReq::RT_DICT_PREPARE;
8190
if (opPtr.p == &opBusy) {
8192
opPtr.p->m_errorCode = BuildIndxRef::Busy;
8193
opPtr.p->m_errorLine = __LINE__;
8194
buildIndex_sendReply(signal, opPtr, opPtr.p->m_isMaster);
8197
c_opBuildIndex.add(opPtr);
8198
// master expects to hear from all
8199
opPtr.p->m_signalCounter = receiverNodes;
8200
buildIndex_sendReply(signal, opPtr, false);
8203
c_opBuildIndex.find(opPtr, req->getConnectionPtr());
8204
if (! opPtr.isNull()) {
8205
opPtr.p->m_requestType = requestType;
8206
if (requestType == BuildIndxReq::RT_DICT_TRIX) {
8208
buildIndex_buildTrix(signal, opPtr);
8211
if (requestType == BuildIndxReq::RT_DICT_TC ||
8212
requestType == BuildIndxReq::RT_DICT_TUX) {
8214
buildIndex_toOnline(signal, opPtr);
8217
if (requestType == BuildIndxReq::RT_DICT_COMMIT ||
8218
requestType == BuildIndxReq::RT_DICT_ABORT) {
8220
buildIndex_sendReply(signal, opPtr, false);
8222
if (! opPtr.p->m_isMaster)
8223
c_opBuildIndex.release(opPtr);
8232
opPtr.p->m_errorCode = BuildIndxRef::BadRequestType;
8233
opPtr.p->m_errorLine = __LINE__;
8234
buildIndex_sendReply(signal, opPtr, true);
8238
Dbdict::execBUILDINDXCONF(Signal* signal)
8241
ndbrequire(signal->getNoOfSections() == 0);
8242
BuildIndxConf* conf = (BuildIndxConf*)signal->getDataPtrSend();
8243
buildIndex_recvReply(signal, conf, 0);
8247
Dbdict::execBUILDINDXREF(Signal* signal)
8250
BuildIndxRef* ref = (BuildIndxRef*)signal->getDataPtrSend();
8251
buildIndex_recvReply(signal, ref->getConf(), ref);
8255
Dbdict::buildIndex_recvReply(Signal* signal, const BuildIndxConf* conf,
8256
const BuildIndxRef* ref)
8259
const Uint32 senderRef = signal->senderBlockRef();
8260
const BuildIndxReq::RequestType requestType = conf->getRequestType();
8261
const Uint32 key = conf->getConnectionPtr();
8262
if (requestType == BuildIndxReq::RT_ALTER_INDEX) {
8264
// part of alter index operation
8265
OpAlterIndexPtr opPtr;
8266
c_opAlterIndex.find(opPtr, key);
8267
ndbrequire(! opPtr.isNull());
8268
opPtr.p->setError(ref);
8269
alterIndex_fromBuildIndex(signal, opPtr);
8273
if (requestType == BuildIndxReq::RT_SYSTEMRESTART) {
8276
infoEvent("DICT: index %u rebuild done", (unsigned)key);
8278
warningEvent("DICT: index %u rebuild failed: code=%d line=%d node=%d",
8279
(unsigned)key, ref->getErrorCode());
8281
rebuildIndexes(signal, key + 1);
8285
OpBuildIndexPtr opPtr;
8286
c_opBuildIndex.find(opPtr, key);
8287
ndbrequire(! opPtr.isNull());
8288
opPtr.p->setError(ref);
8289
if (requestType == BuildIndxReq::RT_TRIX) {
8291
// forward to master
8292
opPtr.p->m_requestType = BuildIndxReq::RT_DICT_TRIX;
8293
buildIndex_sendReply(signal, opPtr, false);
8296
ndbrequire(opPtr.p->m_isMaster);
8297
ndbrequire(opPtr.p->m_requestType == requestType);
8298
opPtr.p->m_signalCounter.clearWaitingFor(refToNode(senderRef));
8299
if (! opPtr.p->m_signalCounter.done()) {
8303
if (requestType == BuildIndxReq::RT_DICT_COMMIT ||
8304
requestType == BuildIndxReq::RT_DICT_ABORT) {
8306
// send reply to user
8307
buildIndex_sendReply(signal, opPtr, true);
8308
c_opBuildIndex.release(opPtr);
8311
if (opPtr.p->hasError()) {
8313
opPtr.p->m_requestType = BuildIndxReq::RT_DICT_ABORT;
8314
buildIndex_sendSlaveReq(signal, opPtr);
8317
TableRecordPtr indexPtr;
8318
c_tableRecordPool.getPtr(indexPtr, opPtr.p->m_request.getIndexId());
8319
if (indexPtr.p->isHashIndex()) {
8320
if (requestType == BuildIndxReq::RT_DICT_PREPARE) {
8322
if (! (opPtr.p->m_requestFlag & RequestFlag::RF_NOBUILD)) {
8323
buildIndex_toCreateConstr(signal, opPtr);
8325
opPtr.p->m_requestType = BuildIndxReq::RT_DICT_TC;
8326
buildIndex_sendSlaveReq(signal, opPtr);
8330
if (requestType == BuildIndxReq::RT_DICT_TRIX) {
8332
ndbrequire(! (opPtr.p->m_requestFlag & RequestFlag::RF_NOBUILD));
8333
buildIndex_toDropConstr(signal, opPtr);
8336
if (requestType == BuildIndxReq::RT_DICT_TC) {
8338
opPtr.p->m_requestType = BuildIndxReq::RT_DICT_COMMIT;
8339
buildIndex_sendSlaveReq(signal, opPtr);
8343
if (indexPtr.p->isOrderedIndex()) {
8344
if (requestType == BuildIndxReq::RT_DICT_PREPARE) {
8346
if (! (opPtr.p->m_requestFlag & RequestFlag::RF_NOBUILD)) {
8347
opPtr.p->m_requestType = BuildIndxReq::RT_DICT_TRIX;
8348
buildIndex_sendSlaveReq(signal, opPtr);
8350
opPtr.p->m_requestType = BuildIndxReq::RT_DICT_TUX;
8351
buildIndex_sendSlaveReq(signal, opPtr);
8355
if (requestType == BuildIndxReq::RT_DICT_TRIX) {
8357
ndbrequire(! (opPtr.p->m_requestFlag & RequestFlag::RF_NOBUILD));
8358
opPtr.p->m_requestType = BuildIndxReq::RT_DICT_TUX;
8359
buildIndex_sendSlaveReq(signal, opPtr);
8362
if (requestType == BuildIndxReq::RT_DICT_TUX) {
8364
opPtr.p->m_requestType = BuildIndxReq::RT_DICT_COMMIT;
8365
buildIndex_sendSlaveReq(signal, opPtr);
8373
Dbdict::buildIndex_toCreateConstr(Signal* signal, OpBuildIndexPtr opPtr)
8376
TableRecordPtr indexPtr;
8377
c_tableRecordPool.getPtr(indexPtr, opPtr.p->m_request.getIndexId());
8378
// request to create constraint trigger
8379
CreateTrigReq* req = (CreateTrigReq*)signal->getDataPtrSend();
8380
req->setUserRef(reference());
8381
req->setConnectionPtr(opPtr.p->key);
8382
req->setRequestType(CreateTrigReq::RT_BUILD_INDEX);
8383
req->addRequestFlag(0); // none
8384
req->setTableId(indexPtr.i);
8385
req->setIndexId(RNIL);
8386
req->setTriggerId(RNIL);
8387
req->setTriggerType(TriggerType::READ_ONLY_CONSTRAINT);
8388
req->setTriggerActionTime(TriggerActionTime::TA_AFTER);
8389
req->setTriggerEvent(TriggerEvent::TE_UPDATE);
8390
req->setMonitorReplicas(false);
8391
req->setMonitorAllAttributes(false);
8392
req->setOnline(true); // alter online after create
8393
req->setReceiverRef(0); // no receiver, REF-ed by TUP
8394
req->getAttributeMask().clear();
8395
// NDB$PK is last attribute
8396
req->getAttributeMask().set(indexPtr.p->noOfAttributes - 1);
8398
char triggerName[MAX_TAB_NAME_SIZE];
8399
Uint32 buffer[2 + ((MAX_TAB_NAME_SIZE + 3) >> 2)]; // SP string
8400
LinearWriter w(buffer, sizeof(buffer) >> 2);
8401
LinearSectionPtr lsPtr[3];
8402
sprintf(triggerName, "NDB$INDEX_%u_BUILD", indexPtr.i);
8404
w.add(CreateTrigReq::TriggerNameKey, triggerName);
8405
lsPtr[0].p = buffer;
8406
lsPtr[0].sz = w.getWordsUsed();
8407
sendSignal(reference(), GSN_CREATE_TRIG_REQ,
8408
signal, CreateTrigReq::SignalLength, JBB, lsPtr, 1);
8412
Dbdict::buildIndex_fromCreateConstr(Signal* signal, OpBuildIndexPtr opPtr)
8415
if (opPtr.p->hasError()) {
8417
opPtr.p->m_requestType = BuildIndxReq::RT_DICT_ABORT;
8418
buildIndex_sendSlaveReq(signal, opPtr);
8421
opPtr.p->m_requestType = BuildIndxReq::RT_DICT_TRIX;
8422
buildIndex_sendSlaveReq(signal, opPtr);
8426
Dbdict::buildIndex_buildTrix(Signal* signal, OpBuildIndexPtr opPtr)
8429
TableRecordPtr indexPtr;
8430
c_tableRecordPool.getPtr(indexPtr, opPtr.p->m_request.getIndexId());
8431
TableRecordPtr tablePtr;
8432
c_tableRecordPool.getPtr(tablePtr, indexPtr.p->primaryTableId);
8434
BuildIndxReq* const req = (BuildIndxReq*)signal->getDataPtrSend();
8435
req->setUserRef(reference());
8436
req->setConnectionPtr(opPtr.p->key);
8437
req->setRequestType(BuildIndxReq::RT_TRIX);
8438
req->setBuildId(0); // not yet..
8439
req->setBuildKey(0); // ..in use
8440
req->setIndexType(indexPtr.p->tableType);
8441
req->setIndexId(indexPtr.i);
8442
req->setTableId(indexPtr.p->primaryTableId);
8443
req->setParallelism(16);
8444
if (indexPtr.p->isHashIndex()) {
8446
getIndexAttrList(indexPtr, opPtr.p->m_attrList);
8447
getTableKeyList(tablePtr, opPtr.p->m_tableKeyList);
8449
LinearSectionPtr lsPtr[3];
8450
lsPtr[0].sz = opPtr.p->m_attrList.sz;
8451
lsPtr[0].p = opPtr.p->m_attrList.id;
8452
lsPtr[1].sz = opPtr.p->m_tableKeyList.sz;
8453
lsPtr[1].p = opPtr.p->m_tableKeyList.id;
8454
sendSignal(calcTrixBlockRef(getOwnNodeId()), GSN_BUILDINDXREQ,
8455
signal, BuildIndxReq::SignalLength, JBB, lsPtr, 2);
8458
if (indexPtr.p->isOrderedIndex()) {
8460
sendSignal(calcTupBlockRef(getOwnNodeId()), GSN_BUILDINDXREQ,
8461
signal, BuildIndxReq::SignalLength, JBB);
8468
Dbdict::buildIndex_toDropConstr(Signal* signal, OpBuildIndexPtr opPtr)
8471
TableRecordPtr indexPtr;
8472
c_tableRecordPool.getPtr(indexPtr, opPtr.p->m_request.getIndexId());
8473
// request to drop constraint trigger
8474
DropTrigReq* req = (DropTrigReq*)signal->getDataPtrSend();
8475
req->setUserRef(reference());
8476
req->setConnectionPtr(opPtr.p->key);
8477
req->setRequestType(DropTrigReq::RT_BUILD_INDEX);
8478
req->addRequestFlag(0); // none
8479
req->setTableId(indexPtr.i);
8480
req->setIndexId(RNIL);
8481
req->setTriggerId(opPtr.p->m_constrTriggerId);
8482
req->setTriggerInfo(0); // not used
8483
sendSignal(reference(), GSN_DROP_TRIG_REQ,
8484
signal, DropTrigReq::SignalLength, JBB);
8488
Dbdict::buildIndex_fromDropConstr(Signal* signal, OpBuildIndexPtr opPtr)
8491
if (opPtr.p->hasError()) {
8493
opPtr.p->m_requestType = BuildIndxReq::RT_DICT_ABORT;
8494
buildIndex_sendSlaveReq(signal, opPtr);
8497
opPtr.p->m_requestType = BuildIndxReq::RT_DICT_TC;
8498
buildIndex_sendSlaveReq(signal, opPtr);
8502
Dbdict::buildIndex_toOnline(Signal* signal, OpBuildIndexPtr opPtr)
8505
TableRecordPtr indexPtr;
8506
c_tableRecordPool.getPtr(indexPtr, opPtr.p->m_request.getIndexId());
8507
TableRecordPtr tablePtr;
8508
c_tableRecordPool.getPtr(tablePtr, indexPtr.p->primaryTableId);
8509
// request to set index online in TC or TUX
8510
AlterIndxReq* const req = (AlterIndxReq*)signal->getDataPtrSend();
8511
req->setUserRef(reference());
8512
req->setConnectionPtr(opPtr.p->key);
8513
if (opPtr.p->m_requestType == BuildIndxReq::RT_DICT_TC) {
8515
req->setRequestType(AlterIndxReq::RT_TC);
8516
} else if (opPtr.p->m_requestType == BuildIndxReq::RT_DICT_TUX) {
8518
req->setRequestType(AlterIndxReq::RT_TUX);
8522
req->setTableId(tablePtr.i);
8523
req->setIndexId(indexPtr.i);
8524
req->setIndexVersion(indexPtr.p->tableVersion);
8525
req->setOnline(true);
8526
BlockReference blockRef = 0;
8527
if (opPtr.p->m_requestType == BuildIndxReq::RT_DICT_TC) {
8529
blockRef = calcTcBlockRef(getOwnNodeId());
8530
} else if (opPtr.p->m_requestType == BuildIndxReq::RT_DICT_TUX) {
8532
blockRef = calcTuxBlockRef(getOwnNodeId());
8537
sendSignal(blockRef, GSN_ALTER_INDX_REQ,
8538
signal, BuildIndxReq::SignalLength, JBB);
8542
Dbdict::buildIndex_fromOnline(Signal* signal, OpBuildIndexPtr opPtr)
8545
// forward to master
8546
buildIndex_sendReply(signal, opPtr, false);
8550
Dbdict::buildIndex_sendSlaveReq(Signal* signal, OpBuildIndexPtr opPtr)
8552
BuildIndxReq* const req = (BuildIndxReq*)signal->getDataPtrSend();
8553
*req = opPtr.p->m_request;
8554
req->setUserRef(opPtr.p->m_coordinatorRef);
8555
req->setConnectionPtr(opPtr.p->key);
8556
req->setRequestType(opPtr.p->m_requestType);
8557
req->addRequestFlag(opPtr.p->m_requestFlag);
8558
if(opPtr.p->m_requestFlag & RequestFlag::RF_LOCAL) {
8560
opPtr.p->m_signalCounter.clearWaitingFor();
8561
opPtr.p->m_signalCounter.setWaitingFor(getOwnNodeId());
8562
sendSignal(reference(), GSN_BUILDINDXREQ,
8563
signal, BuildIndxReq::SignalLength, JBB);
8566
opPtr.p->m_signalCounter = c_aliveNodes;
8567
NodeReceiverGroup rg(DBDICT, c_aliveNodes);
8568
sendSignal(rg, GSN_BUILDINDXREQ,
8569
signal, BuildIndxReq::SignalLength, JBB);
8574
Dbdict::buildIndex_sendReply(Signal* signal, OpBuildIndexPtr opPtr,
8577
BuildIndxRef* rep = (BuildIndxRef*)signal->getDataPtrSend();
8578
Uint32 gsn = GSN_BUILDINDXCONF;
8579
Uint32 length = BuildIndxConf::InternalLength;
8582
sendRef = opPtr.p->hasLastError();
8583
rep->setUserRef(opPtr.p->m_coordinatorRef);
8584
rep->setConnectionPtr(opPtr.p->key);
8585
rep->setRequestType(opPtr.p->m_requestType);
8586
if (opPtr.p->m_requestType == BuildIndxReq::RT_DICT_ABORT)
8589
sendRef = opPtr.p->hasError();
8590
rep->setUserRef(opPtr.p->m_request.getUserRef());
8591
rep->setConnectionPtr(opPtr.p->m_request.getConnectionPtr());
8592
rep->setRequestType(opPtr.p->m_request.getRequestType());
8593
length = BuildIndxConf::SignalLength;
8595
rep->setIndexType(opPtr.p->m_request.getIndexType());
8596
rep->setTableId(opPtr.p->m_request.getTableId());
8597
rep->setIndexId(opPtr.p->m_request.getIndexId());
8599
rep->setErrorCode(opPtr.p->m_errorCode);
8600
rep->masterNodeId = opPtr.p->m_errorNode;
8601
gsn = GSN_BUILDINDXREF;
8602
length = BuildIndxRef::SignalLength;
8604
sendSignal(rep->getUserRef(), gsn, signal, length, JBB);
8608
* MODULE: Create trigger
8610
* Create trigger in all DICT blocks. Optionally start alter trigger
8611
* operation to set the trigger online.
8613
* Request type received in REQ and returned in CONF/REF:
8615
* RT_USER - normal user e.g. BACKUP
8616
* RT_ALTER_INDEX - from alter index online
8617
* RT_DICT_PREPARE - seize operation in each DICT
8618
* RT_DICT_COMMIT - commit create in each DICT
8619
* RT_TC - sending to TC (operation alter trigger)
8620
* RT_LQH - sending to LQH (operation alter trigger)
8624
Dbdict::execCREATE_TRIG_REQ(Signal* signal)
8627
CreateTrigReq* const req = (CreateTrigReq*)signal->getDataPtrSend();
8628
OpCreateTriggerPtr opPtr;
8629
const Uint32 senderRef = signal->senderBlockRef();
8630
const CreateTrigReq::RequestType requestType = req->getRequestType();
8631
if (requestType == CreateTrigReq::RT_USER ||
8632
requestType == CreateTrigReq::RT_ALTER_INDEX ||
8633
requestType == CreateTrigReq::RT_BUILD_INDEX) {
8635
if (! assembleFragments(signal)) {
8639
const bool isLocal = req->getRequestFlag() & RequestFlag::RF_LOCAL;
8640
NdbNodeBitmask receiverNodes = c_aliveNodes;
8642
receiverNodes.clear();
8643
receiverNodes.set(getOwnNodeId());
8645
if (signal->getLength() == CreateTrigReq::SignalLength) {
8647
if (! isLocal && getOwnNodeId() != c_masterNodeId) {
8650
releaseSections(signal);
8651
OpCreateTrigger opBad;
8654
opPtr.p->m_errorCode = CreateTrigRef::NotMaster;
8655
opPtr.p->m_errorLine = __LINE__;
8656
opPtr.p->m_errorNode = c_masterNodeId;
8657
createTrigger_sendReply(signal, opPtr, true);
8660
// forward initial request plus operation key to all
8661
req->setOpKey(++c_opRecordSequence);
8662
NodeReceiverGroup rg(DBDICT, receiverNodes);
8663
sendSignal(rg, GSN_CREATE_TRIG_REQ,
8664
signal, CreateTrigReq::SignalLength + 1, JBB);
8667
// seize operation record
8668
ndbrequire(signal->getLength() == CreateTrigReq::SignalLength + 1);
8669
const Uint32 opKey = req->getOpKey();
8670
OpCreateTrigger opBusy;
8671
if (! c_opCreateTrigger.seize(opPtr))
8674
opPtr.p->m_coordinatorRef = senderRef;
8675
opPtr.p->m_isMaster = (senderRef == reference());
8676
opPtr.p->key = opKey;
8677
opPtr.p->m_requestType = CreateTrigReq::RT_DICT_PREPARE;
8678
if (opPtr.p == &opBusy) {
8680
opPtr.p->m_errorCode = CreateTrigRef::Busy;
8681
opPtr.p->m_errorLine = __LINE__;
8682
releaseSections(signal);
8683
createTrigger_sendReply(signal, opPtr, opPtr.p->m_isMaster);
8686
c_opCreateTrigger.add(opPtr);
8689
SegmentedSectionPtr ssPtr;
8690
signal->getSection(ssPtr, CreateTrigReq::TRIGGER_NAME_SECTION);
8691
SimplePropertiesSectionReader ssReader(ssPtr, getSectionSegmentPool());
8692
if (ssReader.getKey() != CreateTrigReq::TriggerNameKey ||
8693
! ssReader.getString(opPtr.p->m_triggerName)) {
8695
opPtr.p->m_errorCode = CreateTrigRef::InvalidName;
8696
opPtr.p->m_errorLine = __LINE__;
8697
releaseSections(signal);
8698
createTrigger_sendReply(signal, opPtr, opPtr.p->m_isMaster);
8702
releaseSections(signal);
8704
// check that trigger name is unique
8705
TriggerRecordPtr triggerPtr;
8706
TriggerRecord keyRecord;
8707
strcpy(keyRecord.triggerName, opPtr.p->m_triggerName);
8708
c_triggerRecordHash.find(triggerPtr, keyRecord);
8709
if (triggerPtr.i != RNIL) {
8711
opPtr.p->m_errorCode = CreateTrigRef::TriggerExists;
8712
opPtr.p->m_errorLine = __LINE__;
8713
createTrigger_sendReply(signal, opPtr, opPtr.p->m_isMaster);
8718
// master expects to hear from all
8719
if (opPtr.p->m_isMaster)
8720
opPtr.p->m_signalCounter = receiverNodes;
8721
// check request in all participants
8722
createTrigger_slavePrepare(signal, opPtr);
8723
createTrigger_sendReply(signal, opPtr, false);
8726
c_opCreateTrigger.find(opPtr, req->getConnectionPtr());
8727
if (! opPtr.isNull()) {
8728
opPtr.p->m_requestType = requestType;
8729
if (requestType == CreateTrigReq::RT_DICT_CREATE) {
8731
// master has set trigger id
8732
opPtr.p->m_request.setTriggerId(req->getTriggerId());
8733
createTrigger_slaveCreate(signal, opPtr);
8734
createTrigger_sendReply(signal, opPtr, false);
8737
if (requestType == CreateTrigReq::RT_DICT_COMMIT ||
8738
requestType == CreateTrigReq::RT_DICT_ABORT) {
8740
if (requestType == CreateTrigReq::RT_DICT_COMMIT)
8741
createTrigger_slaveCommit(signal, opPtr);
8743
createTrigger_slaveAbort(signal, opPtr);
8744
createTrigger_sendReply(signal, opPtr, false);
8746
if (! opPtr.p->m_isMaster)
8747
c_opCreateTrigger.release(opPtr);
8753
releaseSections(signal);
8754
OpCreateTrigger opBad;
8757
opPtr.p->m_errorCode = CreateTrigRef::BadRequestType;
8758
opPtr.p->m_errorLine = __LINE__;
8759
createTrigger_sendReply(signal, opPtr, true);
8763
Dbdict::execCREATE_TRIG_CONF(Signal* signal)
8766
ndbrequire(signal->getNoOfSections() == 0);
8767
CreateTrigConf* conf = (CreateTrigConf*)signal->getDataPtrSend();
8768
createTrigger_recvReply(signal, conf, 0);
8772
Dbdict::execCREATE_TRIG_REF(Signal* signal)
8775
CreateTrigRef* ref = (CreateTrigRef*)signal->getDataPtrSend();
8776
createTrigger_recvReply(signal, ref->getConf(), ref);
8780
Dbdict::createTrigger_recvReply(Signal* signal, const CreateTrigConf* conf,
8781
const CreateTrigRef* ref)
8784
const Uint32 senderRef = signal->senderBlockRef();
8785
const CreateTrigReq::RequestType requestType = conf->getRequestType();
8786
const Uint32 key = conf->getConnectionPtr();
8787
if (requestType == CreateTrigReq::RT_ALTER_INDEX) {
8789
// part of alter index operation
8790
OpAlterIndexPtr opPtr;
8791
c_opAlterIndex.find(opPtr, key);
8792
ndbrequire(! opPtr.isNull());
8793
opPtr.p->setError(ref);
8794
alterIndex_fromCreateTrigger(signal, opPtr);
8797
if (requestType == CreateTrigReq::RT_BUILD_INDEX) {
8799
// part of build index operation
8800
OpBuildIndexPtr opPtr;
8801
c_opBuildIndex.find(opPtr, key);
8802
ndbrequire(! opPtr.isNull());
8803
opPtr.p->setError(ref);
8804
// fill in trigger id
8805
opPtr.p->m_constrTriggerId = conf->getTriggerId();
8806
buildIndex_fromCreateConstr(signal, opPtr);
8809
if (requestType == CreateTrigReq::RT_TC ||
8810
requestType == CreateTrigReq::RT_LQH) {
8812
// part of alter trigger operation
8813
OpAlterTriggerPtr opPtr;
8814
c_opAlterTrigger.find(opPtr, key);
8815
ndbrequire(! opPtr.isNull());
8816
opPtr.p->setError(ref);
8817
alterTrigger_fromCreateLocal(signal, opPtr);
8820
OpCreateTriggerPtr opPtr;
8821
c_opCreateTrigger.find(opPtr, key);
8822
ndbrequire(! opPtr.isNull());
8823
ndbrequire(opPtr.p->m_isMaster);
8824
ndbrequire(opPtr.p->m_requestType == requestType);
8825
opPtr.p->setError(ref);
8826
opPtr.p->m_signalCounter.clearWaitingFor(refToNode(senderRef));
8827
if (! opPtr.p->m_signalCounter.done()) {
8831
if (requestType == CreateTrigReq::RT_DICT_COMMIT ||
8832
requestType == CreateTrigReq::RT_DICT_ABORT) {
8834
// send reply to user
8835
createTrigger_sendReply(signal, opPtr, true);
8836
c_opCreateTrigger.release(opPtr);
8839
if (opPtr.p->hasError()) {
8841
opPtr.p->m_requestType = CreateTrigReq::RT_DICT_ABORT;
8842
createTrigger_sendSlaveReq(signal, opPtr);
8845
if (requestType == CreateTrigReq::RT_DICT_PREPARE) {
8847
// seize trigger id in master
8848
createTrigger_masterSeize(signal, opPtr);
8849
if (opPtr.p->hasError()) {
8851
opPtr.p->m_requestType = CreateTrigReq::RT_DICT_ABORT;
8852
createTrigger_sendSlaveReq(signal, opPtr);
8855
opPtr.p->m_requestType = CreateTrigReq::RT_DICT_CREATE;
8856
createTrigger_sendSlaveReq(signal, opPtr);
8859
if (requestType == CreateTrigReq::RT_DICT_CREATE) {
8861
if (opPtr.p->m_request.getOnline()) {
8863
// start alter online
8864
createTrigger_toAlterTrigger(signal, opPtr);
8867
opPtr.p->m_requestType = CreateTrigReq::RT_DICT_COMMIT;
8868
createTrigger_sendSlaveReq(signal, opPtr);
8875
Dbdict::createTrigger_slavePrepare(Signal* signal, OpCreateTriggerPtr opPtr)
8878
const CreateTrigReq* const req = &opPtr.p->m_request;
8879
// check trigger type
8880
if (req->getRequestType() == CreateTrigReq::RT_USER &&
8881
req->getTriggerType() == TriggerType::SUBSCRIPTION ||
8882
req->getRequestType() == CreateTrigReq::RT_ALTER_INDEX &&
8883
req->getTriggerType() == TriggerType::SECONDARY_INDEX ||
8884
req->getRequestType() == CreateTrigReq::RT_ALTER_INDEX &&
8885
req->getTriggerType() == TriggerType::ORDERED_INDEX ||
8886
req->getRequestType() == CreateTrigReq::RT_BUILD_INDEX &&
8887
req->getTriggerType() == TriggerType::READ_ONLY_CONSTRAINT) {
8891
opPtr.p->m_errorCode = CreateTrigRef::UnsupportedTriggerType;
8892
opPtr.p->m_errorLine = __LINE__;
8896
const Uint32 tableId = req->getTableId();
8897
if (! (tableId < c_tableRecordPool.getSize())) {
8899
opPtr.p->m_errorCode = CreateTrigRef::InvalidTable;
8900
opPtr.p->m_errorLine = __LINE__;
8903
TableRecordPtr tablePtr;
8904
c_tableRecordPool.getPtr(tablePtr, tableId);
8905
if (tablePtr.p->tabState != TableRecord::DEFINED &&
8906
tablePtr.p->tabState != TableRecord::BACKUP_ONGOING) {
8908
opPtr.p->m_errorCode = CreateTrigRef::InvalidTable;
8909
opPtr.p->m_errorLine = __LINE__;
8915
Dbdict::createTrigger_masterSeize(Signal* signal, OpCreateTriggerPtr opPtr)
8917
TriggerRecordPtr triggerPtr;
8918
if (opPtr.p->m_requestFlag & RequestFlag::RF_LOCAL) {
8919
triggerPtr.i = opPtr.p->m_request.getTriggerId();
8921
triggerPtr.i = getFreeTriggerRecord();
8922
if (triggerPtr.i == RNIL) {
8924
opPtr.p->m_errorCode = CreateTrigRef::TooManyTriggers;
8925
opPtr.p->m_errorLine = __LINE__;
8929
c_triggerRecordPool.getPtr(triggerPtr);
8930
initialiseTriggerRecord(triggerPtr);
8931
triggerPtr.p->triggerState = TriggerRecord::TS_DEFINING;
8932
opPtr.p->m_request.setTriggerId(triggerPtr.i);
8936
Dbdict::createTrigger_slaveCreate(Signal* signal, OpCreateTriggerPtr opPtr)
8939
const CreateTrigReq* const req = &opPtr.p->m_request;
8940
// get the trigger record
8941
const Uint32 triggerId = req->getTriggerId();
8942
TriggerRecordPtr triggerPtr;
8943
c_triggerRecordPool.getPtr(triggerPtr, triggerId);
8944
initialiseTriggerRecord(triggerPtr);
8945
// fill in trigger data
8946
strcpy(triggerPtr.p->triggerName, opPtr.p->m_triggerName);
8947
triggerPtr.p->triggerId = triggerId;
8948
triggerPtr.p->tableId = req->getTableId();
8949
triggerPtr.p->indexId = RNIL;
8950
triggerPtr.p->triggerType = req->getTriggerType();
8951
triggerPtr.p->triggerActionTime = req->getTriggerActionTime();
8952
triggerPtr.p->triggerEvent = req->getTriggerEvent();
8953
triggerPtr.p->monitorReplicas = req->getMonitorReplicas();
8954
triggerPtr.p->monitorAllAttributes = req->getMonitorAllAttributes();
8955
triggerPtr.p->attributeMask = req->getAttributeMask();
8956
triggerPtr.p->triggerState = TriggerRecord::TS_OFFLINE;
8957
// add to hash table
8958
// ndbout_c("++++++++++++ Adding trigger id %u, %s", triggerPtr.p->triggerId, triggerPtr.p->triggerName);
8959
c_triggerRecordHash.add(triggerPtr);
8960
if (triggerPtr.p->triggerType == TriggerType::SECONDARY_INDEX ||
8961
triggerPtr.p->triggerType == TriggerType::ORDERED_INDEX) {
8963
// connect to index record XXX should be done in caller instead
8964
triggerPtr.p->indexId = req->getIndexId();
8965
TableRecordPtr indexPtr;
8966
c_tableRecordPool.getPtr(indexPtr, triggerPtr.p->indexId);
8967
switch (triggerPtr.p->triggerEvent) {
8968
case TriggerEvent::TE_INSERT:
8969
indexPtr.p->insertTriggerId = triggerPtr.p->triggerId;
8971
case TriggerEvent::TE_UPDATE:
8972
indexPtr.p->updateTriggerId = triggerPtr.p->triggerId;
8974
case TriggerEvent::TE_DELETE:
8975
indexPtr.p->deleteTriggerId = triggerPtr.p->triggerId;
8977
case TriggerEvent::TE_CUSTOM:
8978
indexPtr.p->customTriggerId = triggerPtr.p->triggerId;
8985
if (triggerPtr.p->triggerType == TriggerType::READ_ONLY_CONSTRAINT) {
8987
// connect to index record XXX should be done in caller instead
8988
triggerPtr.p->indexId = req->getTableId();
8989
TableRecordPtr indexPtr;
8990
c_tableRecordPool.getPtr(indexPtr, triggerPtr.p->indexId);
8991
indexPtr.p->buildTriggerId = triggerPtr.p->triggerId;
8996
Dbdict::createTrigger_toAlterTrigger(Signal* signal, OpCreateTriggerPtr opPtr)
8999
AlterTrigReq* req = (AlterTrigReq*)signal->getDataPtrSend();
9000
req->setUserRef(reference());
9001
req->setConnectionPtr(opPtr.p->key);
9002
req->setRequestType(AlterTrigReq::RT_CREATE_TRIGGER);
9003
req->addRequestFlag(opPtr.p->m_requestFlag);
9004
req->setTableId(opPtr.p->m_request.getTableId());
9005
req->setTriggerId(opPtr.p->m_request.getTriggerId());
9006
req->setTriggerInfo(0); // not used
9007
req->setOnline(true);
9008
req->setReceiverRef(opPtr.p->m_request.getReceiverRef());
9009
sendSignal(reference(), GSN_ALTER_TRIG_REQ,
9010
signal, AlterTrigReq::SignalLength, JBB);
9014
Dbdict::createTrigger_fromAlterTrigger(Signal* signal, OpCreateTriggerPtr opPtr)
9017
if (opPtr.p->hasError()) {
9019
opPtr.p->m_requestType = CreateTrigReq::RT_DICT_ABORT;
9020
createTrigger_sendSlaveReq(signal, opPtr);
9023
opPtr.p->m_requestType = CreateTrigReq::RT_DICT_COMMIT;
9024
createTrigger_sendSlaveReq(signal, opPtr);
9028
Dbdict::createTrigger_slaveCommit(Signal* signal, OpCreateTriggerPtr opPtr)
9031
const CreateTrigReq* const req = &opPtr.p->m_request;
9032
// get the trigger record
9033
const Uint32 triggerId = req->getTriggerId();
9034
TriggerRecordPtr triggerPtr;
9035
c_triggerRecordPool.getPtr(triggerPtr, triggerId);
9036
if (! req->getOnline()) {
9037
triggerPtr.p->triggerState = TriggerRecord::TS_OFFLINE;
9039
ndbrequire(triggerPtr.p->triggerState == TriggerRecord::TS_ONLINE);
9044
Dbdict::createTrigger_slaveAbort(Signal* signal, OpCreateTriggerPtr opPtr)
9050
Dbdict::createTrigger_sendSlaveReq(Signal* signal, OpCreateTriggerPtr opPtr)
9052
CreateTrigReq* const req = (CreateTrigReq*)signal->getDataPtrSend();
9053
*req = opPtr.p->m_request;
9054
req->setUserRef(opPtr.p->m_coordinatorRef);
9055
req->setConnectionPtr(opPtr.p->key);
9056
req->setRequestType(opPtr.p->m_requestType);
9057
req->addRequestFlag(opPtr.p->m_requestFlag);
9058
NdbNodeBitmask receiverNodes = c_aliveNodes;
9059
if (opPtr.p->m_requestFlag & RequestFlag::RF_LOCAL) {
9060
receiverNodes.clear();
9061
receiverNodes.set(getOwnNodeId());
9063
opPtr.p->m_signalCounter = receiverNodes;
9064
NodeReceiverGroup rg(DBDICT, receiverNodes);
9065
sendSignal(rg, GSN_CREATE_TRIG_REQ,
9066
signal, CreateTrigReq::SignalLength, JBB);
9070
Dbdict::createTrigger_sendReply(Signal* signal, OpCreateTriggerPtr opPtr,
9073
CreateTrigRef* rep = (CreateTrigRef*)signal->getDataPtrSend();
9074
Uint32 gsn = GSN_CREATE_TRIG_CONF;
9075
Uint32 length = CreateTrigConf::InternalLength;
9078
sendRef = opPtr.p->hasLastError();
9079
rep->setUserRef(opPtr.p->m_coordinatorRef);
9080
rep->setConnectionPtr(opPtr.p->key);
9081
rep->setRequestType(opPtr.p->m_requestType);
9082
if (opPtr.p->m_requestType == CreateTrigReq::RT_DICT_ABORT)
9085
sendRef = opPtr.p->hasError();
9086
rep->setUserRef(opPtr.p->m_request.getUserRef());
9087
rep->setConnectionPtr(opPtr.p->m_request.getConnectionPtr());
9088
rep->setRequestType(opPtr.p->m_request.getRequestType());
9089
length = CreateTrigConf::SignalLength;
9091
rep->setTableId(opPtr.p->m_request.getTableId());
9092
rep->setIndexId(opPtr.p->m_request.getIndexId());
9093
rep->setTriggerId(opPtr.p->m_request.getTriggerId());
9094
rep->setTriggerInfo(opPtr.p->m_request.getTriggerInfo());
9096
if (opPtr.p->m_errorNode == 0)
9097
opPtr.p->m_errorNode = getOwnNodeId();
9098
rep->setErrorCode(opPtr.p->m_errorCode);
9099
rep->setErrorLine(opPtr.p->m_errorLine);
9100
rep->setErrorNode(opPtr.p->m_errorNode);
9101
gsn = GSN_CREATE_TRIG_REF;
9102
length = CreateTrigRef::SignalLength;
9104
sendSignal(rep->getUserRef(), gsn, signal, length, JBB);
9108
* MODULE: Drop trigger.
9112
Dbdict::execDROP_TRIG_REQ(Signal* signal)
9115
DropTrigReq* const req = (DropTrigReq*)signal->getDataPtrSend();
9116
OpDropTriggerPtr opPtr;
9117
const Uint32 senderRef = signal->senderBlockRef();
9118
const DropTrigReq::RequestType requestType = req->getRequestType();
9120
if (signal->getNoOfSections() > 0) {
9121
ndbrequire(signal->getNoOfSections() == 1);
9123
TriggerRecord keyRecord;
9124
OpDropTrigger opTmp;
9127
SegmentedSectionPtr ssPtr;
9128
signal->getSection(ssPtr, DropTrigReq::TRIGGER_NAME_SECTION);
9129
SimplePropertiesSectionReader ssReader(ssPtr, getSectionSegmentPool());
9130
if (ssReader.getKey() != DropTrigReq::TriggerNameKey ||
9131
! ssReader.getString(keyRecord.triggerName)) {
9133
opPtr.p->m_errorCode = DropTrigRef::InvalidName;
9134
opPtr.p->m_errorLine = __LINE__;
9135
releaseSections(signal);
9136
dropTrigger_sendReply(signal, opPtr, opPtr.p->m_isMaster);
9139
releaseSections(signal);
9141
TriggerRecordPtr triggerPtr;
9143
// ndbout_c("++++++++++++++ Looking for trigger %s", keyRecord.triggerName);
9144
c_triggerRecordHash.find(triggerPtr, keyRecord);
9145
if (triggerPtr.i == RNIL) {
9147
req->setTriggerId(RNIL);
9150
// ndbout_c("++++++++++ Found trigger %s", triggerPtr.p->triggerName);
9151
req->setTriggerId(triggerPtr.p->triggerId);
9152
req->setTableId(triggerPtr.p->tableId);
9155
if (requestType == DropTrigReq::RT_USER ||
9156
requestType == DropTrigReq::RT_ALTER_INDEX ||
9157
requestType == DropTrigReq::RT_BUILD_INDEX) {
9159
if (signal->getLength() == DropTrigReq::SignalLength) {
9160
if (getOwnNodeId() != c_masterNodeId) {
9162
// forward to DICT master
9163
sendSignal(calcDictBlockRef(c_masterNodeId), GSN_DROP_TRIG_REQ,
9164
signal, signal->getLength(), JBB);
9167
if (!c_triggerRecordPool.findId(req->getTriggerId())) {
9170
OpDropTrigger opBad;
9173
if (! (req->getRequestFlag() & RequestFlag::RF_FORCE)) {
9174
opPtr.p->m_errorCode = DropTrigRef::TriggerNotFound;
9175
opPtr.p->m_errorLine = __LINE__;
9177
dropTrigger_sendReply(signal, opPtr, true);
9180
// forward initial request plus operation key to all
9181
req->setOpKey(++c_opRecordSequence);
9182
NodeReceiverGroup rg(DBDICT, c_aliveNodes);
9183
sendSignal(rg, GSN_DROP_TRIG_REQ,
9184
signal, DropTrigReq::SignalLength + 1, JBB);
9187
// seize operation record
9188
ndbrequire(signal->getLength() == DropTrigReq::SignalLength + 1);
9189
const Uint32 opKey = req->getOpKey();
9190
OpDropTrigger opBusy;
9191
if (! c_opDropTrigger.seize(opPtr))
9194
opPtr.p->m_coordinatorRef = senderRef;
9195
opPtr.p->m_isMaster = (senderRef == reference());
9196
opPtr.p->key = opKey;
9197
opPtr.p->m_requestType = DropTrigReq::RT_DICT_PREPARE;
9198
if (opPtr.p == &opBusy) {
9200
opPtr.p->m_errorCode = DropTrigRef::Busy;
9201
opPtr.p->m_errorLine = __LINE__;
9202
dropTrigger_sendReply(signal, opPtr, opPtr.p->m_isMaster);
9205
c_opDropTrigger.add(opPtr);
9206
// master expects to hear from all
9207
if (opPtr.p->m_isMaster)
9208
opPtr.p->m_signalCounter = c_aliveNodes;
9209
dropTrigger_slavePrepare(signal, opPtr);
9210
dropTrigger_sendReply(signal, opPtr, false);
9213
c_opDropTrigger.find(opPtr, req->getConnectionPtr());
9214
if (! opPtr.isNull()) {
9215
opPtr.p->m_requestType = requestType;
9216
if (requestType == DropTrigReq::RT_DICT_COMMIT ||
9217
requestType == DropTrigReq::RT_DICT_ABORT) {
9219
if (requestType == DropTrigReq::RT_DICT_COMMIT)
9220
dropTrigger_slaveCommit(signal, opPtr);
9222
dropTrigger_slaveAbort(signal, opPtr);
9223
dropTrigger_sendReply(signal, opPtr, false);
9225
if (! opPtr.p->m_isMaster)
9226
c_opDropTrigger.release(opPtr);
9232
OpDropTrigger opBad;
9235
opPtr.p->m_errorCode = DropTrigRef::BadRequestType;
9236
opPtr.p->m_errorLine = __LINE__;
9237
dropTrigger_sendReply(signal, opPtr, true);
9241
Dbdict::execDROP_TRIG_CONF(Signal* signal)
9244
DropTrigConf* conf = (DropTrigConf*)signal->getDataPtrSend();
9245
dropTrigger_recvReply(signal, conf, 0);
9249
Dbdict::execDROP_TRIG_REF(Signal* signal)
9252
DropTrigRef* ref = (DropTrigRef*)signal->getDataPtrSend();
9253
dropTrigger_recvReply(signal, ref->getConf(), ref);
9257
Dbdict::dropTrigger_recvReply(Signal* signal, const DropTrigConf* conf,
9258
const DropTrigRef* ref)
9261
const Uint32 senderRef = signal->senderBlockRef();
9262
const DropTrigReq::RequestType requestType = conf->getRequestType();
9263
const Uint32 key = conf->getConnectionPtr();
9264
if (requestType == DropTrigReq::RT_ALTER_INDEX) {
9266
// part of alter index operation
9267
OpAlterIndexPtr opPtr;
9268
c_opAlterIndex.find(opPtr, key);
9269
ndbrequire(! opPtr.isNull());
9270
opPtr.p->setError(ref);
9271
alterIndex_fromDropTrigger(signal, opPtr);
9274
if (requestType == DropTrigReq::RT_BUILD_INDEX) {
9276
// part of build index operation
9277
OpBuildIndexPtr opPtr;
9278
c_opBuildIndex.find(opPtr, key);
9279
ndbrequire(! opPtr.isNull());
9280
opPtr.p->setError(ref);
9281
buildIndex_fromDropConstr(signal, opPtr);
9284
if (requestType == DropTrigReq::RT_TC ||
9285
requestType == DropTrigReq::RT_LQH) {
9287
// part of alter trigger operation
9288
OpAlterTriggerPtr opPtr;
9289
c_opAlterTrigger.find(opPtr, key);
9290
ndbrequire(! opPtr.isNull());
9291
opPtr.p->setError(ref);
9292
alterTrigger_fromDropLocal(signal, opPtr);
9295
OpDropTriggerPtr opPtr;
9296
c_opDropTrigger.find(opPtr, key);
9297
ndbrequire(! opPtr.isNull());
9298
ndbrequire(opPtr.p->m_isMaster);
9299
ndbrequire(opPtr.p->m_requestType == requestType);
9300
opPtr.p->setError(ref);
9301
opPtr.p->m_signalCounter.clearWaitingFor(refToNode(senderRef));
9302
if (! opPtr.p->m_signalCounter.done()) {
9306
if (requestType == DropTrigReq::RT_DICT_COMMIT ||
9307
requestType == DropTrigReq::RT_DICT_ABORT) {
9309
// send reply to user
9310
dropTrigger_sendReply(signal, opPtr, true);
9311
c_opDropTrigger.release(opPtr);
9314
if (opPtr.p->hasError()) {
9316
opPtr.p->m_requestType = DropTrigReq::RT_DICT_ABORT;
9317
dropTrigger_sendSlaveReq(signal, opPtr);
9320
if (requestType == DropTrigReq::RT_DICT_PREPARE) {
9322
// start alter offline
9323
dropTrigger_toAlterTrigger(signal, opPtr);
9330
Dbdict::dropTrigger_slavePrepare(Signal* signal, OpDropTriggerPtr opPtr)
9336
Dbdict::dropTrigger_toAlterTrigger(Signal* signal, OpDropTriggerPtr opPtr)
9339
AlterTrigReq* req = (AlterTrigReq*)signal->getDataPtrSend();
9340
req->setUserRef(reference());
9341
req->setConnectionPtr(opPtr.p->key);
9342
req->setRequestType(AlterTrigReq::RT_DROP_TRIGGER);
9343
req->addRequestFlag(opPtr.p->m_requestFlag);
9344
req->setTableId(opPtr.p->m_request.getTableId());
9345
req->setTriggerId(opPtr.p->m_request.getTriggerId());
9346
req->setTriggerInfo(0); // not used
9347
req->setOnline(false);
9348
req->setReceiverRef(0);
9349
sendSignal(reference(), GSN_ALTER_TRIG_REQ,
9350
signal, AlterTrigReq::SignalLength, JBB);
9354
Dbdict::dropTrigger_fromAlterTrigger(Signal* signal, OpDropTriggerPtr opPtr)
9358
opPtr.p->m_requestType = DropTrigReq::RT_DICT_COMMIT;
9359
dropTrigger_sendSlaveReq(signal, opPtr);
9363
Dbdict::dropTrigger_sendSlaveReq(Signal* signal, OpDropTriggerPtr opPtr)
9365
DropTrigReq* const req = (DropTrigReq*)signal->getDataPtrSend();
9366
*req = opPtr.p->m_request;
9367
req->setUserRef(opPtr.p->m_coordinatorRef);
9368
req->setConnectionPtr(opPtr.p->key);
9369
req->setRequestType(opPtr.p->m_requestType);
9370
req->addRequestFlag(opPtr.p->m_requestFlag);
9371
opPtr.p->m_signalCounter = c_aliveNodes;
9372
NodeReceiverGroup rg(DBDICT, c_aliveNodes);
9373
sendSignal(rg, GSN_DROP_TRIG_REQ,
9374
signal, DropTrigReq::SignalLength, JBB);
9378
Dbdict::dropTrigger_slaveCommit(Signal* signal, OpDropTriggerPtr opPtr)
9381
const DropTrigReq* const req = &opPtr.p->m_request;
9382
// get trigger record
9383
const Uint32 triggerId = req->getTriggerId();
9384
TriggerRecordPtr triggerPtr;
9385
c_triggerRecordPool.getPtr(triggerPtr, triggerId);
9386
if (triggerPtr.p->triggerType == TriggerType::SECONDARY_INDEX ||
9387
triggerPtr.p->triggerType == TriggerType::ORDERED_INDEX) {
9389
// disconnect from index if index trigger XXX move to drop index
9390
triggerPtr.p->indexId = req->getIndexId();
9391
TableRecordPtr indexPtr;
9392
c_tableRecordPool.getPtr(indexPtr, triggerPtr.p->indexId);
9393
ndbrequire(! indexPtr.isNull());
9394
switch (triggerPtr.p->triggerEvent) {
9395
case TriggerEvent::TE_INSERT:
9396
indexPtr.p->insertTriggerId = RNIL;
9398
case TriggerEvent::TE_UPDATE:
9399
indexPtr.p->updateTriggerId = RNIL;
9401
case TriggerEvent::TE_DELETE:
9402
indexPtr.p->deleteTriggerId = RNIL;
9404
case TriggerEvent::TE_CUSTOM:
9405
indexPtr.p->customTriggerId = RNIL;
9412
if (triggerPtr.p->triggerType == TriggerType::READ_ONLY_CONSTRAINT) {
9414
// disconnect from index record XXX should be done in caller instead
9415
triggerPtr.p->indexId = req->getTableId();
9416
TableRecordPtr indexPtr;
9417
c_tableRecordPool.getPtr(indexPtr, triggerPtr.p->indexId);
9418
indexPtr.p->buildTriggerId = RNIL;
9421
// ndbout_c("++++++++++++ Removing trigger id %u, %s", triggerPtr.p->triggerId, triggerPtr.p->triggerName);
9422
c_triggerRecordHash.remove(triggerPtr);
9423
triggerPtr.p->triggerState = TriggerRecord::TS_NOT_DEFINED;
9427
Dbdict::dropTrigger_slaveAbort(Signal* signal, OpDropTriggerPtr opPtr)
9433
Dbdict::dropTrigger_sendReply(Signal* signal, OpDropTriggerPtr opPtr,
9436
DropTrigRef* rep = (DropTrigRef*)signal->getDataPtrSend();
9437
Uint32 gsn = GSN_DROP_TRIG_CONF;
9438
Uint32 length = DropTrigConf::InternalLength;
9441
sendRef = opPtr.p->hasLastError();
9442
rep->setUserRef(opPtr.p->m_coordinatorRef);
9443
rep->setConnectionPtr(opPtr.p->key);
9444
rep->setRequestType(opPtr.p->m_requestType);
9445
if (opPtr.p->m_requestType == DropTrigReq::RT_DICT_ABORT)
9448
sendRef = opPtr.p->hasError();
9449
rep->setUserRef(opPtr.p->m_request.getUserRef());
9450
rep->setConnectionPtr(opPtr.p->m_request.getConnectionPtr());
9451
rep->setRequestType(opPtr.p->m_request.getRequestType());
9452
length = DropTrigConf::SignalLength;
9454
rep->setTableId(opPtr.p->m_request.getTableId());
9455
rep->setIndexId(opPtr.p->m_request.getIndexId());
9456
rep->setTriggerId(opPtr.p->m_request.getTriggerId());
9458
if (opPtr.p->m_errorNode == 0)
9459
opPtr.p->m_errorNode = getOwnNodeId();
9460
rep->setErrorCode(opPtr.p->m_errorCode);
9461
rep->setErrorLine(opPtr.p->m_errorLine);
9462
rep->setErrorNode(opPtr.p->m_errorNode);
9463
gsn = GSN_DROP_TRIG_REF;
9464
length = CreateTrigRef::SignalLength;
9466
sendSignal(rep->getUserRef(), gsn, signal, length, JBB);
9470
* MODULE: Alter trigger.
9472
* Alter trigger state. Alter online creates the trigger first in all
9473
* TC (if index trigger) and then in all LQH-TUP.
9475
* Request type received in REQ and returned in CONF/REF:
9477
* RT_USER - normal user e.g. BACKUP
9478
* RT_CREATE_TRIGGER - from create trigger
9479
* RT_DROP_TRIGGER - from drop trigger
9480
* RT_DICT_PREPARE - seize operations and check request
9481
* RT_DICT_TC - master to each DICT on way to TC
9482
* RT_DICT_LQH - master to each DICT on way to LQH-TUP
9483
* RT_DICT_COMMIT - commit state change in each DICT (no reply)
9487
Dbdict::execALTER_TRIG_REQ(Signal* signal)
9490
AlterTrigReq* const req = (AlterTrigReq*)signal->getDataPtrSend();
9491
OpAlterTriggerPtr opPtr;
9492
const Uint32 senderRef = signal->senderBlockRef();
9493
const AlterTrigReq::RequestType requestType = req->getRequestType();
9494
if (requestType == AlterTrigReq::RT_USER ||
9495
requestType == AlterTrigReq::RT_CREATE_TRIGGER ||
9496
requestType == AlterTrigReq::RT_DROP_TRIGGER) {
9498
const bool isLocal = req->getRequestFlag() & RequestFlag::RF_LOCAL;
9499
NdbNodeBitmask receiverNodes = c_aliveNodes;
9501
receiverNodes.clear();
9502
receiverNodes.set(getOwnNodeId());
9504
if (signal->getLength() == AlterTrigReq::SignalLength) {
9506
if (! isLocal && getOwnNodeId() != c_masterNodeId) {
9508
// forward to DICT master
9509
sendSignal(calcDictBlockRef(c_masterNodeId), GSN_ALTER_TRIG_REQ,
9510
signal, AlterTrigReq::SignalLength, JBB);
9513
// forward initial request plus operation key to all
9514
req->setOpKey(++c_opRecordSequence);
9515
NodeReceiverGroup rg(DBDICT, receiverNodes);
9516
sendSignal(rg, GSN_ALTER_TRIG_REQ,
9517
signal, AlterTrigReq::SignalLength + 1, JBB);
9520
// seize operation record
9521
ndbrequire(signal->getLength() == AlterTrigReq::SignalLength + 1);
9522
const Uint32 opKey = req->getOpKey();
9523
OpAlterTrigger opBusy;
9524
if (! c_opAlterTrigger.seize(opPtr))
9527
opPtr.p->m_coordinatorRef = senderRef;
9528
opPtr.p->m_isMaster = (senderRef == reference());
9529
opPtr.p->key = opKey;
9530
opPtr.p->m_requestType = AlterTrigReq::RT_DICT_PREPARE;
9531
if (opPtr.p == &opBusy) {
9533
opPtr.p->m_errorCode = AlterTrigRef::Busy;
9534
opPtr.p->m_errorLine = __LINE__;
9535
alterTrigger_sendReply(signal, opPtr, opPtr.p->m_isMaster);
9538
c_opAlterTrigger.add(opPtr);
9539
// master expects to hear from all
9540
if (opPtr.p->m_isMaster) {
9541
opPtr.p->m_nodes = receiverNodes;
9542
opPtr.p->m_signalCounter = receiverNodes;
9544
alterTrigger_slavePrepare(signal, opPtr);
9545
alterTrigger_sendReply(signal, opPtr, false);
9548
c_opAlterTrigger.find(opPtr, req->getConnectionPtr());
9549
if (! opPtr.isNull()) {
9550
opPtr.p->m_requestType = requestType;
9551
if (requestType == AlterTrigReq::RT_DICT_TC ||
9552
requestType == AlterTrigReq::RT_DICT_LQH) {
9554
if (req->getOnline())
9555
alterTrigger_toCreateLocal(signal, opPtr);
9557
alterTrigger_toDropLocal(signal, opPtr);
9560
if (requestType == AlterTrigReq::RT_DICT_COMMIT ||
9561
requestType == AlterTrigReq::RT_DICT_ABORT) {
9563
if (requestType == AlterTrigReq::RT_DICT_COMMIT)
9564
alterTrigger_slaveCommit(signal, opPtr);
9566
alterTrigger_slaveAbort(signal, opPtr);
9567
alterTrigger_sendReply(signal, opPtr, false);
9569
if (! opPtr.p->m_isMaster)
9570
c_opAlterTrigger.release(opPtr);
9576
OpAlterTrigger opBad;
9579
opPtr.p->m_errorCode = AlterTrigRef::BadRequestType;
9580
opPtr.p->m_errorLine = __LINE__;
9581
alterTrigger_sendReply(signal, opPtr, true);
9586
Dbdict::execALTER_TRIG_CONF(Signal* signal)
9589
AlterTrigConf* conf = (AlterTrigConf*)signal->getDataPtrSend();
9590
alterTrigger_recvReply(signal, conf, 0);
9594
Dbdict::execALTER_TRIG_REF(Signal* signal)
9597
AlterTrigRef* ref = (AlterTrigRef*)signal->getDataPtrSend();
9598
alterTrigger_recvReply(signal, ref->getConf(), ref);
9602
Dbdict::alterTrigger_recvReply(Signal* signal, const AlterTrigConf* conf,
9603
const AlterTrigRef* ref)
9606
const Uint32 senderRef = signal->senderBlockRef();
9607
const AlterTrigReq::RequestType requestType = conf->getRequestType();
9608
const Uint32 key = conf->getConnectionPtr();
9609
if (requestType == AlterTrigReq::RT_CREATE_TRIGGER) {
9611
// part of create trigger operation
9612
OpCreateTriggerPtr opPtr;
9613
c_opCreateTrigger.find(opPtr, key);
9614
ndbrequire(! opPtr.isNull());
9615
opPtr.p->setError(ref);
9616
createTrigger_fromAlterTrigger(signal, opPtr);
9619
if (requestType == AlterTrigReq::RT_DROP_TRIGGER) {
9621
// part of drop trigger operation
9622
OpDropTriggerPtr opPtr;
9623
c_opDropTrigger.find(opPtr, key);
9624
ndbrequire(! opPtr.isNull());
9625
opPtr.p->setError(ref);
9626
dropTrigger_fromAlterTrigger(signal, opPtr);
9629
OpAlterTriggerPtr opPtr;
9630
c_opAlterTrigger.find(opPtr, key);
9631
ndbrequire(! opPtr.isNull());
9632
ndbrequire(opPtr.p->m_isMaster);
9633
ndbrequire(opPtr.p->m_requestType == requestType);
9635
* If refuse on drop trig, because of non-existent trigger,
9636
* comes from anyone but the master node - ignore it and
9637
* remove the node from forter ALTER_TRIG communication
9638
* This will happen if a new node has started since the
9639
* trigger whas created.
9642
refToNode(senderRef) != refToNode(reference()) &&
9643
opPtr.p->m_request.getRequestType() == AlterTrigReq::RT_DROP_TRIGGER &&
9644
ref->getErrorCode() == AlterTrigRef::TriggerNotFound) {
9646
ref = 0; // ignore this error
9647
opPtr.p->m_nodes.clear(refToNode(senderRef)); // remove this from group
9649
opPtr.p->setError(ref);
9650
opPtr.p->m_signalCounter.clearWaitingFor(refToNode(senderRef));
9651
if (! opPtr.p->m_signalCounter.done()) {
9655
if (requestType == AlterTrigReq::RT_DICT_COMMIT ||
9656
requestType == AlterTrigReq::RT_DICT_ABORT) {
9658
// send reply to user
9659
alterTrigger_sendReply(signal, opPtr, true);
9660
c_opAlterTrigger.release(opPtr);
9663
if (opPtr.p->hasError()) {
9665
opPtr.p->m_requestType = AlterTrigReq::RT_DICT_ABORT;
9666
alterTrigger_sendSlaveReq(signal, opPtr);
9669
if (! (opPtr.p->m_request.getRequestFlag() & RequestFlag::RF_NOTCTRIGGER)) {
9670
if (requestType == AlterTrigReq::RT_DICT_PREPARE) {
9672
if (opPtr.p->m_request.getOnline()) {
9674
opPtr.p->m_requestType = AlterTrigReq::RT_DICT_TC;
9677
opPtr.p->m_requestType = AlterTrigReq::RT_DICT_LQH;
9679
alterTrigger_sendSlaveReq(signal, opPtr);
9682
if (requestType == AlterTrigReq::RT_DICT_TC) {
9684
if (opPtr.p->m_request.getOnline()) {
9686
opPtr.p->m_requestType = AlterTrigReq::RT_DICT_LQH;
9689
opPtr.p->m_requestType = AlterTrigReq::RT_DICT_COMMIT;
9691
alterTrigger_sendSlaveReq(signal, opPtr);
9694
if (requestType == AlterTrigReq::RT_DICT_LQH) {
9696
if (opPtr.p->m_request.getOnline()) {
9698
opPtr.p->m_requestType = AlterTrigReq::RT_DICT_COMMIT;
9701
opPtr.p->m_requestType = AlterTrigReq::RT_DICT_TC;
9703
alterTrigger_sendSlaveReq(signal, opPtr);
9707
if (requestType == AlterTrigReq::RT_DICT_PREPARE) {
9709
opPtr.p->m_requestType = AlterTrigReq::RT_DICT_LQH;
9710
alterTrigger_sendSlaveReq(signal, opPtr);
9713
if (requestType == AlterTrigReq::RT_DICT_LQH) {
9715
opPtr.p->m_requestType = AlterTrigReq::RT_DICT_COMMIT;
9716
alterTrigger_sendSlaveReq(signal, opPtr);
9724
Dbdict::alterTrigger_slavePrepare(Signal* signal, OpAlterTriggerPtr opPtr)
9727
const AlterTrigReq* const req = &opPtr.p->m_request;
9728
const Uint32 triggerId = req->getTriggerId();
9729
TriggerRecordPtr triggerPtr;
9730
if (! (triggerId < c_triggerRecordPool.getSize())) {
9732
opPtr.p->m_errorCode = AlterTrigRef::TriggerNotFound;
9733
opPtr.p->m_errorLine = __LINE__;
9736
c_triggerRecordPool.getPtr(triggerPtr, triggerId);
9737
if (triggerPtr.p->triggerState == TriggerRecord::TS_NOT_DEFINED) {
9739
opPtr.p->m_errorCode = AlterTrigRef::TriggerNotFound;
9740
opPtr.p->m_errorLine = __LINE__;
9744
if (triggerPtr.p->triggerType == TriggerType::SUBSCRIPTION)
9746
opPtr.p->m_request.addRequestFlag(RequestFlag::RF_NOTCTRIGGER);
9751
Dbdict::alterTrigger_toCreateLocal(Signal* signal, OpAlterTriggerPtr opPtr)
9754
// find trigger record
9755
const Uint32 triggerId = opPtr.p->m_request.getTriggerId();
9756
TriggerRecordPtr triggerPtr;
9757
c_triggerRecordPool.getPtr(triggerPtr, triggerId);
9758
CreateTrigReq* const req = (CreateTrigReq*)signal->getDataPtrSend();
9759
req->setUserRef(reference());
9760
req->setConnectionPtr(opPtr.p->key);
9761
if (opPtr.p->m_requestType == AlterTrigReq::RT_DICT_TC) {
9763
req->setRequestType(CreateTrigReq::RT_TC);
9764
} else if (opPtr.p->m_requestType == AlterTrigReq::RT_DICT_LQH) {
9766
req->setRequestType(CreateTrigReq::RT_LQH);
9770
req->setTableId(triggerPtr.p->tableId);
9771
req->setIndexId(triggerPtr.p->indexId);
9772
req->setTriggerId(triggerPtr.i);
9773
req->setTriggerType(triggerPtr.p->triggerType);
9774
req->setTriggerActionTime(triggerPtr.p->triggerActionTime);
9775
req->setTriggerEvent(triggerPtr.p->triggerEvent);
9776
req->setMonitorReplicas(triggerPtr.p->monitorReplicas);
9777
req->setMonitorAllAttributes(triggerPtr.p->monitorAllAttributes);
9778
req->setOnline(true);
9779
req->setReceiverRef(opPtr.p->m_request.getReceiverRef());
9780
BlockReference blockRef = 0;
9781
if (opPtr.p->m_requestType == AlterTrigReq::RT_DICT_TC) {
9783
blockRef = calcTcBlockRef(getOwnNodeId());
9784
} else if (opPtr.p->m_requestType == AlterTrigReq::RT_DICT_LQH) {
9786
blockRef = calcLqhBlockRef(getOwnNodeId());
9790
req->setAttributeMask(triggerPtr.p->attributeMask);
9791
sendSignal(blockRef, GSN_CREATE_TRIG_REQ,
9792
signal, CreateTrigReq::SignalLength, JBB);
9796
Dbdict::alterTrigger_fromCreateLocal(Signal* signal, OpAlterTriggerPtr opPtr)
9799
if (! opPtr.p->hasLastError()) {
9800
// mark created locally
9801
TriggerRecordPtr triggerPtr;
9802
c_triggerRecordPool.getPtr(triggerPtr, opPtr.p->m_request.getTriggerId());
9803
if (opPtr.p->m_requestType == AlterTrigReq::RT_DICT_TC) {
9805
triggerPtr.p->triggerLocal |= TriggerRecord::TL_CREATED_TC;
9806
} else if (opPtr.p->m_requestType == AlterTrigReq::RT_DICT_LQH) {
9808
triggerPtr.p->triggerLocal |= TriggerRecord::TL_CREATED_LQH;
9813
// forward CONF or REF to master
9814
alterTrigger_sendReply(signal, opPtr, false);
9818
Dbdict::alterTrigger_toDropLocal(Signal* signal, OpAlterTriggerPtr opPtr)
9821
TriggerRecordPtr triggerPtr;
9822
c_triggerRecordPool.getPtr(triggerPtr, opPtr.p->m_request.getTriggerId());
9823
DropTrigReq* const req = (DropTrigReq*)signal->getDataPtrSend();
9824
req->setUserRef(reference());
9825
req->setConnectionPtr(opPtr.p->key);
9826
if (opPtr.p->m_requestType == AlterTrigReq::RT_DICT_TC) {
9828
// broken trigger allowed if force
9829
if (! (triggerPtr.p->triggerLocal & TriggerRecord::TL_CREATED_TC)) {
9831
ndbassert(opPtr.p->m_requestFlag & RequestFlag::RF_FORCE);
9832
alterTrigger_sendReply(signal, opPtr, false);
9835
req->setRequestType(DropTrigReq::RT_TC);
9836
} else if (opPtr.p->m_requestType == AlterTrigReq::RT_DICT_LQH) {
9838
// broken trigger allowed if force
9839
if (! (triggerPtr.p->triggerLocal & TriggerRecord::TL_CREATED_LQH)) {
9841
ndbassert(opPtr.p->m_requestFlag & RequestFlag::RF_FORCE);
9842
alterTrigger_sendReply(signal, opPtr, false);
9845
req->setRequestType(DropTrigReq::RT_LQH);
9849
req->setTableId(triggerPtr.p->tableId);
9850
req->setIndexId(triggerPtr.p->indexId);
9851
req->setTriggerId(triggerPtr.i);
9852
req->setTriggerType(triggerPtr.p->triggerType);
9853
req->setTriggerActionTime(triggerPtr.p->triggerActionTime);
9854
req->setTriggerEvent(triggerPtr.p->triggerEvent);
9855
req->setMonitorReplicas(triggerPtr.p->monitorReplicas);
9856
req->setMonitorAllAttributes(triggerPtr.p->monitorAllAttributes);
9857
BlockReference blockRef = 0;
9858
if (opPtr.p->m_requestType == AlterTrigReq::RT_DICT_TC) {
9860
blockRef = calcTcBlockRef(getOwnNodeId());
9861
} else if (opPtr.p->m_requestType == AlterTrigReq::RT_DICT_LQH) {
9863
blockRef = calcLqhBlockRef(getOwnNodeId());
9867
sendSignal(blockRef, GSN_DROP_TRIG_REQ,
9868
signal, DropTrigReq::SignalLength, JBB);
9872
Dbdict::alterTrigger_fromDropLocal(Signal* signal, OpAlterTriggerPtr opPtr)
9875
if (! opPtr.p->hasLastError()) {
9876
// mark dropped locally
9877
TriggerRecordPtr triggerPtr;
9878
c_triggerRecordPool.getPtr(triggerPtr, opPtr.p->m_request.getTriggerId());
9879
if (opPtr.p->m_requestType == AlterTrigReq::RT_DICT_TC) {
9881
triggerPtr.p->triggerLocal &= ~TriggerRecord::TL_CREATED_TC;
9882
} else if (opPtr.p->m_requestType == AlterTrigReq::RT_DICT_LQH) {
9884
triggerPtr.p->triggerLocal &= ~TriggerRecord::TL_CREATED_LQH;
9889
// forward CONF or REF to master
9890
alterTrigger_sendReply(signal, opPtr, false);
9894
Dbdict::alterTrigger_slaveCommit(Signal* signal, OpAlterTriggerPtr opPtr)
9897
TriggerRecordPtr triggerPtr;
9898
c_triggerRecordPool.getPtr(triggerPtr, opPtr.p->m_request.getTriggerId());
9900
triggerPtr.p->triggerState = TriggerRecord::TS_ONLINE;
9904
Dbdict::alterTrigger_slaveAbort(Signal* signal, OpAlterTriggerPtr opPtr)
9910
Dbdict::alterTrigger_sendSlaveReq(Signal* signal, OpAlterTriggerPtr opPtr)
9912
AlterTrigReq* const req = (AlterTrigReq*)signal->getDataPtrSend();
9913
*req = opPtr.p->m_request;
9914
req->setUserRef(opPtr.p->m_coordinatorRef);
9915
req->setConnectionPtr(opPtr.p->key);
9916
req->setRequestType(opPtr.p->m_requestType);
9917
req->addRequestFlag(opPtr.p->m_requestFlag);
9918
NdbNodeBitmask receiverNodes = c_aliveNodes;
9919
if (opPtr.p->m_requestFlag & RequestFlag::RF_LOCAL) {
9920
receiverNodes.clear();
9921
receiverNodes.set(getOwnNodeId());
9923
opPtr.p->m_nodes.bitAND(receiverNodes);
9924
receiverNodes = opPtr.p->m_nodes;
9926
opPtr.p->m_signalCounter = receiverNodes;
9927
NodeReceiverGroup rg(DBDICT, receiverNodes);
9928
sendSignal(rg, GSN_ALTER_TRIG_REQ,
9929
signal, AlterTrigReq::SignalLength, JBB);
9933
Dbdict::alterTrigger_sendReply(Signal* signal, OpAlterTriggerPtr opPtr,
9937
AlterTrigRef* rep = (AlterTrigRef*)signal->getDataPtrSend();
9938
Uint32 gsn = GSN_ALTER_TRIG_CONF;
9939
Uint32 length = AlterTrigConf::InternalLength;
9942
sendRef = opPtr.p->hasLastError();
9943
rep->setUserRef(opPtr.p->m_coordinatorRef);
9944
rep->setConnectionPtr(opPtr.p->key);
9945
rep->setRequestType(opPtr.p->m_requestType);
9946
if (opPtr.p->m_requestType == AlterTrigReq::RT_DICT_ABORT) {
9953
sendRef = opPtr.p->hasError();
9955
rep->setUserRef(opPtr.p->m_request.getUserRef());
9956
rep->setConnectionPtr(opPtr.p->m_request.getConnectionPtr());
9957
rep->setRequestType(opPtr.p->m_request.getRequestType());
9958
length = AlterTrigConf::SignalLength;
9960
rep->setTableId(opPtr.p->m_request.getTableId());
9961
rep->setTriggerId(opPtr.p->m_request.getTriggerId());
9963
if (opPtr.p->m_errorNode == 0) {
9965
opPtr.p->m_errorNode = getOwnNodeId();
9969
rep->setErrorCode(opPtr.p->m_errorCode);
9970
rep->setErrorLine(opPtr.p->m_errorLine);
9971
rep->setErrorNode(opPtr.p->m_errorNode);
9972
gsn = GSN_ALTER_TRIG_REF;
9973
length = AlterTrigRef::SignalLength;
9975
sendSignal(rep->getUserRef(), gsn, signal, length, JBB);
9979
* MODULE: Support routines for index and trigger.
9983
Dbdict::getTableKeyList(TableRecordPtr tablePtr, AttributeList& list)
9987
for (Uint32 tAttr = tablePtr.p->firstAttribute; tAttr != RNIL; ) {
9988
AttributeRecord* aRec = c_attributeRecordPool.getPtr(tAttr);
9990
list.id[list.sz++] = aRec->attributeId;
9991
tAttr = aRec->nextAttrInTable;
9995
// XXX should store the primary attribute id
9997
Dbdict::getIndexAttr(TableRecordPtr indexPtr, Uint32 itAttr, Uint32* id)
10000
TableRecordPtr tablePtr;
10001
c_tableRecordPool.getPtr(tablePtr, indexPtr.p->primaryTableId);
10002
AttributeRecord* iaRec = c_attributeRecordPool.getPtr(itAttr);
10003
for (Uint32 tAttr = tablePtr.p->firstAttribute; tAttr != RNIL; ) {
10004
AttributeRecord* aRec = c_attributeRecordPool.getPtr(tAttr);
10005
if (iaRec->equal(*aRec)) {
10006
id[0] = aRec->attributeId;
10009
tAttr = aRec->nextAttrInTable;
10015
Dbdict::getIndexAttrList(TableRecordPtr indexPtr, AttributeList& list)
10018
TableRecordPtr tablePtr;
10019
c_tableRecordPool.getPtr(tablePtr, indexPtr.p->primaryTableId);
10021
memset(list.id, 0, sizeof(list.id));
10022
ndbrequire(indexPtr.p->noOfAttributes >= 2);
10023
Uint32 itAttr = indexPtr.p->firstAttribute;
10024
for (Uint32 i = 0; i < (Uint32)indexPtr.p->noOfAttributes - 1; i++) {
10025
getIndexAttr(indexPtr, itAttr, &list.id[list.sz++]);
10026
AttributeRecord* iaRec = c_attributeRecordPool.getPtr(itAttr);
10027
itAttr = iaRec->nextAttrInTable;
10032
Dbdict::getIndexAttrMask(TableRecordPtr indexPtr, AttributeMask& mask)
10035
TableRecordPtr tablePtr;
10036
c_tableRecordPool.getPtr(tablePtr, indexPtr.p->primaryTableId);
10038
ndbrequire(indexPtr.p->noOfAttributes >= 2);
10039
Uint32 itAttr = indexPtr.p->firstAttribute;
10040
for (Uint32 i = 0; i < (Uint32)indexPtr.p->noOfAttributes - 1; i++) {
10042
getIndexAttr(indexPtr, itAttr, &id);
10044
AttributeRecord* iaRec = c_attributeRecordPool.getPtr(itAttr);
10045
itAttr = iaRec->nextAttrInTable;
10049
// DICT lock master
10051
const Dbdict::DictLockType*
10052
Dbdict::getDictLockType(Uint32 lockType)
10054
static const DictLockType lt[] = {
10055
{ DictLockReq::NodeRestartLock, BS_NODE_RESTART, "NodeRestart" }
10057
for (unsigned int i = 0; i < sizeof(lt)/sizeof(lt[0]); i++) {
10058
if ((Uint32) lt[i].lockType == lockType)
10065
Dbdict::sendDictLockInfoEvent(Uint32 pollCount)
10067
DictLockPtr loopPtr;
10068
c_dictLockQueue.first(loopPtr);
10069
unsigned count = 0;
10071
char queue_buf[100];
10072
char *p = &queue_buf[0];
10073
const char *const q = &queue_buf[sizeof(queue_buf)];
10076
while (loopPtr.i != RNIL) {
10078
my_snprintf(p, q-p, "%s%u%s",
10079
++count == 1 ? "" : " ",
10080
(unsigned)refToNode(loopPtr.p->req.userRef),
10081
loopPtr.p->locked ? "L" : "");
10083
c_dictLockQueue.next(loopPtr);
10086
infoEvent("DICT: lock bs: %d ops: %d poll: %d cnt: %d queue: %s",
10088
c_opRecordPool.getSize() - c_opRecordPool.getNoOfFree(),
10089
c_dictLockPoll, (int)pollCount, queue_buf);
10093
Dbdict::sendDictLockInfoEvent(DictLockPtr lockPtr, const char* text)
10095
infoEvent("DICT: %s %u for %s",
10097
(unsigned)refToNode(lockPtr.p->req.userRef), lockPtr.p->lt->text);
10101
Dbdict::execDICT_LOCK_REQ(Signal* signal)
10104
const DictLockReq* req = (const DictLockReq*)&signal->theData[0];
10106
// make sure bad request crashes slave, not master (us)
10108
if (getOwnNodeId() != c_masterNodeId) {
10110
sendDictLockRef(signal, *req, DictLockRef::NotMaster);
10114
const DictLockType* lt = getDictLockType(req->lockType);
10117
sendDictLockRef(signal, *req, DictLockRef::InvalidLockType);
10121
if (req->userRef != signal->getSendersBlockRef() ||
10122
getNodeInfo(refToNode(req->userRef)).m_type != NodeInfo::DB) {
10124
sendDictLockRef(signal, *req, DictLockRef::BadUserRef);
10128
if (c_aliveNodes.get(refToNode(req->userRef))) {
10130
sendDictLockRef(signal, *req, DictLockRef::TooLate);
10134
DictLockPtr lockPtr;
10135
if (! c_dictLockQueue.seize(lockPtr)) {
10137
sendDictLockRef(signal, *req, DictLockRef::TooManyRequests);
10141
lockPtr.p->req = *req;
10142
lockPtr.p->locked = false;
10143
lockPtr.p->lt = lt;
10145
checkDictLockQueue(signal, false);
10147
if (! lockPtr.p->locked)
10148
sendDictLockInfoEvent(lockPtr, "lock request by node");
10151
// only table and index ops are checked
10153
Dbdict::hasDictLockSchemaOp()
10156
! c_opCreateTable.isEmpty() ||
10157
! c_opDropTable.isEmpty() ||
10158
! c_opCreateIndex.isEmpty() ||
10159
! c_opDropIndex.isEmpty();
10163
Dbdict::checkDictLockQueue(Signal* signal, bool poll)
10165
Uint32 pollCount = ! poll ? 0 : signal->theData[1];
10167
DictLockPtr lockPtr;
10170
if (! c_dictLockQueue.first(lockPtr)) {
10172
setDictLockPoll(signal, false, pollCount);
10176
if (lockPtr.p->locked) {
10178
ndbrequire(c_blockState == lockPtr.p->lt->blockState);
10182
if (hasDictLockSchemaOp()) {
10187
if (c_blockState != BS_IDLE)
10190
* If state is BS_NODE_FAILURE, it might be that no op is running
10196
ndbrequire(c_blockState == BS_IDLE);
10197
lockPtr.p->locked = true;
10198
c_blockState = lockPtr.p->lt->blockState;
10199
sendDictLockConf(signal, lockPtr);
10201
sendDictLockInfoEvent(lockPtr, "locked by node");
10204
// poll while first request is open
10205
// this routine is called again when it is removed for any reason
10207
bool on = ! lockPtr.p->locked;
10208
setDictLockPoll(signal, on, pollCount);
10212
Dbdict::execDICT_UNLOCK_ORD(Signal* signal)
10215
const DictUnlockOrd* ord = (const DictUnlockOrd*)&signal->theData[0];
10217
DictLockPtr lockPtr;
10218
c_dictLockQueue.getPtr(lockPtr, ord->lockPtr);
10219
ndbrequire((Uint32) lockPtr.p->lt->lockType == ord->lockType);
10221
if (lockPtr.p->locked) {
10223
ndbrequire(c_blockState == lockPtr.p->lt->blockState);
10224
ndbrequire(! hasDictLockSchemaOp());
10225
ndbrequire(! c_dictLockQueue.hasPrev(lockPtr));
10227
c_blockState = BS_IDLE;
10228
sendDictLockInfoEvent(lockPtr, "unlocked by node");
10230
sendDictLockInfoEvent(lockPtr, "lock request removed by node");
10233
c_dictLockQueue.release(lockPtr);
10235
checkDictLockQueue(signal, false);
10239
Dbdict::sendDictLockConf(Signal* signal, DictLockPtr lockPtr)
10241
DictLockConf* conf = (DictLockConf*)&signal->theData[0];
10242
const DictLockReq& req = lockPtr.p->req;
10244
conf->userPtr = req.userPtr;
10245
conf->lockType = req.lockType;
10246
conf->lockPtr = lockPtr.i;
10248
sendSignal(req.userRef, GSN_DICT_LOCK_CONF, signal,
10249
DictLockConf::SignalLength, JBB);
10253
Dbdict::sendDictLockRef(Signal* signal, DictLockReq req, Uint32 errorCode)
10255
DictLockRef* ref = (DictLockRef*)&signal->theData[0];
10257
ref->userPtr = req.userPtr;
10258
ref->lockType = req.lockType;
10259
ref->errorCode = errorCode;
10261
sendSignal(req.userRef, GSN_DICT_LOCK_REF, signal,
10262
DictLockRef::SignalLength, JBB);
10268
Dbdict::setDictLockPoll(Signal* signal, bool on, Uint32 pollCount)
10272
signal->theData[0] = ZDICT_LOCK_POLL;
10273
signal->theData[1] = pollCount + 1;
10274
sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 100, 2);
10277
bool change = (c_dictLockPoll != on);
10281
c_dictLockPoll = on;
10284
// avoid too many messages if master is stuck busy (BS_NODE_FAILURE)
10287
pollCount < 64 && pollCount % 8 == 0 ||
10288
pollCount < 512 && pollCount % 64 == 0 ||
10289
pollCount < 4096 && pollCount % 512 == 0 ||
10290
pollCount % 4096 == 0; // about every 6 minutes
10292
if (change || periodic)
10293
sendDictLockInfoEvent(pollCount);
10299
Dbdict::removeStaleDictLocks(Signal* signal, const Uint32* theFailedNodes)
10301
DictLockPtr loopPtr;
10302
c_dictLockQueue.first(loopPtr);
10304
if (getOwnNodeId() != c_masterNodeId) {
10305
ndbrequire(loopPtr.i == RNIL);
10309
while (loopPtr.i != RNIL) {
10311
DictLockPtr lockPtr = loopPtr;
10312
c_dictLockQueue.next(loopPtr);
10314
Uint32 nodeId = refToNode(lockPtr.p->req.userRef);
10316
if (NodeBitmask::get(theFailedNodes, nodeId)) {
10317
if (lockPtr.p->locked) {
10319
ndbrequire(c_blockState == lockPtr.p->lt->blockState);
10320
ndbrequire(! hasDictLockSchemaOp());
10321
ndbrequire(! c_dictLockQueue.hasPrev(lockPtr));
10323
c_blockState = BS_IDLE;
10325
sendDictLockInfoEvent(lockPtr, "remove lock by failed node");
10327
sendDictLockInfoEvent(lockPtr, "remove lock request by failed node");
10330
c_dictLockQueue.release(lockPtr);
10334
checkDictLockQueue(signal, false);
10338
/* **************************************************************** */
10339
/* ---------------------------------------------------------------- */
10340
/* MODULE: STORE/RESTORE SCHEMA FILE---------------------- */
10341
/* ---------------------------------------------------------------- */
10343
/* General module used to store the schema file on disk and */
10344
/* similar function to restore it from disk. */
10345
/* ---------------------------------------------------------------- */
10346
/* **************************************************************** */
10349
Dbdict::initSchemaFile(XSchemaFile * xsf, Uint32 firstPage, Uint32 lastPage,
10352
ndbrequire(lastPage <= xsf->noOfPages);
10353
for (Uint32 n = firstPage; n < lastPage; n++) {
10354
SchemaFile * sf = &xsf->schemaPage[n];
10356
memset(sf, 0, NDB_SF_PAGE_SIZE);
10358
Uint32 ndb_version = NDB_VERSION;
10359
if (ndb_version < NDB_SF_VERSION_5_0_6)
10360
ndb_version = NDB_SF_VERSION_5_0_6;
10362
memcpy(sf->Magic, NDB_SF_MAGIC, sizeof(sf->Magic));
10363
sf->ByteOrder = 0x12345678;
10364
sf->NdbVersion = ndb_version;
10365
sf->FileSize = xsf->noOfPages * NDB_SF_PAGE_SIZE;
10366
sf->PageNumber = n;
10368
sf->NoOfTableEntries = NDB_SF_PAGE_ENTRIES;
10370
computeChecksum(xsf, n);
10375
Dbdict::resizeSchemaFile(XSchemaFile * xsf, Uint32 noOfPages)
10377
ndbrequire(noOfPages <= NDB_SF_MAX_PAGES);
10378
if (xsf->noOfPages < noOfPages) {
10380
Uint32 firstPage = xsf->noOfPages;
10381
xsf->noOfPages = noOfPages;
10382
initSchemaFile(xsf, 0, firstPage, false);
10383
initSchemaFile(xsf, firstPage, xsf->noOfPages, true);
10385
if (xsf->noOfPages > noOfPages) {
10387
Uint32 tableId = noOfPages * NDB_SF_PAGE_ENTRIES;
10388
while (tableId < xsf->noOfPages * NDB_SF_PAGE_ENTRIES) {
10389
SchemaFile::TableEntry * te = getTableEntry(xsf, tableId);
10390
if (te->m_tableState != SchemaFile::INIT &&
10391
te->m_tableState != SchemaFile::DROP_TABLE_COMMITTED) {
10396
xsf->noOfPages = noOfPages;
10397
initSchemaFile(xsf, 0, xsf->noOfPages, false);
10402
Dbdict::computeChecksum(XSchemaFile * xsf, Uint32 pageNo){
10403
SchemaFile * sf = &xsf->schemaPage[pageNo];
10405
sf->CheckSum = computeChecksum((Uint32*)sf, NDB_SF_PAGE_SIZE_IN_WORDS);
10409
Dbdict::validateChecksum(const XSchemaFile * xsf){
10411
for (Uint32 n = 0; n < xsf->noOfPages; n++) {
10412
SchemaFile * sf = &xsf->schemaPage[n];
10413
Uint32 c = computeChecksum((Uint32*)sf, NDB_SF_PAGE_SIZE_IN_WORDS);
10421
Dbdict::computeChecksum(const Uint32 * src, Uint32 len){
10423
for(Uint32 i = 0; i<len; i++)
10428
SchemaFile::TableEntry *
10429
Dbdict::getTableEntry(XSchemaFile * xsf, Uint32 tableId)
10431
Uint32 n = tableId / NDB_SF_PAGE_ENTRIES;
10432
Uint32 i = tableId % NDB_SF_PAGE_ENTRIES;
10433
ndbrequire(n < xsf->noOfPages);
10435
SchemaFile * sf = &xsf->schemaPage[n];
10436
return &sf->TableEntries[i];
10439
// global metadata support
10442
Dbdict::getMetaTablePtr(TableRecordPtr& tablePtr, Uint32 tableId, Uint32 tableVersion)
10444
if (tableId >= c_tableRecordPool.getSize()) {
10445
return MetaData::InvalidArgument;
10447
c_tableRecordPool.getPtr(tablePtr, tableId);
10448
if (tablePtr.p->tabState == TableRecord::NOT_DEFINED) {
10449
return MetaData::TableNotFound;
10451
if (tablePtr.p->tableVersion != tableVersion) {
10452
return MetaData::InvalidTableVersion;
10454
// online flag is not maintained by DICT
10455
tablePtr.p->online =
10456
tablePtr.p->isTable() &&
10457
(tablePtr.p->tabState == TableRecord::DEFINED ||
10458
tablePtr.p->tabState == TableRecord::BACKUP_ONGOING) ||
10459
tablePtr.p->isIndex() && tablePtr.p->indexState == TableRecord::IS_ONLINE;
10464
Dbdict::getMetaTable(MetaData::Table& table, Uint32 tableId, Uint32 tableVersion)
10467
TableRecordPtr tablePtr;
10468
if ((ret = getMetaTablePtr(tablePtr, tableId, tableVersion)) < 0) {
10471
new (&table) MetaData::Table(*tablePtr.p);
10476
Dbdict::getMetaTable(MetaData::Table& table, const char* tableName)
10479
TableRecordPtr tablePtr;
10480
if (strlen(tableName) + 1 > MAX_TAB_NAME_SIZE) {
10481
return MetaData::InvalidArgument;
10483
TableRecord keyRecord;
10484
strcpy(keyRecord.tableName, tableName);
10485
c_tableRecordHash.find(tablePtr, keyRecord);
10486
if (tablePtr.i == RNIL) {
10487
return MetaData::TableNotFound;
10489
if ((ret = getMetaTablePtr(tablePtr, tablePtr.i, tablePtr.p->tableVersion)) < 0) {
10492
new (&table) MetaData::Table(*tablePtr.p);
10497
Dbdict::getMetaAttribute(MetaData::Attribute& attr, const MetaData::Table& table, Uint32 attributeId)
10500
TableRecordPtr tablePtr;
10501
if ((ret = getMetaTablePtr(tablePtr, table.tableId, table.tableVersion)) < 0) {
10504
AttributeRecordPtr attrPtr;
10505
attrPtr.i = tablePtr.p->firstAttribute;
10506
while (attrPtr.i != RNIL) {
10507
c_attributeRecordPool.getPtr(attrPtr);
10508
if (attrPtr.p->attributeId == attributeId)
10510
attrPtr.i = attrPtr.p->nextAttrInTable;
10512
if (attrPtr.i == RNIL) {
10513
return MetaData::AttributeNotFound;
10515
new (&attr) MetaData::Attribute(*attrPtr.p);
10520
Dbdict::getMetaAttribute(MetaData::Attribute& attr, const MetaData::Table& table, const char* attributeName)
10523
TableRecordPtr tablePtr;
10524
if ((ret = getMetaTablePtr(tablePtr, table.tableId, table.tableVersion)) < 0) {
10527
AttributeRecordPtr attrPtr;
10528
attrPtr.i = tablePtr.p->firstAttribute;
10529
while (attrPtr.i != RNIL) {
10530
c_attributeRecordPool.getPtr(attrPtr);
10531
if (strcmp(attrPtr.p->attributeName, attributeName) == 0)
10533
attrPtr.i = attrPtr.p->nextAttrInTable;
10535
if (attrPtr.i == RNIL) {
10536
return MetaData::AttributeNotFound;
10538
new (&attr) MetaData::Attribute(*attrPtr.p);
10542
CArray<KeyDescriptor> g_key_descriptor_pool;