1 /* 2 Copyright (c) 2003, 2010, 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 #ifndef DBTC_H 26 #define DBTC_H 27 28 #include <ndb_limits.h> 29 #include <pc.hpp> 30 #include <SimulatedBlock.hpp> 31 #include <DLHashTable.hpp> 32 #include <SLList.hpp> 33 #include <DLList.hpp> 34 #include <DLFifoList.hpp> 35 #include <DataBuffer.hpp> 36 #include <Bitmask.hpp> 37 #include <AttributeList.hpp> 38 #include <signaldata/AttrInfo.hpp> 39 #include <signaldata/LqhTransConf.hpp> 40 #include <signaldata/LqhKey.hpp> 41 #include <signaldata/TrigAttrInfo.hpp> 42 #include <signaldata/TcIndx.hpp> 43 #include <signaldata/TransIdAI.hpp> 44 #include <signaldata/EventReport.hpp> 45 #include <trigger_definitions.h> 46 #include <SignalCounter.hpp> 47 48 #ifdef DBTC_C 49 /* 50 * 2.2 LOCAL SYMBOLS 51 * ----------------- 52 */ 53 #define Z8NIL 255 54 #define ZAPI_CONNECT_FILESIZE 20 55 #define ZCLOSED 2 56 #define ZCOMMITING 0 /* VALUE FOR TRANSTATUS */ 57 #define ZCOMMIT_SETUP 2 58 #define ZCONTINUE_ABORT_080 4 59 #define ZGCP_FILESIZE 10 60 #define ZINTSPH1 1 61 #define ZINTSPH2 2 62 #define ZINTSPH3 3 63 #define ZINTSPH6 6 64 #define ZLASTPHASE 255 65 #define ZNODEBUF_FILESIZE 2000 66 #define ZNR_OF_SEIZE 10 67 #define ZSCANREC_FILE_SIZE 100 68 #define ZSCAN_FRAGREC_FILE_SIZE 400 69 #define ZSCAN_OPREC_FILE_SIZE 400 70 #define ZSPH1 1 71 #define ZTABREC_FILESIZE 16 72 #define ZTAKE_OVER_ACTIVE 1 73 #define ZTAKE_OVER_IDLE 0 74 #define ZTC_CONNECT_FILESIZE 200 75 #define ZTCOPCONF_SIZE 6 76 77 // ---------------------------------------- 78 // Error Codes for Scan 79 // ---------------------------------------- 80 #define ZNO_CONCURRENCY_ERROR 242 81 #define ZTOO_HIGH_CONCURRENCY_ERROR 244 82 #define ZNO_SCANREC_ERROR 245 83 #define ZNO_FRAGMENT_ERROR 246 84 #define ZSCAN_AI_LEN_ERROR 269 85 #define ZSCAN_LQH_ERROR 270 86 #define ZSCAN_FRAG_LQH_ERROR 274 87 88 #define ZSCANTIME_OUT_ERROR 296 89 #define ZSCANTIME_OUT_ERROR2 297 90 91 // ---------------------------------------- 92 // Error Codes for transactions 93 // ---------------------------------------- 94 #define ZSTATE_ERROR 202 95 #define ZLENGTH_ERROR 207 // Also Scan 96 #define ZERO_KEYLEN_ERROR 208 97 #define ZSIGNAL_ERROR 209 98 #define ZGET_ATTRBUF_ERROR 217 // Also Scan 99 #define ZGET_DATAREC_ERROR 218 100 #define ZMORE_AI_IN_TCKEYREQ_ERROR 220 101 #define ZCOMMITINPROGRESS 230 102 #define ZROLLBACKNOTALLOWED 232 103 #define ZNO_FREE_TC_CONNECTION 233 // Also Scan 104 #define ZABORTINPROGRESS 237 105 #define ZPREPAREINPROGRESS 238 106 #define ZWRONG_SCHEMA_VERSION_ERROR 241 // Also Scan 107 #define ZSCAN_NODE_ERROR 250 108 #define ZTRANS_STATUS_ERROR 253 109 #define ZTIME_OUT_ERROR 266 110 #define ZSIMPLE_READ_WITHOUT_AI 271 111 #define ZNO_AI_WITH_UPDATE 272 112 #define ZSEIZE_API_COPY_ERROR 275 113 #define ZSCANINPROGRESS 276 114 #define ZABORT_ERROR 277 115 #define ZCOMMIT_TYPE_ERROR 278 116 117 #define ZNO_FREE_TC_MARKER 279 118 #define ZNODE_SHUTDOWN_IN_PROGRESS 280 119 #define ZCLUSTER_SHUTDOWN_IN_PROGRESS 281 120 #define ZWRONG_STATE 282 121 #define ZCLUSTER_IN_SINGLEUSER_MODE 299 122 123 #define ZDROP_TABLE_IN_PROGRESS 283 124 #define ZNO_SUCH_TABLE 284 125 #define ZUNKNOWN_TABLE_ERROR 285 126 #define ZNODEFAIL_BEFORE_COMMIT 286 127 #define ZINDEX_CORRUPT_ERROR 287 128 #define ZSCAN_FRAGREC_ERROR 291 129 130 // ---------------------------------------- 131 // Seize error 132 // ---------------------------------------- 133 #define ZNO_FREE_API_CONNECTION 219 134 #define ZSYSTEM_NOT_STARTED_ERROR 203 135 136 // ---------------------------------------- 137 // Release errors 138 // ---------------------------------------- 139 #define ZINVALID_CONNECTION 229 140 141 142 #define ZNOT_FOUND 626 143 #define ZALREADYEXIST 630 144 #define ZNOTUNIQUE 893 145 146 #define ZINVALID_KEY 290 147 #define ZUNLOCKED_IVAL_TOO_HIGH 294 148 #define ZUNLOCKED_OP_HAS_BAD_STATE 295 149 #define ZBAD_DIST_KEY 298 150 #define ZTRANS_TOO_BIG 261 151 #endif 152 153 class Dbtc: public SimulatedBlock { 154 public: 155 156 /** 157 * Incase of mt-TC...only one instance will perform actual take-over 158 * let this be TAKE_OVER_INSTANCE 159 */ 160 STATIC_CONST( TAKE_OVER_INSTANCE = 1 ); 161 162 enum ConnectionState { 163 CS_CONNECTED = 0, 164 CS_DISCONNECTED = 1, 165 CS_STARTED = 2, 166 CS_RECEIVING = 3, 167 CS_PREPARED = 4, 168 CS_START_PREPARING = 5, 169 CS_REC_PREPARING = 6, 170 CS_RESTART = 7, 171 CS_ABORTING = 8, 172 CS_COMPLETING = 9, 173 CS_COMPLETE_SENT = 10, 174 CS_PREPARE_TO_COMMIT = 11, 175 CS_COMMIT_SENT = 12, 176 CS_START_COMMITTING = 13, 177 CS_COMMITTING = 14, 178 CS_REC_COMMITTING = 15, 179 CS_WAIT_ABORT_CONF = 16, 180 CS_WAIT_COMPLETE_CONF = 17, 181 CS_WAIT_COMMIT_CONF = 18, 182 CS_FAIL_ABORTING = 19, 183 CS_FAIL_ABORTED = 20, 184 CS_FAIL_PREPARED = 21, 185 CS_FAIL_COMMITTING = 22, 186 CS_FAIL_COMMITTED = 23, 187 CS_FAIL_COMPLETED = 24, 188 CS_START_SCAN = 25, 189 190 /** 191 * Sending FIRE_TRIG_REQ 192 */ 193 CS_SEND_FIRE_TRIG_REQ = 26, 194 195 /** 196 * Waiting for FIRE_TRIG_CONF/REF (or operations generated by this) 197 */ 198 CS_WAIT_FIRE_TRIG_REQ = 27 199 }; 200 201 enum OperationState { 202 OS_CONNECTED = 1, 203 OS_OPERATING = 2, 204 OS_PREPARED = 3, 205 OS_COMMITTING = 4, 206 OS_COMMITTED = 5, 207 OS_COMPLETING = 6, 208 OS_COMPLETED = 7, 209 OS_RESTART = 8, 210 OS_ABORTING = 9, 211 OS_ABORT_SENT = 10, 212 OS_TAKE_OVER = 11, 213 OS_WAIT_DIH = 12, 214 OS_WAIT_KEYINFO = 13, 215 OS_WAIT_ATTR = 14, 216 OS_WAIT_COMMIT_CONF = 15, 217 OS_WAIT_ABORT_CONF = 16, 218 OS_WAIT_COMPLETE_CONF = 17, 219 OS_WAIT_SCAN = 18, 220 221 OS_FIRE_TRIG_REQ = 19, 222 }; 223 224 enum AbortState { 225 AS_IDLE = 0, 226 AS_ACTIVE = 1 227 }; 228 229 enum HostState { 230 HS_ALIVE = 0, 231 HS_DEAD = 1 232 }; 233 234 enum LqhTransState { 235 LTS_IDLE = 0, 236 LTS_ACTIVE = 1 237 }; 238 239 enum FailState { 240 FS_IDLE = 0, 241 FS_LISTENING = 1, 242 FS_COMPLETING = 2 243 }; 244 245 enum SystemStartState { 246 SSS_TRUE = 0, 247 SSS_FALSE = 1 248 }; 249 250 enum TimeOutCheckState { 251 TOCS_TRUE = 0, 252 TOCS_FALSE = 1 253 }; 254 255 enum ReturnSignal { 256 RS_NO_RETURN = 0, 257 RS_TCKEYCONF = 1, 258 RS_TC_COMMITCONF = 3, 259 RS_TCROLLBACKCONF = 4, 260 RS_TCROLLBACKREP = 5 261 }; 262 263 enum IndexOperationState { 264 IOS_NOOP = 0, 265 IOS_INDEX_ACCESS = 1, 266 IOS_INDEX_ACCESS_WAIT_FOR_TCKEYCONF = 2, 267 IOS_INDEX_ACCESS_WAIT_FOR_TRANSID_AI = 3 268 }; 269 270 enum IndexState { 271 IS_BUILDING = 0, // build in progress, start state at create 272 IS_ONLINE = 1 // ready to use 273 }; 274 275 /* Sub states of IndexOperation while waiting for TransId_AI 276 * from index table lookup 277 */ 278 enum IndexTransIdAIState { 279 ITAS_WAIT_HEADER = 0, // Initial state 280 ITAS_WAIT_FRAGID = 1, // Waiting for fragment id word 281 ITAS_WAIT_KEY = 2, // Waiting for (more) key information 282 ITAS_ALL_RECEIVED = 3, // All TransIdAI info received 283 ITAS_WAIT_KEY_FAIL = 4 // Failed collecting key 284 }; 285 286 287 /**-------------------------------------------------------------------------- 288 * LOCAL SYMBOLS PER 'SYMBOL-VALUED' VARIABLE 289 * 290 * 291 * NSYMB ZAPI_CONNECT_FILESIZE = 20 292 * NSYMB ZTC_CONNECT_FILESIZE = 200 293 * NSYMB ZHOST_FILESIZE = 16 294 * NSYMB ZDATABUF_FILESIZE = 4000 295 * NSYMB ZATTRBUF_FILESIZE = 4000 296 * NSYMB ZGCP_FILESIZE = 10 297 * 298 * 299 * ABORTED CODES 300 * TPHASE NSYMB ZSPH1 = 1 301 * NSYMB ZLASTPHASE = 255 302 * 303 * 304 * LQH_TRANS 305 * NSYMB ZTRANS_ABORTED = 1 306 * NSYMB ZTRANS_PREPARED = 2 307 * NSYMB ZTRANS_COMMITTED = 3 308 * NSYMB ZCOMPLETED_LQH_TRANS = 4 309 * NSYMB ZTRANS_COMPLETED = 5 310 * 311 * 312 * TAKE OVER 313 * NSYMB ZTAKE_OVER_IDLE = 0 314 * NSYMB ZTAKE_OVER_ACTIVE = 1 315 * 316 * ATTRBUF (ATTRBUF_RECORD) 317 * NSYMB ZINBUF_DATA_LEN = 24 318 * NSYMB ZINBUF_NEXTFREE = 25 (NOT USED ) 319 * NSYMB ZINBUF_PREV = 26 320 * NSYMB ZINBUF_NEXT = 27 321 -------------------------------------------------------------------------*/ 322 /* 323 2.3 RECORDS AND FILESIZES 324 ------------------------- 325 */ 326 /* **************************************************************** */ 327 /* ---------------------------------------------------------------- */ 328 /* ------------------- TRIGGER AND INDEX DATA --------------------- */ 329 /* ---------------------------------------------------------------- */ 330 /* **************************************************************** */ 331 /* ********* DEFINED TRIGGER DATA ********* */ 332 /* THIS RECORD FORMS LISTS OF ACTIVE */ 333 /* TRIGGERS FOR EACH TABLE. */ 334 /* THE RECORDS ARE MANAGED BY A TRIGGER */ 335 /* POOL WHERE A TRIGGER RECORD IS SEIZED */ 336 /* WHEN A TRIGGER IS ACTIVATED AND RELEASED */ 337 /* WHEN THE TRIGGER IS DEACTIVATED. */ 338 /* **************************************** */ 339 struct TcDefinedTriggerData { TcDefinedTriggerDataDbtc::TcDefinedTriggerData340 TcDefinedTriggerData() {} 341 /** 342 * Trigger id, used to identify the trigger 343 */ 344 UintR triggerId; 345 346 /** 347 * Trigger type, defines what the trigger is used for 348 */ 349 TriggerType::Value triggerType; 350 351 /** 352 * Trigger type, defines what the trigger is used for 353 */ 354 TriggerEvent::Value triggerEvent; 355 356 /** 357 * Next ptr (used in pool/list) 358 */ 359 union { 360 Uint32 nextPool; 361 Uint32 nextList; 362 }; 363 364 /** 365 * Index id, only used by secondary_index triggers. This is same as 366 * index table id in DICT. 367 **/ 368 union { 369 Uint32 indexId; // For unique index trigger 370 Uint32 tableId; // For reorg trigger 371 }; 372 373 /** 374 * Prev pointer (used in list) 375 */ 376 Uint32 prevList; 377 378 Uint32 oldTriggerIds[2]; // For upgrade :( 379 printDbtc::TcDefinedTriggerData380 inline void print(NdbOut & s) const { 381 s << "[DefinedTriggerData = " << triggerId << "]"; 382 } 383 }; 384 typedef Ptr<TcDefinedTriggerData> DefinedTriggerPtr; 385 386 /** 387 * Pool of trigger data record 388 */ 389 ArrayPool<TcDefinedTriggerData> c_theDefinedTriggerPool; 390 391 /** 392 * The list of active triggers 393 */ 394 DLList<TcDefinedTriggerData> c_theDefinedTriggers; 395 396 typedef DataBuffer<11> AttributeBuffer; 397 398 AttributeBuffer::DataBufferPool c_theAttributeBufferPool; 399 400 UintR c_transactionBufferSpace; 401 402 403 /* ********** FIRED TRIGGER DATA ********** */ 404 /* THIS RECORD FORMS LISTS OF FIRED */ 405 /* TRIGGERS FOR A TRANSACTION. */ 406 /* THE RECORDS ARE MANAGED BY A TRIGGER */ 407 /* POOL WHERE A TRIGGER RECORD IS SEIZED */ 408 /* WHEN A TRIGGER IS ACTIVATED AND RELEASED */ 409 /* WHEN THE TRIGGER IS DEACTIVATED. */ 410 /* **************************************** */ 411 struct TcFiredTriggerData { TcFiredTriggerDataDbtc::TcFiredTriggerData412 TcFiredTriggerData() {} 413 414 /** 415 * Trigger id, used to identify the trigger 416 **/ 417 Uint32 triggerId; 418 419 /** 420 * The operation that fired the trigger 421 */ 422 Uint32 fireingOperation; 423 424 /** 425 * The fragment id of the firing operation. This will be appended 426 * to the Primary Key such that the record can be found even in the 427 * case of user defined partitioning. 428 */ 429 Uint32 fragId; 430 431 /** 432 * Used for scrapping in case of node failure 433 */ 434 Uint32 nodeId; 435 436 /** 437 * Trigger type, defines what the trigger is used for 438 */ 439 TriggerType::Value triggerType; 440 441 /** 442 * Trigger type, defines what the trigger is used for 443 */ 444 TriggerEvent::Value triggerEvent; 445 446 /** 447 * Trigger attribute info, primary key value(s) 448 */ 449 AttributeBuffer::Head keyValues; 450 451 /** 452 * Trigger attribute info, attribute value(s) before operation 453 */ 454 AttributeBuffer::Head beforeValues; 455 456 /** 457 * Trigger attribute info, attribute value(s) after operation 458 */ 459 AttributeBuffer::Head afterValues; 460 461 /** 462 * Next ptr (used in pool/list) 463 */ 464 union { 465 Uint32 nextPool; 466 Uint32 nextList; 467 Uint32 nextHash; 468 }; 469 470 /** 471 * Prev pointer (used in list) 472 */ 473 union { 474 Uint32 prevList; 475 Uint32 prevHash; 476 }; 477 printDbtc::TcFiredTriggerData478 inline void print(NdbOut & s) const { 479 s << "[FiredTriggerData = " << triggerId << "]"; 480 } 481 hashValueDbtc::TcFiredTriggerData482 inline Uint32 hashValue() const { 483 return fireingOperation ^ nodeId; 484 } 485 equalDbtc::TcFiredTriggerData486 inline bool equal(const TcFiredTriggerData & rec) const { 487 return fireingOperation == rec.fireingOperation && nodeId == rec.nodeId; 488 } 489 }; 490 typedef Ptr<TcFiredTriggerData> FiredTriggerPtr; 491 492 /** 493 * Pool of trigger data record 494 */ 495 ArrayPool<TcFiredTriggerData> c_theFiredTriggerPool; 496 DLHashTable<TcFiredTriggerData> c_firedTriggerHash; 497 AttributeBuffer::DataBufferPool c_theTriggerAttrInfoPool; 498 499 Uint32 c_maxNumberOfDefinedTriggers; 500 Uint32 c_maxNumberOfFiredTriggers; 501 502 struct AttrInfoRecord { 503 /** 504 * Pre-allocated AttrInfo signal 505 */ 506 AttrInfo attrInfo; 507 508 /** 509 * Next ptr (used in pool/list) 510 */ 511 union { 512 Uint32 nextPool; 513 Uint32 nextList; 514 }; 515 /** 516 * Prev pointer (used in list) 517 */ 518 Uint32 prevList; 519 }; 520 521 522 /* ************* INDEX DATA *************** */ 523 /* THIS RECORD FORMS LISTS OF ACTIVE */ 524 /* INDEX FOR EACH TABLE. */ 525 /* THE RECORDS ARE MANAGED BY A INDEX */ 526 /* POOL WHERE AN INDEX RECORD IS SEIZED */ 527 /* WHEN AN INDEX IS CREATED AND RELEASED */ 528 /* WHEN THE INDEX IS DROPPED. */ 529 /* **************************************** */ 530 struct TcIndexData { TcIndexDataDbtc::TcIndexData531 TcIndexData() {} 532 533 /** 534 * IndexState 535 */ 536 IndexState indexState; 537 538 /** 539 * Index id, same as index table id in DICT 540 */ 541 Uint32 indexId; 542 543 /** 544 * Index attribute list. Only the length is used in v21x. 545 */ 546 IndexAttributeList attributeList; 547 548 /** 549 * Primary table id, the primary table to be indexed 550 */ 551 Uint32 primaryTableId; 552 553 /** 554 * Primary key position in secondary table 555 */ 556 Uint32 primaryKeyPos; 557 558 /** 559 * Next ptr (used in pool/list) 560 */ 561 union { 562 Uint32 nextPool; 563 Uint32 nextList; 564 }; 565 /** 566 * Prev pointer (used in list) 567 */ 568 Uint32 prevList; 569 }; 570 571 typedef Ptr<TcIndexData> TcIndexDataPtr; 572 573 /** 574 * Pool of index data record 575 */ 576 ArrayPool<TcIndexData> c_theIndexPool; 577 578 /** 579 * The list of defined indexes 580 */ 581 DLList<TcIndexData> c_theIndexes; 582 UintR c_maxNumberOfIndexes; 583 584 struct TcIndexOperation { TcIndexOperationDbtc::TcIndexOperation585 TcIndexOperation() : 586 indexOpState(IOS_NOOP), 587 pendingKeyInfo(0), 588 keyInfoSectionIVal(RNIL), 589 pendingAttrInfo(0), 590 attrInfoSectionIVal(RNIL), 591 transIdAIState(ITAS_WAIT_HEADER), 592 pendingTransIdAI(0), 593 transIdAISectionIVal(RNIL), 594 indexReadTcConnect(RNIL) 595 {} 596 ~TcIndexOperationDbtc::TcIndexOperation597 ~TcIndexOperation() 598 { 599 } 600 601 // Index data 602 Uint32 indexOpId; 603 IndexOperationState indexOpState; // Used to mark on-going TcKeyReq 604 Uint32 pendingKeyInfo; 605 Uint32 keyInfoSectionIVal; 606 Uint32 pendingAttrInfo; 607 Uint32 attrInfoSectionIVal; 608 IndexTransIdAIState transIdAIState; 609 Uint32 pendingTransIdAI; 610 Uint32 transIdAISectionIVal; // For accumulating TransId_AI 611 Uint32 fragmentId; 612 613 TcKeyReq tcIndxReq; 614 UintR connectionIndex; 615 UintR indexReadTcConnect; // 616 617 /** 618 * Next ptr (used in pool/list) 619 */ 620 union { 621 Uint32 nextPool; 622 Uint32 nextList; 623 }; 624 /** 625 * Prev pointer (used in list) 626 */ 627 Uint32 prevList; 628 }; 629 630 typedef Ptr<TcIndexOperation> TcIndexOperationPtr; 631 632 /** 633 * Pool of index data record 634 */ 635 ArrayPool<TcIndexOperation> c_theIndexOperationPool; 636 637 UintR c_maxNumberOfIndexOperations; 638 639 /************************** API CONNECT RECORD *********************** 640 * The API connect record contains the connection record to which the 641 * application connects. 642 * 643 * The application can send one operation at a time. It can send a 644 * new operation immediately after sending the previous operation. 645 * Thereby several operations can be active in one transaction within TC. 646 * This is achieved by using the API connect record. 647 * Each active operation is handled by the TC connect record. 648 * As soon as the TC connect record has sent the 649 * request to the LQH it is ready to receive new operations. 650 * The LQH connect record takes care of waiting for an operation to 651 * complete. 652 * When an operation has completed on the LQH connect record, 653 * a new operation can be started on this LQH connect record. 654 ******************************************************************* 655 * 656 * API CONNECT RECORD ALIGNED TO BE 256 BYTES 657 ********************************************************************/ 658 659 /*******************************************************************>*/ 660 // We break out the API Timer for optimisation on scanning rather than 661 // on fast access. 662 /*******************************************************************>*/ setApiConTimer(Uint32 apiConPtrI,Uint32 value,Uint32 line)663 inline void setApiConTimer(Uint32 apiConPtrI, Uint32 value, Uint32 line){ 664 c_apiConTimer[apiConPtrI] = value; 665 c_apiConTimer_line[apiConPtrI] = line; 666 } 667 getApiConTimer(Uint32 apiConPtrI) const668 inline Uint32 getApiConTimer(Uint32 apiConPtrI) const { 669 return c_apiConTimer[apiConPtrI]; 670 } 671 UintR* c_apiConTimer; 672 UintR* c_apiConTimer_line; 673 674 struct ApiConnectRecord { ApiConnectRecordDbtc::ApiConnectRecord675 ApiConnectRecord(ArrayPool<TcFiredTriggerData> & firedTriggerPool, 676 ArrayPool<TcIndexOperation> & seizedIndexOpPool): 677 m_special_op_flags(0), 678 theFiredTriggers(firedTriggerPool), 679 theSeizedIndexOperations(seizedIndexOpPool) 680 {} 681 682 //--------------------------------------------------- 683 // First 16 byte cache line. Hot variables. 684 //--------------------------------------------------- 685 ConnectionState apiConnectstate; 686 UintR transid[2]; 687 UintR firstTcConnect; 688 689 //--------------------------------------------------- 690 // Second 16 byte cache line. Hot variables. 691 //--------------------------------------------------- 692 UintR lqhkeyconfrec; 693 UintR cachePtr; 694 UintR currSavePointId; 695 UintR counter; 696 697 //--------------------------------------------------- 698 // Third 16 byte cache line. First and second cache 699 // line plus this will be enough for copy API records. 700 // Variables used in late phases. 701 //--------------------------------------------------- 702 UintR nextGcpConnect; 703 UintR prevGcpConnect; 704 UintR gcpPointer; 705 UintR ndbapiConnect; 706 707 //--------------------------------------------------- 708 // Fourth 16 byte cache line. Only used in late phases. 709 // Plus 4 bytes of error handling. 710 //--------------------------------------------------- 711 UintR nextApiConnect; 712 BlockReference ndbapiBlockref; 713 UintR apiCopyRecord; 714 Uint64 globalcheckpointid; 715 716 //--------------------------------------------------- 717 // Second 64 byte cache line starts. First 16 byte 718 // cache line in this one. Variables primarily used 719 // in early phase. 720 //--------------------------------------------------- 721 UintR lastTcConnect; 722 UintR lqhkeyreqrec; 723 union { 724 Uint32 buddyPtr; 725 Int32 pendingTriggers; // For deferred triggers 726 }; 727 union { 728 UintR apiScanRec; 729 UintR commitAckMarker; 730 }; 731 732 Uint32 no_commit_ack_markers; 733 Uint32 m_write_count; 734 ReturnSignal returnsignal; 735 AbortState abortState; 736 737 enum TransactionFlags 738 { 739 TF_INDEX_OP_RETURN = 1, 740 TF_TRIGGER_PENDING = 2, // Used to mark waiting for a CONTINUEB 741 TF_EXEC_FLAG = 4, 742 TF_COMMIT_ACK_MARKER_RECEIVED = 8, 743 TF_DEFERRED_CONSTRAINTS = 16, // check constraints in deferred fashion 744 TF_DEFERRED_TRIGGERS = 32, // trans has deferred triggers 745 TF_END = 0 746 }; 747 Uint32 m_flags; 748 749 Uint8 m_special_op_flags; // Used to mark on-going TcKeyReq as indx table 750 751 Uint8 takeOverRec; 752 Uint8 currentReplicaNo; 753 754 Uint8 tckeyrec; // Changed from R 755 756 Uint8 tcindxrec; 757 Uint8 apiFailState; // Changed R 758 Uint8 timeOutCounter; 759 Uint8 singleUserMode; 760 761 Uint16 returncode; 762 Uint16 takeOverInd; 763 //--------------------------------------------------- 764 // Error Handling variables. If cache line 32 bytes 765 // ensures that cache line is still only read in 766 // early phases. 767 //--------------------------------------------------- 768 UintR currentTcConnect; 769 BlockReference tcBlockref; 770 UintR failureNr; 771 772 //--------------------------------------------------- 773 // Second 64 byte cache line. Third 16 byte cache line 774 // in this one. Variables primarily used in early phase 775 // and checked in late phase. 776 // Fourth cache line is the tcSendArray that is used 777 // when two and three operations are responded to in 778 // parallel. The first two entries in tcSendArray is 779 // part of the third cache line. 780 //--------------------------------------------------- 781 //--------------------------------------------------- 782 // timeOutCounter is used waiting for ABORTCONF, COMMITCONF 783 // and COMPLETECONF 784 //--------------------------------------------------- 785 UintR tcSendArray[6]; 786 NdbNodeBitmask m_transaction_nodes; 787 788 // Trigger data 789 790 /** 791 * The list of fired triggers 792 */ 793 DLFifoList<TcFiredTriggerData> theFiredTriggers; 794 795 796 // Index data 797 798 UintR noIndexOp; // No outstanding index ops 799 800 // Index op return context 801 UintR indexOp; 802 UintR clientData; 803 Uint32 errorData; 804 UintR attrInfoLen; 805 Uint32 immediateTriggerId; // Id of trigger op being fired NOW 806 807 UintR accumulatingIndexOp; 808 UintR executingIndexOp; 809 UintR tcIndxSendArray[6]; 810 DLList<TcIndexOperation> theSeizedIndexOperations; 811 812 #ifdef ERROR_INSERT 813 Uint32 continueBCount; // ERROR_INSERT 8082 814 #endif 815 Uint8 m_pre_commit_pass; 816 isExecutingDeferredTriggersDbtc::ApiConnectRecord817 bool isExecutingDeferredTriggers() const { 818 return apiConnectstate == CS_SEND_FIRE_TRIG_REQ || 819 apiConnectstate == CS_WAIT_FIRE_TRIG_REQ ; 820 } 821 }; 822 823 typedef Ptr<ApiConnectRecord> ApiConnectRecordPtr; 824 825 826 /************************** TC CONNECT RECORD ************************/ 827 /* *******************************************************************/ 828 /* TC CONNECT RECORD KEEPS ALL INFORMATION TO CARRY OUT A TRANSACTION*/ 829 /* THE TRANSACTION CONTROLLER ESTABLISHES CONNECTIONS TO DIFFERENT */ 830 /* BLOCKS TO CARRY OUT THE TRANSACTION. THERE CAN BE SEVERAL RECORDS */ 831 /* PER ACTIVE TRANSACTION. THE TC CONNECT RECORD COOPERATES WITH THE */ 832 /* API CONNECT RECORD FOR COMMUNICATION WITH THE API AND WITH THE */ 833 /* LQH CONNECT RECORD FOR COMMUNICATION WITH THE LQH'S INVOLVED IN */ 834 /* THE TRANSACTION. TC CONNECT RECORD IS PERMANENTLY CONNECTED TO A */ 835 /* RECORD IN DICT AND ONE IN DIH. IT CONTAINS A LIST OF ACTIVE LQH */ 836 /* CONNECT RECORDS AND A LIST OF STARTED BUT NOT ACTIVE LQH CONNECT */ 837 /* RECORDS. IT DOES ALSO CONTAIN A LIST OF ALL OPERATIONS THAT ARE */ 838 /* EXECUTED WITH THE TC CONNECT RECORD. */ 839 /*******************************************************************>*/ 840 /* TC_CONNECT RECORD ALIGNED TO BE 128 BYTES */ 841 /*******************************************************************>*/ 842 struct TcConnectRecord { 843 //--------------------------------------------------- 844 // First 16 byte cache line. Those variables are only 845 // used in error cases. 846 //--------------------------------------------------- 847 UintR tcOprec; /* TC OPREC of operation being taken over */ 848 Uint16 failData[4]; /* Failed nodes when taking over an operation */ 849 UintR nextTcFailHash; 850 851 //--------------------------------------------------- 852 // Second 16 byte cache line. Those variables are used 853 // from LQHKEYCONF to sending COMMIT and COMPLETED. 854 //--------------------------------------------------- 855 UintR lastLqhCon; /* Connect record in last replicas Lqh record */ 856 Uint16 lastLqhNodeId; /* Node id of last replicas Lqh */ 857 Uint16 m_execAbortOption;/* TcKeyReq::ExecuteAbortOption */ 858 UintR commitAckMarker; /* CommitMarker I value */ 859 860 //--------------------------------------------------- 861 // Third 16 byte cache line. The hottest variables. 862 //--------------------------------------------------- 863 OperationState tcConnectstate; /* THE STATE OF THE CONNECT*/ 864 UintR apiConnect; /* POINTER TO API CONNECT RECORD */ 865 UintR nextTcConnect; /* NEXT TC RECORD*/ 866 Uint8 dirtyOp; 867 Uint8 opSimple; 868 Uint8 lastReplicaNo; /* NUMBER OF THE LAST REPLICA IN THE OPERATION */ 869 Uint8 noOfNodes; /* TOTAL NUMBER OF NODES IN OPERATION */ 870 Uint8 operation; /* OPERATION TYPE */ 871 /* 0 = READ REQUEST */ 872 /* 1 = UPDATE REQUEST */ 873 /* 2 = INSERT REQUEST */ 874 /* 3 = DELETE REQUEST */ 875 Uint8 m_special_op_flags; // See ApiConnectRecord::SpecialOpFlags 876 enum SpecialOpFlags { 877 SOF_NORMAL = 0, 878 SOF_INDEX_TABLE_READ = 1, // Read index table 879 SOF_INDEX_BASE_TABLE_ACCESS = 2,// Execute on "real" table 880 SOF_REORG_TRIGGER_BASE = 4, 881 SOF_REORG_TRIGGER = 4 | 16, // A reorg trigger 882 SOF_REORG_MOVING = 8, // A record that should be moved 883 SOF_TRIGGER = 16, // A trigger 884 SOF_REORG_COPY = 32, 885 SOF_REORG_DELETE = 64, 886 SOF_DEFERRED_TRIGGER = 128 // Op has deferred trigger 887 }; 888 isIndexOpDbtc::TcConnectRecord889 static inline bool isIndexOp(Uint8 flags) { 890 return 891 flags == SOF_INDEX_TABLE_READ || 892 flags == SOF_INDEX_BASE_TABLE_ACCESS; 893 } 894 895 //--------------------------------------------------- 896 // Fourth 16 byte cache line. The mildly hot variables. 897 // tcNodedata expands 4 Bytes into the next cache line 898 // with indexes almost never used. 899 //--------------------------------------------------- 900 UintR clientData; /* SENDERS OPERATION POINTER */ 901 UintR prevTcConnect; /* DOUBLY LINKED LIST OF TC CONNECT RECORDS*/ 902 UintR savePointId; 903 904 Uint16 tcNodedata[4]; 905 /* Instance key to send to LQH. Receiver maps it to actual instance. */ 906 Uint16 lqhInstanceKey; 907 908 // Trigger data 909 UintR noFiredTriggers; // As reported by lqhKeyConf 910 UintR noReceivedTriggers; // FIRE_TRIG_ORD 911 UintR triggerExecutionCount;// No of outstanding op due to triggers 912 UintR savedState[LqhKeyConf::SignalLength]; 913 914 UintR triggeringOperation; // Which operation was "cause" of this op 915 916 // Index data 917 UintR indexOp; 918 UintR currentTriggerId; 919 UintR attrInfoLen; 920 }; 921 922 friend struct TcConnectRecord; 923 924 typedef Ptr<TcConnectRecord> TcConnectRecordPtr; 925 926 // ********************** CACHE RECORD ************************************** 927 //--------------------------------------------------------------------------- 928 // This record is used between reception of TCKEYREQ and sending of LQHKEYREQ 929 // It is separatedso as to improve the cache hit rate and also to minimise 930 // the necessary memory storage in NDB Cluster. 931 //--------------------------------------------------------------------------- 932 933 struct CacheRecord { 934 /* Fields used by TCKEYREQ/TCINDXREQ/SCANTABREQ */ 935 Uint32 keyInfoSectionI; /* KeyInfo section I-val */ 936 Uint32 attrInfoSectionI; /* AttrInfo section I-val */ 937 938 // TODO : Consider using section length + other vars for this 939 UintR currReclenAi; /* AttrInfo words received so far */ 940 Uint16 attrlength; /* Total AttrInfo length */ 941 Uint16 save1; /* KeyInfo words received so far */ 942 Uint16 keylen; /* KEY LENGTH SENT BY REQUEST SIGNAL */ 943 944 /* Distribution information */ 945 // TODO : Consider placing this info into other records 946 Uint8 distributionKeyIndicator; 947 Uint8 viaSPJFlag; /* Send request via the SPJ block.*/ 948 UintR distributionKey; 949 /* End of fields used by TCKEYREQ/TCINDXREQ/SCANTABREQ */ 950 951 952 /* TCKEYREQ/TCINDXREQ only fields */ 953 UintR schemaVersion;/* SCHEMA VERSION USED IN TRANSACTION */ 954 UintR tableref; /* POINTER TO THE TABLE IN WHICH THE FRAGMENT EXISTS*/ 955 Uint16 apiVersionNo; 956 957 UintR fragmentid; /* THE COMPUTED FRAGMENT ID */ 958 UintR hashValue; /* THE HASH VALUE USED TO LOCATE FRAGMENT */ 959 960 Uint8 m_special_hash; // collation or distribution key 961 Uint8 m_no_hash; // Hash not required for LQH (special variant) 962 Uint8 m_no_disk_flag; 963 Uint8 m_op_queue; 964 Uint8 lenAiInTckeyreq; /* LENGTH OF ATTRIBUTE INFORMATION IN TCKEYREQ */ 965 966 Uint8 fragmentDistributionKey; /* DIH generation no */ 967 968 /** 969 * EXECUTION MODE OF OPERATION 970 * 0 = NORMAL EXECUTION, 1 = INTERPRETED EXECUTION 971 */ 972 Uint8 opExec; 973 974 /* Use of Long signals */ 975 Uint8 isLongTcKeyReq; /* Incoming TcKeyReq used long signal */ 976 Uint8 useLongLqhKeyReq; /* Outgoing LqhKeyReq should be long */ 977 978 UintR nextCacheRec; 979 Uint32 scanInfo; 980 981 Uint32 scanTakeOverInd; 982 Uint32 unlockNodeId; /* NodeId for unlock operation */ 983 /* End of TCKEYREQ/TCINDXREQ only fields */ 984 985 }; 986 987 typedef Ptr<CacheRecord> CacheRecordPtr; 988 989 /* ************************ HOST RECORD ********************************** */ 990 /********************************************************/ 991 /* THIS RECORD CONTAINS ALIVE-STATUS ON ALL NODES IN THE*/ 992 /* SYSTEM */ 993 /********************************************************/ 994 /* THIS RECORD IS ALIGNED TO BE 128 BYTES. */ 995 /********************************************************/ 996 struct HostRecord { 997 HostState hostStatus; 998 LqhTransState lqhTransStatus; 999 bool inPackedList; 1000 UintR noOfPackedWordsLqh; 1001 UintR packedWordsLqh[26]; 1002 UintR noOfWordsTCKEYCONF; 1003 UintR packedWordsTCKEYCONF[30]; 1004 BlockReference hostLqhBlockRef; 1005 1006 enum NodeFailBits 1007 { 1008 NF_TAKEOVER = 0x1, 1009 NF_CHECK_SCAN = 0x2, 1010 NF_CHECK_TRANSACTION = 0x4, 1011 NF_BLOCK_HANDLE = 0x8, 1012 NF_NODE_FAIL_BITS = 0xF // All bits... 1013 }; 1014 Uint32 m_nf_bits; 1015 NdbNodeBitmask m_lqh_trans_conf; 1016 }; /* p2c: size = 128 bytes */ 1017 1018 typedef Ptr<HostRecord> HostRecordPtr; 1019 1020 /* *********** TABLE RECORD ********************************************* */ 1021 1022 /********************************************************/ 1023 /* THIS RECORD CONTAINS THE CURRENT SCHEMA VERSION OF */ 1024 /* ALL TABLES IN THE SYSTEM. */ 1025 /********************************************************/ 1026 struct TableRecord { TableRecordDbtc::TableRecord1027 TableRecord() {} 1028 Uint32 currentSchemaVersion; 1029 Uint16 m_flags; 1030 Uint8 tableType; 1031 Uint8 singleUserMode; 1032 1033 enum { 1034 TR_ENABLED = 1 << 0, 1035 TR_DROPPING = 1 << 1, 1036 TR_STORED_TABLE = 1 << 2, 1037 TR_PREPARED = 1 << 3 1038 ,TR_USER_DEFINED_PARTITIONING = 1 << 4 1039 }; get_enabledDbtc::TableRecord1040 Uint8 get_enabled() const { return (m_flags & TR_ENABLED) != 0; } get_droppingDbtc::TableRecord1041 Uint8 get_dropping() const { return (m_flags & TR_DROPPING) != 0; } get_storedTableDbtc::TableRecord1042 Uint8 get_storedTable() const { return (m_flags & TR_STORED_TABLE) != 0; } get_preparedDbtc::TableRecord1043 Uint8 get_prepared() const { return (m_flags & TR_PREPARED) != 0; } set_enabledDbtc::TableRecord1044 void set_enabled(Uint8 f) { f ? m_flags |= (Uint16)TR_ENABLED : m_flags &= ~(Uint16)TR_ENABLED; } set_droppingDbtc::TableRecord1045 void set_dropping(Uint8 f) { f ? m_flags |= (Uint16)TR_DROPPING : m_flags &= ~(Uint16)TR_DROPPING; } set_storedTableDbtc::TableRecord1046 void set_storedTable(Uint8 f) { f ? m_flags |= (Uint16)TR_STORED_TABLE : m_flags &= ~(Uint16)TR_STORED_TABLE; } set_preparedDbtc::TableRecord1047 void set_prepared(Uint8 f) { f ? m_flags |= (Uint16)TR_PREPARED : m_flags &= ~(Uint16)TR_PREPARED; } 1048 get_user_defined_partitioningDbtc::TableRecord1049 Uint8 get_user_defined_partitioning() const { 1050 return (m_flags & TR_USER_DEFINED_PARTITIONING) != 0; 1051 } 1052 set_user_defined_partitioningDbtc::TableRecord1053 void set_user_defined_partitioning(Uint8 f) { 1054 f ? 1055 m_flags |= (Uint16)TR_USER_DEFINED_PARTITIONING : 1056 m_flags &= ~(Uint16)TR_USER_DEFINED_PARTITIONING; 1057 } 1058 1059 Uint8 noOfKeyAttr; 1060 Uint8 hasCharAttr; 1061 Uint8 noOfDistrKeys; 1062 Uint8 hasVarKeys; 1063 checkTableDbtc::TableRecord1064 bool checkTable(Uint32 schemaVersion) const { 1065 return !get_dropping() && 1066 ((/** normal transaction path */ 1067 get_enabled() && table_version_major(schemaVersion) == table_version_major(currentSchemaVersion)) 1068 || 1069 (/** 1070 * unique index is relaxed for DbUtil and transactions ongoing 1071 * while index is created 1072 */ 1073 get_prepared() && schemaVersion == currentSchemaVersion && 1074 DictTabInfo::isUniqueIndex(tableType))); 1075 } 1076 1077 Uint32 getErrorCode(Uint32 schemaVersion) const; 1078 }; 1079 typedef Ptr<TableRecord> TableRecordPtr; 1080 1081 /** 1082 * There is max 16 ScanFragRec's for 1083 * each scan started in TC. Each ScanFragRec is used by 1084 * a scan fragment "process" that scans one fragment at a time. 1085 * It will receive max 16 tuples in each request 1086 */ 1087 struct ScanFragRec { ScanFragRecDbtc::ScanFragRec1088 ScanFragRec(){ 1089 stopFragTimer(); 1090 lqhBlockref = 0; 1091 scanFragState = IDLE; 1092 scanRec = RNIL; 1093 } 1094 /** 1095 * ScanFragState 1096 * WAIT_GET_PRIMCONF : Waiting for DIGETPRIMCONF when starting a new 1097 * fragment scan 1098 * LQH_ACTIVE : The scan process has sent a command to LQH and is 1099 * waiting for the response 1100 * LQH_ACTIVE_CLOSE : The scan process has sent close to LQH and is 1101 * waiting for the response 1102 * DELIVERED : The result have been delivered, this scan frag process 1103 * are waiting for a SCAN_NEXTREQ to tell us to continue scanning 1104 * RETURNING_FROM_DELIVERY : SCAN_NEXTREQ received and continuing scan 1105 * soon 1106 * QUEUED_FOR_DELIVERY : Result queued in TC and waiting for delivery 1107 * to API 1108 * COMPLETED : The fragment scan processes has completed and finally 1109 * sent a SCAN_PROCCONF 1110 */ 1111 enum ScanFragState { 1112 IDLE = 0, 1113 WAIT_GET_PRIMCONF = 1, 1114 LQH_ACTIVE = 2, 1115 DELIVERED = 4, 1116 QUEUED_FOR_DELIVERY = 6, 1117 COMPLETED = 7 1118 }; 1119 // Timer for checking timeout of this fragment scan 1120 Uint32 scanFragTimer; 1121 1122 // Id of the current scanned fragment 1123 Uint32 scanFragId; 1124 1125 // Blockreference of LQH 1126 BlockReference lqhBlockref; 1127 1128 // getNodeInfo.m_connectCount, set at seize used so that 1129 // I don't accidently kill a starting node 1130 Uint32 m_connectCount; 1131 1132 // State of this fragment scan 1133 ScanFragState scanFragState; 1134 1135 // Id of the ScanRecord this fragment scan belongs to 1136 Uint32 scanRec; 1137 1138 // The value of fragmentCompleted in the last received SCAN_FRAGCONF 1139 Uint8 m_scan_frag_conf_status; 1140 startFragTimerDbtc::ScanFragRec1141 inline void startFragTimer(Uint32 timeVal){ 1142 scanFragTimer = timeVal; 1143 } stopFragTimerDbtc::ScanFragRec1144 inline void stopFragTimer(void){ 1145 scanFragTimer = 0; 1146 } 1147 1148 Uint32 m_ops; 1149 Uint32 m_chksum; 1150 Uint32 m_apiPtr; 1151 Uint32 m_totalLen; 1152 union { 1153 Uint32 nextPool; 1154 Uint32 nextList; 1155 }; 1156 Uint32 prevList; 1157 }; 1158 1159 typedef Ptr<ScanFragRec> ScanFragRecPtr; 1160 typedef LocalDLList<ScanFragRec> ScanFragList; 1161 1162 /** 1163 * Each scan allocates one ScanRecord to store information 1164 * about the current scan 1165 * 1166 */ 1167 struct ScanRecord { ScanRecordDbtc::ScanRecord1168 ScanRecord() {} 1169 /** NOTE! This is the old comment for ScanState. - MASV 1170 * STATE TRANSITIONS OF SCAN_STATE. SCAN_STATE IS THE STATE 1171 * VARIABLE OF THE RECEIVE AND DELIVERY PROCESS. 1172 * THE PROCESS HAS THREE STEPS IT GOES THROUGH. 1173 * 1) THE INITIAL STATES WHEN RECEIVING DATA FOR THE SCAN. 1174 * - WAIT_SCAN_TAB_INFO 1175 * - WAIT_AI 1176 * - WAIT_FRAGMENT_COUNT 1177 * 2) THE EXECUTION STATES WHEN THE SCAN IS PERFORMED. 1178 * - SCAN_NEXT_ORDERED 1179 * - DELIVERED 1180 * - QUEUED_DELIVERED 1181 * 3) THE CLOSING STATE WHEN THE SCAN PROCESS IS CLOSING UP 1182 * EVERYTHING. 1183 * - CLOSING_SCAN 1184 * INITIAL START WHEN SCAN_TABREQ RECEIVED 1185 * -> WAIT_SCAN_TAB_INFO (IF ANY SCAN_TABINFO TO BE RECEIVED) 1186 * -> WAIT_AI (IF NO SCAN_TAB_INFO BUT ATTRINFO IS RECEIVED) 1187 * -> WAIT_FRAGMENT_COUNT (IF NEITHER SCAN_TABINFO OR ATTRINFO 1188 * RECEIVED) 1189 * 1190 * WAIT_SCAN_TAB_INFO TRANSITIONS: 1191 * -> WAIT_SCAN_TABINFO (WHEN MORE SCAN_TABINFO RECEIVED) 1192 * -> WAIT_AI (WHEN ATTRINFO RECEIVED AFTER RECEIVING ALL 1193 * SCAN_TABINFO) 1194 * -> WAIT_FRAGMENT_COUNT (WHEN NO ATTRINFO RECEIVED AFTER 1195 * RECEIVING ALL SCAN_TABINFO ) 1196 * WAIT_AI TRANSITIONS: 1197 * -> WAIT_AI (WHEN MORE ATTRINFO RECEIVED) 1198 * -> WAIT_FRAGMENT_COUNT (WHEN ALL ATTRINFO RECEIVED) 1199 * 1200 * WAIT_FRAGMENT_COUNT TRANSITIONS: 1201 * -> SCAN_NEXT_ORDERED 1202 * 1203 * SCAN_NEXT_ORDERED TRANSITIONS: 1204 * -> DELIVERED (WHEN FIRST SCAN_FRAGCONF ARRIVES WITH OPERATIONS 1205 * TO REPORT IN IT) 1206 * -> CLOSING_SCAN (WHEN SCAN IS CLOSED BY SCAN_NEXTREQ OR BY SOME 1207 * ERROR) 1208 * 1209 * DELIVERED TRANSITIONS: 1210 * -> SCAN_NEXT_ORDERED (IF SCAN_NEXTREQ ARRIVES BEFORE ANY NEW 1211 * OPERATIONS TO REPORT ARRIVES) 1212 * -> QUEUED_DELIVERED (IF NEW OPERATION TO REPORT ARRIVES BEFORE 1213 * SCAN_NEXTREQ) 1214 * -> CLOSING_SCAN (WHEN SCAN IS CLOSED BY SCAN_NEXTREQ OR BY SOME 1215 * ERROR) 1216 * 1217 * QUEUED_DELIVERED TRANSITIONS: 1218 * -> DELIVERED (WHEN SCAN_NEXTREQ ARRIVES AND QUEUED OPERATIONS 1219 * TO REPORT ARE SENT TO THE APPLICATION) 1220 * -> CLOSING_SCAN (WHEN SCAN IS CLOSED BY SCAN_NEXTREQ OR BY 1221 * SOME ERROR) 1222 */ 1223 enum ScanState { 1224 IDLE = 0, 1225 WAIT_SCAN_TAB_INFO = 1, 1226 WAIT_AI = 2, 1227 WAIT_FRAGMENT_COUNT = 3, 1228 RUNNING = 4, 1229 CLOSING_SCAN = 5 1230 }; 1231 1232 // State of this scan 1233 ScanState scanState; 1234 1235 DLList<ScanFragRec>::Head m_running_scan_frags; // Currently in LQH 1236 union { Uint32 m_queued_count; Uint32 scanReceivedOperations; }; 1237 DLList<ScanFragRec>::Head m_queued_scan_frags; // In TC !sent to API 1238 DLList<ScanFragRec>::Head m_delivered_scan_frags;// Delivered to API 1239 1240 // Id of the next fragment to be scanned. Used by scan fragment 1241 // processes when they are ready for the next fragment 1242 Uint32 scanNextFragId; 1243 1244 // Total number of fragments in the table we are scanning 1245 Uint32 scanNoFrag; 1246 1247 // Index of next ScanRecords when in free list 1248 Uint32 nextScan; 1249 1250 // Length of expected attribute information 1251 union { Uint32 scanAiLength; Uint32 m_booked_fragments_count; }; 1252 1253 Uint32 scanKeyLen; 1254 1255 // Reference to ApiConnectRecord 1256 Uint32 scanApiRec; 1257 1258 // Reference to TcConnectRecord 1259 Uint32 scanTcrec; 1260 1261 // Number of scan frag processes that belong to this scan 1262 Uint32 scanParallel; 1263 1264 // Schema version used by this scan 1265 Uint32 scanSchemaVersion; 1266 1267 // Index of stored procedure belonging to this scan 1268 Uint32 scanStoredProcId; 1269 1270 // The index of table that is scanned 1271 Uint32 scanTableref; 1272 Uint32 m_scan_cookie; 1273 1274 // Number of operation records per scanned fragment 1275 // Number of operations in first batch 1276 // Max number of bytes per batch 1277 union { 1278 Uint16 first_batch_size_rows; 1279 Uint16 batch_size_rows; 1280 }; 1281 Uint32 batch_byte_size; 1282 Uint32 m_scan_block_no; 1283 1284 Uint32 scanRequestInfo; // ScanFrag format 1285 1286 // Close is ordered 1287 bool m_close_scan_req; 1288 // All SCAN_FRAGCONS should be passed on to the API as SCAN_TABCONFS. 1289 // This is needed to correctly propagate 'node masks' when scanning via the 1290 // SPJ block. 1291 bool m_pass_all_confs; 1292 1293 /** 1294 * Send opcount/total len as different words 1295 */ 1296 bool m_4word_conf; 1297 }; 1298 typedef Ptr<ScanRecord> ScanRecordPtr; 1299 1300 /*************************************************************************>*/ 1301 /* GLOBAL CHECKPOINT INFORMATION RECORD */ 1302 /* */ 1303 /* THIS RECORD IS USED TO STORE THE GLOBALCHECKPOINT NUMBER AND A 1304 * COUNTER DURING THE COMPLETION PHASE OF THE TRANSACTION */ 1305 /*************************************************************************>*/ 1306 /* */ 1307 /* GCP RECORD ALIGNED TO BE 32 BYTES */ 1308 /*************************************************************************>*/ 1309 struct GcpRecord { 1310 Uint16 gcpUnused0; 1311 Uint16 gcpNomoretransRec; 1312 UintR gcpUnused1[2]; /* p2c: Not used */ 1313 UintR firstApiConnect; 1314 UintR lastApiConnect; 1315 UintR nextGcp; 1316 Uint64 gcpId; 1317 }; /* p2c: size = 32 bytes */ 1318 1319 typedef Ptr<GcpRecord> GcpRecordPtr; 1320 1321 /*************************************************************************>*/ 1322 /* TC_FAIL_RECORD */ 1323 /* THIS RECORD IS USED WHEN HANDLING TAKE OVER OF ANOTHER FAILED 1324 * TC NODE. */ 1325 /*************************************************************************>*/ 1326 struct TcFailRecord { 1327 Uint16 queueList[MAX_NDB_NODES]; 1328 Uint8 takeOverProcState[MAX_NDB_NODES]; 1329 UintR completedTakeOver; 1330 UintR currentHashIndexTakeOver; 1331 FailState failStatus; 1332 Uint16 queueIndex; 1333 Uint16 takeOverNode; 1334 }; /* p2c: size = 64 bytes */ 1335 1336 typedef Ptr<TcFailRecord> TcFailRecordPtr; 1337 1338 public: 1339 Dbtc(Block_context&, Uint32 instanceNumber = 0); 1340 virtual ~Dbtc(); 1341 1342 private: 1343 BLOCK_DEFINES(Dbtc); 1344 1345 // Transit signals 1346 void execPACKED_SIGNAL(Signal* signal); 1347 void execABORTED(Signal* signal); 1348 void execATTRINFO(Signal* signal); 1349 void execCONTINUEB(Signal* signal); 1350 void execKEYINFO(Signal* signal); 1351 void execSCAN_NEXTREQ(Signal* signal); 1352 void execSCAN_PROCREQ(Signal* signal); 1353 void execSCAN_PROCCONF(Signal* signal); 1354 void execTAKE_OVERTCREQ(Signal* signal); 1355 void execTAKE_OVERTCCONF(Signal* signal); 1356 void execLQHKEYREF(Signal* signal); 1357 void execTRANSID_AI_R(Signal* signal); 1358 void execKEYINFO20_R(Signal* signal); 1359 void execROUTE_ORD(Signal* signal); 1360 // Received signals 1361 void execDUMP_STATE_ORD(Signal* signal); 1362 void execDBINFO_SCANREQ(Signal* signal); 1363 void execSEND_PACKED(Signal* signal); 1364 void execCOMPLETED(Signal* signal); 1365 void execCOMMITTED(Signal* signal); 1366 void execDIGETNODESREF(Signal* signal); 1367 void execDIH_SCAN_GET_NODES_REF(Signal* signal); 1368 void execDIH_SCAN_GET_NODES_CONF(Signal* signal); 1369 void execDIVERIFYCONF(Signal* signal); 1370 void execDIH_SCAN_TAB_REF(Signal* signal); 1371 void execDIH_SCAN_TAB_CONF(Signal* signal); 1372 void execGCP_NOMORETRANS(Signal* signal); 1373 void execLQHKEYCONF(Signal* signal); 1374 void execNDB_STTOR(Signal* signal); 1375 void execREAD_NODESCONF(Signal* signal); 1376 void execREAD_NODESREF(Signal* signal); 1377 void execSTTOR(Signal* signal); 1378 void execTC_COMMITREQ(Signal* signal); 1379 void execTC_CLOPSIZEREQ(Signal* signal); 1380 void execTCGETOPSIZEREQ(Signal* signal); 1381 void execTCKEYREQ(Signal* signal); 1382 void execTCRELEASEREQ(Signal* signal); 1383 void execTCSEIZEREQ(Signal* signal); 1384 void execTCROLLBACKREQ(Signal* signal); 1385 void execTC_HBREP(Signal* signal); 1386 void execTC_SCHVERREQ(Signal* signal); 1387 void execTAB_COMMITREQ(Signal* signal); 1388 void execSCAN_TABREQ(Signal* signal); 1389 void execSCAN_TABINFO(Signal* signal); 1390 void execSCAN_FRAGCONF(Signal* signal); 1391 void execSCAN_FRAGREF(Signal* signal); 1392 void execREAD_CONFIG_REQ(Signal* signal); 1393 void execLQH_TRANSCONF(Signal* signal); 1394 void execCOMPLETECONF(Signal* signal); 1395 void execCOMMITCONF(Signal* signal); 1396 void execABORTCONF(Signal* signal); 1397 void execNODE_FAILREP(Signal* signal); 1398 void execINCL_NODEREQ(Signal* signal); 1399 void execTIME_SIGNAL(Signal* signal); 1400 void execAPI_FAILREQ(Signal* signal); 1401 void execSCAN_HBREP(Signal* signal); 1402 1403 void execABORT_ALL_REQ(Signal* signal); 1404 1405 void execCREATE_TRIG_IMPL_REQ(Signal* signal); 1406 void execDROP_TRIG_IMPL_REQ(Signal* signal); 1407 void execFIRE_TRIG_ORD(Signal* signal); 1408 void execTRIG_ATTRINFO(Signal* signal); 1409 void execCREATE_INDX_IMPL_REQ(Signal* signal); 1410 void execDROP_INDX_IMPL_REQ(Signal* signal); 1411 void execTCINDXREQ(Signal* signal); 1412 void execINDXKEYINFO(Signal* signal); 1413 void execINDXATTRINFO(Signal* signal); 1414 void execALTER_INDX_IMPL_REQ(Signal* signal); 1415 void execSIGNAL_DROPPED_REP(Signal* signal); 1416 1417 void execFIRE_TRIG_REF(Signal*); 1418 void execFIRE_TRIG_CONF(Signal*); 1419 1420 // Index table lookup 1421 void execTCKEYCONF(Signal* signal); 1422 void execTCKEYREF(Signal* signal); 1423 void execTRANSID_AI(Signal* signal); 1424 void execTCROLLBACKREP(Signal* signal); 1425 1426 void execCREATE_TAB_REQ(Signal* signal); 1427 void execPREP_DROP_TAB_REQ(Signal* signal); 1428 void execDROP_TAB_REQ(Signal* signal); 1429 void checkWaitDropTabFailedLqh(Signal*, Uint32 nodeId, Uint32 tableId); 1430 void execALTER_TAB_REQ(Signal* signal); 1431 void set_timeout_value(Uint32 timeOut); 1432 void set_appl_timeout_value(Uint32 timeOut); 1433 void set_no_parallel_takeover(Uint32); 1434 void updateBuddyTimer(ApiConnectRecordPtr); 1435 1436 // Statement blocks 1437 void updatePackedList(Signal* signal, HostRecord* ahostptr, 1438 Uint16 ahostIndex); 1439 void clearTcNodeData(Signal* signal, 1440 UintR TLastLqhIndicator, 1441 UintR Tstart); 1442 void errorReport(Signal* signal, int place); 1443 void warningReport(Signal* signal, int place); 1444 void printState(Signal* signal, int place); 1445 int seizeTcRecord(Signal* signal); 1446 int seizeCacheRecord(Signal* signal); 1447 void TCKEY_abort(Signal* signal, int place); 1448 void copyFromToLen(UintR* sourceBuffer, UintR* destBuffer, UintR copyLen); 1449 void reportNodeFailed(Signal* signal, Uint32 nodeId); 1450 void sendPackedTCKEYCONF(Signal* signal, 1451 HostRecord * ahostptr, 1452 UintR hostId); 1453 void sendPackedSignalLqh(Signal* signal, HostRecord * ahostptr); 1454 Uint32 sendCommitLqh(Signal* signal, 1455 TcConnectRecord * const regTcPtr); 1456 Uint32 sendCompleteLqh(Signal* signal, 1457 TcConnectRecord * const regTcPtr); 1458 1459 void sendFireTrigReq(Signal*, Ptr<ApiConnectRecord>, Uint32 firstTcConnect); 1460 Uint32 sendFireTrigReqLqh(Signal*, Ptr<TcConnectRecord>, Uint32 pass); 1461 1462 void sendTCKEY_FAILREF(Signal* signal, ApiConnectRecord *); 1463 void sendTCKEY_FAILCONF(Signal* signal, ApiConnectRecord *); 1464 void routeTCKEY_FAILREFCONF(Signal* signal, const ApiConnectRecord *, 1465 Uint32 gsn, Uint32 len); 1466 void execTCKEY_FAILREFCONF_R(Signal* signal); 1467 void checkStartTimeout(Signal* signal); 1468 void checkStartFragTimeout(Signal* signal); 1469 void timeOutFoundFragLab(Signal* signal, Uint32 TscanConPtr); 1470 void timeOutLoopStartFragLab(Signal* signal, Uint32 TscanConPtr); 1471 int releaseAndAbort(Signal* signal); 1472 void findApiConnectFail(Signal* signal); 1473 void findTcConnectFail(Signal* signal, Uint32 instanceKey); 1474 void initApiConnectFail(Signal* signal); 1475 void initTcConnectFail(Signal* signal, Uint32 instanceKey); 1476 void initTcFail(Signal* signal); 1477 void releaseTakeOver(Signal* signal); 1478 void setupFailData(Signal* signal); 1479 void updateApiStateFail(Signal* signal); 1480 void updateTcStateFail(Signal* signal, Uint32 instanceKey); 1481 void handleApiFailState(Signal* signal, UintR anApiConnectptr); 1482 void handleFailedApiNode(Signal* signal, 1483 UintR aFailedNode, 1484 UintR anApiConnectPtr); 1485 void handleScanStop(Signal* signal, UintR aFailedNode); 1486 void initScanTcrec(Signal* signal); 1487 Uint32 initScanrec(ScanRecordPtr, const class ScanTabReq*, 1488 const UintR scanParallel, 1489 const UintR noOprecPerFrag, 1490 const Uint32 aiLength, 1491 const Uint32 keyLength); 1492 void initScanfragrec(Signal* signal); 1493 void releaseScanResources(Signal*, ScanRecordPtr, bool not_started = false); 1494 ScanRecordPtr seizeScanrec(Signal* signal); 1495 void sendScanFragReq(Signal*, ScanRecord*, ScanFragRec*, bool); 1496 void sendScanTabConf(Signal* signal, ScanRecordPtr); 1497 void close_scan_req(Signal*, ScanRecordPtr, bool received_req); 1498 void close_scan_req_send_conf(Signal*, ScanRecordPtr); 1499 1500 void checkGcp(Signal* signal); 1501 void commitGciHandling(Signal* signal, Uint64 Tgci); 1502 void copyApi(Ptr<ApiConnectRecord> dst, Ptr<ApiConnectRecord> src); 1503 void DIVER_node_fail_handling(Signal* signal, Uint64 Tgci); 1504 void gcpTcfinished(Signal* signal, Uint64 gci); 1505 void handleGcp(Signal* signal, Ptr<ApiConnectRecord>); 1506 void hash(Signal* signal); 1507 bool handle_special_hash(Uint32 dstHash[4], 1508 const Uint32* src, Uint32 srcLen, 1509 Uint32 tabPtrI, bool distr); 1510 1511 void initApiConnect(Signal* signal); 1512 void initApiConnectRec(Signal* signal, 1513 ApiConnectRecord * const regApiPtr, 1514 bool releaseIndexOperations = false); 1515 void initgcp(Signal* signal); 1516 void inithost(Signal* signal); 1517 void initialiseScanrec(Signal* signal); 1518 void initialiseScanFragrec(Signal* signal); 1519 void initialiseScanOprec(Signal* signal); 1520 void initTable(Signal* signal); 1521 void initialiseTcConnect(Signal* signal); 1522 void linkApiToGcp(Ptr<GcpRecord>, Ptr<ApiConnectRecord>); 1523 void linkGciInGcilist(Ptr<GcpRecord>); 1524 void linkTcInConnectionlist(Signal* signal); 1525 void releaseAbortResources(Signal* signal); 1526 void releaseApiCon(Signal* signal, UintR aApiConnectPtr); 1527 void releaseApiConCopy(Signal* signal); 1528 void releaseApiConnectFail(Signal* signal); 1529 void releaseAttrinfo(); 1530 void releaseKeys(); 1531 void releaseDirtyRead(Signal*, ApiConnectRecordPtr, TcConnectRecord*); 1532 void releaseDirtyWrite(Signal* signal); 1533 void releaseTcCon(); 1534 void releaseTcConnectFail(Signal* signal); 1535 void releaseTransResources(Signal* signal); 1536 void seizeApiConnect(Signal* signal); 1537 void seizeApiConnectCopy(Signal* signal); 1538 void seizeApiConnectFail(Signal* signal); 1539 void crash_gcp(Uint32 line); 1540 void seizeGcp(Ptr<GcpRecord> & dst, Uint64 gci); 1541 void seizeTcConnect(Signal* signal); 1542 void seizeTcConnectFail(Signal* signal); 1543 Ptr<ApiConnectRecord> sendApiCommit(Signal* signal); 1544 bool sendAttrInfoTrain(Signal* signal, 1545 UintR TBRef, 1546 Uint32 connectPtr, 1547 Uint32 offset, 1548 Uint32 attrInfoIVal); 1549 void sendContinueTimeOutControl(Signal* signal, Uint32 TapiConPtr); 1550 void sendlqhkeyreq(Signal* signal, 1551 BlockReference TBRef); 1552 void sendSystemError(Signal* signal, int line); 1553 void sendtckeyconf(Signal* signal, UintR TcommitFlag); 1554 void unlinkApiConnect(Ptr<GcpRecord>, Ptr<ApiConnectRecord>); 1555 void unlinkGcp(Ptr<GcpRecord>); 1556 void unlinkReadyTcCon(Signal* signal); 1557 void handleFailedOperation(Signal* signal, 1558 const LqhKeyRef * const lqhKeyRef, 1559 bool gotLqhKeyRef); 1560 void markOperationAborted(ApiConnectRecord * const regApiPtr, 1561 TcConnectRecord * const regTcPtr); 1562 void clearCommitAckMarker(ApiConnectRecord * const regApiPtr, 1563 TcConnectRecord * const regTcPtr); 1564 // Trigger and index handling 1565 int saveINDXKEYINFO(Signal* signal, 1566 TcIndexOperation* indexOp, 1567 const Uint32 *src, 1568 Uint32 len); 1569 bool receivedAllINDXKEYINFO(TcIndexOperation* indexOp); 1570 int saveINDXATTRINFO(Signal* signal, 1571 TcIndexOperation* indexOp, 1572 const Uint32 *src, 1573 Uint32 len); 1574 bool receivedAllINDXATTRINFO(TcIndexOperation* indexOp); 1575 bool saveTRANSID_AI(Signal* signal, 1576 TcIndexOperation* indexOp, 1577 const Uint32 *src, 1578 Uint32 len); 1579 bool receivedAllTRANSID_AI(TcIndexOperation* indexOp); 1580 void readIndexTable(Signal* signal, 1581 ApiConnectRecord* regApiPtr, 1582 TcIndexOperation* indexOp); 1583 void executeIndexOperation(Signal* signal, 1584 ApiConnectRecord* regApiPtr, 1585 TcIndexOperation* indexOp); 1586 bool seizeIndexOperation(ApiConnectRecord* regApiPtr, 1587 TcIndexOperationPtr& indexOpPtr); 1588 void releaseIndexOperation(ApiConnectRecord* regApiPtr, 1589 TcIndexOperation* indexOp); 1590 void releaseAllSeizedIndexOperations(ApiConnectRecord* regApiPtr); 1591 void setupIndexOpReturn(ApiConnectRecord* regApiPtr, 1592 TcConnectRecord* regTcPtr); 1593 1594 void saveTriggeringOpState(Signal* signal, 1595 TcConnectRecord* trigOp); 1596 void restoreTriggeringOpState(Signal* signal, 1597 TcConnectRecord* trigOp); 1598 void trigger_op_finished(Signal* signal, ApiConnectRecordPtr, 1599 TcConnectRecord* triggeringOp); 1600 void continueTriggeringOp(Signal* signal, TcConnectRecord* trigOp); 1601 1602 void executeTriggers(Signal* signal, ApiConnectRecordPtr* transPtr); 1603 void executeTrigger(Signal* signal, 1604 TcFiredTriggerData* firedTriggerData, 1605 ApiConnectRecordPtr* transPtr, 1606 TcConnectRecordPtr* opPtr); 1607 void executeIndexTrigger(Signal* signal, 1608 TcDefinedTriggerData* definedTriggerData, 1609 TcFiredTriggerData* firedTriggerData, 1610 ApiConnectRecordPtr* transPtr, 1611 TcConnectRecordPtr* opPtr); 1612 bool appendAttrDataToSection(Uint32& sectionIVal, 1613 DataBuffer<11>& values, 1614 bool withHeaders, 1615 Uint32& attrId, 1616 bool& hasNull); 1617 void insertIntoIndexTable(Signal* signal, 1618 TcFiredTriggerData* firedTriggerData, 1619 ApiConnectRecordPtr* transPtr, 1620 TcConnectRecordPtr* opPtr, 1621 TcIndexData* indexData); 1622 void deleteFromIndexTable(Signal* signal, 1623 TcFiredTriggerData* firedTriggerData, 1624 ApiConnectRecordPtr* transPtr, 1625 TcConnectRecordPtr* opPtr, 1626 TcIndexData* indexData); 1627 1628 void executeReorgTrigger(Signal* signal, 1629 TcDefinedTriggerData* definedTriggerData, 1630 TcFiredTriggerData* firedTriggerData, 1631 ApiConnectRecordPtr* transPtr, 1632 TcConnectRecordPtr* opPtr); 1633 1634 void releaseFiredTriggerData(DLFifoList<TcFiredTriggerData>* triggers); 1635 void abortTransFromTrigger(Signal* signal, const ApiConnectRecordPtr& transPtr, 1636 Uint32 error); 1637 // Generated statement blocks 1638 void warningHandlerLab(Signal* signal, int line); 1639 void systemErrorLab(Signal* signal, int line); 1640 void sendSignalErrorRefuseLab(Signal* signal); 1641 void scanTabRefLab(Signal* signal, Uint32 errCode); 1642 void diFcountReqLab(Signal* signal, ScanRecordPtr); 1643 void signalErrorRefuseLab(Signal* signal); 1644 void abort080Lab(Signal* signal); 1645 void sendKeyInfoTrain(Signal* signal, 1646 BlockReference TBRef, 1647 Uint32 connectPtr, 1648 Uint32 offset, 1649 Uint32 keyInfoIVal); 1650 void abortScanLab(Signal* signal, ScanRecordPtr, Uint32 errCode, 1651 bool not_started = false); 1652 void sendAbortedAfterTimeout(Signal* signal, int Tcheck); 1653 void abort010Lab(Signal* signal); 1654 void abort015Lab(Signal* signal); 1655 void packLqhkeyreq(Signal* signal, 1656 BlockReference TBRef); 1657 void packLqhkeyreq040Lab(Signal* signal, 1658 BlockReference TBRef); 1659 void returnFromQueuedDeliveryLab(Signal* signal); 1660 void startTakeOverLab(Signal* signal); 1661 void toCompleteHandlingLab(Signal* signal); 1662 void toCommitHandlingLab(Signal* signal); 1663 void toAbortHandlingLab(Signal* signal); 1664 void abortErrorLab(Signal* signal); 1665 void nodeTakeOverCompletedLab(Signal* signal); 1666 void ndbsttorry010Lab(Signal* signal); 1667 void commit020Lab(Signal* signal); 1668 void complete010Lab(Signal* signal); 1669 void releaseAtErrorLab(Signal* signal); 1670 void seizeDatabuferrorLab(Signal* signal); 1671 void appendToSectionErrorLab(Signal* signal); 1672 void scanKeyinfoLab(Signal* signal); 1673 void scanAttrinfoLab(Signal* signal, UintR Tlen); 1674 void attrinfoDihReceivedLab(Signal* signal); 1675 void aiErrorLab(Signal* signal); 1676 void scanReleaseResourcesLab(Signal* signal); 1677 void scanCompletedLab(Signal* signal); 1678 void scanError(Signal* signal, ScanRecordPtr, Uint32 errorCode); 1679 void diverify010Lab(Signal* signal); 1680 void intstartphase3x010Lab(Signal* signal); 1681 void sttorryLab(Signal* signal); 1682 void abortBeginErrorLab(Signal* signal); 1683 void tabStateErrorLab(Signal* signal); 1684 void wrongSchemaVersionErrorLab(Signal* signal); 1685 void noFreeConnectionErrorLab(Signal* signal); 1686 void tckeyreq050Lab(Signal* signal); 1687 void timeOutFoundLab(Signal* signal, UintR anAdd, Uint32 errCode); 1688 void completeTransAtTakeOverLab(Signal* signal, UintR TtakeOverInd); 1689 void completeTransAtTakeOverDoLast(Signal* signal, UintR TtakeOverInd); 1690 void completeTransAtTakeOverDoOne(Signal* signal, UintR TtakeOverInd); 1691 void timeOutLoopStartLab(Signal* signal, Uint32 apiConnectPtr); 1692 void initialiseRecordsLab(Signal* signal, UintR Tdata0, Uint32, Uint32); 1693 void tckeyreq020Lab(Signal* signal); 1694 void intstartphase1x010Lab(Signal* signal); 1695 void startphase1x010Lab(Signal* signal); 1696 1697 void lqhKeyConf_checkTransactionState(Signal * signal, 1698 Ptr<ApiConnectRecord> regApiPtr); 1699 1700 void checkDropTab(Signal* signal); 1701 1702 void checkScanActiveInFailedLqh(Signal* signal, 1703 Uint32 scanPtrI, 1704 Uint32 failedNodeId); 1705 void checkScanFragList(Signal*, Uint32 failedNodeId, ScanRecord * scanP, 1706 LocalDLList<ScanFragRec>::Head&); 1707 1708 void nodeFailCheckTransactions(Signal*,Uint32 transPtrI,Uint32 failedNodeId); 1709 void ndbdFailBlockCleanupCallback(Signal* signal, Uint32 failedNodeId, Uint32 ignoredRc); 1710 void checkNodeFailComplete(Signal* signal, Uint32 failedNodeId, Uint32 bit); 1711 1712 void apiFailBlockCleanupCallback(Signal* signal, Uint32 failedNodeId, Uint32 ignoredRc); 1713 bool isRefreshSupported() const; 1714 1715 // Initialisation 1716 void initData(); 1717 void initRecords(); 1718 1719 protected: 1720 virtual bool getParam(const char* name, Uint32* count); 1721 1722 private: 1723 1724 // Transit signals 1725 1726 1727 ApiConnectRecord *apiConnectRecord; 1728 ApiConnectRecordPtr apiConnectptr; 1729 UintR capiConnectFilesize; 1730 1731 TcConnectRecord *tcConnectRecord; 1732 TcConnectRecordPtr tcConnectptr; 1733 UintR ctcConnectFilesize; 1734 1735 CacheRecord *cacheRecord; 1736 CacheRecordPtr cachePtr; 1737 UintR ccacheFilesize; 1738 1739 HostRecord *hostRecord; 1740 HostRecordPtr hostptr; 1741 UintR chostFilesize; 1742 NdbNodeBitmask c_alive_nodes; 1743 1744 Uint32 c_ongoing_take_over_cnt; 1745 GcpRecord *gcpRecord; 1746 UintR cgcpFilesize; 1747 1748 TableRecord *tableRecord; 1749 UintR ctabrecFilesize; 1750 1751 UintR thashValue; 1752 UintR tdistrHashValue; 1753 1754 UintR ttransid_ptr; 1755 UintR cfailure_nr; 1756 UintR coperationsize; 1757 UintR ctcTimer; 1758 UintR cDbHbInterval; 1759 1760 Uint64 tcheckGcpId; 1761 1762 // Montonically increasing counters 1763 struct MonotonicCounters { 1764 Uint64 cattrinfoCount; 1765 Uint64 ctransCount; 1766 Uint64 ccommitCount; 1767 Uint64 creadCount; 1768 Uint64 csimpleReadCount; 1769 Uint64 cwriteCount; 1770 Uint64 cabortCount; 1771 Uint64 c_scan_count; 1772 Uint64 c_range_scan_count; 1773 1774 // Resource usage counter(not monotonic) 1775 Uint32 cconcurrentOp; 1776 MonotonicCountersDbtc::MonotonicCounters1777 MonotonicCounters() : 1778 cattrinfoCount(0), 1779 ctransCount(0), 1780 ccommitCount(0), 1781 creadCount(0), 1782 csimpleReadCount(0), 1783 cwriteCount(0), 1784 cabortCount(0), 1785 c_scan_count(0), 1786 c_range_scan_count(0), 1787 cconcurrentOp(0) {} 1788 build_event_repDbtc::MonotonicCounters1789 Uint32 build_event_rep(Signal* signal) 1790 { 1791 /* 1792 Read saved value from CONTINUEB, subtract from 1793 counter and write to EVENT_REP 1794 */ 1795 const Uint32 attrinfoCount = diff(signal, 1, cattrinfoCount); 1796 const Uint32 transCount = diff(signal, 3, ctransCount); 1797 const Uint32 commitCount = diff(signal, 5, ccommitCount); 1798 const Uint32 readCount = diff(signal, 7, creadCount); 1799 const Uint32 simpleReadCount = diff(signal, 9, csimpleReadCount); 1800 const Uint32 writeCount = diff(signal, 11, cwriteCount); 1801 const Uint32 abortCount = diff(signal, 13, cabortCount); 1802 const Uint32 scan_count = diff(signal, 15, c_scan_count); 1803 const Uint32 range_scan_count = diff(signal, 17, c_range_scan_count); 1804 1805 signal->theData[0] = NDB_LE_TransReportCounters; 1806 signal->theData[1] = transCount; 1807 signal->theData[2] = commitCount; 1808 signal->theData[3] = readCount; 1809 signal->theData[4] = simpleReadCount; 1810 signal->theData[5] = writeCount; 1811 signal->theData[6] = attrinfoCount; 1812 signal->theData[7] = cconcurrentOp; // Exception that confirms the rule! 1813 signal->theData[8] = abortCount; 1814 signal->theData[9] = scan_count; 1815 signal->theData[10] = range_scan_count; 1816 return 11; 1817 } 1818 build_continueBDbtc::MonotonicCounters1819 Uint32 build_continueB(Signal* signal) const 1820 { 1821 /* Save current value of counters to CONTINUEB */ 1822 const Uint64* vars[] = { 1823 &cattrinfoCount, &ctransCount, &ccommitCount, 1824 &creadCount, &csimpleReadCount, &cwriteCount, 1825 &cabortCount, &c_scan_count, &c_range_scan_count }; 1826 const size_t num = sizeof(vars)/sizeof(vars[0]); 1827 1828 for (size_t i = 0; i < num; i++) 1829 { 1830 signal->theData[1+i*2] = Uint32(*vars[i] >> 32); 1831 signal->theData[1+i*2+1] = Uint32(*vars[i]); 1832 } 1833 return 1 + num * 2; 1834 } 1835 private: diffDbtc::MonotonicCounters1836 Uint32 diff(Signal* signal, size_t pos, Uint64 curr) const 1837 { 1838 const Uint64 old = 1839 (signal->theData[pos+1] | (Uint64(signal->theData[pos]) << 32)); 1840 return (Uint32)(curr - old); 1841 } 1842 } c_counters; 1843 1844 Uint16 cownNodeid; 1845 Uint16 terrorCode; 1846 1847 UintR cfirstfreeTcConnect; 1848 UintR cfirstfreeApiConnectCopy; 1849 UintR cfirstfreeCacheRec; 1850 1851 UintR cfirstgcp; 1852 UintR clastgcp; 1853 UintR cfirstfreeGcp; 1854 UintR cfirstfreeScanrec; 1855 1856 TableRecordPtr tabptr; 1857 UintR cfirstfreeApiConnectFail; 1858 UintR cfirstfreeApiConnect; 1859 1860 BlockReference cdihblockref; 1861 BlockReference cownref; /* OWN BLOCK REFERENCE */ 1862 1863 ApiConnectRecordPtr timeOutptr; 1864 1865 ScanRecord *scanRecord; 1866 UintR cscanrecFileSize; 1867 1868 UnsafeArrayPool<ScanFragRec> c_scan_frag_pool; 1869 ScanFragRecPtr scanFragptr; 1870 1871 UintR cscanFragrecFileSize; 1872 1873 BlockReference cdictblockref; 1874 BlockReference cerrorBlockref; 1875 BlockReference clqhblockref; 1876 BlockReference cndbcntrblockref; 1877 1878 Uint16 csignalKey; 1879 Uint16 csystemnodes; 1880 Uint16 cnodes[4]; 1881 NodeId cmasterNodeId; 1882 UintR cnoParallelTakeOver; 1883 TimeOutCheckState ctimeOutCheckFragActive; 1884 1885 UintR ctimeOutCheckFragCounter; 1886 UintR ctimeOutCheckCounter; 1887 UintR ctimeOutValue; 1888 UintR ctimeOutCheckDelay; 1889 Uint32 ctimeOutCheckHeartbeat; 1890 Uint32 ctimeOutCheckLastHeartbeat; 1891 Uint32 ctimeOutMissedHeartbeats; 1892 Uint32 c_appl_timeout_value; 1893 1894 SystemStartState csystemStart; 1895 TimeOutCheckState ctimeOutCheckActive; 1896 1897 BlockReference capiFailRef; 1898 UintR cpackedListIndex; 1899 Uint16 cpackedList[MAX_NODES]; 1900 UintR capiConnectClosing[MAX_NODES]; 1901 UintR con_lineNodes; 1902 1903 UintR treqinfo; 1904 UintR ttransid1; 1905 UintR ttransid2; 1906 1907 UintR tabortInd; 1908 1909 NodeId tnodeid; 1910 BlockReference tblockref; 1911 1912 LqhTransConf::OperationStatus ttransStatus; 1913 UintR ttcOprec; 1914 NodeId tfailedNodeId; 1915 Uint8 tcurrentReplicaNo; 1916 Uint8 tpad1; 1917 1918 Uint64 tgci; 1919 UintR tapplRef; 1920 UintR tapplOprec; 1921 1922 UintR tindex; 1923 UintR tmaxData; 1924 UintR tmp; 1925 1926 UintR tnodes; 1927 BlockReference tusersblkref; 1928 UintR tuserpointer; 1929 UintR tloadCode; 1930 1931 UintR tconfig1; 1932 UintR tconfig2; 1933 1934 UintR cdata[32]; 1935 UintR ctransidFailHash[512]; 1936 UintR ctcConnectFailHash[1024]; 1937 1938 /** 1939 * Commit Ack handling 1940 */ 1941 public: 1942 struct CommitAckMarker { CommitAckMarkerDbtc::CommitAckMarker1943 CommitAckMarker() {} 1944 Uint32 transid1; 1945 Uint32 transid2; 1946 union { Uint32 nextPool; Uint32 nextHash; }; 1947 Uint32 prevHash; 1948 Uint32 apiConnectPtr; 1949 Uint16 apiNodeId; 1950 NdbNodeBitmask m_commit_ack_marker_nodes; 1951 equalDbtc::CommitAckMarker1952 inline bool equal(const CommitAckMarker & p) const { 1953 return ((p.transid1 == transid1) && (p.transid2 == transid2)); 1954 } 1955 hashValueDbtc::CommitAckMarker1956 inline Uint32 hashValue() const { 1957 return transid1; 1958 } 1959 }; 1960 1961 private: 1962 typedef Ptr<CommitAckMarker> CommitAckMarkerPtr; 1963 typedef DLHashTable<CommitAckMarker>::Iterator CommitAckMarkerIterator; 1964 1965 ArrayPool<CommitAckMarker> m_commitAckMarkerPool; 1966 DLHashTable<CommitAckMarker> m_commitAckMarkerHash; 1967 1968 void execTC_COMMIT_ACK(Signal* signal); 1969 void sendRemoveMarkers(Signal*, const CommitAckMarker *); 1970 void sendRemoveMarker(Signal* signal, 1971 NodeId nodeId, 1972 Uint32 transid1, 1973 Uint32 transid2); 1974 void removeMarkerForFailedAPI(Signal* signal, Uint32 nodeId, Uint32 bucket); 1975 getAllowStartTransaction(Uint32 nodeId,Uint32 table_single_user_mode) const1976 bool getAllowStartTransaction(Uint32 nodeId, Uint32 table_single_user_mode) const { 1977 if (unlikely(getNodeState().getSingleUserMode())) 1978 { 1979 if (getNodeState().getSingleUserApi() == nodeId || table_single_user_mode) 1980 return true; 1981 else 1982 return false; 1983 } 1984 return getNodeState().startLevel < NodeState::SL_STOPPING_2; 1985 } 1986 1987 void checkAbortAllTimeout(Signal* signal, Uint32 sleepTime); 1988 struct AbortAllRecord { AbortAllRecordDbtc::AbortAllRecord1989 AbortAllRecord(){ clientRef = 0; } 1990 Uint32 clientData; 1991 BlockReference clientRef; 1992 1993 Uint32 oldTimeOutValue; 1994 }; 1995 AbortAllRecord c_abortRec; 1996 1997 bool validate_filter(Signal*); 1998 bool match_and_print(Signal*, ApiConnectRecordPtr); 1999 2000 #ifdef ERROR_INSERT 2001 bool testFragmentDrop(Signal* signal); 2002 #endif 2003 2004 /************************** API CONNECT RECORD ***********************/ 2005 /* *******************************************************************/ 2006 /* THE API CONNECT RECORD CONTAINS THE CONNECTION RECORD TO WHICH THE*/ 2007 /* APPLICATION CONNECTS. THE APPLICATION CAN SEND ONE OPERATION AT A */ 2008 /* TIME. IT CAN SEND A NEW OPERATION IMMEDIATELY AFTER SENDING THE */ 2009 /* PREVIOUS OPERATION. THEREBY SEVERAL OPERATIONS CAN BE ACTIVE IN */ 2010 /* ONE TRANSACTION WITHIN TC. THIS IS ACHIEVED BY USING THE API */ 2011 /* CONNECT RECORD. EACH ACTIVE OPERATION IS HANDLED BY THE TC */ 2012 /* CONNECT RECORD. AS SOON AS THE TC CONNECT RECORD HAS SENT THE */ 2013 /* REQUEST TO THE LQH IT IS READY TO RECEIVE NEW OPERATIONS. THE */ 2014 /* LQH CONNECT RECORD TAKES CARE OF WAITING FOR AN OPERATION TO */ 2015 /* COMPLETE. WHEN AN OPERATION HAS COMPLETED ON THE LQH CONNECT */ 2016 /* RECORD A NEW OPERATION CAN BE STARTED ON THIS LQH CONNECT RECORD. */ 2017 /*******************************************************************>*/ 2018 /* */ 2019 /* API CONNECT RECORD ALIGNED TO BE 256 BYTES */ 2020 /*******************************************************************>*/ 2021 /************************** TC CONNECT RECORD ************************/ 2022 /* *******************************************************************/ 2023 /* TC CONNECT RECORD KEEPS ALL INFORMATION TO CARRY OUT A TRANSACTION*/ 2024 /* THE TRANSACTION CONTROLLER ESTABLISHES CONNECTIONS TO DIFFERENT */ 2025 /* BLOCKS TO CARRY OUT THE TRANSACTION. THERE CAN BE SEVERAL RECORDS */ 2026 /* PER ACTIVE TRANSACTION. THE TC CONNECT RECORD COOPERATES WITH THE */ 2027 /* API CONNECT RECORD FOR COMMUNICATION WITH THE API AND WITH THE */ 2028 /* LQH CONNECT RECORD FOR COMMUNICATION WITH THE LQH'S INVOLVED IN */ 2029 /* THE TRANSACTION. TC CONNECT RECORD IS PERMANENTLY CONNECTED TO A */ 2030 /* RECORD IN DICT AND ONE IN DIH. IT CONTAINS A LIST OF ACTIVE LQH */ 2031 /* CONNECT RECORDS AND A LIST OF STARTED BUT NOT ACTIVE LQH CONNECT */ 2032 /* RECORDS. IT DOES ALSO CONTAIN A LIST OF ALL OPERATIONS THAT ARE */ 2033 /* EXECUTED WITH THE TC CONNECT RECORD. */ 2034 /*******************************************************************>*/ 2035 /* TC_CONNECT RECORD ALIGNED TO BE 128 BYTES */ 2036 /*******************************************************************>*/ 2037 UintR cfirstfreeTcConnectFail; 2038 2039 /* POINTER FOR THE LQH RECORD*/ 2040 /* ************************ HOST RECORD ********************************* */ 2041 /********************************************************/ 2042 /* THIS RECORD CONTAINS ALIVE-STATUS ON ALL NODES IN THE*/ 2043 /* SYSTEM */ 2044 /********************************************************/ 2045 /* THIS RECORD IS ALIGNED TO BE 8 BYTES. */ 2046 /********************************************************/ 2047 /* ************************ TABLE RECORD ******************************** */ 2048 /********************************************************/ 2049 /* THIS RECORD CONTAINS THE CURRENT SCHEMA VERSION OF */ 2050 /* ALL TABLES IN THE SYSTEM. */ 2051 /********************************************************/ 2052 /*-------------------------------------------------------------------------*/ 2053 /* THE TC CONNECTION USED BY THIS SCAN. */ 2054 /*-------------------------------------------------------------------------*/ 2055 /*-------------------------------------------------------------------------*/ 2056 /* LENGTH READ FOR A PARTICULAR SCANNED OPERATION. */ 2057 /*-------------------------------------------------------------------------*/ 2058 /*-------------------------------------------------------------------------*/ 2059 /* REFERENCE TO THE SCAN RECORD FOR THIS SCAN PROCESS. */ 2060 /*-------------------------------------------------------------------------*/ 2061 /* *********************************************************************** */ 2062 /* ******$ DATA BUFFER ******$ */ 2063 /* */ 2064 /* THIS BUFFER IS USED AS A GENERAL DATA STORAGE. */ 2065 /* *********************************************************************** */ 2066 /* *********************************************************************** */ 2067 /* ******$ ATTRIBUTE INFORMATION RECORD ******$ */ 2068 /* 2069 CAN CONTAIN ONE (1) ATTRINFO SIGNAL. ONE SIGNAL CONTAINS 24 ATTR. 2070 INFO WORDS. BUT 32 ELEMENTS ARE USED TO MAKE PLEX HAPPY. 2071 SOME OF THE ELEMENTS ARE USED TO THE FOLLOWING THINGS: 2072 DATA LENGHT IN THIS RECORD IS STORED IN THE ELEMENT INDEXED BY 2073 ZINBUF_DATA_LEN. 2074 NEXT FREE ATTRBUF IS POINTED OUT BY THE ELEMENT INDEXED BY 2075 PREVIOUS ATTRBUF IS POINTED OUT BY THE ELEMENT INDEXED BY ZINBUF_PREV 2076 (NOT USED YET). 2077 NEXT ATTRBUF IS POINTED OUT BY THE ELEMENT INDEXED BY ZINBUF_NEXT. 2078 */ 2079 /* ********************************************************************** */ 2080 /**************************************************************************/ 2081 /* GLOBAL CHECKPOINT INFORMATION RECORD */ 2082 /* */ 2083 /* THIS RECORD IS USED TO STORE THE GCP NUMBER AND A COUNTER */ 2084 /* DURING THE COMPLETION PHASE OF THE TRANSACTION */ 2085 /**************************************************************************/ 2086 /* */ 2087 /* GCP RECORD ALIGNED TO BE 32 BYTES */ 2088 /**************************************************************************/ 2089 /**************************************************************************/ 2090 /* TC_FAIL_RECORD */ 2091 /* THIS RECORD IS USED WHEN HANDLING TAKE OVER OF ANOTHER FAILED TC NODE.*/ 2092 /**************************************************************************/ 2093 TcFailRecord *tcFailRecord; 2094 TcFailRecordPtr tcNodeFailptr; 2095 /**************************************************************************/ 2096 // Temporary variables that are not allowed to use for storage between 2097 // signals. They 2098 // can only be used in a signal to transfer values between subroutines. 2099 // In the long run 2100 // those variables should be removed and exchanged for stack 2101 // variable communication. 2102 /**************************************************************************/ 2103 2104 Uint32 c_gcp_ref; 2105 Uint32 c_gcp_data; 2106 2107 Uint32 c_sttor_ref; 2108 2109 #ifdef ERROR_INSERT 2110 // Used with ERROR_INSERT 8078 + 8079 to check API_FAILREQ handling 2111 Uint32 c_lastFailedApi; 2112 #endif 2113 Uint32 m_deferred_enabled; 2114 Uint32 m_max_writes_per_trans; 2115 }; 2116 2117 #endif 2118