1 /** **/
2 /*
3 Copyright (C) 2003-2008 MySQL AB, 2008-2010 Sun Microsystems, Inc.
4 All rights reserved. Use is subject to license terms.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License, version 2.0,
8 as published by the Free Software Foundation.
9
10 This program is also distributed with certain software (including
11 but not limited to OpenSSL) that is licensed under separate terms,
12 as designated in a particular file or component or in included license
13 documentation. The authors of MySQL hereby grant you an additional
14 permission to link the program and your derivative works with the
15 separately licensed software that they have included with MySQL.
16
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License, version 2.0, for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 */
26
27 #ifndef DBACC_H
28 #define DBACC_H
29
30 #if defined (VM_TRACE) && !defined(ACC_SAFE_QUEUE)
31 #define ACC_SAFE_QUEUE
32 #endif
33
34 #include <pc.hpp>
35 #include <SimulatedBlock.hpp>
36
37 #ifdef DBACC_C
38 // Debug Macros
39 #define dbgWord32(ptr, ind, val)
40
41 /*
42 #define dbgWord32(ptr, ind, val) \
43 if(debug_jan){ \
44 tmp_val = val; \
45 switch(ind){ \
46 case 1: strcpy(tmp_string, "ZPOS_PAGE_TYPE "); \
47 break; \
48 case 2: strcpy(tmp_string, "ZPOS_NO_ELEM_IN_PAGE"); \
49 break; \
50 case 3: strcpy(tmp_string, "ZPOS_CHECKSUM "); \
51 break; \
52 case 4: strcpy(tmp_string, "ZPOS_OVERFLOWREC "); \
53 break; \
54 case 5: strcpy(tmp_string, "ZPOS_FREE_AREA_IN_PAGE"); \
55 break; \
56 case 6: strcpy(tmp_string, "ZPOS_LAST_INDEX "); \
57 break; \
58 case 7: strcpy(tmp_string, "ZPOS_INSERT_INDEX "); \
59 break; \
60 case 8: strcpy(tmp_string, "ZPOS_ARRAY_POS "); \
61 break; \
62 case 9: strcpy(tmp_string, "ZPOS_NEXT_FREE_INDEX"); \
63 break; \
64 case 10: strcpy(tmp_string, "ZPOS_NEXT_PAGE "); \
65 break; \
66 case 11: strcpy(tmp_string, "ZPOS_PREV_PAGE "); \
67 break; \
68 default: sprintf(tmp_string, "%-20d", ind);\
69 } \
70 ndbout << "Ptr: " << ptr.p->word32 << " \tIndex: " << tmp_string << " \tValue: " << tmp_val << " \tLINE: " << __LINE__ << endl; \
71 }\
72 */
73
74 // Constants
75 /** ------------------------------------------------------------------------
76 * THESE ARE CONSTANTS THAT ARE USED FOR DEFINING THE SIZE OF BUFFERS, THE
77 * SIZE OF PAGE HEADERS, THE NUMBER OF BUFFERS IN A PAGE AND A NUMBER OF
78 * OTHER CONSTANTS WHICH ARE CHANGED WHEN THE BUFFER SIZE IS CHANGED.
79 * ----------------------------------------------------------------------- */
80 #define ZHEAD_SIZE 32
81 #define ZCON_HEAD_SIZE 2
82 #define ZBUF_SIZE 28
83 #define ZEMPTYLIST 72
84 #define ZUP_LIMIT 14
85 #define ZDOWN_LIMIT 12
86 #define ZSHIFT_PLUS 5
87 #define ZSHIFT_MINUS 2
88 #define ZFREE_LIMIT 65
89 #define ZNO_CONTAINERS 64
90 #define ZELEM_HEAD_SIZE 1
91 /* ------------------------------------------------------------------------- */
92 /* THESE CONSTANTS DEFINE THE USE OF THE PAGE HEADER IN THE INDEX PAGES. */
93 /* ------------------------------------------------------------------------- */
94 #define ZPOS_PAGE_ID 0
95 #define ZPOS_PAGE_TYPE 1
96 #define ZPOS_PAGE_TYPE_BIT 14
97 #define ZPOS_EMPTY_LIST 1
98 #define ZPOS_ALLOC_CONTAINERS 2
99 #define ZPOS_CHECKSUM 3
100 #define ZPOS_OVERFLOWREC 4
101 #define ZPOS_NO_ELEM_IN_PAGE 2
102 #define ZPOS_FREE_AREA_IN_PAGE 5
103 #define ZPOS_LAST_INDEX 6
104 #define ZPOS_INSERT_INDEX 7
105 #define ZPOS_ARRAY_POS 8
106 #define ZPOS_NEXT_FREE_INDEX 9
107 #define ZPOS_NEXT_PAGE 10
108 #define ZPOS_PREV_PAGE 11
109 #define ZNORMAL_PAGE_TYPE 0
110 #define ZOVERFLOW_PAGE_TYPE 1
111 #define ZDEFAULT_LIST 3
112 #define ZWORDS_IN_PAGE 2048
113 #define ZADDFRAG 0
114 #define ZDIRARRAY 68
115 #define ZDIRRANGESIZE 65
116 //#define ZEMPTY_FRAGMENT 0
117 #define ZFRAGMENTSIZE 64
118 #define ZFIRSTTIME 1
119 #define ZFS_CONNECTSIZE 300
120 #define ZFS_OPSIZE 100
121 #define ZKEYINKEYREQ 4
122 #define ZLEFT 1
123 #define ZLOCALLOGFILE 2
124 #define ZLOCKED 0
125 #define ZMAXSCANSIGNALLEN 20
126 #define ZMAINKEYLEN 8
127 #define ZNO_OF_DISK_VERSION 3
128 #define ZNO_OF_OP_PER_SIGNAL 20
129 //#define ZNOT_EMPTY_FRAGMENT 1
130 #define ZOP_HEAD_INFO_LN 3
131 #define ZOPRECSIZE 740
132 #define ZOVERFLOWRECSIZE 5
133 #define ZPAGE8_BASE_ADD 1
134 #define ZPAGESIZE 128
135 #define ZPARALLEL_QUEUE 1
136 #define ZPDIRECTORY 1
137 #define ZSCAN_MAX_LOCK 4
138 #define ZSERIAL_QUEUE 2
139 #define ZSPH1 1
140 #define ZSPH2 2
141 #define ZSPH3 3
142 #define ZSPH6 6
143 #define ZREADLOCK 0
144 #define ZRIGHT 2
145 #define ZROOTFRAGMENTSIZE 32
146 #define ZSCAN_LOCK_ALL 3
147 /**
148 * Check kernel_types for other operation types
149 */
150 #define ZSCAN_OP 8
151 #define ZSCAN_REC_SIZE 256
152 #define ZSTAND_BY 2
153 #define ZTABLESIZE 16
154 #define ZTABMAXINDEX 3
155 #define ZUNDEFINED_OP 6
156 #define ZUNLOCKED 1
157
158 /* --------------------------------------------------------------------------------- */
159 /* CONTINUEB CODES */
160 /* --------------------------------------------------------------------------------- */
161 #define ZINITIALISE_RECORDS 1
162 #define ZREL_ROOT_FRAG 5
163 #define ZREL_FRAG 6
164 #define ZREL_DIR 7
165
166 /* ------------------------------------------------------------------------- */
167 /* ERROR CODES */
168 /* ------------------------------------------------------------------------- */
169 #define ZLIMIT_OF_ERROR 600 // Limit check for error codes
170 #define ZCHECKROOT_ERROR 601 // Delete fragment error code
171 #define ZCONNECT_SIZE_ERROR 602 // ACC_SEIZEREF
172 #define ZDIR_RANGE_ERROR 603 // Add fragment error code
173 #define ZFULL_FRAGRECORD_ERROR 604 // Add fragment error code
174 #define ZFULL_ROOTFRAGRECORD_ERROR 605 // Add fragment error code
175 #define ZROOTFRAG_STATE_ERROR 606 // Add fragment
176 #define ZOVERTAB_REC_ERROR 607 // Add fragment
177
178 #define ZSCAN_REFACC_CONNECT_ERROR 608 // ACC_SCANREF
179 #define ZFOUR_ACTIVE_SCAN_ERROR 609 // ACC_SCANREF
180 #define ZNULL_SCAN_REC_ERROR 610 // ACC_SCANREF
181
182 #define ZDIRSIZE_ERROR 623
183 #define ZOVER_REC_ERROR 624 // Insufficient Space
184 #define ZPAGESIZE_ERROR 625
185 #define ZTUPLE_DELETED_ERROR 626
186 #define ZREAD_ERROR 626
187 #define ZWRITE_ERROR 630
188 #define ZTO_OP_STATE_ERROR 631
189 #define ZTOO_EARLY_ACCESS_ERROR 632
190 #define ZDIR_RANGE_FULL_ERROR 633 // on fragment
191 #endif
192
193 class ElementHeader {
194 /**
195 *
196 * l = Locked -- If true contains operation else scan bits + hash value
197 * s = Scan bits
198 * h = Hash value
199 * o = Operation ptr I
200 *
201 * 1111111111222222222233
202 * 01234567890123456789012345678901
203 * lssssssssssss hhhhhhhhhhhhhhhh
204 * ooooooooooooooooooooooooooooooo
205 */
206 public:
207 STATIC_CONST( HASH_VALUE_PART_MASK = 0xFFFF );
208
209 static bool getLocked(Uint32 data);
210 static bool getUnlocked(Uint32 data);
211 static Uint32 getScanBits(Uint32 data);
212 static Uint32 getHashValuePart(Uint32 data);
213 static Uint32 getOpPtrI(Uint32 data);
214
215 static Uint32 setLocked(Uint32 opPtrI);
216 static Uint32 setUnlocked(Uint32 hashValuePart, Uint32 scanBits);
217 static Uint32 setScanBit(Uint32 header, Uint32 scanBit);
218 static Uint32 clearScanBit(Uint32 header, Uint32 scanBit);
219 };
220
221 inline
222 bool
getLocked(Uint32 data)223 ElementHeader::getLocked(Uint32 data){
224 return (data & 1) == 0;
225 }
226
227 inline
228 bool
getUnlocked(Uint32 data)229 ElementHeader::getUnlocked(Uint32 data){
230 return (data & 1) == 1;
231 }
232
233 inline
234 Uint32
getScanBits(Uint32 data)235 ElementHeader::getScanBits(Uint32 data){
236 assert(getUnlocked(data));
237 return (data >> 1) & ((1 << MAX_PARALLEL_SCANS_PER_FRAG) - 1);
238 }
239
240 inline
241 Uint32
getHashValuePart(Uint32 data)242 ElementHeader::getHashValuePart(Uint32 data){
243 assert(getUnlocked(data));
244 return data >> 16;
245 }
246
247 inline
248 Uint32
getOpPtrI(Uint32 data)249 ElementHeader::getOpPtrI(Uint32 data){
250 assert(getLocked(data));
251 return data >> 1;
252 }
253
254 inline
255 Uint32
setLocked(Uint32 opPtrI)256 ElementHeader::setLocked(Uint32 opPtrI){
257 return (opPtrI << 1) + 0;
258 }
259 inline
260 Uint32
setUnlocked(Uint32 hashValue,Uint32 scanBits)261 ElementHeader::setUnlocked(Uint32 hashValue, Uint32 scanBits){
262 return (hashValue << 16) + (scanBits << 1) + 1;
263 }
264
265 inline
266 Uint32
setScanBit(Uint32 header,Uint32 scanBit)267 ElementHeader::setScanBit(Uint32 header, Uint32 scanBit){
268 assert(getUnlocked(header));
269 return header | (scanBit << 1);
270 }
271
272 inline
273 Uint32
clearScanBit(Uint32 header,Uint32 scanBit)274 ElementHeader::clearScanBit(Uint32 header, Uint32 scanBit){
275 assert(getUnlocked(header));
276 return header & (~(scanBit << 1));
277 }
278
279
280 class Dbacc: public SimulatedBlock {
281 friend class DbaccProxy;
282
283 public:
284 // State values
285 enum State {
286 FREEFRAG = 0,
287 ACTIVEFRAG = 1,
288 //SEND_QUE_OP = 2,
289 WAIT_NOTHING = 10,
290 WAIT_ONE_CONF = 26,
291 FREE_OP = 30,
292 WAIT_EXE_OP = 32,
293 WAIT_IN_QUEUE = 34,
294 EXE_OP = 35,
295 SCAN_ACTIVE = 36,
296 SCAN_WAIT_IN_QUEUE = 37,
297 IDLE = 39,
298 ACTIVE = 40,
299 WAIT_COMMIT_ABORT = 41,
300 ABORT = 42,
301 ABORTADDFRAG = 43,
302 REFUSEADDFRAG = 44,
303 DELETEFRAG = 45,
304 DELETETABLE = 46,
305 UNDEFINEDROOT = 47,
306 ADDFIRSTFRAG = 48,
307 ADDSECONDFRAG = 49,
308 DELETEFIRSTFRAG = 50,
309 DELETESECONDFRAG = 51,
310 ACTIVEROOT = 52
311 };
312
313 // Records
314
315 /* --------------------------------------------------------------------------------- */
316 /* DIRECTORY RANGE */
317 /* --------------------------------------------------------------------------------- */
318 struct DirRange {
319 Uint32 dirArray[256];
320 }; /* p2c: size = 1024 bytes */
321
322 typedef Ptr<DirRange> DirRangePtr;
323
324 /* --------------------------------------------------------------------------------- */
325 /* DIRECTORYARRAY */
326 /* --------------------------------------------------------------------------------- */
327 struct Directoryarray {
328 Uint32 pagep[256];
329 }; /* p2c: size = 1024 bytes */
330
331 typedef Ptr<Directoryarray> DirectoryarrayPtr;
332
333 /* --------------------------------------------------------------------------------- */
334 /* FRAGMENTREC. ALL INFORMATION ABOUT FRAMENT AND HASH TABLE IS SAVED IN FRAGMENT */
335 /* REC A POINTER TO FRAGMENT RECORD IS SAVED IN ROOTFRAGMENTREC FRAGMENT */
336 /* --------------------------------------------------------------------------------- */
337 struct Fragmentrec {
338 Uint32 scan[MAX_PARALLEL_SCANS_PER_FRAG];
339 union {
340 Uint32 mytabptr;
341 Uint32 myTableId;
342 };
343 union {
344 Uint32 fragmentid;
345 Uint32 myfid;
346 };
347 Uint32 roothashcheck;
348 Uint32 noOfElements;
349 Uint32 m_commit_count;
350 State rootState;
351
352 //-----------------------------------------------------------------------------
353 // These variables keep track of allocated pages, the number of them and the
354 // start file page of them. Used during local checkpoints.
355 //-----------------------------------------------------------------------------
356 Uint32 datapages[8];
357 Uint32 activeDataPage;
358
359 //-----------------------------------------------------------------------------
360 // Temporary variables used during shrink and expand process.
361 //-----------------------------------------------------------------------------
362 Uint32 expReceivePageptr;
363 Uint32 expReceiveIndex;
364 Uint32 expReceiveForward;
365 Uint32 expSenderDirIndex;
366 Uint32 expSenderDirptr;
367 Uint32 expSenderIndex;
368 Uint32 expSenderPageptr;
369
370 //-----------------------------------------------------------------------------
371 // List of lock owners and list of lock waiters to support LCP handling
372 //-----------------------------------------------------------------------------
373 Uint32 lockOwnersList;
374
375 //-----------------------------------------------------------------------------
376 // References to Directory Ranges (which in turn references directories, which
377 // in its turn references the pages) for the bucket pages and the overflow
378 // bucket pages.
379 //-----------------------------------------------------------------------------
380 Uint32 directory;
381 Uint32 dirsize;
382 Uint32 overflowdir;
383 Uint32 lastOverIndex;
384
385 //-----------------------------------------------------------------------------
386 // We have a list of overflow pages with free areas. We have a special record,
387 // the overflow record representing these pages. The reason is that the
388 // same record is also used to represent pages in the directory array that have
389 // been released since they were empty (there were however higher indexes with
390 // data in them). These are put in the firstFreeDirIndexRec-list.
391 // An overflow record representing a page can only be in one of these lists.
392 //-----------------------------------------------------------------------------
393 Uint32 firstOverflowRec;
394 Uint32 lastOverflowRec;
395 Uint32 firstFreeDirindexRec;
396
397 //-----------------------------------------------------------------------------
398 // Counter keeping track of how many times we have expanded. We need to ensure
399 // that we do not shrink so many times that this variable becomes negative.
400 //-----------------------------------------------------------------------------
401 Uint32 expandCounter;
402
403 //-----------------------------------------------------------------------------
404 // These variables are important for the linear hashing algorithm.
405 // localkeylen is the size of the local key (1 and 2 is currently supported)
406 // maxloadfactor is the factor specifying when to expand
407 // minloadfactor is the factor specifying when to shrink (hysteresis model)
408 // maxp and p
409 // maxp and p is the variables most central to linear hashing. p + maxp + 1 is the
410 // current number of buckets. maxp is the largest value of the type 2**n - 1
411 // which is smaller than the number of buckets. These values are used to find
412 // correct bucket with the aid of the hash value.
413 //
414 // slack is the variable keeping track of whether we have inserted more than
415 // the current size is suitable for or less. Slack together with the boundaries
416 // set by maxloadfactor and minloadfactor decides when to expand/shrink
417 // slackCheck When slack goes over this value it is time to expand.
418 // slackCheck = (maxp + p + 1)*(maxloadfactor - minloadfactor) or
419 // bucketSize * hysteresis
420 //-----------------------------------------------------------------------------
421 Uint32 localkeylen;
422 Uint32 maxp;
423 Uint32 maxloadfactor;
424 Uint32 minloadfactor;
425 Uint32 p;
426 Uint32 slack;
427 Uint32 slackCheck;
428
429 //-----------------------------------------------------------------------------
430 // nextfreefrag is the next free fragment if linked into a free list
431 //-----------------------------------------------------------------------------
432 Uint32 nextfreefrag;
433
434 //-----------------------------------------------------------------------------
435 // This variable is used during restore to keep track of page id of read pages.
436 // During read of bucket pages this is used to calculate the page id and also
437 // to verify that the page id of the read page is correct. During read of over-
438 // flow pages it is only used to keep track of the number of pages read.
439 //-----------------------------------------------------------------------------
440 Uint32 nextAllocPage;
441
442 //-----------------------------------------------------------------------------
443 // Number of pages read from file during restore
444 //-----------------------------------------------------------------------------
445 Uint32 noOfExpectedPages;
446
447 //-----------------------------------------------------------------------------
448 // Fragment State, mostly applicable during LCP and restore
449 //-----------------------------------------------------------------------------
450 State fragState;
451
452 //-----------------------------------------------------------------------------
453 // elementLength: Length of element in bucket and overflow pages
454 // keyLength: Length of key
455 //-----------------------------------------------------------------------------
456 Uint8 elementLength;
457 Uint16 keyLength;
458
459 //-----------------------------------------------------------------------------
460 // This flag is used to avoid sending a big number of expand or shrink signals
461 // when simultaneously committing many inserts or deletes.
462 //-----------------------------------------------------------------------------
463 Uint8 expandFlag;
464
465 //-----------------------------------------------------------------------------
466 // hashcheckbit is the bit to check whether to send element to split bucket or not
467 // k (== 6) is the number of buckets per page
468 // lhfragbits is the number of bits used to calculate the fragment id
469 // lhdirbits is the number of bits used to calculate the page id
470 //-----------------------------------------------------------------------------
471 Uint8 hashcheckbit;
472 Uint8 k;
473 Uint8 lhfragbits;
474 Uint8 lhdirbits;
475
476 //-----------------------------------------------------------------------------
477 // nodetype can only be STORED in this release. Is currently only set, never read
478 //-----------------------------------------------------------------------------
479 Uint8 nodetype;
480
481 //-----------------------------------------------------------------------------
482 // flag to avoid accessing table record if no char attributes
483 //-----------------------------------------------------------------------------
484 Uint8 hasCharAttr;
485
486 //-----------------------------------------------------------------------------
487 // flag to mark that execEXPANDCHECK2 has failed due to DirRange full
488 //-----------------------------------------------------------------------------
489 Uint8 dirRangeFull;
490 };
491
492 typedef Ptr<Fragmentrec> FragmentrecPtr;
493
494 /* --------------------------------------------------------------------------------- */
495 /* OPERATIONREC */
496 /* --------------------------------------------------------------------------------- */
497 struct Operationrec {
498 Uint32 m_op_bits;
499 Uint32 localdata[2];
500 Uint32 elementIsforward;
501 Uint32 elementPage;
502 Uint32 elementPointer;
503 Uint32 fid;
504 Uint32 fragptr;
505 Uint32 hashvaluePart;
506 Uint32 hashValue;
507 Uint32 nextLockOwnerOp;
508 Uint32 nextOp;
509 Uint32 nextParallelQue;
510 union {
511 Uint32 nextSerialQue;
512 Uint32 m_lock_owner_ptr_i; // if nextParallelQue = RNIL, else undefined
513 };
514 Uint32 prevOp;
515 Uint32 prevLockOwnerOp;
516 union {
517 Uint32 prevParallelQue;
518 Uint32 m_lo_last_parallel_op_ptr_i;
519 };
520 union {
521 Uint32 prevSerialQue;
522 Uint32 m_lo_last_serial_op_ptr_i;
523 };
524 Uint32 scanRecPtr;
525 Uint32 transId1;
526 Uint32 transId2;
527 Uint32 userptr;
528 Uint16 elementContainer;
529 Uint16 tupkeylen;
530 Uint32 xfrmtupkeylen;
531 Uint32 userblockref;
532 Uint32 scanBits;
533
534 enum OpBits {
535 OP_MASK = 0x0000F // 4 bits for operation type
536 ,OP_LOCK_MODE = 0x00010 // 0 - shared lock, 1 = exclusive lock
537 ,OP_ACC_LOCK_MODE = 0x00020 // Or:de lock mode of all operation
538 // before me
539 ,OP_LOCK_OWNER = 0x00040
540 ,OP_RUN_QUEUE = 0x00080 // In parallell queue of lock owner
541 ,OP_DIRTY_READ = 0x00100
542 ,OP_LOCK_REQ = 0x00200 // isAccLockReq
543 ,OP_COMMIT_DELETE_CHECK = 0x00400
544 ,OP_INSERT_IS_DONE = 0x00800
545 ,OP_ELEMENT_DISAPPEARED = 0x01000
546
547 ,OP_STATE_MASK = 0xF0000
548 ,OP_STATE_IDLE = 0xF0000
549 ,OP_STATE_WAITING = 0x00000
550 ,OP_STATE_RUNNING = 0x10000
551 ,OP_STATE_EXECUTED = 0x30000
552
553 ,OP_EXECUTED_DIRTY_READ = 0x3050F
554 ,OP_INITIAL = ~(Uint32)0
555 };
556
OperationrecDbacc::Operationrec557 Operationrec() {}
is_same_transDbacc::Operationrec558 bool is_same_trans(const Operationrec* op) const {
559 return
560 transId1 == op->transId1 && transId2 == op->transId2;
561 }
562
563 }; /* p2c: size = 168 bytes */
564
565 typedef Ptr<Operationrec> OperationrecPtr;
566
567 /* --------------------------------------------------------------------------------- */
568 /* OVERFLOW_RECORD */
569 /* --------------------------------------------------------------------------------- */
570 struct OverflowRecord {
571 Uint32 dirindex;
572 Uint32 nextOverRec;
573 Uint32 nextOverList;
574 Uint32 prevOverRec;
575 Uint32 prevOverList;
576 Uint32 overpage;
577 Uint32 nextfreeoverrec;
578 };
579
580 typedef Ptr<OverflowRecord> OverflowRecordPtr;
581
582 /* --------------------------------------------------------------------------------- */
583 /* PAGE8 */
584 /* --------------------------------------------------------------------------------- */
585 struct Page8 {
586 Uint32 word32[2048];
587 }; /* p2c: size = 8192 bytes */
588
589 typedef Ptr<Page8> Page8Ptr;
590
591 /* --------------------------------------------------------------------------------- */
592 /* SCAN_REC */
593 /* --------------------------------------------------------------------------------- */
594 struct ScanRec {
595 enum ScanState {
596 WAIT_NEXT,
597 SCAN_DISCONNECT
598 };
599 enum ScanBucketState {
600 FIRST_LAP,
601 SECOND_LAP,
602 SCAN_COMPLETED
603 };
604 Uint32 activeLocalFrag;
605 Uint32 nextBucketIndex;
606 Uint32 scanNextfreerec;
607 Uint32 scanFirstActiveOp;
608 Uint32 scanFirstLockedOp;
609 Uint32 scanLastLockedOp;
610 Uint32 scanFirstQueuedOp;
611 Uint32 scanLastQueuedOp;
612 Uint32 scanUserptr;
613 Uint32 scanTrid1;
614 Uint32 scanTrid2;
615 Uint32 startNoOfBuckets;
616 Uint32 minBucketIndexToRescan;
617 Uint32 maxBucketIndexToRescan;
618 Uint32 scanOpsAllocated;
619 ScanBucketState scanBucketState;
620 ScanState scanState;
621 Uint16 scanLockHeld;
622 Uint32 scanUserblockref;
623 Uint32 scanMask;
624 Uint8 scanLockMode;
625 Uint8 scanReadCommittedFlag;
626 };
627
628 typedef Ptr<ScanRec> ScanRecPtr;
629
630
631 /* --------------------------------------------------------------------------------- */
632 /* TABREC */
633 /* --------------------------------------------------------------------------------- */
634 struct Tabrec {
635 Uint32 fragholder[MAX_FRAG_PER_NODE];
636 Uint32 fragptrholder[MAX_FRAG_PER_NODE];
637 Uint32 tabUserPtr;
638 BlockReference tabUserRef;
639 Uint32 tabUserGsn;
640 };
641 typedef Ptr<Tabrec> TabrecPtr;
642
643 public:
644 Dbacc(Block_context&, Uint32 instanceNumber = 0);
645 virtual ~Dbacc();
646
647 // pointer to TUP instance in this thread
648 class Dbtup* c_tup;
649 class Dblqh* c_lqh;
650
651 void execACCMINUPDATE(Signal* signal);
652 void removerow(Uint32 op, const Local_key*);
653
654 private:
655 BLOCK_DEFINES(Dbacc);
656
657 // Transit signals
658 void execDEBUG_SIG(Signal* signal);
659 void execCONTINUEB(Signal* signal);
660 void execACC_CHECK_SCAN(Signal* signal);
661 void execEXPANDCHECK2(Signal* signal);
662 void execSHRINKCHECK2(Signal* signal);
663 void execACC_OVER_REC(Signal* signal);
664 void execNEXTOPERATION(Signal* signal);
665 void execREAD_PSEUDO_REQ(Signal* signal);
666
667 // Received signals
668 void execSTTOR(Signal* signal);
669 void execACCKEYREQ(Signal* signal);
670 void execACCSEIZEREQ(Signal* signal);
671 void execACCFRAGREQ(Signal* signal);
672 void execNEXT_SCANREQ(Signal* signal);
673 void execACC_ABORTREQ(Signal* signal);
674 void execACC_SCANREQ(Signal* signal);
675 void execACC_COMMITREQ(Signal* signal);
676 void execACC_TO_REQ(Signal* signal);
677 void execACC_LOCKREQ(Signal* signal);
678 void execNDB_STTOR(Signal* signal);
679 void execDROP_TAB_REQ(Signal* signal);
680 void execREAD_CONFIG_REQ(Signal* signal);
681 void execDUMP_STATE_ORD(Signal* signal);
682
683 void execDROP_FRAG_REQ(Signal*);
684
685 void execDBINFO_SCANREQ(Signal *signal);
686
687 // Statement blocks
688 void ACCKEY_error(Uint32 fromWhere);
689
690 void commitDeleteCheck();
691 void report_dealloc(Signal* signal, const Operationrec* opPtrP);
692
693 typedef void * RootfragmentrecPtr;
694 void initRootFragPageZero(FragmentrecPtr, Page8Ptr);
695 void initFragAdd(Signal*, FragmentrecPtr);
696 void initFragPageZero(FragmentrecPtr, Page8Ptr);
697 void initFragGeneral(FragmentrecPtr);
698 void verifyFragCorrect(FragmentrecPtr regFragPtr);
699 void releaseFragResources(Signal* signal, Uint32 fragIndex);
700 void releaseRootFragRecord(Signal* signal, RootfragmentrecPtr rootPtr);
701 void releaseRootFragResources(Signal* signal, Uint32 tableId);
702 void releaseDirResources(Signal* signal,
703 Uint32 fragIndex,
704 Uint32 dirIndex,
705 Uint32 startIndex);
706 void releaseDirectoryResources(Signal* signal,
707 Uint32 fragIndex,
708 Uint32 dirIndex,
709 Uint32 startIndex,
710 Uint32 directoryIndex);
711 void releaseOverflowResources(Signal* signal, FragmentrecPtr regFragPtr);
712 void releaseDirIndexResources(Signal* signal, FragmentrecPtr regFragPtr);
713 void releaseFragRecord(Signal* signal, FragmentrecPtr regFragPtr);
714 void initScanFragmentPart(Signal* signal);
715 Uint32 checkScanExpand(Signal* signal);
716 Uint32 checkScanShrink(Signal* signal);
717 void initialiseDirRec(Signal* signal);
718 void initialiseDirRangeRec(Signal* signal);
719 void initialiseFragRec(Signal* signal);
720 void initialiseFsConnectionRec(Signal* signal);
721 void initialiseFsOpRec(Signal* signal);
722 void initialiseOperationRec(Signal* signal);
723 void initialiseOverflowRec(Signal* signal);
724 void initialisePageRec(Signal* signal);
725 void initialiseRootfragRec(Signal* signal);
726 void initialiseScanRec(Signal* signal);
727 void initialiseTableRec(Signal* signal);
728 bool addfragtotab(Signal* signal, Uint32 rootIndex, Uint32 fragId);
729 void initOpRec(Signal* signal);
730 void sendAcckeyconf(Signal* signal);
731 Uint32 getNoParallelTransaction(const Operationrec*);
732
733 #ifdef VM_TRACE
734 Uint32 getNoParallelTransactionFull(const Operationrec*);
735 #endif
736 #ifdef ACC_SAFE_QUEUE
737 bool validate_lock_queue(OperationrecPtr opPtr);
738 Uint32 get_parallel_head(OperationrecPtr opPtr);
739 void dump_lock_queue(OperationrecPtr loPtr);
740 #else
validate_lock_queue(OperationrecPtr)741 bool validate_lock_queue(OperationrecPtr) { return true;}
742 #endif
743
744 public:
745 void execACCKEY_ORD(Signal* signal, Uint32 opPtrI);
746 void startNext(Signal* signal, OperationrecPtr lastOp);
747
748 private:
749 Uint32 placeReadInLockQueue(OperationrecPtr lockOwnerPtr);
750 Uint32 placeWriteInLockQueue(OperationrecPtr lockOwnerPtr);
751 void placeSerialQueue(OperationrecPtr lockOwner, OperationrecPtr op);
752 void abortSerieQueueOperation(Signal* signal, OperationrecPtr op);
753 void abortParallelQueueOperation(Signal* signal, OperationrecPtr op);
754
755 void expandcontainer(Signal* signal);
756 void shrinkcontainer(Signal* signal);
757 void nextcontainerinfoExp(Signal* signal);
758 void releaseAndCommitActiveOps(Signal* signal);
759 void releaseAndCommitQueuedOps(Signal* signal);
760 void releaseAndAbortLockedOps(Signal* signal);
761 void containerinfo(Signal* signal);
762 bool getScanElement(Signal* signal);
763 void initScanOpRec(Signal* signal);
764 void nextcontainerinfo(Signal* signal);
765 void putActiveScanOp(Signal* signal);
766 void putOpScanLockQue();
767 void putReadyScanQueue(Signal* signal, Uint32 scanRecIndex);
768 void releaseScanBucket(Signal* signal);
769 void releaseScanContainer(Signal* signal);
770 void releaseScanRec(Signal* signal);
771 bool searchScanContainer(Signal* signal);
772 void sendNextScanConf(Signal* signal);
773 void setlock(Signal* signal);
774 void takeOutActiveScanOp(Signal* signal);
775 void takeOutScanLockQueue(Uint32 scanRecIndex);
776 void takeOutReadyScanQueue(Signal* signal);
777 void insertElement(Signal* signal);
778 void insertContainer(Signal* signal);
779 void addnewcontainer(Signal* signal);
780 void getfreelist(Signal* signal);
781 void increaselistcont(Signal* signal);
782 void seizeLeftlist(Signal* signal);
783 void seizeRightlist(Signal* signal);
784 Uint32 readTablePk(Uint32 lkey1, Uint32 lkey2, Uint32 eh, OperationrecPtr);
785 Uint32 getElement(Signal* signal, OperationrecPtr& lockOwner);
786 void getdirindex(Signal* signal);
787 void commitdelete(Signal* signal);
788 void deleteElement(Signal* signal);
789 void getLastAndRemove(Signal* signal);
790 void releaseLeftlist(Signal* signal);
791 void releaseRightlist(Signal* signal);
792 void checkoverfreelist(Signal* signal);
793 void abortOperation(Signal* signal);
794 void commitOperation(Signal* signal);
795 void copyOpInfo(OperationrecPtr dst, OperationrecPtr src);
796 Uint32 executeNextOperation(Signal* signal);
797 void releaselock(Signal* signal);
798 void release_lockowner(Signal* signal, OperationrecPtr, bool commit);
799 void startNew(Signal* signal, OperationrecPtr newOwner);
800 void abortWaitingOperation(Signal*, OperationrecPtr);
801 void abortExecutedOperation(Signal*, OperationrecPtr);
802
803 void takeOutFragWaitQue(Signal* signal);
804 void check_lock_upgrade(Signal* signal, OperationrecPtr release_op, bool lo);
805 void check_lock_upgrade(Signal* signal, OperationrecPtr lock_owner,
806 OperationrecPtr release_op);
807 void allocOverflowPage(Signal* signal);
808 bool getfragmentrec(Signal* signal, FragmentrecPtr&, Uint32 fragId);
809 void insertLockOwnersList(Signal* signal, const OperationrecPtr&);
810 void takeOutLockOwnersList(Signal* signal, const OperationrecPtr&);
811
812 void initFsOpRec(Signal* signal);
813 void initOverpage(Signal* signal);
814 void initPage(Signal* signal);
815 void initRootfragrec(Signal* signal);
816 void putOpInFragWaitQue(Signal* signal);
817 void putOverflowRecInFrag(Signal* signal);
818 void putRecInFreeOverdir(Signal* signal);
819 void releaseDirectory(Signal* signal);
820 void releaseDirrange(Signal* signal);
821 void releaseFsConnRec(Signal* signal);
822 void releaseFsOpRec(Signal* signal);
823 void releaseOpRec(Signal* signal);
824 void releaseOverflowRec(Signal* signal);
825 void releaseOverpage(Signal* signal);
826 void releasePage(Signal* signal);
827 void releaseLogicalPage(Fragmentrec * fragP, Uint32 logicalPageId);
828 void seizeDirectory(Signal* signal);
829 void seizeDirrange(Signal* signal);
830 void seizeFragrec(Signal* signal);
831 void seizeFsConnectRec(Signal* signal);
832 void seizeFsOpRec(Signal* signal);
833 void seizeOpRec(Signal* signal);
834 void seizeOverRec(Signal* signal);
835 void seizePage(Signal* signal);
836 void seizeRootfragrec(Signal* signal);
837 void seizeScanRec(Signal* signal);
838 void sendSystemerror(Signal* signal, int line);
839 void takeRecOutOfFreeOverdir(Signal* signal);
840 void takeRecOutOfFreeOverpage(Signal* signal);
841
842 void addFragRefuse(Signal* signal, Uint32 errorCode);
843 void ndbsttorryLab(Signal* signal);
844 void acckeyref1Lab(Signal* signal, Uint32 result_code);
845 void insertelementLab(Signal* signal);
846 void checkNextFragmentLab(Signal* signal);
847 void endofexpLab(Signal* signal);
848 void endofshrinkbucketLab(Signal* signal);
849 void senddatapagesLab(Signal* signal);
850 void sttorrysignalLab(Signal* signal);
851 void sendholdconfsignalLab(Signal* signal);
852 void accIsLockedLab(Signal* signal, OperationrecPtr lockOwnerPtr);
853 void insertExistElemLab(Signal* signal, OperationrecPtr lockOwnerPtr);
854 void refaccConnectLab(Signal* signal);
855 void releaseScanLab(Signal* signal);
856 void ndbrestart1Lab(Signal* signal);
857 void initialiseRecordsLab(Signal* signal, Uint32 ref, Uint32 data);
858 void checkNextBucketLab(Signal* signal);
859 void storeDataPageInDirectoryLab(Signal* signal);
860
861 void zpagesize_error(const char* where);
862
863 void reenable_expand_after_redo_log_exection_complete(Signal*);
864
865 // charsets
866 void xfrmKeyData(Signal* signal);
867
868 // Initialisation
869 void initData();
870 void initRecords();
871
872 #ifdef VM_TRACE
873 void debug_lh_vars(const char* where);
874 #else
debug_lh_vars(const char * where)875 void debug_lh_vars(const char* where) {}
876 #endif
877
878 // Variables
879 /* --------------------------------------------------------------------------------- */
880 /* DIRECTORY RANGE */
881 /* --------------------------------------------------------------------------------- */
882 DirRange *dirRange;
883 DirRangePtr expDirRangePtr;
884 DirRangePtr gnsDirRangePtr;
885 DirRangePtr newDirRangePtr;
886 DirRangePtr rdDirRangePtr;
887 DirRangePtr nciOverflowrangeptr;
888 Uint32 cdirrangesize;
889 Uint32 cfirstfreeDirrange;
890 /* --------------------------------------------------------------------------------- */
891 /* DIRECTORYARRAY */
892 /* --------------------------------------------------------------------------------- */
893 Directoryarray *directoryarray;
894 DirectoryarrayPtr expDirptr;
895 DirectoryarrayPtr rdDirptr;
896 DirectoryarrayPtr sdDirptr;
897 DirectoryarrayPtr nciOverflowDirptr;
898 Uint32 cdirarraysize;
899 Uint32 cdirmemory;
900 Uint32 cfirstfreedir;
901 /* --------------------------------------------------------------------------------- */
902 /* FRAGMENTREC. ALL INFORMATION ABOUT FRAMENT AND HASH TABLE IS SAVED IN FRAGMENT */
903 /* REC A POINTER TO FRAGMENT RECORD IS SAVED IN ROOTFRAGMENTREC FRAGMENT */
904 /* --------------------------------------------------------------------------------- */
905 Fragmentrec *fragmentrec;
906 FragmentrecPtr fragrecptr;
907 Uint32 cfirstfreefrag;
908 Uint32 cfragmentsize;
909 RSS_OP_COUNTER(cnoOfFreeFragrec);
910 RSS_OP_SNAPSHOT(cnoOfFreeFragrec);
911
912
913 /* --------------------------------------------------------------------------------- */
914 /* FS_CONNECTREC */
915 /* --------------------------------------------------------------------------------- */
916 /* OPERATIONREC */
917 /* --------------------------------------------------------------------------------- */
918 Operationrec *operationrec;
919 OperationrecPtr operationRecPtr;
920 OperationrecPtr idrOperationRecPtr;
921 OperationrecPtr mlpqOperPtr;
922 OperationrecPtr queOperPtr;
923 OperationrecPtr readWriteOpPtr;
924 Uint32 cfreeopRec;
925 Uint32 coprecsize;
926 /* --------------------------------------------------------------------------------- */
927 /* OVERFLOW_RECORD */
928 /* --------------------------------------------------------------------------------- */
929 OverflowRecord *overflowRecord;
930 OverflowRecordPtr iopOverflowRecPtr;
931 OverflowRecordPtr tfoOverflowRecPtr;
932 OverflowRecordPtr porOverflowRecPtr;
933 OverflowRecordPtr priOverflowRecPtr;
934 OverflowRecordPtr rorOverflowRecPtr;
935 OverflowRecordPtr sorOverflowRecPtr;
936 OverflowRecordPtr troOverflowRecPtr;
937 Uint32 cfirstfreeoverrec;
938 Uint32 coverflowrecsize;
939
940 /* --------------------------------------------------------------------------------- */
941 /* PAGE8 */
942 /* --------------------------------------------------------------------------------- */
943 Page8 *page8;
944 /* 8 KB PAGE */
945 Page8Ptr ancPageptr;
946 Page8Ptr colPageptr;
947 Page8Ptr ccoPageptr;
948 Page8Ptr datapageptr;
949 Page8Ptr delPageptr;
950 Page8Ptr excPageptr;
951 Page8Ptr expPageptr;
952 Page8Ptr gdiPageptr;
953 Page8Ptr gePageptr;
954 Page8Ptr gflPageptr;
955 Page8Ptr idrPageptr;
956 Page8Ptr ilcPageptr;
957 Page8Ptr inpPageptr;
958 Page8Ptr iopPageptr;
959 Page8Ptr lastPageptr;
960 Page8Ptr lastPrevpageptr;
961 Page8Ptr lcnPageptr;
962 Page8Ptr lcnCopyPageptr;
963 Page8Ptr lupPageptr;
964 Page8Ptr ciPageidptr;
965 Page8Ptr gsePageidptr;
966 Page8Ptr isoPageptr;
967 Page8Ptr nciPageidptr;
968 Page8Ptr rsbPageidptr;
969 Page8Ptr rscPageidptr;
970 Page8Ptr slPageidptr;
971 Page8Ptr sscPageidptr;
972 Page8Ptr rlPageptr;
973 Page8Ptr rlpPageptr;
974 Page8Ptr ropPageptr;
975 Page8Ptr rpPageptr;
976 Page8Ptr slPageptr;
977 Page8Ptr spPageptr;
978 Uint32 cfirstfreepage;
979 Uint32 cpagesize;
980 Uint32 cpageCount;
981 Uint32 cnoOfAllocatedPages;
982 Uint32 cnoOfAllocatedPagesMax;
983 /* --------------------------------------------------------------------------------- */
984 /* ROOTFRAGMENTREC */
985 /* DURING EXPAND FRAGMENT PROCESS, EACH FRAGMEND WILL BE EXPAND INTO TWO */
986 /* NEW FRAGMENTS.TO MAKE THIS PROCESS EASIER, DURING ADD FRAGMENT PROCESS */
987 /* NEXT FRAGMENT IDENTIIES WILL BE CALCULATED, AND TWO FRAGMENTS WILL BE */
988 /* ADDED IN (NDBACC). THEREBY EXPAND OF FRAGMENT CAN BE PERFORMED QUICK AND */
989 /* EASY.THE NEW FRAGMENT ID SENDS TO TUP MANAGER FOR ALL OPERATION PROCESS. */
990 /* --------------------------------------------------------------------------------- */
991 /* --------------------------------------------------------------------------------- */
992 /* SCAN_REC */
993 /* --------------------------------------------------------------------------------- */
994 ScanRec *scanRec;
995 ScanRecPtr scanPtr;
996 Uint32 cscanRecSize;
997 Uint32 cfirstFreeScanRec;
998 /* --------------------------------------------------------------------------------- */
999 /* TABREC */
1000 /* --------------------------------------------------------------------------------- */
1001 Tabrec *tabrec;
1002 TabrecPtr tabptr;
1003 Uint32 ctablesize;
1004 Uint32 tgseElementptr;
1005 Uint32 tgseContainerptr;
1006 Uint32 trlHead;
1007 Uint32 trlRelCon;
1008 Uint32 trlNextused;
1009 Uint32 trlPrevused;
1010 Uint32 tlcnChecksum;
1011 Uint32 tlupElemIndex;
1012 Uint32 tlupIndex;
1013 Uint32 tlupForward;
1014 Uint32 tancNext;
1015 Uint32 tancBufType;
1016 Uint32 tancContainerptr;
1017 Uint32 tancPageindex;
1018 Uint32 tancPageid;
1019 Uint32 tidrResult;
1020 Uint32 tidrElemhead;
1021 Uint32 tidrForward;
1022 Uint32 tidrPageindex;
1023 Uint32 tidrContainerptr;
1024 Uint32 tidrContainerhead;
1025 Uint32 tlastForward;
1026 Uint32 tlastPageindex;
1027 Uint32 tlastContainerlen;
1028 Uint32 tlastElementptr;
1029 Uint32 tlastContainerptr;
1030 Uint32 tlastContainerhead;
1031 Uint32 trlPageindex;
1032 Uint32 tdelContainerptr;
1033 Uint32 tdelElementptr;
1034 Uint32 tdelForward;
1035 Uint32 tiopPageId;
1036 Uint32 tipPageId;
1037 Uint32 tgeContainerptr;
1038 Uint32 tgeElementptr;
1039 Uint32 tgeForward;
1040 Uint32 texpReceivedBucket;
1041 Uint32 texpDirInd;
1042 Uint32 texpDirRangeIndex;
1043 Uint32 texpDirPageIndex;
1044 Uint32 tdata0;
1045 Uint32 tcheckpointid;
1046 Uint32 tciContainerptr;
1047 Uint32 tnciContainerptr;
1048 Uint32 tisoContainerptr;
1049 Uint32 trscContainerptr;
1050 Uint32 tsscContainerptr;
1051 Uint32 tciContainerlen;
1052 Uint32 trscContainerlen;
1053 Uint32 tsscContainerlen;
1054 Uint32 tciContainerhead;
1055 Uint32 tnciContainerhead;
1056 Uint32 tslElementptr;
1057 Uint32 tisoElementptr;
1058 Uint32 tsscElementptr;
1059 Uint32 tfid;
1060 Uint32 tscanFlag;
1061 Uint32 tgflBufType;
1062 Uint32 tgseIsforward;
1063 Uint32 tsscIsforward;
1064 Uint32 trscIsforward;
1065 Uint32 tciIsforward;
1066 Uint32 tnciIsforward;
1067 Uint32 tisoIsforward;
1068 Uint32 tgseIsLocked;
1069 Uint32 tsscIsLocked;
1070 Uint32 tkeylen;
1071 Uint32 tmp;
1072 Uint32 tmpP;
1073 Uint32 tmpP2;
1074 Uint32 tmp1;
1075 Uint32 tmp2;
1076 Uint32 tgflPageindex;
1077 Uint32 tmpindex;
1078 Uint32 tslNextfree;
1079 Uint32 tslPageindex;
1080 Uint32 tgsePageindex;
1081 Uint32 tnciNextSamePage;
1082 Uint32 tslPrevfree;
1083 Uint32 tciPageindex;
1084 Uint32 trsbPageindex;
1085 Uint32 tnciPageindex;
1086 Uint32 tlastPrevconptr;
1087 Uint32 tresult;
1088 Uint32 tslUpdateHeader;
1089 Uint32 tuserptr;
1090 BlockReference tuserblockref;
1091 Uint32 tlqhPointer;
1092 Uint32 tholdSentOp;
1093 Uint32 tholdMore;
1094 Uint32 tgdiPageindex;
1095 Uint32 tiopIndex;
1096 Uint32 tnciTmp;
1097 Uint32 tullIndex;
1098 Uint32 turlIndex;
1099 Uint32 tlfrTmp1;
1100 Uint32 tlfrTmp2;
1101 Uint32 tscanTrid1;
1102 Uint32 tscanTrid2;
1103
1104 Uint32 ctest;
1105 Uint32 clqhPtr;
1106 BlockReference clqhBlockRef;
1107 Uint32 cminusOne;
1108 NodeId cmynodeid;
1109 BlockReference cownBlockref;
1110 BlockReference cndbcntrRef;
1111 Uint16 csignalkey;
1112 Uint32 czero;
1113 Uint32 cexcForward;
1114 Uint32 cexcPageindex;
1115 Uint32 cexcContainerptr;
1116 Uint32 cexcContainerhead;
1117 Uint32 cexcContainerlen;
1118 Uint32 cexcElementptr;
1119 Uint32 cexcPrevconptr;
1120 Uint32 cexcMovedLen;
1121 Uint32 cexcPrevpageptr;
1122 Uint32 cexcPrevpageindex;
1123 Uint32 cexcPrevforward;
1124 Uint32 clocalkey[32];
1125 union {
1126 Uint32 ckeys[2048 * MAX_XFRM_MULTIPLY];
1127 Uint64 ckeys_align;
1128 };
1129
1130 Uint32 c_errorInsert3000_TableId;
1131 Uint32 c_memusage_report_frequency;
1132 };
1133
1134 #endif
1135