diff options
Diffstat (limited to 'storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp')
-rw-r--r-- | storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp | 2953 |
1 files changed, 2953 insertions, 0 deletions
diff --git a/storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp b/storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp new file mode 100644 index 00000000000..e7debe1f978 --- /dev/null +++ b/storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp @@ -0,0 +1,2953 @@ +/* Copyright (C) 2003 MySQL AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#ifndef DBLQH_H +#define DBLQH_H + +#include <pc.hpp> +#include <ndb_limits.h> +#include <SimulatedBlock.hpp> +#include <DLList.hpp> +#include <DLFifoList.hpp> +#include <DLHashTable.hpp> + +#include <NodeBitmask.hpp> +#include <signaldata/LCP.hpp> +#include <signaldata/LqhTransConf.hpp> +#include <signaldata/LqhFrag.hpp> + +// primary key is stored in TUP +#include <../dbtup/Dbtup.hpp> + +#ifdef DBLQH_C +// Constants +/* ------------------------------------------------------------------------- */ +/* CONSTANTS USED WHEN MASTER REQUESTS STATE OF COPY FRAGMENTS. */ +/* ------------------------------------------------------------------------- */ +#define ZCOPY_CLOSING 0 +#define ZCOPY_ONGOING 1 +#define ZCOPY_ACTIVATION 2 +/* ------------------------------------------------------------------------- */ +/* STATES FOR THE VARIABLE GCP_LOG_PART_STATE */ +/* ------------------------------------------------------------------------- */ +#define ZIDLE 0 +#define ZWAIT_DISK 1 +#define ZON_DISK 2 +#define ZACTIVE 1 +/* ------------------------------------------------------------------------- */ +/* STATES FOR THE VARIABLE CSR_PHASES_STARTED */ +/* ------------------------------------------------------------------------- */ +#define ZSR_NO_PHASE_STARTED 0 +#define ZSR_PHASE1_COMPLETED 1 +#define ZSR_PHASE2_COMPLETED 2 +#define ZSR_BOTH_PHASES_STARTED 3 +/* ------------------------------------------------------------------------- */ +/* THE NUMBER OF PAGES IN A MBYTE, THE TWO LOGARITHM OF THIS. */ +/* THE NUMBER OF MBYTES IN A LOG FILE. */ +/* THE MAX NUMBER OF PAGES READ/WRITTEN FROM/TO DISK DURING */ +/* A WRITE OR READ. */ +/* ------------------------------------------------------------------------- */ +#define ZNOT_DIRTY 0 +#define ZDIRTY 1 +#define ZREAD_AHEAD_SIZE 8 +/* ------------------------------------------------------------------------- */ +/* CONSTANTS OF THE LOG PAGES */ +/* ------------------------------------------------------------------------- */ +#define ZPAGE_HEADER_SIZE 32 +#define ZNO_MBYTES_IN_FILE 16 +#define ZPAGE_SIZE 8192 +#define ZPAGES_IN_MBYTE 32 +#define ZTWOLOG_NO_PAGES_IN_MBYTE 5 +#define ZTWOLOG_PAGE_SIZE 13 +#define ZMAX_MM_BUFFER_SIZE 32 // Main memory window during log execution + +#define ZMAX_PAGES_WRITTEN 8 // Max pages before writing to disk (=> config) +#define ZMIN_READ_BUFFER_SIZE 2 // Minimum number of pages to execute log +#define ZMIN_LOG_PAGES_OPERATION 10 // Minimum no of pages before stopping + +#define ZPOS_CHECKSUM 0 +#define ZPOS_LOG_LAP 1 +#define ZPOS_MAX_GCI_COMPLETED 2 +#define ZPOS_MAX_GCI_STARTED 3 +#define ZNEXT_PAGE 4 +#define ZPREV_PAGE 5 +#define ZPOS_VERSION 6 +#define ZPOS_NO_LOG_FILES 7 +#define ZCURR_PAGE_INDEX 8 +#define ZLAST_LOG_PREP_REF 10 +#define ZPOS_DIRTY 11 +/* ------------------------------------------------------------------------- */ +/* CONSTANTS FOR THE VARIOUS REPLICA AND NODE TYPES. */ +/* ------------------------------------------------------------------------- */ +#define ZPRIMARY_NODE 0 +#define ZBACKUP_NODE 1 +#define ZSTANDBY_NODE 2 +#define ZTC_NODE 3 +#define ZLOG_NODE 3 +/* ------------------------------------------------------------------------- */ +/* VARIOUS CONSTANTS USED AS FLAGS TO THE FILE MANAGER. */ +/* ------------------------------------------------------------------------- */ +#define ZOPEN_READ 0 +#define ZOPEN_WRITE 1 +#define ZOPEN_READ_WRITE 2 +#define ZVAR_NO_LOG_PAGE_WORD 1 +#define ZLIST_OF_PAIRS 0 +#define ZLIST_OF_PAIRS_SYNCH 16 +#define ZARRAY_OF_PAGES 1 +#define ZLIST_OF_MEM_PAGES 2 +#define ZLIST_OF_MEM_PAGES_SYNCH 18 +#define ZCLOSE_NO_DELETE 0 +#define ZCLOSE_DELETE 1 +#define ZPAGE_ZERO 0 +/* ------------------------------------------------------------------------- */ +/* THE FOLLOWING CONSTANTS ARE USED TO DESCRIBE THE TYPES OF */ +/* LOG RECORDS, THE SIZE OF THE VARIOUS LOG RECORD TYPES AND */ +/* THE POSITIONS WITHIN THOSE LOG RECORDS. */ +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ +/* THESE CONSTANTS DESCRIBE THE SIZES OF VARIOUS TYPES OF LOG REORDS. */ +/* NEXT_LOG_SIZE IS ACTUALLY ONE. THE REASON WE SET IT TO 2 IS TO */ +/* SIMPLIFY THE CODE SINCE OTHERWISE HAVE TO USE A SPECIAL VERSION */ +/* OF READ_LOGWORD WHEN READING LOG RECORD TYPE */ +/* SINCE NEXT MBYTE TYPE COULD BE THE VERY LAST WORD IN THE MBYTE. */ +/* BY SETTING IT TO 2 WE ENSURE IT IS NEVER THE VERY LAST WORD */ +/* IN THE MBYTE. */ +/* ------------------------------------------------------------------------- */ +#define ZFD_HEADER_SIZE 3 +#define ZFD_PART_SIZE 48 +#define ZLOG_HEAD_SIZE 6 +#define ZNEXT_LOG_SIZE 2 +#define ZABORT_LOG_SIZE 3 +#define ZCOMMIT_LOG_SIZE 9 +#define ZCOMPLETED_GCI_LOG_SIZE 2 +/* ------------------------------------------------------------------------- */ +/* THESE CONSTANTS DESCRIBE THE TYPE OF A LOG RECORD. */ +/* THIS IS THE FIRST WORD OF A LOG RECORD. */ +/* ------------------------------------------------------------------------- */ +#define ZNEW_PREP_OP_TYPE 0 +#define ZPREP_OP_TYPE 1 +#define ZCOMMIT_TYPE 2 +#define ZABORT_TYPE 3 +#define ZFD_TYPE 4 +#define ZFRAG_SPLIT_TYPE 5 +#define ZNEXT_LOG_RECORD_TYPE 6 +#define ZNEXT_MBYTE_TYPE 7 +#define ZCOMPLETED_GCI_TYPE 8 +#define ZINVALID_COMMIT_TYPE 9 +/* ------------------------------------------------------------------------- */ +/* THE POSITIONS OF LOGGED DATA IN A FILE DESCRIPTOR LOG RECORD HEADER.*/ +/* ALSO THE MAXIMUM NUMBER OF FILE DESCRIPTORS IN A LOG RECORD. */ +/* ------------------------------------------------------------------------- */ +#define ZPOS_LOG_TYPE 0 +#define ZPOS_NO_FD 1 +#define ZPOS_FILE_NO 2 +#define ZMAX_LOG_FILES_IN_PAGE_ZERO 40 +/* ------------------------------------------------------------------------- */ +/* THE POSITIONS WITHIN A PREPARE LOG RECORD AND A NEW PREPARE */ +/* LOG RECORD. */ +/* ------------------------------------------------------------------------- */ +#define ZPOS_HASH_VALUE 2 +#define ZPOS_SCHEMA_VERSION 3 +#define ZPOS_TRANS_TICKET 4 +#define ZPOS_OP_TYPE 5 +#define ZPOS_NO_ATTRINFO 6 +#define ZPOS_NO_KEYINFO 7 +/* ------------------------------------------------------------------------- */ +/* THE POSITIONS WITHIN A COMMIT LOG RECORD. */ +/* ------------------------------------------------------------------------- */ +#define ZPOS_COMMIT_TRANSID1 1 +#define ZPOS_COMMIT_TRANSID2 2 +#define ZPOS_COMMIT_GCI 3 +#define ZPOS_COMMIT_TABLE_REF 4 +#define ZPOS_COMMIT_FRAGID 5 +#define ZPOS_COMMIT_FILE_NO 6 +#define ZPOS_COMMIT_START_PAGE_NO 7 +#define ZPOS_COMMIT_START_PAGE_INDEX 8 +#define ZPOS_COMMIT_STOP_PAGE_NO 9 +/* ------------------------------------------------------------------------- */ +/* THE POSITIONS WITHIN A ABORT LOG RECORD. */ +/* ------------------------------------------------------------------------- */ +#define ZPOS_ABORT_TRANSID1 1 +#define ZPOS_ABORT_TRANSID2 2 +/* ------------------------------------------------------------------------- */ +/* THE POSITION WITHIN A COMPLETED GCI LOG RECORD. */ +/* ------------------------------------------------------------------------- */ +#define ZPOS_COMPLETED_GCI 1 +/* ------------------------------------------------------------------------- */ +/* THE POSITIONS WITHIN A NEW PREPARE LOG RECORD. */ +/* ------------------------------------------------------------------------- */ +#define ZPOS_NEW_PREP_FILE_NO 8 +#define ZPOS_NEW_PREP_PAGE_REF 9 + +#define ZLAST_WRITE_IN_FILE 1 +#define ZENFORCE_WRITE 2 +/* ------------------------------------------------------------------------- */ +/* CONSTANTS USED AS INPUT TO SUBROUTINE WRITE_LOG_PAGES AMONG OTHERS. */ +/* ------------------------------------------------------------------------- */ +#define ZNORMAL 0 +#define ZINIT 1 +/* ------------------------------------------------------------------------- */ +/* CONSTANTS USED BY CONTINUEB TO DEDUCE WHICH CONTINUE SIGNAL IS TO */ +/* BE EXECUTED AS A RESULT OF THIS CONTINUEB SIGNAL. */ +/* ------------------------------------------------------------------------- */ +#define ZLOG_LQHKEYREQ 0 +#define ZPACK_LQHKEYREQ 1 +#define ZSEND_ATTRINFO 2 +#define ZSR_GCI_LIMITS 3 +#define ZSR_LOG_LIMITS 4 +#define ZSEND_EXEC_CONF 5 +#define ZEXEC_SR 6 +#define ZSR_FOURTH_COMP 7 +#define ZINIT_FOURTH 8 +#define ZTIME_SUPERVISION 9 +#define ZSR_PHASE3_START 10 +#define ZLQH_TRANS_NEXT 11 +#define ZLQH_RELEASE_AT_NODE_FAILURE 12 +#define ZSCAN_TC_CONNECT 13 +#define ZINITIALISE_RECORDS 14 +#define ZINIT_GCP_REC 15 +#define ZRESTART_OPERATIONS_AFTER_STOP 16 +#define ZCHECK_LCP_STOP_BLOCKED 17 +#define ZSCAN_MARKERS 18 +#define ZOPERATION_EVENT_REP 19 +#define ZPREP_DROP_TABLE 20 + +/* ------------------------------------------------------------------------- */ +/* NODE STATE DURING SYSTEM RESTART, VARIABLES CNODES_SR_STATE */ +/* AND CNODES_EXEC_SR_STATE. */ +/* ------------------------------------------------------------------------- */ +#define ZSTART_SR 1 +#define ZEXEC_SR_COMPLETED 2 +/* ------------------------------------------------------------------------- */ +/* CONSTANTS USED BY NODE STATUS TO DEDUCE THE STATUS OF A NODE. */ +/* ------------------------------------------------------------------------- */ +#define ZNODE_UP 0 +#define ZNODE_DOWN 1 +/* ------------------------------------------------------------------------- */ +/* START PHASES */ +/* ------------------------------------------------------------------------- */ +#define ZLAST_START_PHASE 255 +#define ZSTART_PHASE1 1 +#define ZSTART_PHASE2 2 +#define ZSTART_PHASE3 3 +#define ZSTART_PHASE4 4 +#define ZSTART_PHASE6 6 +/* ------------------------------------------------------------------------- */ +/* CONSTANTS USED BY SCAN AND COPY FRAGMENT PROCEDURES */ +/* ------------------------------------------------------------------------- */ +#define ZSTORED_PROC_SCAN 0 +#define ZSTORED_PROC_COPY 2 +#define ZDELETE_STORED_PROC_ID 3 +//#define ZSCAN_NEXT 1 +//#define ZSCAN_NEXT_COMMIT 2 +//#define ZSCAN_NEXT_ABORT 12 +#define ZCOPY_COMMIT 3 +#define ZCOPY_REPEAT 4 +#define ZCOPY_ABORT 5 +#define ZCOPY_CLOSE 6 +//#define ZSCAN_CLOSE 6 +//#define ZEMPTY_FRAGMENT 0 +#define ZWRITE_LOCK 1 +#define ZSCAN_FRAG_CLOSED 2 +/* ------------------------------------------------------------------------- */ +/* ERROR CODES ADDED IN VERSION 0.1 AND 0.2 */ +/* ------------------------------------------------------------------------- */ +#define ZNOT_FOUND 1 // Not an error code, a return value +#define ZNO_FREE_LQH_CONNECTION 414 +#define ZGET_DATAREC_ERROR 418 +#define ZGET_ATTRINBUF_ERROR 419 +#define ZNO_FREE_FRAGMENTREC 460 // Insert new fragment error code +#define ZTAB_FILE_SIZE 464 // Insert new fragment error code + Start kernel +#define ZNO_ADD_FRAGREC 465 // Insert new fragment error code +/* ------------------------------------------------------------------------- */ +/* ERROR CODES ADDED IN VERSION 0.3 */ +/* ------------------------------------------------------------------------- */ +#define ZTAIL_PROBLEM_IN_LOG_ERROR 410 +#define ZGCI_TOO_LOW_ERROR 429 // GCP_SAVEREF error code +#define ZTAB_STATE_ERROR 474 // Insert new fragment error code +#define ZTOO_NEW_GCI_ERROR 479 // LCP Start error +/* ------------------------------------------------------------------------- */ +/* ERROR CODES ADDED IN VERSION 0.4 */ +/* ------------------------------------------------------------------------- */ + +#define ZNO_FREE_FRAG_SCAN_REC_ERROR 490 // SCAN_FRAGREF error code +#define ZCOPY_NO_FRAGMENT_ERROR 491 // COPY_FRAGREF error code +#define ZTAKE_OVER_ERROR 499 +#define ZCOPY_NODE_ERROR 1204 +#define ZTOO_MANY_COPY_ACTIVE_ERROR 1208 // COPY_FRAG and COPY_ACTIVEREF code +#define ZCOPY_ACTIVE_ERROR 1210 // COPY_ACTIVEREF error code +#define ZNO_TC_CONNECT_ERROR 1217 // Simple Read + SCAN +/* ------------------------------------------------------------------------- */ +/* ERROR CODES ADDED IN VERSION 1.X */ +/* ------------------------------------------------------------------------- */ +//#define ZSCAN_BOOK_ACC_OP_ERROR 1219 // SCAN_FRAGREF error code +#define ZFILE_CHANGE_PROBLEM_IN_LOG_ERROR 1220 +#define ZTEMPORARY_REDO_LOG_FAILURE 1221 +#define ZNO_FREE_MARKER_RECORDS_ERROR 1222 +#define ZNODE_SHUTDOWN_IN_PROGESS 1223 +#define ZTOO_MANY_FRAGMENTS 1224 +#define ZTABLE_NOT_DEFINED 1225 +#define ZDROP_TABLE_IN_PROGRESS 1226 +#define ZINVALID_SCHEMA_VERSION 1227 + +/* ------------------------------------------------------------------------- */ +/* ERROR CODES ADDED IN VERSION 2.X */ +/* ------------------------------------------------------------------------- */ +#define ZNODE_FAILURE_ERROR 400 +/* ------------------------------------------------------------------------- */ +/* ERROR CODES FROM ACC */ +/* ------------------------------------------------------------------------- */ +#define ZNO_TUPLE_FOUND 626 +#define ZTUPLE_ALREADY_EXIST 630 +/* ------------------------------------------------------------------------- */ +/* ERROR CODES FROM TUP */ +/* ------------------------------------------------------------------------- */ +#define ZSEARCH_CONDITION_FALSE 899 +#define ZUSER_ERROR_CODE_LIMIT 6000 +#endif + +/** + * @class dblqh + * + * @section secIntro Introduction + * + * Dblqh is the coordinator of the LDM. Dblqh is responsible for + * performing operations on tuples. It does this job with help of + * Dbacc block (that manages the index structures) and Dbtup + * (that manages the tuples). + * + * Dblqh also keeps track of the participants and acts as a coordinator of + * 2-phase commits. Logical redo logging is also handled by the Dblqh + * block. + * + * @section secModules Modules + * + * The code is partitioned into the following modules: + * - START / RESTART + * - Start phase 1: Load our block reference and our processor id + * - Start phase 2: Initiate all records within the block + * Connect LQH with ACC and TUP. + * - Start phase 4: Connect LQH with LQH. Connect every LQH with + * every LQH in the database system. + * If initial start, then create the fragment log files. + * If system restart or node restart, + * then open the fragment log files and + * find the end of the log files. + * - ADD / DELETE FRAGMENT<br> + * Used by dictionary to create new fragments and delete old fragments. + * - EXECUTION<br> + * handles the reception of lqhkeyreq and all processing + * of operations on behalf of this request. + * This does also involve reception of various types of attrinfo + * and keyinfo. + * It also involves communication with ACC and TUP. + * - LOG<br> + * The log module handles the reading and writing of the log. + * It is also responsible for handling system restart. + * It controls the system restart in TUP and ACC as well. + * - TRANSACTION<br> + * This module handles the commit and the complete phases. + * - MODULE TO HANDLE TC FAILURE<br> + * - SCAN<br> + * This module contains the code that handles a scan of a particular + * fragment. + * It operates under the control of TC and orders ACC to + * perform a scan of all tuples in the fragment. + * TUP performs the necessary search conditions + * to ensure that only valid tuples are returned to the application. + * - NODE RECOVERY<br> + * Used when a node has failed. + * It performs a copy of a fragment to a new replica of the fragment. + * It does also shut down all connections to the failed node. + * - LOCAL CHECKPOINT<br> + * Handles execution and control of LCPs + * It controls the LCPs in TUP and ACC. + * It also interacts with DIH to control which GCPs are recoverable. + * - GLOBAL CHECKPOINT<br> + * Helps DIH in discovering when GCPs are recoverable. + * It handles the request gcp_savereq that requests LQH to + * save a particular GCP to disk and respond when completed. + * - FILE HANDLING<br> + * With submodules: + * - SIGNAL RECEPTION + * - NORMAL OPERATION + * - FILE CHANGE + * - INITIAL START + * - SYSTEM RESTART PHASE ONE + * - SYSTEM RESTART PHASE TWO, + * - SYSTEM RESTART PHASE THREE + * - SYSTEM RESTART PHASE FOUR + * - ERROR + * - TEST + * - LOG + */ +class Dblqh: public SimulatedBlock { +public: + enum LcpCloseState { + LCP_IDLE = 0, + LCP_RUNNING = 1, // LCP is running + LCP_CLOSE_STARTED = 2, // Completion(closing of files) has started + ACC_LCP_CLOSE_COMPLETED = 3, + TUP_LCP_CLOSE_COMPLETED = 4 + }; + + enum ExecUndoLogState { + EULS_IDLE = 0, + EULS_STARTED = 1, + EULS_COMPLETED = 2, + EULS_ACC_COMPLETED = 3, + EULS_TUP_COMPLETED = 4 + }; + + struct AddFragRecord { + enum AddFragStatus { + FREE = 0, + ACC_ADDFRAG = 1, + WAIT_TWO_TUP = 2, + WAIT_ONE_TUP = 3, + WAIT_TWO_TUX = 4, + WAIT_ONE_TUX = 5, + WAIT_ADD_ATTR = 6, + TUP_ATTR_WAIT1 = 7, + TUP_ATTR_WAIT2 = 8, + TUX_ATTR_WAIT1 = 9, + TUX_ATTR_WAIT2 = 10 + }; + LqhAddAttrReq::Entry attributes[LqhAddAttrReq::MAX_ATTRIBUTES]; + UintR accConnectptr; + AddFragStatus addfragStatus; + UintR dictConnectptr; + UintR fragmentPtr; + UintR nextAddfragrec; + UintR noOfAllocPages; + UintR schemaVer; + UintR tup1Connectptr; + UintR tup2Connectptr; + UintR tux1Connectptr; + UintR tux2Connectptr; + UintR checksumIndicator; + UintR GCPIndicator; + BlockReference dictBlockref; + Uint32 m_senderAttrPtr; + Uint16 addfragErrorCode; + Uint16 attrSentToTup; + Uint16 attrReceived; + Uint16 addFragid; + Uint16 fragid1; + Uint16 fragid2; + Uint16 noOfAttr; + Uint16 noOfNull; + Uint16 tabId; + Uint16 totalAttrReceived; + Uint16 fragCopyCreation; + Uint16 noOfKeyAttr; + Uint32 noOfNewAttr; // noOfCharsets in upper half + Uint16 noOfAttributeGroups; + Uint16 lh3DistrBits; + Uint16 tableType; + Uint16 primaryTableId; + };// Size 108 bytes + typedef Ptr<AddFragRecord> AddFragRecordPtr; + + /* $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ */ + /* $$$$$$$ ATTRIBUTE INFORMATION RECORD $$$$$$$ */ + /* $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ */ + /** + * Can contain one (1) attrinfo signal. + * One signal contains 24 attr. info words. + * But 32 elements are used to make plex happy. + * Some of the elements are used to the following things: + * - Data length in this record is stored in the + * element indexed by ZINBUF_DATA_LEN. + * - Next attrinbuf is pointed out by the element + * indexed by ZINBUF_NEXT. + */ + struct Attrbuf { + UintR attrbuf[32]; + }; // Size 128 bytes + typedef Ptr<Attrbuf> AttrbufPtr; + + /* $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ */ + /* $$$$$$$ DATA BUFFER $$$$$$$ */ + /* $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ */ + /** + * This buffer is used as a general data storage. + */ + struct Databuf { + UintR data[4]; + UintR nextDatabuf; + }; // size 20 bytes + typedef Ptr<Databuf> DatabufPtr; + + struct ScanRecord { + enum ScanState { + SCAN_FREE = 0, + WAIT_STORED_PROC_COPY = 1, + WAIT_STORED_PROC_SCAN = 2, + WAIT_NEXT_SCAN_COPY = 3, + WAIT_NEXT_SCAN = 4, + WAIT_DELETE_STORED_PROC_ID_SCAN = 5, + WAIT_DELETE_STORED_PROC_ID_COPY = 6, + WAIT_ACC_COPY = 7, + WAIT_ACC_SCAN = 8, + WAIT_SCAN_NEXTREQ = 10, + WAIT_CLOSE_SCAN = 12, + WAIT_CLOSE_COPY = 13, + WAIT_RELEASE_LOCK = 14, + WAIT_TUPKEY_COPY = 15, + WAIT_LQHKEY_COPY = 16, + IN_QUEUE = 17 + }; + enum ScanType { + ST_IDLE = 0, + SCAN = 1, + COPY = 2 + }; + + UintR scan_acc_op_ptr[32]; + Uint32 scan_acc_index; + Uint32 scan_acc_attr_recs; + UintR scanApiOpPtr; + UintR scanLocalref[2]; + + Uint32 m_max_batch_size_rows; + Uint32 m_max_batch_size_bytes; + + Uint32 m_curr_batch_size_rows; + Uint32 m_curr_batch_size_bytes; + + bool check_scan_batch_completed() const; + + UintR copyPtr; + union { + Uint32 nextPool; + Uint32 nextList; + }; + Uint32 prevList; + Uint32 nextHash; + Uint32 prevHash; + bool equal(const ScanRecord & key) const { + return scanNumber == key.scanNumber && fragPtrI == key.fragPtrI; + } + Uint32 hashValue() const { + return fragPtrI ^ scanNumber; + } + + UintR scanAccPtr; + UintR scanAiLength; + UintR scanErrorCounter; + UintR scanLocalFragid; + UintR scanSchemaVersion; + + /** + * This is _always_ main table, even in range scan + * in which case scanTcrec->fragmentptr is different + */ + Uint32 fragPtrI; + UintR scanStoredProcId; + ScanState scanState; + UintR scanTcrec; + ScanType scanType; + BlockReference scanApiBlockref; + NodeId scanNodeId; + Uint16 scanReleaseCounter; + Uint16 scanNumber; + + Uint8 scanCompletedStatus; + Uint8 scanFlag; + Uint8 scanLockHold; + Uint8 scanLockMode; + Uint8 readCommitted; + Uint8 rangeScan; + Uint8 descending; + Uint8 scanTcWaiting; + Uint8 scanKeyinfoFlag; + Uint8 m_last_row; + }; // Size 272 bytes + typedef Ptr<ScanRecord> ScanRecordPtr; + + struct Fragrecord { + enum ExecSrStatus { + IDLE = 0, + ACTIVE_REMOVE_AFTER = 1, + ACTIVE = 2 + }; + /** + * Possible state transitions are: + * - FREE -> DEFINED Fragment record is allocated + * - DEFINED -> ACTIVE Add fragment is completed and + * fragment is ready to + * receive operations. + * - DEFINED -> ACTIVE_CREATION Add fragment is completed and + * fragment is ready to + * receive operations in parallel + * with a copy fragment + * which is performed from the + * primary replica + * - DEFINED -> CRASH_RECOVERING A fragment is ready to be + * recovered from a local + * checkpoint on disk + * - ACTIVE -> BLOCKED A local checkpoint is to be + * started. No more operations + * are allowed to be started until + * the local checkpoint + * has been started. + * - ACTIVE -> REMOVING A fragment is removed from the node + * - BLOCKED -> ACTIVE Operations are allowed again in + * the fragment. + * - CRASH_RECOVERING -> ACTIVE A fragment has been recovered and + * are now ready for + * operations again. + * - CRASH_RECOVERING -> REMOVING Fragment recovery failed or + * was cancelled. + * - ACTIVE_CREATION -> ACTIVE A fragment is now copied and now + * is a normal fragment + * - ACTIVE_CREATION -> REMOVING Copying of the fragment failed + * - REMOVING -> FREE Removing of the fragment is + * completed and the fragment + * is now free again. + */ + enum FragStatus { + FREE = 0, ///< Fragment record is currently not in use + FSACTIVE = 1, ///< Fragment is defined and usable for operations + DEFINED = 2, ///< Fragment is defined but not yet usable by + ///< operations + BLOCKED = 3, ///< LQH is waiting for all active operations to + ///< complete the current phase so that the + ///< local checkpoint can be started. + ACTIVE_CREATION = 4, ///< Fragment is defined and active but is under + ///< creation by the primary LQH. + CRASH_RECOVERING = 5, ///< Fragment is recovering after a crash by + ///< executing the fragment log and so forth. + ///< Will need further breakdown. + REMOVING = 6 ///< The fragment is currently removed. + ///< Operations are not allowed. + }; + enum LogFlag { + STATE_TRUE = 0, + STATE_FALSE = 1 + }; + enum SrStatus { + SS_IDLE = 0, + SS_STARTED = 1, + SS_COMPLETED = 2 + }; + enum LcpFlag { + LCP_STATE_TRUE = 0, + LCP_STATE_FALSE = 1 + }; + /** + * Last GCI for executing the fragment log in this phase. + */ + UintR execSrLastGci[4]; + /** + * Start GCI for executing the fragment log in this phase. + */ + UintR execSrStartGci[4]; + /** + * Requesting user pointer for executing the fragment log in + * this phase + */ + UintR execSrUserptr[4]; + /** + * The LCP identifier of the LCP's. + * =0 means that the LCP number has not been stored. + * The LCP identifier is supplied by DIH when starting the LCP. + */ + UintR lcpId[MAX_LCP_STORED]; + UintR maxGciInLcp; + /** + * This variable contains the maximum global checkpoint + * identifier that exists in a certain local checkpoint. + * Maximum 4 local checkpoints is possible in this release. + */ + UintR maxGciCompletedInLcp; + UintR srLastGci[4]; + UintR srStartGci[4]; + /** + * The fragment pointers in ACC + */ + UintR accFragptr[2]; + /** + * The EXEC_SR variables are used to keep track of which fragments + * that are interested in being executed as part of executing the + * fragment loop. + * It is initialised for every phase of executing the + * fragment log (the fragment log can be executed upto four times). + * + * Each execution is capable of executing the log records on four + * fragment replicas. + */ + /** + * Requesting block reference for executing the fragment log + * in this phase. + */ + BlockReference execSrBlockref[4]; + /** + * This variable contains references to active scan and copy + * fragment operations on the fragment. + * A maximum of four concurrently active is allowed. + */ + typedef Bitmask<4> ScanNumberMask; + ScanNumberMask m_scanNumberMask; + DLList<ScanRecord>::Head m_activeScans; + DLFifoList<ScanRecord>::Head m_queuedScans; + + Uint16 srLqhLognode[4]; + /** + * The fragment pointers in TUP and TUX + */ + UintR tupFragptr[2]; + UintR tuxFragptr[2]; + /** + * This queue is where operations are put when blocked in ACC + * during start of a local chkp. + */ + UintR accBlockedList; + /** + * This is the queue where all operations that are active on the + * fragment is put. + * This is used to deduct when the fragment do + * no longer contain any active operations. + * This is needed when starting a local checkpoint. + */ + UintR activeList; + /** + * This variable keeps track of how many operations that are + * active that have skipped writing the log but not yet committed + * or aborted. This is used during start of fragment. + */ + UintR activeTcCounter; + /** + * This status specifies whether this fragment is actively + * engaged in executing the fragment log. + */ + ExecSrStatus execSrStatus; + /** + * The fragment id of this fragment. + */ + UintR fragId; + /** + * Status of fragment + */ + FragStatus fragStatus; + /** + * Indicates a local checkpoint is active and thus can generate + * UNDO log records. + */ + UintR fragActiveStatus; + /** + * Reference to current LCP record. + * If no LCP is ongoing on the fragment then the value is RNIL. + * If LCP_REF /= RNIL then a local checkpoint is ongoing in the + * fragment. + * LCP_STATE in LCP_RECORD specifies the state of the + * local checkpoint. + */ + UintR lcpRef; + /** + * This flag indicates whether logging is currently activated at + * the fragment. + * During a system restart it is temporarily shut off. + * Some fragments have it permanently shut off. + */ + LogFlag logFlag; + UintR masterPtr; + /** + * This variable contains the maximum global checkpoint identifier + * which was completed when the local checkpoint was started. + */ + /** + * Reference to the next fragment record in a free list of fragment + * records. + */ + UintR nextFrag; + /** + * The newest GCI that has been committed on fragment + */ + UintR newestGci; + SrStatus srStatus; + UintR srUserptr; + /** + * The starting global checkpoint of this fragment. + */ + UintR startGci; + /** + * A reference to the table owning this fragment. + */ + UintR tabRef; + /** + * This is the queue to put operations that have been blocked + * during start of a local chkp. + */ + UintR firstWaitQueue; + UintR lastWaitQueue; + /** + * The block reference to ACC on the fragment makes it + * possible to have different ACC blocks for different + * fragments in the future. + */ + BlockReference accBlockref; + /** + * Ordered index block. + */ + BlockReference tuxBlockref; + /** + * The master block reference as sent in COPY_ACTIVEREQ. + */ + BlockReference masterBlockref; + /** + * These variables are used during system restart to recall + * from which node to execute the fragment log and which GCI's + * this node should start and stop from. Also to remember who + * to send the response to when system restart is completed. + */ + BlockReference srBlockref; + /** + * The block reference to TUP on the fragment makes it + * possible to have different TUP blocks for different + * fragments in the future. + */ + BlockReference tupBlockref; + /** + * This state indicates if the fragment will participate in a + * checkpoint. + * Temporary tables with Fragrecord::logFlag permanently off + * will also have Fragrecord::lcpFlag off. + */ + LcpFlag lcpFlag; + /** + * Used to ensure that updates started with old + * configuration do not arrive here after the copy fragment + * has started. + * If they are allowed to arrive after they + * could update a record that has already been replicated to + * the new node. This type of arrival should be extremely + * rare but we must anyway ensure that no harm is done. + */ + Uint16 copyNode; + /** + * This variable ensures that only one copy fragment is + * active at a time on the fragment. + */ + Uint8 copyFragState; + /** + * The number of fragment replicas that will execute the log + * records in this round of executing the fragment + * log. Maximum four is possible. + */ + Uint8 execSrNoReplicas; + /** + * This variable contains what type of replica this fragment + * is. Two types are possible: + * - Primary/Backup replica = 0 + * - Stand-by replica = 1 + * + * It is not possible to distinguish between primary and + * backup on a fragment. + * This can only be done per transaction. + * DIH can change from primary to backup without informing + * the various replicas about this change. + */ + Uint8 fragCopy; + /** + * This is the last fragment distribution key that we have + * heard of. + */ + Uint8 fragDistributionKey; + /** + * The identity of the next local checkpoint this fragment + * should perform. + */ + Uint8 nextLcp; + /** + * How many local checkpoints does the fragment contain + */ + Uint8 srChkpnr; + Uint8 srNoLognodes; + /** + * Table type. + */ + Uint8 tableType; + /** + * For ordered index fragment, i-value of corresponding + * fragment in primary table. + */ + UintR tableFragptr; + }; + typedef Ptr<Fragrecord> FragrecordPtr; + + /* $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ */ + /* $$$$$$$ GLOBAL CHECKPOINT RECORD $$$$$$ */ + /* $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ */ + /** + * This record describes a global checkpoint that is + * completed. It waits for all log records belonging to this + * global checkpoint to be saved on disk. + */ + struct GcpRecord { + /** + * The file number within each log part where the log was + * located when gcp_savereq was received. The last record + * belonging to this global checkpoint is certainly before + * this place in the log. We could come even closer but it + * would cost performance and doesn't seem like a good + * idea. This is simple and it works. + */ + Uint16 gcpFilePtr[4]; + /** + * The page number within the file for each log part. + */ + Uint16 gcpPageNo[4]; + /** + * The word number within the last page that was written for + * each log part. + */ + Uint16 gcpWordNo[4]; + /** + * The identity of this global checkpoint. + */ + UintR gcpId; + /** + * The state of this global checkpoint, one for each log part. + */ + Uint8 gcpLogPartState[4]; + /** + * The sync state of this global checkpoint, one for each + * log part. + */ + Uint8 gcpSyncReady[4]; + /** + * User pointer of the sender of gcp_savereq (= master DIH). + */ + UintR gcpUserptr; + /** + * Block reference of the sender of gcp_savereq + * (= master DIH). + */ + BlockReference gcpBlockref; + }; // Size 44 bytes + typedef Ptr<GcpRecord> GcpRecordPtr; + + struct HostRecord { + bool inPackedList; + UintR noOfPackedWordsLqh; + UintR packedWordsLqh[30]; + UintR noOfPackedWordsTc; + UintR packedWordsTc[29]; + BlockReference hostLqhBlockRef; + BlockReference hostTcBlockRef; + };// Size 128 bytes + typedef Ptr<HostRecord> HostRecordPtr; + + /* $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ */ + /* $$$$$$$ LOCAL CHECKPOINT RECORD $$$$$$$ */ + /* $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ */ + /** + * This record contains the information about a local + * checkpoint that is ongoing. This record is also used as a + * system restart record. + */ + struct LcpRecord { + LcpRecord() { m_EMPTY_LCP_REQ.clear(); } + + enum LcpState { + LCP_IDLE = 0, + LCP_STARTED = 1, + LCP_COMPLETED = 2, + LCP_WAIT_FRAGID = 3, + LCP_WAIT_TUP_PREPLCP = 4, + LCP_WAIT_HOLDOPS = 5, + LCP_WAIT_ACTIVE_FINISH = 6, + LCP_START_CHKP = 7, + LCP_BLOCKED_COMP = 8, + LCP_SR_WAIT_FRAGID = 9, + LCP_SR_STARTED = 10, + LCP_SR_COMPLETED = 11 + }; + Uint32 firstLcpLocAcc; + Uint32 firstLcpLocTup; + Uint32 lcpAccptr; + + LcpState lcpState; + bool lastFragmentFlag; + + struct FragOrd { + Uint32 fragPtrI; + LcpFragOrd lcpFragOrd; + }; + FragOrd currentFragment; + + bool lcpQueued; + FragOrd queuedFragment; + + bool reportEmpty; + NdbNodeBitmask m_EMPTY_LCP_REQ; + }; // Size 76 bytes + typedef Ptr<LcpRecord> LcpRecordPtr; + + /* $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ */ + /* $$$$$$ LOCAL CHECKPOINT SUPPORT RECORD $$$$$$$ */ + /* $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ */ + /** + * This record contains the information about an outstanding + * request to TUP or ACC. Used for both local checkpoints and + * system restart. + */ + struct LcpLocRecord { + enum LcpLocstate { + IDLE = 0, + WAIT_TUP_PREPLCP = 1, + WAIT_LCPHOLDOP = 2, + HOLDOP_READY = 3, + ACC_WAIT_STARTED = 4, + ACC_STARTED = 5, + ACC_COMPLETED = 6, + TUP_WAIT_STARTED = 7, + TUP_STARTED = 8, + TUP_COMPLETED = 9, + SR_ACC_STARTED = 10, + SR_TUP_STARTED = 11, + SR_ACC_COMPLETED = 12, + SR_TUP_COMPLETED = 13 + }; + enum WaitingBlock { + ACC = 0, + TUP = 1, + NONE = 2 + }; + + LcpLocstate lcpLocstate; + UintR locFragid; + UintR masterLcpRec; + UintR nextLcpLoc; + UintR tupRef; + WaitingBlock waitingBlock; + Uint32 accContCounter; + }; // 28 bytes + typedef Ptr<LcpLocRecord> LcpLocRecordPtr; + + /* $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ */ + /* $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ */ + /* */ + /* THE RECORDS THAT START BY LOG_ ARE A PART OF THE LOG MANAGER. */ + /* THESE RECORDS ARE USED TO HANDLE THE FRAGMENT LOG. */ + /* */ + /* $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ */ + /* $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ */ + /* $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ */ + /* $$$$$$$ LOG RECORD $$$$$$$ */ + /* */ + /* $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ */ + /* THIS RECORD IS ALIGNED TO BE 256 BYTES. */ + /* $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ */ + /** + * This record describes the current state of a log. + * A log consists of a number of log files. + * These log files are described by the log file record. + * + * There will be 4 sets of log files. + * Different tables will use different log files dependent + * on the table id. + * This ensures that more than one outstanding request can + * be sent to the file system. + * The log file to use is found by performing a very simple hash + * function. + */ + struct LogPartRecord { + enum LogPartState { + IDLE = 0, ///< Nothing happens at the moment + ACTIVE = 1, ///< An operation is active logging + SR_FIRST_PHASE = 2, ///< Finding the end of the log and + ///< the information about global + ///< checkpoints in the log is ongoing. + SR_FIRST_PHASE_COMPLETED = 3, ///< First phase completed + SR_THIRD_PHASE_STARTED = 4, ///< Executing fragment log is in 3rd ph + SR_THIRD_PHASE_COMPLETED = 5, + SR_FOURTH_PHASE_STARTED = 6, ///< Finding the log tail and head + ///< is the fourth phase. + SR_FOURTH_PHASE_COMPLETED = 7, + FILE_CHANGE_PROBLEM = 8, ///< For some reason the write to + ///< page zero in file zero have not + ///< finished after 15 mbyte of + ///< log data have been written + TAIL_PROBLEM = 9 ///< Only 1 mbyte of log left. + ///< No operations allowed to enter the + ///< log. Only special log records + ///< are allowed + }; + enum WaitWriteGciLog { + WWGL_TRUE = 0, + WWGL_FALSE = 1 + }; + enum LogExecState { + LES_IDLE = 0, + LES_SEARCH_STOP = 1, + LES_SEARCH_START = 2, + LES_EXEC_LOG = 3, + LES_EXEC_LOG_NEW_MBYTE = 4, + LES_EXEC_LOG_NEW_FILE = 5, + LES_EXEC_LOGREC_FROM_FILE = 6, + LES_EXEC_LOG_COMPLETED = 7, + LES_WAIT_READ_EXEC_SR_NEW_MBYTE = 8, + LES_WAIT_READ_EXEC_SR = 9, + LES_EXEC_LOG_INVALIDATE = 10 + }; + + /** + * Is a CONTINUEB(ZLOG_LQHKEYREQ) signal sent and + * outstanding. We do not want several instances of this + * signal out in the air since that would create multiple + * writers of the list. + */ + UintR LogLqhKeyReqSent; + /** + * Contains the current log file where log records are + * written. During system restart it is used to indicate the + * last log file. + */ + UintR currentLogfile; + /** + * The log file used to execute log records from far behind. + */ + UintR execSrExecLogFile; + /** + * The currently executing prepare record starts in this log + * page. This variable is used to enable that a log record is + * executed multiple times in execution of the log. + */ + UintR execSrLogPage; + /** + * This variable keeps track of the lfo record where the + * pages that were read from disk when an operations log + * record were not found in the main memory buffer for log + * pages. + */ + UintR execSrLfoRec; + /** + * The starting page number when reading log from far behind. + */ + UintR execSrStartPageNo; + /** + * The last page number when reading log from far behind. + */ + UintR execSrStopPageNo; + /** + * Contains a reference to the first log file, file number 0. + */ + UintR firstLogfile; + /** + * The head of the operations queued for logging. + */ + UintR firstLogQueue; + /** + * This variable contains the oldest operation in this log + * part which have not been committed yet. + */ + UintR firstLogTcrec; + /** + * The first reference to a set of 8 pages. These are used + * during execution of the log to keep track of which pages + * are in memory and which are not. + */ + UintR firstPageRef; + /** + * This variable contains the global checkpoint record + * waiting for disk writes to complete. + */ + UintR gcprec; + /** + * The last reference to a set of 8 pages. These are used + * during execution of the log to keep track of which pages + * are in memory and which are not. + */ + UintR lastPageRef; + /** + * The tail of the operations queued for logging. + */ + UintR lastLogQueue; + /** + * This variable contains the newest operation in this log + * part which have not been committed yet. + */ + UintR lastLogTcrec; + /** + * This variable indicates which was the last mbyte that was + * written before the system crashed. Discovered during + * system restart. + */ + UintR lastLogfile; + /** + * This variable is used to keep track of the state during + * the third phase of the system restart, i.e. when + * LogPartRecord::logPartState == + * LogPartRecord::SR_THIRD_PHASE_STARTED. + */ + LogExecState logExecState; + /** + * This variable contains the lap number of this log part. + */ + UintR logLap; + /** + * This variable contains the place to stop executing the log + * in this phase. + */ + UintR logLastGci; + /** + * This variable contains the place to start executing the + * log in this phase. + */ + UintR logStartGci; + /** + * The latest GCI completed in this log part. + */ + UintR logPartNewestCompletedGCI; + /** + * The current state of this log part. + */ + LogPartState logPartState; + /** + * A timer that is set every time a log page is sent to disk. + * Ensures that log pages are not kept in main memory for + * more than a certain time. + */ + UintR logPartTimer; + /** + * The current timer which is set by the periodic signal + * received by LQH + */ + UintR logTimer; + /** + * Contains the number of the log tail file and the mbyte + * reference within that file. This information ensures that + * the tail is not overwritten when writing new log records. + */ + UintR logTailFileNo; + /** + * The TcConnectionrec used during execution of this log part. + */ + UintR logTcConrec; + /** + * The number of pages that currently resides in the main + * memory buffer. It does not refer pages that are currently + * read from the log files. Only to pages already read + * from the log file. + */ + UintR mmBufferSize; + /** + * Contains the current number of log files in this log part. + */ + UintR noLogFiles; + /** + * This variable is used only during execution of a log + * record. It keeps track of in which page record a log + * record was started. It is used then to deduce which + * pages that are dirty after that the log records on the + * page have been executed. + * + * It is also used to find out where to write the invalidate + * command when that is needed. + */ + UintR prevLogpage; + /** + * The number of files remaining to gather GCI information + * for during system restart. Only used if number of files + * is larger than 60. + */ + UintR srRemainingFiles; + /** + * The log file where to start executing the log during + * system restart. + */ + UintR startLogfile; + /** + * The last log file in which to execute the log during system + * restart. + */ + UintR stopLogfile; + /** + * This variable keeps track of when we want to write a complete + * gci log record but have been blocked by an ongoing log operation. + */ + WaitWriteGciLog waitWriteGciLog; + /** + * The currently executing prepare record starts in this index + * in the log page. + */ + Uint16 execSrLogPageIndex; + /** + * Which of the four exec_sr's in the fragment is currently executing + */ + Uint16 execSrExecuteIndex; + /** + * The number of pages executed in the current mbyte. + */ + Uint16 execSrPagesExecuted; + /** + * The number of pages read from disk that have arrived and are + * currently awaiting execution of the log. + */ + Uint16 execSrPagesRead; + /** + * The number of pages read from disk and currently not arrived + * to the block. + */ + Uint16 execSrPagesReading; + /** + * This variable refers to the new header file where we will + * start writing the log after a system restart have been completed. + */ + Uint16 headFileNo; + /** + * This variable refers to the page number within the header file. + */ + Uint16 headPageNo; + /** + * This variable refers to the index within the new header + * page. + */ + Uint16 headPageIndex; + /** + * This variables indicates which was the last mbyte in the last + * logfile before a system crash. Discovered during system restart. + */ + Uint16 lastMbyte; + /** + * This variable is used only during execution of a log + * record. It keeps track of in which file page a log + * record was started. It is used if it is needed to write a + * dirty page to disk during log execution (this happens when + * commit records are invalidated). + */ + Uint16 prevFilepage; + /** + * This is used to save where we were in the execution of log + * records when we find a commit record that needs to be + * executed. + * + * This variable is also used to remember the index where the + * log type was in the log record. It is only used in this + * role when finding a commit record that needs to be + * invalidated. + */ + Uint16 savePageIndex; + Uint8 logTailMbyte; + /** + * The mbyte within the starting log file where to start + * executing the log. + */ + Uint8 startMbyte; + /** + * The last mbyte in which to execute the log during system + * restart. + */ + Uint8 stopMbyte; + /** + * This variable refers to the file where invalidation is + * occuring during system/node restart. + */ + Uint16 invalidateFileNo; + /** + * This variable refers to the page where invalidation is + * occuring during system/node restart. + */ + Uint16 invalidatePageNo; + }; // Size 164 Bytes + typedef Ptr<LogPartRecord> LogPartRecordPtr; + + /* $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ */ + /* $$$$$$$ LOG FILE RECORD $$$$$$$ */ + /* $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ */ + /* THIS RECORD IS ALIGNED TO BE 288 (256 + 32) BYTES. */ + /* $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ */ + /** + * This record contains information about a log file. + * A log file contains log records from several tables and + * fragments of a table. LQH can contain more than + * one log file to ensure faster log processing. + * + * The number of pages to write to disk at a time is + * configurable. + */ + struct LogFileRecord { + enum FileChangeState { + NOT_ONGOING = 0, + BOTH_WRITES_ONGOING = 1, + LAST_WRITE_ONGOING = 2, + FIRST_WRITE_ONGOING = 3, + WRITE_PAGE_ZERO_ONGOING = 4 + }; + enum LogFileStatus { + LFS_IDLE = 0, ///< Log file record not in use + CLOSED = 1, ///< Log file closed + OPENING_INIT = 2, + OPEN_SR_FRONTPAGE = 3, ///< Log file opened as part of system + ///< restart. Open file 0 to find + ///< the front page of the log part. + OPEN_SR_LAST_FILE = 4, ///< Open last log file that was written + ///< before the system restart. + OPEN_SR_NEXT_FILE = 5, ///< Open a log file which is 16 files + ///< backwards to find the next + ///< information about GCPs. + OPEN_EXEC_SR_START = 6, ///< Log file opened as part of + ///< executing + ///< log during system restart. + OPEN_EXEC_SR_NEW_MBYTE = 7, + OPEN_SR_FOURTH_PHASE = 8, + OPEN_SR_FOURTH_NEXT = 9, + OPEN_SR_FOURTH_ZERO = 10, + OPENING_WRITE_LOG = 11, ///< Log file opened as part of writing + ///< log during normal operation. + OPEN_EXEC_LOG = 12, + CLOSING_INIT = 13, + CLOSING_SR = 14, ///< Log file closed as part of system + ///< restart. Currently trying to + ///< find where to start executing the + ///< log + CLOSING_EXEC_SR = 15, ///< Log file closed as part of + ///< executing log during system restart + CLOSING_EXEC_SR_COMPLETED = 16, + CLOSING_WRITE_LOG = 17, ///< Log file closed as part of writing + ///< log during normal operation. + CLOSING_EXEC_LOG = 18, + OPEN_INIT = 19, + OPEN = 20, ///< Log file open + OPEN_SR_INVALIDATE_PAGES = 21, + CLOSE_SR_INVALIDATE_PAGES = 22 + }; + + /** + * When a new mbyte is started in the log we have to find out + * how far back in the log we still have prepared operations + * which have been neither committed or aborted. This variable + * keeps track of this value for each of the mbytes in this + * log file. This is used in writing down these values in the + * header of each log file. That information is used during + * system restart to find the tail of the log. + */ + UintR logLastPrepRef[16]; + /** + * The max global checkpoint completed before the mbyte in the + * log file was started. One variable per mbyte. + */ + UintR logMaxGciCompleted[16]; + /** + * The max global checkpoint started before the mbyte in the log + * file was started. One variable per mbyte. + */ + UintR logMaxGciStarted[16]; + /** + * This variable contains the file name as needed by the file + * system when opening the file. + */ + UintR fileName[4]; + /** + * This variable has a reference to the log page which is + * currently in use by the log. + */ + UintR currentLogpage; + /** + * The number of the current mbyte in the log file. + */ + UintR currentMbyte; + /** + * This variable is used when changing files. It is to find + * out when both the last write in the previous file and the + * first write in this file has been completed. After these + * writes have completed the variable keeps track of when the + * write to page zero in file zero is completed. + */ + FileChangeState fileChangeState; + /** + * The number of the file within this log part. + */ + UintR fileNo; + /** + * This variable shows where to read/write the next pages into + * the log. Used when writing the log during normal operation + * and when reading the log during system restart. It + * specifies the page position where each page is 8 kbyte. + */ + UintR filePosition; + /** + * This contains the file pointer needed by the file system + * when reading/writing/closing and synching. + */ + UintR fileRef; + /** + * The head of the pages waiting for shipment to disk. + * They are filled with log info. + */ + UintR firstFilledPage; + /** + * A list of active read/write operations on the log file. + * Operations are always put in last and the first should + * always complete first. + */ + UintR firstLfo; + UintR lastLfo; + /** + * The tail of the pages waiting for shipment to disk. + * They are filled with log info. + */ + UintR lastFilledPage; + /** + * This variable keeps track of the last written page in the + * file while writing page zero in file zero when changing log + * file. + */ + UintR lastPageWritten; + /** + * This variable keeps track of the last written word in the + * last page written in the file while writing page zero in + * file zero when changing log file. + */ + UintR lastWordWritten; + /** + * This variable contains the last word written in the last page. + */ + UintR logFilePagesToDiskWithoutSynch; + /** + * This variable keeps track of the number of pages written since + * last synch on this log file. + */ + LogFileStatus logFileStatus; + /** + * A reference to page zero in this file. + * This page is written before the file is closed. + */ + UintR logPageZero; + /** + * This variable contains a reference to the record describing + * this log part. One of four records (0,1,2 or 3). + */ + UintR logPartRec; + /** + * Next free log file record or next log file in this log. + */ + UintR nextLogFile; + /** + * The previous log file. + */ + UintR prevLogFile; + /** + * The number of remaining words in this mbyte of the log file. + */ + UintR remainingWordsInMbyte; + /** + * The current file page within the current log file. This is + * a reference within the file and not a reference to a log + * page record. It is used to deduce where log records are + * written. Particularly completed gcp records and prepare log + * records. + */ + Uint16 currentFilepage; + /** + * The number of pages in the list referenced by + * LOG_PAGE_BUFFER. + */ + Uint16 noLogpagesInBuffer; + }; // Size 288 bytes + typedef Ptr<LogFileRecord> LogFileRecordPtr; + + /* $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ */ + /* $$$$$$$ LOG OPERATION RECORD $$$$$$$ */ + /* $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ */ + /** + * This record contains a currently active file operation + * that has started by the log module. + */ + struct LogFileOperationRecord { + enum LfoState { + IDLE = 0, ///< Operation is not used at the moment + INIT_WRITE_AT_END = 1, ///< Write in file so that it grows to + ///< 16 Mbyte + INIT_FIRST_PAGE = 2, ///< Initialise the first page in a file + WRITE_GCI_ZERO = 3, + WRITE_INIT_MBYTE = 4, + WRITE_DIRTY = 5, + READ_SR_FRONTPAGE = 6, ///< Read page zero in file zero during + ///< system restart + READ_SR_LAST_FILE = 7, ///< Read page zero in last file open + ///< before system crash + READ_SR_NEXT_FILE = 8, ///< Read 60 files backwards to find + ///< further information GCPs in page + ///< zero + READ_SR_LAST_MBYTE = 9, + READ_EXEC_SR = 10, + READ_EXEC_LOG = 11, + READ_SR_FOURTH_PHASE = 12, + READ_SR_FOURTH_ZERO = 13, + FIRST_PAGE_WRITE_IN_LOGFILE = 14, + LAST_WRITE_IN_FILE = 15, + WRITE_PAGE_ZERO = 16, + ACTIVE_WRITE_LOG = 17, ///< A write operation during + ///< writing of log + READ_SR_INVALIDATE_PAGES = 18, + WRITE_SR_INVALIDATE_PAGES = 19 + }; + /** + * We have to remember the log pages read. + * Otherwise we cannot build the linked list after the pages have + * arrived to main memory. + */ + UintR logPageArray[16]; + /** + * A list of the pages that are part of this active operation. + */ + UintR firstLfoPage; + /** + * A timer to ensure that records are not lost. + */ + UintR lfoTimer; + /** + * The word number of the last written word in the last during + * a file write. + */ + UintR lfoWordWritten; + /** + * This variable contains the state of the log file operation. + */ + LfoState lfoState; + /** + * The log file that the file operation affects. + */ + UintR logFileRec; + /** + * The log file operations on a file are kept in a linked list. + */ + UintR nextLfo; + /** + * The page number of the first read/written page during a file + * read/write. + */ + Uint16 lfoPageNo; + /** + * The number of pages written or read during an operation to + * the log file. + */ + Uint16 noPagesRw; + }; // 92 bytes + typedef Ptr<LogFileOperationRecord> LogFileOperationRecordPtr; + + /* $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ */ + /* $$$$$$$ LOG PAGE RECORD $$$$$$$ */ + /* $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ */ + /** + * These are the 8 k pages used to store log records before storing + * them in the file system. + * Since 64 kbyte is sent to disk at a time it is necessary to have + * at least 4*64 kbytes of log pages. + * To handle multiple outstanding requests we need some additional pages. + * Thus we allocate 1 mbyte to ensure that we do not get problems with + * insufficient number of pages. + */ + struct LogPageRecord { + /** + * This variable contains the pages that are sent to disk. + * + * All pages contain a header of 12 words: + * - WORD 0: CHECKSUM Calculated before storing on disk and + * checked when read from disk. + * - WORD 1: LAP How many wraparounds have the log + * experienced since initial start of the + * system. + * - WORD 2: MAX_GCI_COMPLETED Which is the maximum gci which have + * completed before this page. This + * gci will not be found in this + * page and hereafter in the log. + * - WORD 3: MAX_GCI_STARTED The maximum gci which have started + * before this page. + * - WORD 4: NEXT_PAGE Pointer to the next page. + * Only used in main memory + * - WORD 5: PREVIOUS_PAGE Pointer to the previous page. + * Currently not used. + * - WORD 6: VERSION NDB version that wrote the page. + * - WORD 7: NO_LOG_FILES Number of log files in this log part. + * - WORD 8: CURRENT PAGE INDEX This keeps track of where we are in the + * page. + * This is only used when pages is in + * memory. + * - WORD 9: OLD PREPARE FILE NO This keeps track of the oldest prepare + * operation still alive (not committed + * or aborted) when this mbyte started. + * - WORD 10: OLD PREPARE PAGE REF File page reference within this file + * number. + * Page no + Page index. + * If no prepare was alive then these + * values points this mbyte. + * - WORD 11: DIRTY FLAG = 0 means not dirty and + * = 1 means the page is dirty. + * Is used when executing log when + * a need to write invalid commit + * records arise. + * + * The remaining 2036 words are used for log information, i.e. + * log records. + * + * A log record on this page has the following layout: + * - WORD 0: LOG RECORD TYPE + * The following types are supported: + * - PREPARE OPERATION An operation not yet committed. + * - NEW PREPARE OPERATION A prepared operation already + * logged is inserted + * into the log again so that the + * log tail can be advanced. + * This can happen when a transaction is + * committed for a long time. + * - ABORT TRANSACTION A previously prepared transaction + * was aborted. + * - COMMIT TRANSACTION A previously prepared transaction + * was committed. + * - INVALID COMMIT A previous commit record was + * invalidated by a + * subsequent system restart. + * A log record must be invalidated + * in a system restart if it belongs + * to a global checkpoint id which + * is not included in the system + * restart. + * Otherwise it will be included in + * a subsequent system restart since + * it will then most likely belong + * to a global checkpoint id which + * is part of that system + * restart. + * This is not a correct behaviour + * since this operation is lost in a + * system restart and should not + * reappear at a later system + * restart. + * - COMPLETED GCI A GCI has now been completed. + * - FRAGMENT SPLIT A fragment has been split + * (not implemented yet) + * - FILE DESCRIPTOR This is always the first log record + * in a file. + * It is always placed on page 0 after + * the header. + * It is written when the file is + * opened and when the file is closed. + * - NEXT LOG RECORD This log record only records where + * the next log record starts. + * - NEXT MBYTE RECORD This log record specifies that there + * are no more log records in this mbyte. + * + * + * A FILE DESCRIPTOR log record continues as follows: + * - WORD 1: NO_LOG_DESCRIPTORS This defines the number of + * descriptors of log files that + * will follow hereafter (max 32). + * the log descriptor will describe + * information about + * max_gci_completed, + * max_gci_started and log_lap at + * every 1 mbyte of the log file + * since a log file is 16 mbyte + * always, i need 16 entries in the + * array with max_gci_completed, + * max_gci_started and log_lap. thus + * 32 entries per log file + * descriptor (max 32*48 = 1536, + * always fits in page 0). + * - WORD 2: LAST LOG FILE The number of the log file currently + * open. This is only valid in file 0. + * - WORD 3 - WORD 18: MAX_GCI_COMPLETED for every 1 mbyte + * in this log file. + * - WORD 19 - WORD 34: MAX_GCI_STARTED for every 1 mbyte + * in this log file. + * + * Then it continues for NO_LOG_DESCRIPTORS until all subsequent + * log files (max 32) have been properly described. + * + * + * A PREPARE OPERATION log record continues as follows: + * - WORD 1: LOG RECORD SIZE + * - WORD 2: HASH VALUE + * - WORD 3: SCHEMA VERSION + * - WORD 4: OPERATION TYPE + * = 0 READ, + * = 1 UPDATE, + * = 2 INSERT, + * = 3 DELETE + * - WORD 5: NUMBER OF WORDS IN ATTRINFO PART + * - WORD 6: KEY LENGTH IN WORDS + * - WORD 7 - (WORD 7 + KEY_LENGTH - 1) The tuple key + * - (WORD 7 + KEY_LENGTH) - + * (WORD 7 + KEY_LENGTH + ATTRINFO_LENGTH - 1) The attrinfo + * + * A log record can be spread in several pages in some cases. + * The next log record always starts immediately after this log record. + * A log record does however never traverse a 1 mbyte boundary. + * This is used to ensure that we can always come back if something + * strange occurs in the log file. + * To ensure this we also have log records which only records + * the next log record. + * + * + * A COMMIT TRANSACTION log record continues as follows: + * - WORD 1: TRANSACTION ID PART 1 + * - WORD 2: TRANSACTION ID PART 2 + * - WORD 3: FRAGMENT ID OF THE OPERATION + * - WORD 4: TABLE ID OF THE OPERATION + * - WORD 5: THE FILE NUMBER OF THE PREPARE RECORD + * - WORD 6: THE STARTING PAGE NUMBER OF THE PREPARE RECORD + * - WORD 7: THE STARTING PAGE INDEX OF THE PREPARE RECORD + * - WORD 8: THE STOP PAGE NUMBER OF THE PREPARE RECORD + * - WORD 9: GLOBAL CHECKPOINT OF THE TRANSACTION + * + * + * An ABORT TRANSACTION log record continues as follows: + * - WORD 1: TRANSACTION ID PART 1 + * - WORD 2: TRANSACTION ID PART 2 + * + * + * A COMPLETED CGI log record continues as follows: + * - WORD 1: THE COMPLETED GCI + * + * + * A NEXT LOG RECORD log record continues as follows: + * - There is no more information needed. + * The next log record will always refer to the start of the next page. + * + * A NEXT MBYTE RECORD log record continues as follows: + * - There is no more information needed. + * The next mbyte will always refer to the start of the next mbyte. + */ + UintR logPageWord[8192]; // Size 32 kbytes + }; + typedef Ptr<LogPageRecord> LogPageRecordPtr; + + struct PageRefRecord { + UintR pageRef[8]; + UintR prNext; + UintR prPrev; + Uint16 prFileNo; + Uint16 prPageNo; + }; // size 44 bytes + typedef Ptr<PageRefRecord> PageRefRecordPtr; + + struct Tablerec { + enum TableStatus { + TABLE_DEFINED = 0, + NOT_DEFINED = 1, + ADD_TABLE_ONGOING = 2, + PREP_DROP_TABLE_ONGOING = 3, + PREP_DROP_TABLE_DONE = 4 + }; + + UintR fragrec[MAX_FRAG_PER_NODE]; + Uint16 fragid[MAX_FRAG_PER_NODE]; + /** + * Status of the table + */ + TableStatus tableStatus; + /** + * Table type and target table of index. + */ + Uint16 tableType; + Uint16 primaryTableId; + Uint32 schemaVersion; + + Uint32 usageCount; + NdbNodeBitmask waitingTC; + NdbNodeBitmask waitingDIH; + }; // Size 100 bytes + typedef Ptr<Tablerec> TablerecPtr; + + struct TcConnectionrec { + enum ListState { + NOT_IN_LIST = 0, + IN_ACTIVE_LIST = 1, + ACC_BLOCK_LIST = 2, + WAIT_QUEUE_LIST = 3 + }; + enum LogWriteState { + NOT_STARTED = 0, + NOT_WRITTEN = 1, + NOT_WRITTEN_WAIT = 2, + WRITTEN = 3 + }; + enum AbortState { + ABORT_IDLE = 0, + ABORT_ACTIVE = 1, + NEW_FROM_TC = 2, + REQ_FROM_TC = 3, + ABORT_FROM_TC = 4, + ABORT_FROM_LQH = 5 + }; + enum TransactionState { + IDLE = 0, + + /* -------------------------------------------------------------------- */ + // Transaction in progress states + /* -------------------------------------------------------------------- */ + WAIT_ACC = 1, + WAIT_TUPKEYINFO = 2, + WAIT_ATTR = 3, + WAIT_TUP = 4, + STOPPED = 5, + LOG_QUEUED = 6, + PREPARED = 7, + LOG_COMMIT_WRITTEN_WAIT_SIGNAL = 8, + LOG_COMMIT_QUEUED_WAIT_SIGNAL = 9, + + /* -------------------------------------------------------------------- */ + // Commit in progress states + /* -------------------------------------------------------------------- */ + COMMIT_STOPPED = 10, + LOG_COMMIT_QUEUED = 11, + COMMIT_QUEUED = 12, + COMMITTED = 13, + + /* -------------------------------------------------------------------- */ + // Abort in progress states + /* -------------------------------------------------------------------- */ + WAIT_ACC_ABORT = 14, + ABORT_QUEUED = 15, + ABORT_STOPPED = 16, + WAIT_AI_AFTER_ABORT = 17, + LOG_ABORT_QUEUED = 18, + WAIT_TUP_TO_ABORT = 19, + + /* -------------------------------------------------------------------- */ + // Scan in progress states + /* -------------------------------------------------------------------- */ + WAIT_SCAN_AI = 20, + SCAN_STATE_USED = 21, + SCAN_FIRST_STOPPED = 22, + SCAN_CHECK_STOPPED = 23, + SCAN_STOPPED = 24, + SCAN_RELEASE_STOPPED = 25, + SCAN_CLOSE_STOPPED = 26, + COPY_CLOSE_STOPPED = 27, + COPY_FIRST_STOPPED = 28, + COPY_STOPPED = 29, + SCAN_TUPKEY = 30, + COPY_TUPKEY = 31, + + TC_NOT_CONNECTED = 32, + PREPARED_RECEIVED_COMMIT = 33, // Temporary state in write commit log + LOG_COMMIT_WRITTEN = 34 // Temporary state in write commit log + }; + enum ConnectState { + DISCONNECTED = 0, + CONNECTED = 1, + COPY_CONNECTED = 2, + LOG_CONNECTED = 3 + }; + ConnectState connectState; + UintR copyCountWords; + UintR firstAttrinfo[5]; + UintR tupkeyData[4]; + UintR transid[2]; + AbortState abortState; + UintR accConnectrec; + UintR applOprec; + UintR clientConnectrec; + UintR tcTimer; + UintR currReclenAi; + UintR currTupAiLen; + UintR firstAttrinbuf; + UintR firstTupkeybuf; + UintR fragmentid; + UintR fragmentptr; + UintR gci; + UintR hashValue; + UintR lastTupkeybuf; + UintR lastAttrinbuf; + /** + * Each operation (TcConnectrec) can be stored in max one out of many + * lists. + * This variable keeps track of which list it is in. + */ + ListState listState; + + UintR logStartFileNo; + LogWriteState logWriteState; + UintR nextHashRec; + UintR nextLogTcrec; + UintR nextTcLogQueue; + UintR nextTc; + UintR nextTcConnectrec; + UintR prevHashRec; + UintR prevLogTcrec; + UintR prevTc; + UintR readlenAi; + UintR reqRef; + UintR reqinfo; + UintR schemaVersion; + UintR storedProcId; + UintR simpleTcConnect; + UintR tableref; + UintR tcOprec; + UintR tcScanInfo; + UintR tcScanRec; + UintR totReclenAi; + UintR totSendlenAi; + UintR tupConnectrec; + UintR savePointId; + TransactionState transactionState; + BlockReference applRef; + BlockReference clientBlockref; + + BlockReference reqBlockref; + BlockReference tcBlockref; + BlockReference tcAccBlockref; + BlockReference tcTuxBlockref; + BlockReference tcTupBlockref; + Uint32 commitAckMarker; + union { + Uint32 m_scan_curr_range_no; + UintR noFiredTriggers; + }; + Uint16 errorCode; + Uint16 logStartPageIndex; + Uint16 logStartPageNo; + Uint16 logStopPageNo; + Uint16 nextReplica; + Uint16 primKeyLen; + Uint16 save1; + Uint16 nodeAfterNext[3]; + + Uint8 activeCreat; + Uint8 apiVersionNo; + Uint8 dirtyOp; + Uint8 indTakeOver; + Uint8 lastReplicaNo; + Uint8 localFragptr; + Uint8 lockType; + Uint8 nextSeqNoReplica; + Uint8 opSimple; + Uint8 opExec; + Uint8 operation; + Uint8 reclenAiLqhkey; + Uint8 m_offset_current_keybuf; + Uint8 replicaType; + Uint8 simpleRead; + Uint8 seqNoReplica; + Uint8 tcNodeFailrec; + }; /* p2c: size = 280 bytes */ + + typedef Ptr<TcConnectionrec> TcConnectionrecPtr; + + struct TcNodeFailRecord { + enum TcFailStatus { + TC_STATE_TRUE = 0, + TC_STATE_FALSE = 1, + TC_STATE_BREAK = 2 + }; + UintR lastNewTcRef; + UintR newTcRef; + TcFailStatus tcFailStatus; + UintR tcRecNow; + BlockReference lastNewTcBlockref; + BlockReference newTcBlockref; + Uint16 oldNodeId; + }; // Size 28 bytes + typedef Ptr<TcNodeFailRecord> TcNodeFailRecordPtr; + + struct CommitLogRecord { + Uint32 startPageNo; + Uint32 startPageIndex; + Uint32 stopPageNo; + Uint32 fileNo; + }; + +public: + Dblqh(const class Configuration &); + virtual ~Dblqh(); + +private: + BLOCK_DEFINES(Dblqh); + + void execPACKED_SIGNAL(Signal* signal); + void execDEBUG_SIG(Signal* signal); + void execATTRINFO(Signal* signal); + void execKEYINFO(Signal* signal); + void execLQHKEYREQ(Signal* signal); + void execLQHKEYREF(Signal* signal); + void execCOMMIT(Signal* signal); + void execCOMPLETE(Signal* signal); + void execLQHKEYCONF(Signal* signal); + void execTESTSIG(Signal* signal); + void execLQH_RESTART_OP(Signal* signal); + void execCONTINUEB(Signal* signal); + void execSTART_RECREQ(Signal* signal); + void execSTART_RECCONF(Signal* signal); + void execEXEC_FRAGREQ(Signal* signal); + void execEXEC_FRAGCONF(Signal* signal); + void execEXEC_FRAGREF(Signal* signal); + void execSTART_EXEC_SR(Signal* signal); + void execEXEC_SRREQ(Signal* signal); + void execEXEC_SRCONF(Signal* signal); + void execREAD_PSUEDO_REQ(Signal* signal); + + void execDUMP_STATE_ORD(Signal* signal); + void execACC_COM_BLOCK(Signal* signal); + void execACC_COM_UNBLOCK(Signal* signal); + void execTUP_COM_BLOCK(Signal* signal); + void execTUP_COM_UNBLOCK(Signal* signal); + void execACC_ABORTCONF(Signal* signal); + void execNODE_FAILREP(Signal* signal); + void execCHECK_LCP_STOP(Signal* signal); + void execSEND_PACKED(Signal* signal); + void execTUP_ATTRINFO(Signal* signal); + void execREAD_CONFIG_REQ(Signal* signal); + void execLQHFRAGREQ(Signal* signal); + void execLQHADDATTREQ(Signal* signal); + void execTUP_ADD_ATTCONF(Signal* signal); + void execTUP_ADD_ATTRREF(Signal* signal); + void execACCFRAGCONF(Signal* signal); + void execACCFRAGREF(Signal* signal); + void execTUPFRAGCONF(Signal* signal); + void execTUPFRAGREF(Signal* signal); + void execTAB_COMMITREQ(Signal* signal); + void execACCSEIZECONF(Signal* signal); + void execACCSEIZEREF(Signal* signal); + void execREAD_NODESCONF(Signal* signal); + void execREAD_NODESREF(Signal* signal); + void execSTTOR(Signal* signal); + void execNDB_STTOR(Signal* signal); + void execTUPSEIZECONF(Signal* signal); + void execTUPSEIZEREF(Signal* signal); + void execACCKEYCONF(Signal* signal); + void execACCKEYREF(Signal* signal); + void execTUPKEYCONF(Signal* signal); + void execTUPKEYREF(Signal* signal); + void execABORT(Signal* signal); + void execABORTREQ(Signal* signal); + void execCOMMITREQ(Signal* signal); + void execCOMPLETEREQ(Signal* signal); + void execMEMCHECKREQ(Signal* signal); + void execSCAN_FRAGREQ(Signal* signal); + void execSCAN_NEXTREQ(Signal* signal); + void execACC_SCANCONF(Signal* signal); + void execACC_SCANREF(Signal* signal); + void execNEXT_SCANCONF(Signal* signal); + void execNEXT_SCANREF(Signal* signal); + void execACC_TO_REF(Signal* signal); + void execSTORED_PROCCONF(Signal* signal); + void execSTORED_PROCREF(Signal* signal); + void execCOPY_FRAGREQ(Signal* signal); + void execCOPY_ACTIVEREQ(Signal* signal); + void execCOPY_STATEREQ(Signal* signal); + void execLQH_TRANSREQ(Signal* signal); + void execTRANSID_AI(Signal* signal); + void execINCL_NODEREQ(Signal* signal); + void execACC_LCPCONF(Signal* signal); + void execACC_LCPREF(Signal* signal); + void execACC_LCPSTARTED(Signal* signal); + void execACC_CONTOPCONF(Signal* signal); + void execLCP_FRAGIDCONF(Signal* signal); + void execLCP_FRAGIDREF(Signal* signal); + void execLCP_HOLDOPCONF(Signal* signal); + void execLCP_HOLDOPREF(Signal* signal); + void execTUP_PREPLCPCONF(Signal* signal); + void execTUP_PREPLCPREF(Signal* signal); + void execTUP_LCPCONF(Signal* signal); + void execTUP_LCPREF(Signal* signal); + void execTUP_LCPSTARTED(Signal* signal); + void execEND_LCPCONF(Signal* signal); + + void execLCP_FRAG_ORD(Signal* signal); + void execEMPTY_LCP_REQ(Signal* signal); + + void execSTART_FRAGREQ(Signal* signal); + void execSTART_RECREF(Signal* signal); + void execSR_FRAGIDCONF(Signal* signal); + void execSR_FRAGIDREF(Signal* signal); + void execACC_SRCONF(Signal* signal); + void execACC_SRREF(Signal* signal); + void execTUP_SRCONF(Signal* signal); + void execTUP_SRREF(Signal* signal); + void execGCP_SAVEREQ(Signal* signal); + void execFSOPENCONF(Signal* signal); + void execFSOPENREF(Signal* signal); + void execFSCLOSECONF(Signal* signal); + void execFSCLOSEREF(Signal* signal); + void execFSWRITECONF(Signal* signal); + void execFSWRITEREF(Signal* signal); + void execFSREADCONF(Signal* signal); + void execFSREADREF(Signal* signal); + void execSCAN_HBREP(Signal* signal); + void execSET_VAR_REQ(Signal* signal); + void execTIME_SIGNAL(Signal* signal); + void execFSSYNCCONF(Signal* signal); + void execFSSYNCREF(Signal* signal); + + void execALTER_TAB_REQ(Signal* signal); + void execALTER_TAB_CONF(Signal* signal); + + void execCREATE_TRIG_CONF(Signal* signal); + void execCREATE_TRIG_REF(Signal* signal); + void execCREATE_TRIG_REQ(Signal* signal); + + void execDROP_TRIG_CONF(Signal* signal); + void execDROP_TRIG_REF(Signal* signal); + void execDROP_TRIG_REQ(Signal* signal); + + void execPREP_DROP_TAB_REQ(Signal* signal); + void execWAIT_DROP_TAB_REQ(Signal* signal); + void execDROP_TAB_REQ(Signal* signal); + + void execLQH_ALLOCREQ(Signal* signal); + void execLQH_WRITELOG_REQ(Signal* signal); + + void execTUXFRAGCONF(Signal* signal); + void execTUXFRAGREF(Signal* signal); + void execTUX_ADD_ATTRCONF(Signal* signal); + void execTUX_ADD_ATTRREF(Signal* signal); + + // Statement blocks + + void init_acc_ptr_list(ScanRecord*); + bool seize_acc_ptr_list(ScanRecord*, Uint32); + void release_acc_ptr_list(ScanRecord*); + Uint32 get_acc_ptr_from_scan_record(ScanRecord*, Uint32, bool); + void set_acc_ptr_in_scan_record(ScanRecord*, Uint32, Uint32); + void i_get_acc_ptr(ScanRecord*, Uint32*&, Uint32); + + void removeTable(Uint32 tableId); + void sendLCP_COMPLETE_REP(Signal* signal, Uint32 lcpId); + void sendEMPTY_LCP_CONF(Signal* signal, bool idle); + void sendLCP_FRAGIDREQ(Signal* signal); + void sendLCP_FRAG_REP(Signal * signal, const LcpRecord::FragOrd &) const; + + void updatePackedList(Signal* signal, HostRecord * ahostptr, Uint16 hostId); + void LQHKEY_abort(Signal* signal, int errortype); + void LQHKEY_error(Signal* signal, int errortype); + void nextRecordCopy(Signal* signal); + void calculateHash(Signal* signal); + void continueAfterCheckLcpStopBlocked(Signal* signal); + void checkLcpStopBlockedLab(Signal* signal); + void sendCommittedTc(Signal* signal, BlockReference atcBlockref); + void sendCompletedTc(Signal* signal, BlockReference atcBlockref); + void sendLqhkeyconfTc(Signal* signal, BlockReference atcBlockref); + void sendCommitLqh(Signal* signal, BlockReference alqhBlockref); + void sendCompleteLqh(Signal* signal, BlockReference alqhBlockref); + void sendPackedSignalLqh(Signal* signal, HostRecord * ahostptr); + void sendPackedSignalTc(Signal* signal, HostRecord * ahostptr); + Uint32 handleLongTupKey(Signal* signal, + Uint32 lenSofar, + Uint32 primKeyLen, + Uint32* dataPtr); + void cleanUp(Signal* signal); + void sendAttrinfoLoop(Signal* signal); + void sendAttrinfoSignal(Signal* signal); + void sendLqhAttrinfoSignal(Signal* signal); + void sendKeyinfoAcc(Signal* signal, Uint32 pos); + Uint32 initScanrec(const class ScanFragReq *); + void initScanTc(Signal* signal, + Uint32 transid1, + Uint32 transid2, + Uint32 fragId, + Uint32 nodeId); + void finishScanrec(Signal* signal); + void releaseScanrec(Signal* signal); + void seizeScanrec(Signal* signal); + Uint32 sendKeyinfo20(Signal* signal, ScanRecord *, TcConnectionrec *); + void sendScanFragConf(Signal* signal, Uint32 scanCompleted); + void initCopyrec(Signal* signal); + void initCopyTc(Signal* signal); + void sendCopyActiveConf(Signal* signal,Uint32 tableId); + void checkLcpCompleted(Signal* signal); + void checkLcpHoldop(Signal* signal); + void checkLcpStarted(Signal* signal); + void checkLcpTupprep(Signal* signal); + void getNextFragForLcp(Signal* signal); + void initLcpLocAcc(Signal* signal, Uint32 fragId); + void initLcpLocTup(Signal* signal, Uint32 fragId); + void moveAccActiveFrag(Signal* signal); + void moveActiveToAcc(Signal* signal); + void releaseLocalLcps(Signal* signal); + void seizeLcpLoc(Signal* signal); + void sendAccContOp(Signal* signal); + void sendStartLcp(Signal* signal); + void setLogTail(Signal* signal, Uint32 keepGci); + Uint32 remainingLogSize(const LogFileRecordPtr &sltCurrLogFilePtr, + const LogPartRecordPtr &sltLogPartPtr); + void checkGcpCompleted(Signal* signal, Uint32 pageWritten, Uint32 wordWritten); + void initFsopenconf(Signal* signal); + void initFsrwconf(Signal* signal); + void initLfo(Signal* signal); + void initLogfile(Signal* signal, Uint32 fileNo); + void initLogpage(Signal* signal); + void openFileRw(Signal* signal, LogFileRecordPtr olfLogFilePtr); + void openLogfileInit(Signal* signal); + void openNextLogfile(Signal* signal); + void releaseLfo(Signal* signal); + void releaseLfoPages(Signal* signal); + void releaseLogpage(Signal* signal); + void seizeLfo(Signal* signal); + void seizeLogfile(Signal* signal); + void seizeLogpage(Signal* signal); + void writeFileDescriptor(Signal* signal); + void writeFileHeaderOpen(Signal* signal, Uint32 type); + void writeInitMbyte(Signal* signal); + void writeSinglePage(Signal* signal, Uint32 pageNo, Uint32 wordWritten); + void buildLinkedLogPageList(Signal* signal); + void changeMbyte(Signal* signal); + Uint32 checkIfExecLog(Signal* signal); + void checkNewMbyte(Signal* signal); + void checkReadExecSr(Signal* signal); + void checkScanTcCompleted(Signal* signal); + void checkSrCompleted(Signal* signal); + void closeFile(Signal* signal, LogFileRecordPtr logFilePtr); + void completedLogPage(Signal* signal, Uint32 clpType); + void deleteFragrec(Uint32 fragId); + void deleteTransidHash(Signal* signal); + void findLogfile(Signal* signal, + Uint32 fileNo, + LogPartRecordPtr flfLogPartPtr, + LogFileRecordPtr* parLogFilePtr); + void findPageRef(Signal* signal, CommitLogRecord* commitLogRecord); + int findTransaction(UintR Transid1, UintR Transid2, UintR TcOprec); + void getFirstInLogQueue(Signal* signal); + bool getFragmentrec(Signal* signal, Uint32 fragId); + void initialiseAddfragrec(Signal* signal); + void initialiseAttrbuf(Signal* signal); + void initialiseDatabuf(Signal* signal); + void initialiseFragrec(Signal* signal); + void initialiseGcprec(Signal* signal); + void initialiseLcpRec(Signal* signal); + void initialiseLcpLocrec(Signal* signal); + void initialiseLfo(Signal* signal); + void initialiseLogFile(Signal* signal); + void initialiseLogPage(Signal* signal); + void initialiseLogPart(Signal* signal); + void initialisePageRef(Signal* signal); + void initialiseScanrec(Signal* signal); + void initialiseTabrec(Signal* signal); + void initialiseTcrec(Signal* signal); + void initialiseTcNodeFailRec(Signal* signal); + void initFragrec(Signal* signal, + Uint32 tableId, + Uint32 fragId, + Uint32 copyType); + void initFragrecSr(Signal* signal); + void initGciInLogFileRec(Signal* signal, Uint32 noFdDesc); + void initLcpSr(Signal* signal, + Uint32 lcpNo, + Uint32 lcpId, + Uint32 tableId, + Uint32 fragId, + Uint32 fragPtr); + void initLogpart(Signal* signal); + void initLogPointers(Signal* signal); + void initReqinfoExecSr(Signal* signal); + bool insertFragrec(Signal* signal, Uint32 fragId); + void linkActiveFrag(Signal* signal); + void linkFragQueue(Signal* signal); + void linkWaitLog(Signal* signal, LogPartRecordPtr regLogPartPtr); + void logNextStart(Signal* signal); + void moveToPageRef(Signal* signal); + void readAttrinfo(Signal* signal); + void readCommitLog(Signal* signal, CommitLogRecord* commitLogRecord); + void readExecLog(Signal* signal); + void readExecSrNewMbyte(Signal* signal); + void readExecSr(Signal* signal); + void readKey(Signal* signal); + void readLogData(Signal* signal, Uint32 noOfWords, Uint32* dataPtr); + void readLogHeader(Signal* signal); + Uint32 readLogword(Signal* signal); + Uint32 readLogwordExec(Signal* signal); + void readSinglePage(Signal* signal, Uint32 pageNo); + void releaseAccList(Signal* signal); + void releaseActiveCopy(Signal* signal); + void releaseActiveFrag(Signal* signal); + void releaseActiveList(Signal* signal); + void releaseAddfragrec(Signal* signal); + void releaseFragrec(); + void releaseLcpLoc(Signal* signal); + void releaseOprec(Signal* signal); + void releasePageRef(Signal* signal); + void releaseMmPages(Signal* signal); + void releasePrPages(Signal* signal); + void releaseTcrec(Signal* signal, TcConnectionrecPtr tcConnectptr); + void releaseTcrecLog(Signal* signal, TcConnectionrecPtr tcConnectptr); + void releaseWaitQueue(Signal* signal); + void removeLogTcrec(Signal* signal); + void removePageRef(Signal* signal); + Uint32 returnExecLog(Signal* signal); + int saveTupattrbuf(Signal* signal, Uint32* dataPtr, Uint32 length); + void seizeAddfragrec(Signal* signal); + void seizeAttrinbuf(Signal* signal); + Uint32 seize_attrinbuf(); + Uint32 release_attrinbuf(Uint32); + Uint32 copy_bounds(Uint32 * dst, TcConnectionrec*); + + void seizeFragmentrec(Signal* signal); + void seizePageRef(Signal* signal); + void seizeTcrec(); + void seizeTupkeybuf(Signal* signal); + void sendAborted(Signal* signal); + void sendLqhTransconf(Signal* signal, LqhTransConf::OperationStatus); + void sendTupkey(Signal* signal); + void startExecSr(Signal* signal); + void startNextExecSr(Signal* signal); + void startTimeSupervision(Signal* signal); + void stepAhead(Signal* signal, Uint32 stepAheadWords); + void systemError(Signal* signal); + void writeAbortLog(Signal* signal); + void writeCommitLog(Signal* signal, LogPartRecordPtr regLogPartPtr); + void writeCompletedGciLog(Signal* signal); + void writeDirty(Signal* signal); + void writeKey(Signal* signal); + void writeLogHeader(Signal* signal); + void writeLogWord(Signal* signal, Uint32 data); + void writeNextLog(Signal* signal); + void errorReport(Signal* signal, int place); + void warningReport(Signal* signal, int place); + void invalidateLogAfterLastGCI(Signal *signal); + void readFileInInvalidate(Signal *signal); + void exitFromInvalidate(Signal* signal); + Uint32 calcPageCheckSum(LogPageRecordPtr logP); + + // Generated statement blocks + void systemErrorLab(Signal* signal); + void initFourth(Signal* signal); + void packLqhkeyreqLab(Signal* signal); + void sendNdbSttorryLab(Signal* signal); + void execSrCompletedLab(Signal* signal); + void execLogRecord(Signal* signal); + void srPhase3Comp(Signal* signal); + void srLogLimits(Signal* signal); + void srGciLimits(Signal* signal); + void srPhase3Start(Signal* signal); + void warningHandlerLab(Signal* signal); + void checkStartCompletedLab(Signal* signal); + void continueAbortLab(Signal* signal); + void abortContinueAfterBlockedLab(Signal* signal, bool canBlock); + void abortCommonLab(Signal* signal); + void localCommitLab(Signal* signal); + void abortErrorLab(Signal* signal); + void continueAfterReceivingAllAiLab(Signal* signal); + void abortStateHandlerLab(Signal* signal); + void writeAttrinfoLab(Signal* signal); + void scanAttrinfoLab(Signal* signal, Uint32* dataPtr, Uint32 length); + void abort_scan(Signal* signal, Uint32 scan_ptr_i, Uint32 errcode); + void localAbortStateHandlerLab(Signal* signal); + void logLqhkeyreqLab(Signal* signal); + void lqhAttrinfoLab(Signal* signal, Uint32* dataPtr, Uint32 length); + void rwConcludedAiLab(Signal* signal); + void aiStateErrorCheckLab(Signal* signal, Uint32* dataPtr, Uint32 length); + void takeOverErrorLab(Signal* signal); + void endgettupkeyLab(Signal* signal); + void noFreeRecordLab(Signal* signal, + const class LqhKeyReq * lqhKeyReq, + Uint32 errorCode); + void logLqhkeyrefLab(Signal* signal); + void closeCopyLab(Signal* signal); + void commitReplyLab(Signal* signal); + void completeUnusualLab(Signal* signal); + void completeTransNotLastLab(Signal* signal); + void completedLab(Signal* signal); + void copyCompletedLab(Signal* signal); + void completeLcpRoundLab(Signal* signal); + void continueAfterLogAbortWriteLab(Signal* signal); + void sendAttrinfoLab(Signal* signal); + void sendExecConf(Signal* signal); + void execSr(Signal* signal); + void srFourthComp(Signal* signal); + void timeSup(Signal* signal); + void closeCopyRequestLab(Signal* signal); + void closeScanRequestLab(Signal* signal); + void scanTcConnectLab(Signal* signal, Uint32 startTcCon, Uint32 fragId); + void initGcpRecLab(Signal* signal); + void prepareContinueAfterBlockedLab(Signal* signal); + void commitContinueAfterBlockedLab(Signal* signal); + void continueCopyAfterBlockedLab(Signal* signal); + void continueFirstCopyAfterBlockedLab(Signal* signal); + void continueFirstScanAfterBlockedLab(Signal* signal); + void continueScanAfterBlockedLab(Signal* signal); + void continueScanReleaseAfterBlockedLab(Signal* signal); + void continueCloseScanAfterBlockedLab(Signal* signal); + void continueCloseCopyAfterBlockedLab(Signal* signal); + void sendExecFragRefLab(Signal* signal); + void fragrefLab(Signal* signal, BlockReference retRef, + Uint32 retPtr, Uint32 errorCode); + void abortAddFragOps(Signal* signal); + void rwConcludedLab(Signal* signal); + void sendsttorryLab(Signal* signal); + void initialiseRecordsLab(Signal* signal, Uint32 data, Uint32, Uint32); + void startphase2Lab(Signal* signal, Uint32 config); + void startphase3Lab(Signal* signal); + void startphase4Lab(Signal* signal); + void startphase6Lab(Signal* signal); + void moreconnectionsLab(Signal* signal); + void scanReleaseLocksLab(Signal* signal); + void closeScanLab(Signal* signal); + void nextScanConfLoopLab(Signal* signal); + void scanNextLoopLab(Signal* signal); + void commitReqLab(Signal* signal, Uint32 gci); + void completeTransLastLab(Signal* signal); + void tupScanCloseConfLab(Signal* signal); + void tupCopyCloseConfLab(Signal* signal); + void accScanCloseConfLab(Signal* signal); + void accCopyCloseConfLab(Signal* signal); + void nextScanConfScanLab(Signal* signal); + void nextScanConfCopyLab(Signal* signal); + void continueScanNextReqLab(Signal* signal); + void keyinfoLab(const Uint32 * src, const Uint32 * end); + void copySendTupkeyReqLab(Signal* signal); + void storedProcConfScanLab(Signal* signal); + void storedProcConfCopyLab(Signal* signal); + void copyStateFinishedLab(Signal* signal); + void lcpCompletedLab(Signal* signal); + void lcpStartedLab(Signal* signal); + void contChkpNextFragLab(Signal* signal); + void startLcpRoundLab(Signal* signal); + void startFragRefLab(Signal* signal); + void srCompletedLab(Signal* signal); + void openFileInitLab(Signal* signal); + void openSrFrontpageLab(Signal* signal); + void openSrLastFileLab(Signal* signal); + void openSrNextFileLab(Signal* signal); + void openExecSrStartLab(Signal* signal); + void openExecSrNewMbyteLab(Signal* signal); + void openSrFourthPhaseLab(Signal* signal); + void openSrFourthZeroSkipInitLab(Signal* signal); + void openSrFourthZeroLab(Signal* signal); + void openExecLogLab(Signal* signal); + void checkInitCompletedLab(Signal* signal); + void closingSrLab(Signal* signal); + void closeExecSrLab(Signal* signal); + void execLogComp(Signal* signal); + void closeWriteLogLab(Signal* signal); + void closeExecLogLab(Signal* signal); + void writePageZeroLab(Signal* signal); + void lastWriteInFileLab(Signal* signal); + void initWriteEndLab(Signal* signal); + void initFirstPageLab(Signal* signal); + void writeGciZeroLab(Signal* signal); + void writeDirtyLab(Signal* signal); + void writeInitMbyteLab(Signal* signal); + void writeLogfileLab(Signal* signal); + void firstPageWriteLab(Signal* signal); + void readSrLastMbyteLab(Signal* signal); + void readSrLastFileLab(Signal* signal); + void readSrNextFileLab(Signal* signal); + void readExecSrLab(Signal* signal); + void readExecLogLab(Signal* signal); + void readSrFourthPhaseLab(Signal* signal); + void readSrFourthZeroLab(Signal* signal); + void copyLqhKeyRefLab(Signal* signal); + void restartOperationsLab(Signal* signal); + void lqhTransNextLab(Signal* signal); + void restartOperationsAfterStopLab(Signal* signal); + void sttorStartphase1Lab(Signal* signal); + void startphase1Lab(Signal* signal, Uint32 config, Uint32 nodeId); + void tupkeyConfLab(Signal* signal); + void copyTupkeyConfLab(Signal* signal); + void scanTupkeyConfLab(Signal* signal); + void scanTupkeyRefLab(Signal* signal); + void accScanConfScanLab(Signal* signal); + void accScanConfCopyLab(Signal* signal); + void scanLockReleasedLab(Signal* signal); + void openSrFourthNextLab(Signal* signal); + void closingInitLab(Signal* signal); + void closeExecSrCompletedLab(Signal* signal); + void readSrFrontpageLab(Signal* signal); + + void sendAddFragReq(Signal* signal); + void sendAddAttrReq(Signal* signal); + void checkDropTab(Signal*); + Uint32 checkDropTabState(Tablerec::TableStatus, Uint32) const; + + // Initialisation + void initData(); + void initRecords(); + + Dbtup* c_tup; + Uint32 readPrimaryKeys(ScanRecord*, TcConnectionrec*, Uint32 * dst); +// ---------------------------------------------------------------- +// These are variables handling the records. For most records one +// pointer to the array of structs, one pointer-struct, a file size +// and a first free record variable. The pointer struct are temporary +// variables that are kept on the class object since there are often a +// great deal of those variables that exist simultaneously and +// thus no perfect solution of handling them is currently available. +// ---------------------------------------------------------------- +/* ------------------------------------------------------------------------- */ +/* POSITIONS WITHIN THE ATTRINBUF AND THE MAX SIZE OF DATA WITHIN AN */ +/* ATTRINBUF. */ +/* ------------------------------------------------------------------------- */ + + +#define ZADDFRAGREC_FILE_SIZE 1 + AddFragRecord *addFragRecord; + AddFragRecordPtr addfragptr; + UintR cfirstfreeAddfragrec; + UintR caddfragrecFileSize; + +#define ZATTRINBUF_FILE_SIZE 12288 // 1.5 MByte +#define ZINBUF_DATA_LEN 24 /* POSITION OF 'DATA LENGHT'-VARIABLE. */ +#define ZINBUF_NEXT 25 /* POSITION OF 'NEXT'-VARIABLE. */ + Attrbuf *attrbuf; + AttrbufPtr attrinbufptr; + UintR cfirstfreeAttrinbuf; + UintR cattrinbufFileSize; + Uint32 c_no_attrinbuf_recs; + +#define ZDATABUF_FILE_SIZE 10000 // 200 kByte + Databuf *databuf; + DatabufPtr databufptr; + UintR cfirstfreeDatabuf; + UintR cdatabufFileSize; + +// Configurable + Fragrecord *fragrecord; + FragrecordPtr fragptr; + UintR cfirstfreeFragrec; + UintR cfragrecFileSize; + +#define ZGCPREC_FILE_SIZE 1 + GcpRecord *gcpRecord; + GcpRecordPtr gcpPtr; + UintR cgcprecFileSize; + +// MAX_NDB_NODES is the size of this array + HostRecord *hostRecord; + UintR chostFileSize; + +#define ZNO_CONCURRENT_LCP 1 + LcpRecord *lcpRecord; + LcpRecordPtr lcpPtr; + UintR cfirstfreeLcpLoc; + UintR clcpFileSize; + +#define ZLCP_LOCREC_FILE_SIZE 4 + LcpLocRecord *lcpLocRecord; + LcpLocRecordPtr lcpLocptr; + UintR clcpLocrecFileSize; + +#define ZLOG_PART_FILE_SIZE 4 + LogPartRecord *logPartRecord; + LogPartRecordPtr logPartPtr; + UintR clogPartFileSize; + +// Configurable + LogFileRecord *logFileRecord; + LogFileRecordPtr logFilePtr; + UintR cfirstfreeLogFile; + UintR clogFileFileSize; + +#define ZLFO_FILE_SIZE 256 /* MAX 256 OUTSTANDING FILE OPERATIONS */ + LogFileOperationRecord *logFileOperationRecord; + LogFileOperationRecordPtr lfoPtr; + UintR cfirstfreeLfo; + UintR clfoFileSize; + + LogPageRecord *logPageRecord; + LogPageRecordPtr logPagePtr; + UintR cfirstfreeLogPage; + UintR clogPageFileSize; + +#define ZPAGE_REF_FILE_SIZE 20 + PageRefRecord *pageRefRecord; + PageRefRecordPtr pageRefPtr; + UintR cfirstfreePageRef; + UintR cpageRefFileSize; + +#define ZSCANREC_FILE_SIZE 100 + ArrayPool<ScanRecord> c_scanRecordPool; + ScanRecordPtr scanptr; + UintR cscanNoFreeRec; + Uint32 cscanrecFileSize; + +// Configurable + Tablerec *tablerec; + TablerecPtr tabptr; + UintR ctabrecFileSize; + +// Configurable + TcConnectionrec *tcConnectionrec; + TcConnectionrecPtr tcConnectptr; + UintR cfirstfreeTcConrec; + UintR ctcConnectrecFileSize; + +// MAX_NDB_NODES is the size of this array + TcNodeFailRecord *tcNodeFailRecord; + TcNodeFailRecordPtr tcNodeFailptr; + UintR ctcNodeFailrecFileSize; + + Uint16 terrorCode; + + Uint32 c_firstInNodeGroup; + +// ------------------------------------------------------------------------ +// These variables are used to store block state which do not need arrays +// of struct's. +// ------------------------------------------------------------------------ + Uint32 c_lcpId; + Uint32 cnoOfFragsCheckpointed; + +/* ------------------------------------------------------------------------- */ +// cmaxWordsAtNodeRec keeps track of how many words that currently are +// outstanding in a node recovery situation. +// cbookedAccOps keeps track of how many operation records that have been +// booked in ACC for the scan processes. +// cmaxAccOps contains the maximum number of operation records which can be +// allocated for scan purposes in ACC. +/* ------------------------------------------------------------------------- */ + UintR cmaxWordsAtNodeRec; + UintR cbookedAccOps; + UintR cmaxAccOps; +/* ------------------------------------------------------------------------- */ +/*THIS STATE VARIABLE IS ZTRUE IF AN ADD NODE IS ONGOING. ADD NODE MEANS */ +/*THAT CONNECTIONS ARE SET-UP TO THE NEW NODE. */ +/* ------------------------------------------------------------------------- */ + Uint8 caddNodeState; +/* ------------------------------------------------------------------------- */ +/*THIS VARIABLE SPECIFIES WHICH TYPE OF RESTART THAT IS ONGOING */ +/* ------------------------------------------------------------------------- */ + Uint16 cstartType; +/* ------------------------------------------------------------------------- */ +/*THIS VARIABLE INDICATES WHETHER AN INITIAL RESTART IS ONGOING OR NOT. */ +/* ------------------------------------------------------------------------- */ + Uint8 cinitialStartOngoing; +/* ------------------------------------------------------------------------- */ +/*THIS VARIABLE KEEPS TRACK OF WHEN TUP AND ACC HAVE COMPLETED EXECUTING */ +/*THEIR UNDO LOG. */ +/* ------------------------------------------------------------------------- */ + ExecUndoLogState csrExecUndoLogState; +/* ------------------------------------------------------------------------- */ +/*THIS VARIABLE KEEPS TRACK OF WHEN TUP AND ACC HAVE CONFIRMED COMPLETION */ +/*OF A LOCAL CHECKPOINT ROUND. */ +/* ------------------------------------------------------------------------- */ + LcpCloseState clcpCompletedState; +/* ------------------------------------------------------------------------- */ +/*DURING CONNECTION PROCESSES IN SYSTEM RESTART THESE VARIABLES KEEP TRACK */ +/*OF HOW MANY CONNECTIONS AND RELEASES THAT ARE TO BE PERFORMED. */ +/* ------------------------------------------------------------------------- */ +/***************************************************************************>*/ +/*THESE VARIABLES CONTAIN INFORMATION USED DURING SYSTEM RESTART. */ +/***************************************************************************>*/ +/* ------------------------------------------------------------------------- */ +/*THIS VARIABLE IS ZTRUE IF THE SIGNAL START_REC_REQ HAVE BEEN RECEIVED. */ +/*RECEPTION OF THIS SIGNAL INDICATES THAT ALL FRAGMENTS THAT THIS NODE */ +/*SHOULD START HAVE BEEN RECEIVED. */ +/* ------------------------------------------------------------------------- */ + Uint8 cstartRecReq; +/* ------------------------------------------------------------------------- */ +/*THIS VARIABLE KEEPS TRACK OF HOW MANY FRAGMENTS THAT PARTICIPATE IN */ +/*EXECUTING THE LOG. IF ZERO WE DON'T NEED TO EXECUTE THE LOG AT ALL. */ +/* ------------------------------------------------------------------------- */ + UintR cnoFragmentsExecSr; +/* ------------------------------------------------------------------------- */ +/*THIS VARIABLE KEEPS TRACK OF WHICH OF THE FIRST TWO RESTART PHASES THAT */ +/*HAVE COMPLETED. */ +/* ------------------------------------------------------------------------- */ + Uint8 csrPhaseStarted; +/* ------------------------------------------------------------------------- */ +/*NUMBER OF PHASES COMPLETED OF EXECUTING THE FRAGMENT LOG. */ +/* ------------------------------------------------------------------------- */ + Uint8 csrPhasesCompleted; +/* ------------------------------------------------------------------------- */ +/*THE BLOCK REFERENCE OF THE MASTER DIH DURING SYSTEM RESTART. */ +/* ------------------------------------------------------------------------- */ + BlockReference cmasterDihBlockref; +/* ------------------------------------------------------------------------- */ +/*THIS VARIABLE IS THE HEAD OF A LINKED LIST OF FRAGMENTS WAITING TO BE */ +/*RESTORED FROM DISK. */ +/* ------------------------------------------------------------------------- */ + UintR cfirstWaitFragSr; +/* ------------------------------------------------------------------------- */ +/*THIS VARIABLE IS THE HEAD OF A LINKED LIST OF FRAGMENTS THAT HAVE BEEN */ +/*RESTORED FROM DISK THAT AWAITS EXECUTION OF THE FRAGMENT LOG. */ +/* ------------------------------------------------------------------------- */ + UintR cfirstCompletedFragSr; + + /** + * List of fragment that the log execution is completed for + */ + Uint32 c_redo_log_complete_frags; + +/* ------------------------------------------------------------------------- */ +/*USED DURING SYSTEM RESTART, INDICATES THE OLDEST GCI THAT CAN BE RESTARTED */ +/*FROM AFTER THIS SYSTEM RESTART. USED TO FIND THE LOG TAIL. */ +/* ------------------------------------------------------------------------- */ + UintR crestartOldestGci; +/* ------------------------------------------------------------------------- */ +/*USED DURING SYSTEM RESTART, INDICATES THE NEWEST GCI THAT CAN BE RESTARTED */ +/*AFTER THIS SYSTEM RESTART. USED TO FIND THE LOG HEAD. */ +/* ------------------------------------------------------------------------- */ + UintR crestartNewestGci; +/* ------------------------------------------------------------------------- */ +/*THE NUMBER OF LOG FILES. SET AS A PARAMETER WHEN NDB IS STARTED. */ +/* ------------------------------------------------------------------------- */ + UintR cnoLogFiles; +/* ------------------------------------------------------------------------- */ +/*THESE TWO VARIABLES CONTAIN THE NEWEST GCI RECEIVED IN THE BLOCK AND THE */ +/*NEWEST COMPLETED GCI IN THE BLOCK. */ +/* ------------------------------------------------------------------------- */ + UintR cnewestGci; + UintR cnewestCompletedGci; +/* ------------------------------------------------------------------------- */ +/*THIS VARIABLE ONLY PASSES INFORMATION FROM STTOR TO STTORRY = TEMPORARY */ +/* ------------------------------------------------------------------------- */ + Uint16 csignalKey; +/* ------------------------------------------------------------------------- */ +/*THIS VARIABLE CONTAINS THE CURRENT START PHASE IN THE BLOCK. IS ZNIL IF */ +/*NO SYSTEM RESTART IS ONGOING. */ +/* ------------------------------------------------------------------------- */ + Uint16 cstartPhase; +/* ------------------------------------------------------------------------- */ +/*THIS VARIABLE CONTAIN THE CURRENT GLOBAL CHECKPOINT RECORD. IT'S RNIL IF */ +/*NOT A GCP SAVE IS ONGOING. */ +/* ------------------------------------------------------------------------- */ + UintR ccurrentGcprec; +/* ------------------------------------------------------------------------- */ +/*THESE VARIABLES ARE USED TO KEEP TRACK OF ALL ACTIVE COPY FRAGMENTS IN LQH.*/ +/* ------------------------------------------------------------------------- */ + Uint8 cnoActiveCopy; + UintR cactiveCopy[4]; + +/* ------------------------------------------------------------------------- */ +/*THESE VARIABLES CONTAIN THE BLOCK REFERENCES OF THE OTHER NDB BLOCKS. */ +/*ALSO THE BLOCK REFERENCE OF MY OWN BLOCK = LQH */ +/* ------------------------------------------------------------------------- */ + BlockReference caccBlockref; + BlockReference ctupBlockref; + BlockReference ctuxBlockref; + BlockReference cownref; + UintR cLqhTimeOutCount; + UintR cLqhTimeOutCheckCount; + UintR cnoOfLogPages; + bool caccCommitBlocked; + bool ctupCommitBlocked; + bool cCommitBlocked; + UintR cCounterAccCommitBlocked; + UintR cCounterTupCommitBlocked; +/* ------------------------------------------------------------------------- */ +/*THIS VARIABLE CONTAINS MY OWN PROCESSOR ID. */ +/* ------------------------------------------------------------------------- */ + NodeId cownNodeid; + +/* ------------------------------------------------------------------------- */ +/*THESE VARIABLES CONTAIN INFORMATION ABOUT THE OTHER NODES IN THE SYSTEM */ +/*THESE VARIABLES ARE MOSTLY USED AT SYSTEM RESTART AND ADD NODE TO SET-UP */ +/*AND RELEASE CONNECTIONS TO OTHER NODES IN THE CLUSTER. */ +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ +/*THIS ARRAY CONTAINS THE PROCESSOR ID'S OF THE NODES THAT ARE ALIVE. */ +/*CNO_OF_NODES SPECIFIES HOW MANY NODES THAT ARE CURRENTLY ALIVE. */ +/*CNODE_VERSION SPECIFIES THE NDB VERSION EXECUTING ON THE NODE. */ +/* ------------------------------------------------------------------------- */ + UintR cpackedListIndex; + Uint16 cpackedList[MAX_NDB_NODES]; + UintR cnodeData[MAX_NDB_NODES]; + UintR cnodeStatus[MAX_NDB_NODES]; +/* ------------------------------------------------------------------------- */ +/*THIS VARIABLE INDICATES WHETHER A CERTAIN NODE HAS SENT ALL FRAGMENTS THAT */ +/*NEED TO HAVE THE LOG EXECUTED. */ +/* ------------------------------------------------------------------------- */ + Uint8 cnodeSrState[MAX_NDB_NODES]; +/* ------------------------------------------------------------------------- */ +/*THIS VARIABLE INDICATES WHETHER A CERTAIN NODE HAVE EXECUTED THE LOG */ +/* ------------------------------------------------------------------------- */ + Uint8 cnodeExecSrState[MAX_NDB_NODES]; + UintR cnoOfNodes; + +/* ------------------------------------------------------------------------- */ +/* THIS VARIABLE CONTAINS THE DIRECTORY OF A HASH TABLE OF ALL ACTIVE */ +/* OPERATION IN THE BLOCK. IT IS USED TO BE ABLE TO QUICKLY ABORT AN */ +/* OPERATION WHERE THE CONNECTION WAS LOST DUE TO NODE FAILURES. IT IS */ +/* ACTUALLY USED FOR ALL ABORTS COMMANDED BY TC. */ +/* ------------------------------------------------------------------------- */ + UintR preComputedRequestInfoMask; + UintR ctransidHash[1024]; + + Uint32 c_diskless; + +public: + /** + * + */ + struct CommitAckMarker { + Uint32 transid1; + Uint32 transid2; + + Uint32 apiRef; // Api block ref + Uint32 apiOprec; // Connection Object in NDB API + Uint32 tcNodeId; + union { Uint32 nextPool; Uint32 nextHash; }; + Uint32 prevHash; + + inline bool equal(const CommitAckMarker & p) const { + return ((p.transid1 == transid1) && (p.transid2 == transid2)); + } + + inline Uint32 hashValue() const { + return transid1; + } + }; + + typedef Ptr<CommitAckMarker> CommitAckMarkerPtr; + ArrayPool<CommitAckMarker> m_commitAckMarkerPool; + DLHashTable<CommitAckMarker> m_commitAckMarkerHash; + typedef DLHashTable<CommitAckMarker>::Iterator CommitAckMarkerIterator; + void execREMOVE_MARKER_ORD(Signal* signal); + void scanMarkers(Signal* signal, Uint32 tcNodeFail, Uint32 bucket, Uint32 i); + + struct Counters { + Uint32 operations; + + inline void clear(){ + operations = 0; + } + }; + + Counters c_Counters; + + inline bool getAllowRead() const { + return getNodeState().startLevel < NodeState::SL_STOPPING_3; + } + + DLHashTable<ScanRecord> c_scanTakeOverHash; +}; + +inline +bool +Dblqh::ScanRecord::check_scan_batch_completed() const +{ + Uint32 max_rows = m_max_batch_size_rows; + Uint32 max_bytes = m_max_batch_size_bytes; + + return (max_rows > 0 && (m_curr_batch_size_rows >= max_rows)) || + (max_bytes > 0 && (m_curr_batch_size_bytes >= max_bytes)); +} + +inline +void +Dblqh::i_get_acc_ptr(ScanRecord* scanP, Uint32* &acc_ptr, Uint32 index) +{ + if (index == 0) { + acc_ptr= (Uint32*)&scanP->scan_acc_op_ptr[0]; + } else { + Uint32 attr_buf_index, attr_buf_rec; + + AttrbufPtr regAttrPtr; + jam(); + attr_buf_rec= (index + 31) / 32; + attr_buf_index= (index - 1) & 31; + regAttrPtr.i= scanP->scan_acc_op_ptr[attr_buf_rec]; + ptrCheckGuard(regAttrPtr, cattrinbufFileSize, attrbuf); + acc_ptr= (Uint32*)®AttrPtr.p->attrbuf[attr_buf_index]; + } +} + +#endif |