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