1 /*
2 Copyright (c) 2003, 2021, Oracle and/or its affiliates.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License, version 2.0,
6 as published by the Free Software Foundation.
7
8 This program is also distributed with certain software (including
9 but not limited to OpenSSL) that is licensed under separate terms,
10 as designated in a particular file or component or in included license
11 documentation. The authors of MySQL hereby grant you an additional
12 permission to link the program and your derivative works with the
13 separately licensed software that they have included with MySQL.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License, version 2.0, for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 */
24
25
26 #define DBTUP_C
27 #define DBTUP_GEN_CPP
28 #include "Dbtup.hpp"
29 #include <RefConvert.hpp>
30 #include <ndb_limits.h>
31 #include <pc.hpp>
32 #include <AttributeDescriptor.hpp>
33 #include "AttributeOffset.hpp"
34 #include <AttributeHeader.hpp>
35 #include <Interpreter.hpp>
36 #include <signaldata/FsConf.hpp>
37 #include <signaldata/FsRef.hpp>
38 #include <signaldata/FsRemoveReq.hpp>
39 #include <signaldata/TupCommit.hpp>
40 #include <signaldata/TupKey.hpp>
41 #include <signaldata/NodeFailRep.hpp>
42 #include <signaldata/NodeStateSignalData.hpp>
43
44 #include <signaldata/DropTab.hpp>
45 #include <IntrusiveList.hpp>
46
47 #include <EventLogger.hpp>
48
49 #define JAM_FILE_ID 420
50
51 extern EventLogger * g_eventLogger;
52
53 #define DEBUG(x) { ndbout << "TUP::" << x << endl; }
54
initData()55 void Dbtup::initData()
56 {
57 TablerecPtr tablePtr;
58 (void)tablePtr; // hide unused warning
59 cnoOfFragrec = NDB_ARRAY_SIZE(tablePtr.p->fragrec);
60 cnoOfFragoprec = NDB_ARRAY_SIZE(tablePtr.p->fragrec);
61 cnoOfAlterTabOps = NDB_ARRAY_SIZE(tablePtr.p->fragrec);
62 c_maxTriggersPerTable = ZDEFAULT_MAX_NO_TRIGGERS_PER_TABLE;
63 c_noOfBuildIndexRec = 32;
64
65 cCopyProcedure = RNIL;
66 cCopyLastSeg = RNIL;
67 cCopyOverwrite = 0;
68 cCopyOverwriteLen = 0;
69
70 // Records with constant sizes
71 init_list_sizes();
72 cpackedListIndex = 0;
73
74 m_minFreePages = 0;
75 }//Dbtup::initData()
76
Dbtup(Block_context & ctx,Uint32 instanceNumber)77 Dbtup::Dbtup(Block_context& ctx, Uint32 instanceNumber)
78 : SimulatedBlock(DBTUP, ctx, instanceNumber),
79 c_lqh(0),
80 c_backup(0),
81 c_tsman(0),
82 c_lgman(0),
83 c_pgman(0),
84 c_extent_hash(c_extent_pool),
85 c_storedProcPool(),
86 c_buildIndexList(c_buildIndexPool),
87 c_undo_buffer(&ctx.m_mm),
88 m_pages_allocated(0),
89 m_pages_allocated_max(0),
90 f_undo_done(true)
91 {
92 BLOCK_CONSTRUCTOR(Dbtup);
93
94 addRecSignal(GSN_DEBUG_SIG, &Dbtup::execDEBUG_SIG);
95 addRecSignal(GSN_CONTINUEB, &Dbtup::execCONTINUEB);
96 addRecSignal(GSN_LCP_FRAG_ORD, &Dbtup::execLCP_FRAG_ORD);
97 addRecSignal(GSN_NODE_FAILREP, &Dbtup::execNODE_FAILREP);
98
99 addRecSignal(GSN_DUMP_STATE_ORD, &Dbtup::execDUMP_STATE_ORD);
100 addRecSignal(GSN_DBINFO_SCANREQ, &Dbtup::execDBINFO_SCANREQ);
101 addRecSignal(GSN_SEND_PACKED, &Dbtup::execSEND_PACKED, true);
102 addRecSignal(GSN_STTOR, &Dbtup::execSTTOR);
103 addRecSignal(GSN_MEMCHECKREQ, &Dbtup::execMEMCHECKREQ);
104 addRecSignal(GSN_TUPSEIZEREQ, &Dbtup::execTUPSEIZEREQ);
105 addRecSignal(GSN_TUPRELEASEREQ, &Dbtup::execTUPRELEASEREQ);
106 addRecSignal(GSN_STORED_PROCREQ, &Dbtup::execSTORED_PROCREQ);
107
108 addRecSignal(GSN_CREATE_TAB_REQ, &Dbtup::execCREATE_TAB_REQ);
109 addRecSignal(GSN_TUPFRAGREQ, &Dbtup::execTUPFRAGREQ);
110 addRecSignal(GSN_TUP_ADD_ATTRREQ, &Dbtup::execTUP_ADD_ATTRREQ);
111 addRecSignal(GSN_ALTER_TAB_REQ, &Dbtup::execALTER_TAB_REQ);
112 addRecSignal(GSN_TUP_COMMITREQ, &Dbtup::execTUP_COMMITREQ);
113 addRecSignal(GSN_TUP_ABORTREQ, &Dbtup::execTUP_ABORTREQ);
114 addRecSignal(GSN_NDB_STTOR, &Dbtup::execNDB_STTOR);
115 addRecSignal(GSN_READ_CONFIG_REQ, &Dbtup::execREAD_CONFIG_REQ, true);
116 addRecSignal(GSN_NODE_STATE_REP, &Dbtup::execNODE_STATE_REP, true);
117
118 // Trigger Signals
119 addRecSignal(GSN_CREATE_TRIG_IMPL_REQ, &Dbtup::execCREATE_TRIG_IMPL_REQ);
120 addRecSignal(GSN_DROP_TRIG_IMPL_REQ, &Dbtup::execDROP_TRIG_IMPL_REQ);
121
122 addRecSignal(GSN_DROP_TAB_REQ, &Dbtup::execDROP_TAB_REQ);
123
124 addRecSignal(GSN_TUP_DEALLOCREQ, &Dbtup::execTUP_DEALLOCREQ);
125 addRecSignal(GSN_TUP_WRITELOG_REQ, &Dbtup::execTUP_WRITELOG_REQ);
126
127 // Ordered index related
128 addRecSignal(GSN_BUILD_INDX_IMPL_REQ, &Dbtup::execBUILD_INDX_IMPL_REQ);
129 addRecSignal(GSN_BUILD_INDX_IMPL_REF, &Dbtup::execBUILD_INDX_IMPL_REF);
130 addRecSignal(GSN_BUILD_INDX_IMPL_CONF, &Dbtup::execBUILD_INDX_IMPL_CONF);
131 addRecSignal(GSN_ALTER_TAB_CONF, &Dbtup::execALTER_TAB_CONF);
132 m_max_parallel_index_build = 0;
133
134 // Tup scan
135 addRecSignal(GSN_ACC_SCANREQ, &Dbtup::execACC_SCANREQ);
136 addRecSignal(GSN_NEXT_SCANREQ, &Dbtup::execNEXT_SCANREQ);
137 addRecSignal(GSN_ACC_CHECK_SCAN, &Dbtup::execACC_CHECK_SCAN);
138 addRecSignal(GSN_ACCKEYCONF, &Dbtup::execACCKEYCONF);
139 addRecSignal(GSN_ACCKEYREF, &Dbtup::execACCKEYREF);
140 addRecSignal(GSN_ACC_ABORTCONF, &Dbtup::execACC_ABORTCONF);
141
142 // Drop table
143 addRecSignal(GSN_FSREMOVEREF, &Dbtup::execFSREMOVEREF, true);
144 addRecSignal(GSN_FSREMOVECONF, &Dbtup::execFSREMOVECONF, true);
145
146 addRecSignal(GSN_DROP_FRAG_REQ, &Dbtup::execDROP_FRAG_REQ);
147 addRecSignal(GSN_SUB_GCP_COMPLETE_REP, &Dbtup::execSUB_GCP_COMPLETE_REP);
148
149 addRecSignal(GSN_FIRE_TRIG_REQ, &Dbtup::execFIRE_TRIG_REQ);
150
151 fragoperrec = 0;
152 fragrecord = 0;
153 alterTabOperRec = 0;
154 hostBuffer = 0;
155 tablerec = 0;
156 tableDescriptor = 0;
157
158 initData();
159 CLEAR_ERROR_INSERT_VALUE;
160
161 RSS_OP_COUNTER_INIT(cnoOfFreeFragoprec);
162 RSS_OP_COUNTER_INIT(cnoOfFreeFragrec);
163 RSS_OP_COUNTER_INIT(cnoOfFreeTabDescrRec);
164 c_storedProcCountNonAPI = 0;
165
166 {
167 CallbackEntry& ce = m_callbackEntry[THE_NULL_CALLBACK];
168 ce.m_function = TheNULLCallback.m_callbackFunction;
169 ce.m_flags = 0;
170 }
171 { // 1
172 CallbackEntry& ce = m_callbackEntry[UNDO_CREATETABLE_LOGSYNC_CALLBACK];
173 ce.m_function = safe_cast(&Dbtup::undo_createtable_logsync_callback);
174 ce.m_flags = 0;
175 }
176 { // 2
177 CallbackEntry& ce = m_callbackEntry[DROP_TABLE_LOGSYNC_CALLBACK];
178 ce.m_function = safe_cast(&Dbtup::drop_table_logsync_callback);
179 ce.m_flags = 0;
180 }
181 { // 3
182 CallbackEntry& ce = m_callbackEntry[UNDO_CREATETABLE_CALLBACK];
183 ce.m_function = safe_cast(&Dbtup::undo_createtable_callback);
184 ce.m_flags = 0;
185 }
186 { // 4
187 CallbackEntry& ce = m_callbackEntry[DROP_TABLE_LOG_BUFFER_CALLBACK];
188 ce.m_function = safe_cast(&Dbtup::drop_table_log_buffer_callback);
189 ce.m_flags = 0;
190 }
191 { // 5
192 CallbackEntry& ce = m_callbackEntry[DROP_FRAGMENT_FREE_EXTENT_LOG_BUFFER_CALLBACK];
193 ce.m_function = safe_cast(&Dbtup::drop_fragment_free_extent_log_buffer_callback);
194 ce.m_flags = 0;
195 }
196 { // 6
197 CallbackEntry& ce = m_callbackEntry[NR_DELETE_LOG_BUFFER_CALLBACK];
198 ce.m_function = safe_cast(&Dbtup::nr_delete_log_buffer_callback);
199 ce.m_flags = 0;
200 }
201 { // 7
202 CallbackEntry& ce = m_callbackEntry[DISK_PAGE_LOG_BUFFER_CALLBACK];
203 ce.m_function = safe_cast(&Dbtup::disk_page_log_buffer_callback);
204 ce.m_flags = CALLBACK_ACK;
205 }
206 {
207 CallbackTable& ct = m_callbackTable;
208 ct.m_count = COUNT_CALLBACKS;
209 ct.m_entry = m_callbackEntry;
210 m_callbackTableAddr = &ct;
211 }
212 }//Dbtup::Dbtup()
213
~Dbtup()214 Dbtup::~Dbtup()
215 {
216 /* Free Fragment Copy Procedure info */
217 freeCopyProcedure();
218
219 // Records with dynamic sizes
220 c_page_pool.clear();
221
222 deallocRecord((void **)&fragoperrec,"Fragoperrec",
223 sizeof(Fragoperrec),
224 cnoOfFragoprec);
225
226 deallocRecord((void **)&fragrecord,"Fragrecord",
227 sizeof(Fragrecord),
228 cnoOfFragrec);
229
230 deallocRecord((void **)&alterTabOperRec,"AlterTabOperRec",
231 sizeof(alterTabOperRec),
232 cnoOfAlterTabOps);
233
234 deallocRecord((void **)&hostBuffer,"HostBuffer",
235 sizeof(HostBuffer),
236 MAX_NODES);
237
238 deallocRecord((void **)&tablerec,"Tablerec",
239 sizeof(Tablerec),
240 cnoOfTablerec);
241
242 deallocRecord((void **)&tableDescriptor, "TableDescriptor",
243 sizeof(TableDescriptor),
244 cnoOfTabDescrRec);
245
246 }//Dbtup::~Dbtup()
247
Apply_undo()248 Dbtup::Apply_undo::Apply_undo()
249 {
250 m_type = 0;
251 m_len = 0;
252 m_ptr = 0;
253 m_lsn = (Uint64)0;
254 m_table_ptr.setNull();
255 m_fragment_ptr.setNull();
256 m_page_ptr.setNull();
257 m_extent_ptr.setNull();
258 m_key.setNull();
259 }
260
BLOCK_FUNCTIONS(Dbtup)261 BLOCK_FUNCTIONS(Dbtup)
262
263 void Dbtup::execCONTINUEB(Signal* signal)
264 {
265 jamEntry();
266 Uint32 actionType = signal->theData[0];
267 Uint32 dataPtr = signal->theData[1];
268
269 switch (actionType) {
270 case ZINITIALISE_RECORDS:
271 jam();
272 initialiseRecordsLab(signal, dataPtr,
273 signal->theData[2], signal->theData[3]);
274 break;
275 case ZREL_FRAG:
276 jam();
277 releaseFragment(signal, dataPtr, signal->theData[2]);
278 break;
279 case ZBUILD_INDEX:
280 jam();
281 buildIndex(signal, dataPtr);
282 break;
283 case ZTUP_SCAN:
284 jam();
285 {
286 ScanOpPtr scanPtr;
287 c_scanOpPool.getPtr(scanPtr, dataPtr);
288 scanCont(signal, scanPtr);
289 }
290 return;
291 case ZFREE_EXTENT:
292 {
293 jam();
294 TablerecPtr tabPtr;
295 tabPtr.i= dataPtr;
296 FragrecordPtr fragPtr;
297 fragPtr.i= signal->theData[2];
298 ptrCheckGuard(tabPtr, cnoOfTablerec, tablerec);
299 ptrCheckGuard(fragPtr, cnoOfFragrec, fragrecord);
300 drop_fragment_free_extent(signal, tabPtr, fragPtr, signal->theData[3]);
301 return;
302 }
303 case ZUNMAP_PAGES:
304 {
305 jam();
306 TablerecPtr tabPtr;
307 tabPtr.i= dataPtr;
308 FragrecordPtr fragPtr;
309 fragPtr.i= signal->theData[2];
310 ptrCheckGuard(tabPtr, cnoOfTablerec, tablerec);
311 ptrCheckGuard(fragPtr, cnoOfFragrec, fragrecord);
312 drop_fragment_unmap_pages(signal, tabPtr, fragPtr, signal->theData[3]);
313 return;
314 }
315 case ZFREE_VAR_PAGES:
316 {
317 jam();
318 drop_fragment_free_var_pages(signal);
319 return;
320 }
321 case ZFREE_PAGES:
322 {
323 jam();
324 drop_fragment_free_pages(signal);
325 return;
326 }
327 case ZREBUILD_FREE_PAGE_LIST:
328 {
329 jam();
330 rebuild_page_free_list(signal);
331 return;
332 }
333 case ZDISK_RESTART_UNDO:
334 {
335 jam();
336 if (!assembleFragments(signal)) {
337 jam();
338 return;
339 }
340 Uint32 type = signal->theData[1];
341 Uint32 len = signal->theData[2];
342 Uint64 lsn_hi = signal->theData[3];
343 Uint64 lsn_lo = signal->theData[4];
344 Uint64 lsn = (lsn_hi << 32) | lsn_lo;
345 SectionHandle handle(this, signal);
346 ndbrequire(handle.m_cnt == 1);
347 SegmentedSectionPtr ssptr;
348 handle.getSection(ssptr, 0);
349 ::copy(c_proxy_undo_data, ssptr);
350 releaseSections(handle);
351 disk_restart_undo(signal, lsn, type, c_proxy_undo_data, len);
352 return;
353 }
354
355 default:
356 ndbrequire(false);
357 break;
358 }//switch
359 }//Dbtup::execTUP_CONTINUEB()
360
361 /* **************************************************************** */
362 /* ---------------------------------------------------------------- */
363 /* ------------------- SYSTEM RESTART MODULE ---------------------- */
364 /* ---------------------------------------------------------------- */
365 /* **************************************************************** */
execSTTOR(Signal * signal)366 void Dbtup::execSTTOR(Signal* signal)
367 {
368 jamEntry();
369 Uint32 startPhase = signal->theData[1];
370 Uint32 sigKey = signal->theData[6];
371 switch (startPhase) {
372 case ZSTARTPHASE1:
373 jam();
374 ndbrequire((c_lqh= (Dblqh*)globalData.getBlock(DBLQH, instance())) != 0);
375 ndbrequire((c_backup= (Backup*)globalData.getBlock(BACKUP, instance())) != 0);
376 ndbrequire((c_tsman= (Tsman*)globalData.getBlock(TSMAN)) != 0);
377 ndbrequire((c_lgman= (Lgman*)globalData.getBlock(LGMAN)) != 0);
378 ndbrequire((c_pgman= (Pgman*)globalData.getBlock(PGMAN, instance())) != 0);
379 cownref = calcInstanceBlockRef(DBTUP);
380 break;
381 default:
382 jam();
383 break;
384 }//switch
385 signal->theData[0] = sigKey;
386 signal->theData[1] = 3;
387 signal->theData[2] = 2;
388 signal->theData[3] = ZSTARTPHASE1;
389 signal->theData[4] = 255;
390 BlockReference cntrRef = !isNdbMtLqh() ? NDBCNTR_REF : DBTUP_REF;
391 sendSignal(cntrRef, GSN_STTORRY, signal, 5, JBB);
392 return;
393 }//Dbtup::execSTTOR()
394
395 /************************************************************************************************/
396 // SIZE_ALTREP INITIALIZE DATA STRUCTURES, FILES AND DS VARIABLES, GET READY FOR EXTERNAL
397 // CONNECTIONS.
398 /************************************************************************************************/
execREAD_CONFIG_REQ(Signal * signal)399 void Dbtup::execREAD_CONFIG_REQ(Signal* signal)
400 {
401 const ReadConfigReq * req = (ReadConfigReq*)signal->getDataPtr();
402 Uint32 ref = req->senderRef;
403 Uint32 senderData = req->senderData;
404 ndbrequire(req->noOfParameters == 0);
405
406 jamEntry();
407
408 const ndb_mgm_configuration_iterator * p =
409 m_ctx.m_config.getOwnConfigIterator();
410 ndbrequire(p != 0);
411
412 ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_TUP_FRAG, &cnoOfFragrec));
413
414 Uint32 noOfTriggers= 0;
415 Uint32 noOfAttribs = 0;
416
417 ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_TUP_TABLE, &cnoOfTablerec));
418 ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_DB_NO_ATTRIBUTES, &noOfAttribs));
419
420 Uint32 noOfStoredProc;
421 ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_TUP_STORED_PROC,
422 &noOfStoredProc));
423 ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_DB_NO_TRIGGERS,
424 &noOfTriggers));
425
426
427 {
428 Uint32 keyDesc = noOfAttribs;
429 Uint32 maxKeyDesc = cnoOfTablerec * MAX_ATTRIBUTES_IN_INDEX;
430 if (keyDesc > maxKeyDesc)
431 {
432 /**
433 * There can be no-more key's
434 * than "cnoOfTablerec * MAX_ATTRIBUTES_IN_INDEX"
435 */
436 jam();
437 keyDesc = maxKeyDesc;
438 }
439
440 cnoOfTabDescrRec =
441 cnoOfTablerec * 2 * (ZTD_SIZE + ZTD_TRAILER_SIZE) +
442 noOfAttribs * (sizeOfReadFunction() + // READ
443 sizeOfReadFunction() + // UPDATE
444 (sizeof(char*) >> 2) + // Charset
445 ZAD_SIZE + // Descriptor
446 1 + // real order
447 InternalMaxDynFix) + // Worst case dynamic
448 keyDesc; // key-descr
449
450 cnoOfTabDescrRec = (cnoOfTabDescrRec & 0xFFFFFFF0) + 16;
451 }
452
453 initRecords();
454
455 c_storedProcPool.setSize(noOfStoredProc);
456
457 // Allocate fragment copy procedure
458 allocCopyProcedure();
459
460 c_buildIndexPool.setSize(c_noOfBuildIndexRec);
461 c_triggerPool.setSize(noOfTriggers, false, true, true, CFG_DB_NO_TRIGGERS);
462
463 c_extent_hash.setSize(1024); // 4k
464
465 Pool_context pc;
466 pc.m_block = this;
467 c_page_request_pool.wo_pool_init(RT_DBTUP_PAGE_REQUEST, pc);
468 c_extent_pool.init(RT_DBTUP_EXTENT_INFO, pc);
469 NdbMutex_Init(&c_page_map_pool_mutex);
470 c_page_map_pool.init(&c_page_map_pool_mutex, RT_DBTUP_PAGE_MAP, pc);
471
472 Uint32 nScanOp; // use TUX config for now
473 ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_TUX_SCAN_OP, &nScanOp));
474 c_scanOpPool.setSize(nScanOp + 1);
475 Uint32 nScanBatch;
476 ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_DB_BATCH_SIZE, &nScanBatch));
477 c_scanLockPool.setSize(nScanOp * nScanBatch);
478
479
480 /* read ahead for disk scan can not be more that disk page buffer */
481 {
482 Uint64 tmp = 64*1024*1024;
483 ndb_mgm_get_int64_parameter(p, CFG_DB_DISK_PAGE_BUFFER_MEMORY, &tmp);
484 tmp = (tmp + GLOBAL_PAGE_SIZE - 1) / GLOBAL_PAGE_SIZE; // in pages
485 // never read ahead more than 32 pages
486 if (tmp > 32)
487 m_max_page_read_ahead = 32;
488 else
489 m_max_page_read_ahead = (Uint32)tmp;
490 }
491
492
493 ScanOpPtr lcp;
494 ndbrequire(c_scanOpPool.seize(lcp));
495 new (lcp.p) ScanOp();
496 c_lcp_scan_op= lcp.i;
497
498 czero = 0;
499 cminusOne = czero - 1;
500 clastBitMask = 1;
501 clastBitMask = clastBitMask << 31;
502
503 ndb_mgm_get_int_parameter(p, CFG_DB_MT_BUILD_INDEX,
504 &m_max_parallel_index_build);
505
506 if (isNdbMtLqh() && globalData.ndbMtLqhThreads > 1)
507 {
508 /**
509 * Divide by LQH threads
510 */
511 Uint32 val = m_max_parallel_index_build;
512 val = (val + instance() - 1) / globalData.ndbMtLqhThreads;
513 m_max_parallel_index_build = val;
514 }
515
516 initialiseRecordsLab(signal, 0, ref, senderData);
517
518 {
519 Uint32 val = 0;
520 ndb_mgm_get_int_parameter(p, CFG_DB_CRASH_ON_CORRUPTED_TUPLE,
521 &val);
522 c_crashOnCorruptedTuple = val ? true : false;
523 }
524
525 }
526
initRecords()527 void Dbtup::initRecords()
528 {
529 unsigned i;
530 Uint32 tmp;
531 Uint32 tmp1 = 0;
532 const ndb_mgm_configuration_iterator * p =
533 m_ctx.m_config.getOwnConfigIterator();
534 ndbrequire(p != 0);
535
536 // Records with dynamic sizes
537 void* ptr = m_ctx.m_mm.get_memroot();
538 c_page_pool.set((Page*)ptr, (Uint32)~0);
539
540 fragoperrec = (Fragoperrec*)allocRecord("Fragoperrec",
541 sizeof(Fragoperrec),
542 cnoOfFragoprec);
543
544 fragrecord = (Fragrecord*)allocRecord("Fragrecord",
545 sizeof(Fragrecord),
546 cnoOfFragrec);
547
548 alterTabOperRec = (AlterTabOperation*)allocRecord("AlterTabOperation",
549 sizeof(AlterTabOperation),
550 cnoOfAlterTabOps);
551
552 hostBuffer = (HostBuffer*)allocRecord("HostBuffer",
553 sizeof(HostBuffer),
554 MAX_NODES);
555
556 tableDescriptor = (TableDescriptor*)allocRecord("TableDescriptor",
557 sizeof(TableDescriptor),
558 cnoOfTabDescrRec);
559
560 ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_TUP_OP_RECS, &tmp));
561 ndb_mgm_get_int_parameter(p, CFG_DB_NO_LOCAL_OPS, &tmp1);
562 c_operation_pool.setSize(tmp, false, true, true,
563 tmp1 == 0 ? CFG_DB_NO_OPS : CFG_DB_NO_LOCAL_OPS);
564
565 tablerec = (Tablerec*)allocRecord("Tablerec",
566 sizeof(Tablerec),
567 cnoOfTablerec);
568
569 for (i = 0; i<cnoOfTablerec; i++) {
570 void * p = &tablerec[i];
571 new (p) Tablerec(c_triggerPool);
572 }
573 }//Dbtup::initRecords()
574
initialiseRecordsLab(Signal * signal,Uint32 switchData,Uint32 retRef,Uint32 retData)575 void Dbtup::initialiseRecordsLab(Signal* signal, Uint32 switchData,
576 Uint32 retRef, Uint32 retData)
577 {
578 switch (switchData) {
579 case 0:
580 jam();
581 initializeHostBuffer();
582 break;
583 case 1:
584 jam();
585 initializeOperationrec();
586 break;
587 case 2:
588 jam();
589 initializePage();
590 break;
591 case 3:
592 jam();
593 break;
594 case 4:
595 jam();
596 initializeTablerec();
597 break;
598 case 5:
599 jam();
600 break;
601 case 6:
602 jam();
603 initializeFragrecord();
604 break;
605 case 7:
606 jam();
607 initializeFragoperrec();
608 break;
609 case 8:
610 jam();
611 break;
612 case 9:
613 jam();
614 initializeTabDescr();
615 break;
616 case 10:
617 jam();
618 initializeAlterTabOperation();
619 break;
620 case 11:
621 jam();
622 break;
623 case 12:
624 jam();
625 break;
626 case 13:
627 jam();
628 break;
629 case 14:
630 jam();
631
632 {
633 ReadConfigConf * conf = (ReadConfigConf*)signal->getDataPtrSend();
634 conf->senderRef = reference();
635 conf->senderData = retData;
636 sendSignal(retRef, GSN_READ_CONFIG_CONF, signal,
637 ReadConfigConf::SignalLength, JBB);
638 }
639 return;
640 default:
641 ndbrequire(false);
642 break;
643 }//switch
644 signal->theData[0] = ZINITIALISE_RECORDS;
645 signal->theData[1] = switchData + 1;
646 signal->theData[2] = retRef;
647 signal->theData[3] = retData;
648 sendSignal(reference(), GSN_CONTINUEB, signal, 4, JBB);
649 return;
650 }//Dbtup::initialiseRecordsLab()
651
execNDB_STTOR(Signal * signal)652 void Dbtup::execNDB_STTOR(Signal* signal)
653 {
654 jamEntry();
655 cndbcntrRef = signal->theData[0];
656 Uint32 ownNodeId = signal->theData[1];
657 Uint32 startPhase = signal->theData[2];
658 switch (startPhase) {
659 case ZSTARTPHASE1:
660 jam();
661 cownNodeId = ownNodeId;
662 cownref = calcInstanceBlockRef(DBTUP);
663 initializeDefaultValuesFrag();
664 break;
665 case ZSTARTPHASE2:
666 jam();
667 break;
668 case ZSTARTPHASE3:
669 jam();
670 break;
671 case ZSTARTPHASE4:
672 jam();
673 break;
674 case ZSTARTPHASE6:
675 jam();
676 break;
677 default:
678 jam();
679 break;
680 }//switch
681 signal->theData[0] = cownref;
682 BlockReference cntrRef = !isNdbMtLqh() ? NDBCNTR_REF : DBTUP_REF;
683 sendSignal(cntrRef, GSN_NDB_STTORRY, signal, 1, JBB);
684 }//Dbtup::execNDB_STTOR()
685
initializeDefaultValuesFrag()686 void Dbtup::initializeDefaultValuesFrag()
687 {
688 /* Grab and initialize a fragment record for storing default
689 * values for the table fragments held by this TUP instance
690 */
691 seizeFragrecord(DefaultValuesFragment);
692 DefaultValuesFragment.p->fragStatus = Fragrecord::FS_ONLINE;
693 DefaultValuesFragment.p->m_undo_complete= false;
694 DefaultValuesFragment.p->m_lcp_scan_op = RNIL;
695 DefaultValuesFragment.p->noOfPages = 0;
696 DefaultValuesFragment.p->noOfVarPages = 0;
697 DefaultValuesFragment.p->m_varWordsFree = 0;
698 DefaultValuesFragment.p->m_max_page_cnt = 0;
699 DefaultValuesFragment.p->m_free_page_id_list = FREE_PAGE_RNIL;
700 ndbrequire(DefaultValuesFragment.p->m_page_map.isEmpty());
701 DefaultValuesFragment.p->m_restore_lcp_id = RNIL;
702 for (Uint32 i = 0; i<MAX_FREE_LIST+1; i++)
703 ndbrequire(DefaultValuesFragment.p->free_var_page_array[i].isEmpty());
704
705 DefaultValuesFragment.p->m_logfile_group_id = RNIL;
706
707 return;
708 }
709
initializeFragoperrec()710 void Dbtup::initializeFragoperrec()
711 {
712 FragoperrecPtr fragoperPtr;
713 for (fragoperPtr.i = 0; fragoperPtr.i < cnoOfFragoprec; fragoperPtr.i++) {
714 ptrAss(fragoperPtr, fragoperrec);
715 fragoperPtr.p->nextFragoprec = fragoperPtr.i + 1;
716 }//for
717 fragoperPtr.i = cnoOfFragoprec - 1;
718 ptrAss(fragoperPtr, fragoperrec);
719 fragoperPtr.p->nextFragoprec = RNIL;
720 cfirstfreeFragopr = 0;
721 }//Dbtup::initializeFragoperrec()
722
initializeFragrecord()723 void Dbtup::initializeFragrecord()
724 {
725 FragrecordPtr regFragPtr;
726 for (regFragPtr.i = 0; regFragPtr.i < cnoOfFragrec; regFragPtr.i++) {
727 refresh_watch_dog();
728 ptrAss(regFragPtr, fragrecord);
729 new (regFragPtr.p) Fragrecord();
730 regFragPtr.p->nextfreefrag = regFragPtr.i + 1;
731 regFragPtr.p->fragStatus = Fragrecord::FS_FREE;
732 }//for
733 regFragPtr.i = cnoOfFragrec - 1;
734 ptrAss(regFragPtr, fragrecord);
735 regFragPtr.p->nextfreefrag = RNIL;
736 cfirstfreefrag = 0;
737 }//Dbtup::initializeFragrecord()
738
initializeAlterTabOperation()739 void Dbtup::initializeAlterTabOperation()
740 {
741 AlterTabOperationPtr regAlterTabOpPtr;
742 for (regAlterTabOpPtr.i= 0;
743 regAlterTabOpPtr.i<cnoOfAlterTabOps;
744 regAlterTabOpPtr.i++)
745 {
746 refresh_watch_dog();
747 ptrAss(regAlterTabOpPtr, alterTabOperRec);
748 new (regAlterTabOpPtr.p) AlterTabOperation();
749 regAlterTabOpPtr.p->nextAlterTabOp= regAlterTabOpPtr.i+1;
750 }
751 regAlterTabOpPtr.i= cnoOfAlterTabOps-1;
752 ptrAss(regAlterTabOpPtr, alterTabOperRec);
753 regAlterTabOpPtr.p->nextAlterTabOp= RNIL;
754 cfirstfreeAlterTabOp= 0;
755 }
756
initializeHostBuffer()757 void Dbtup::initializeHostBuffer()
758 {
759 Uint32 hostId;
760 cpackedListIndex = 0;
761 for (hostId = 0; hostId < MAX_NODES; hostId++) {
762 hostBuffer[hostId].inPackedList = false;
763 hostBuffer[hostId].noOfPacketsTA = 0;
764 hostBuffer[hostId].packetLenTA = 0;
765 }//for
766 }//Dbtup::initializeHostBuffer()
767
768
initializeOperationrec()769 void Dbtup::initializeOperationrec()
770 {
771 refresh_watch_dog();
772 }//Dbtup::initializeOperationrec()
773
initializeTablerec()774 void Dbtup::initializeTablerec()
775 {
776 TablerecPtr regTabPtr;
777 for (regTabPtr.i = 0; regTabPtr.i < cnoOfTablerec; regTabPtr.i++) {
778 jam();
779 refresh_watch_dog();
780 ptrAss(regTabPtr, tablerec);
781 initTab(regTabPtr.p);
782 }//for
783 }//Dbtup::initializeTablerec()
784
785 void
initTab(Tablerec * const regTabPtr)786 Dbtup::initTab(Tablerec* const regTabPtr)
787 {
788 for (Uint32 i = 0; i < NDB_ARRAY_SIZE(regTabPtr->fragid); i++) {
789 regTabPtr->fragid[i] = RNIL;
790 regTabPtr->fragrec[i] = RNIL;
791 }//for
792 regTabPtr->readFunctionArray = NULL;
793 regTabPtr->updateFunctionArray = NULL;
794 regTabPtr->charsetArray = NULL;
795
796 regTabPtr->tabDescriptor = RNIL;
797 regTabPtr->readKeyArray = RNIL;
798 regTabPtr->dynTabDescriptor[MM] = RNIL;
799 regTabPtr->dynTabDescriptor[DD] = RNIL;
800 regTabPtr->dynFixSizeMask[MM] = NULL;
801 regTabPtr->dynVarSizeMask[MM] = NULL;
802 regTabPtr->dynFixSizeMask[DD] = NULL;
803 regTabPtr->dynVarSizeMask[DD] = NULL;
804
805 regTabPtr->m_bits = 0;
806
807 regTabPtr->m_no_of_attributes = 0;
808 regTabPtr->noOfKeyAttr = 0;
809
810 regTabPtr->m_dropTable.tabUserPtr = RNIL;
811 regTabPtr->m_dropTable.tabUserRef = 0;
812 regTabPtr->tableStatus = NOT_DEFINED;
813 regTabPtr->m_default_value_location.setNull();
814
815 // Clear trigger data
816 if (!regTabPtr->afterInsertTriggers.isEmpty())
817 while (regTabPtr->afterInsertTriggers.releaseFirst());
818 if (!regTabPtr->afterDeleteTriggers.isEmpty())
819 while (regTabPtr->afterDeleteTriggers.releaseFirst());
820 if (!regTabPtr->afterUpdateTriggers.isEmpty())
821 while (regTabPtr->afterUpdateTriggers.releaseFirst());
822 if (!regTabPtr->subscriptionInsertTriggers.isEmpty())
823 while (regTabPtr->subscriptionInsertTriggers.releaseFirst());
824 if (!regTabPtr->subscriptionDeleteTriggers.isEmpty())
825 while (regTabPtr->subscriptionDeleteTriggers.releaseFirst());
826 if (!regTabPtr->subscriptionUpdateTriggers.isEmpty())
827 while (regTabPtr->subscriptionUpdateTriggers.releaseFirst());
828 if (!regTabPtr->constraintUpdateTriggers.isEmpty())
829 while (regTabPtr->constraintUpdateTriggers.releaseFirst());
830 if (!regTabPtr->tuxCustomTriggers.isEmpty())
831 while (regTabPtr->tuxCustomTriggers.releaseFirst());
832 }//Dbtup::initTab()
833
initializeTabDescr()834 void Dbtup::initializeTabDescr()
835 {
836 TableDescriptorPtr regTabDesPtr;
837 for (Uint32 i = 0; i < 16; i++) {
838 cfreeTdList[i] = RNIL;
839 }//for
840 for (regTabDesPtr.i = 0; regTabDesPtr.i < cnoOfTabDescrRec; regTabDesPtr.i++) {
841 refresh_watch_dog();
842 ptrAss(regTabDesPtr, tableDescriptor);
843 regTabDesPtr.p->tabDescr = RNIL;
844 }//for
845 freeTabDescr(0, cnoOfTabDescrRec);
846 }//Dbtup::initializeTabDescr()
847
848 /* ---------------------------------------------------------------- */
849 /* ---------------------------------------------------------------- */
850 /* --------------- CONNECT/DISCONNECT MODULE ---------------------- */
851 /* ---------------------------------------------------------------- */
852 /* ---------------------------------------------------------------- */
execTUPSEIZEREQ(Signal * signal)853 void Dbtup::execTUPSEIZEREQ(Signal* signal)
854 {
855 OperationrecPtr regOperPtr;
856 jamEntry();
857 Uint32 userPtr = signal->theData[0];
858 BlockReference userRef = signal->theData[1];
859 if (!c_operation_pool.seize(regOperPtr))
860 {
861 jam();
862 signal->theData[0] = userPtr;
863 signal->theData[1] = ZGET_OPREC_ERROR;
864 sendSignal(userRef, GSN_TUPSEIZEREF, signal, 2, JBB);
865 return;
866 }//if
867
868 new (regOperPtr.p) Operationrec();
869 regOperPtr.p->m_any_value = 0;
870 regOperPtr.p->op_type = ZREAD;
871 regOperPtr.p->op_struct.bit_field.in_active_list = false;
872 set_trans_state(regOperPtr.p, TRANS_DISCONNECTED);
873 regOperPtr.p->prevActiveOp = RNIL;
874 regOperPtr.p->nextActiveOp = RNIL;
875 regOperPtr.p->op_struct.bit_field.tupVersion = ZNIL;
876 regOperPtr.p->op_struct.bit_field.delete_insert_flag = false;
877
878 initOpConnection(regOperPtr.p);
879 regOperPtr.p->userpointer = userPtr;
880 signal->theData[0] = regOperPtr.p->userpointer;
881 signal->theData[1] = regOperPtr.i;
882 sendSignal(userRef, GSN_TUPSEIZECONF, signal, 2, JBB);
883 return;
884 }//Dbtup::execTUPSEIZEREQ()
885
886 #define printFragment(t){ for(Uint32 i = 0; i < NDB_ARRAY_SIZE(t.p->fragid);i++){ \
887 ndbout_c("table = %d fragid[%d] = %d fragrec[%d] = %d", \
888 t.i, t.p->fragid[i], i, t.p->fragrec[i]); }}
889
execTUPRELEASEREQ(Signal * signal)890 void Dbtup::execTUPRELEASEREQ(Signal* signal)
891 {
892 OperationrecPtr regOperPtr;
893 jamEntry();
894 regOperPtr.i = signal->theData[0];
895 c_operation_pool.getPtr(regOperPtr);
896 set_trans_state(regOperPtr.p, TRANS_DISCONNECTED);
897 c_operation_pool.release(regOperPtr);
898
899 signal->theData[0] = regOperPtr.p->userpointer;
900 sendSignal(DBLQH_REF, GSN_TUPRELEASECONF, signal, 1, JBB);
901 return;
902 }//Dbtup::execTUPRELEASEREQ()
903
releaseFragrec(FragrecordPtr regFragPtr)904 void Dbtup::releaseFragrec(FragrecordPtr regFragPtr)
905 {
906 regFragPtr.p->nextfreefrag = cfirstfreefrag;
907 cfirstfreefrag = regFragPtr.i;
908 RSS_OP_FREE(cnoOfFreeFragrec);
909 }//Dbtup::releaseFragrec()
910
911
execNODE_FAILREP(Signal * signal)912 void Dbtup::execNODE_FAILREP(Signal* signal)
913 {
914 jamEntry();
915 const NodeFailRep * rep = (NodeFailRep*)signal->getDataPtr();
916 NdbNodeBitmask failed;
917 failed.assign(NdbNodeBitmask::Size, rep->theNodes);
918
919 /* Block level cleanup */
920 for(unsigned i = 1; i < MAX_NDB_NODES; i++) {
921 jam();
922 if(failed.get(i)) {
923 jam();
924 Uint32 elementsCleaned = simBlockNodeFailure(signal, i); // No callback
925 ndbassert(elementsCleaned == 0); // No distributed fragmented signals
926 (void) elementsCleaned; // Remove compiler warning
927 }//if
928 }//for
929 }
930
931 extern Uint32 compute_acc_32kpages(const ndb_mgm_configuration_iterator * p);
932
933 void
execNODE_STATE_REP(Signal * signal)934 Dbtup::execNODE_STATE_REP(Signal* signal)
935 {
936 jamEntry();
937 const NodeStateRep* rep = CAST_CONSTPTR(NodeStateRep,
938 signal->getDataPtr());
939
940 if (rep->nodeState.startLevel == NodeState::SL_STARTED)
941 {
942 jam();
943
944 const ndb_mgm_configuration_iterator * p =
945 m_ctx.m_config.getOwnConfigIterator();
946 ndbrequire(p != 0);
947
948 Uint32 free_pct = 5;
949 ndb_mgm_get_int_parameter(p, CFG_DB_FREE_PCT, &free_pct);
950
951 Uint32 accpages = compute_acc_32kpages(p);
952
953 Resource_limit rl;
954 m_ctx.m_mm.get_resource_limit(RG_DATAMEM, rl);
955 m_minFreePages = ((rl.m_min - accpages) * free_pct) / 100;
956 }
957 SimulatedBlock::execNODE_STATE_REP(signal);
958 }
959