1 /*
2    Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
3 
4    This program is free software; you can redistribute it and/or modify
5    it under the terms of the GNU General Public License, version 2.0,
6    as published by the Free Software Foundation.
7 
8    This program is also distributed with certain software (including
9    but not limited to OpenSSL) that is licensed under separate terms,
10    as designated in a particular file or component or in included license
11    documentation.  The authors of MySQL hereby grant you an additional
12    permission to link the program and your derivative works with the
13    separately licensed software that they have included with MySQL.
14 
15    This program is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18    GNU General Public License, version 2.0, for more details.
19 
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
23 */
24 
25 #ifndef TRIX_H
26 #define TRIX_H
27 
28 #include <SimulatedBlock.hpp>
29 #include <trigger_definitions.h>
30 #include <DataBuffer.hpp>
31 #include <SimpleProperties.hpp>
32 #include <signaldata/DictTabInfo.hpp>
33 #include <signaldata/CreateTrig.hpp>
34 #include <signaldata/BuildIndx.hpp>
35 #include <signaldata/IndexStatSignal.hpp>
36 #include <signaldata/GetTabInfo.hpp>
37 #include <signaldata/TuxBound.hpp>
38 #define ZNOT_FOUND 626
39 
40 // Error codes
41 #define INTERNAL_ERROR_ILLEGAL_CALL 4344
42 #define INTERNAL_ERROR_TRIX_BUSY 4345
43 
44 /**
45  * TRIX - This block manages triggers and index (in coop with DICT)
46  */
47 class Trix : public SimulatedBlock
48 {
49 public:
50   Trix(Block_context&);
51   virtual ~Trix();
52 
53 public:
54   // Subscription data, when communicating with SUMA
55 
56   enum RequestType {
57     REORG_COPY = 0
58     ,REORG_DELETE = 1
59     ,INDEX_BUILD = 2
60     ,STAT_UTIL = 3  // PK op of HEAD table directly via DBUTIL
61     ,STAT_CLEAN = 4
62     ,STAT_SCAN = 5
63     //ALTER_TABLE
64   };
65   typedef DataBuffer<11> AttrOrderBuffer;
66 
67 private:
68   // Private attributes
69 
70   BLOCK_DEFINES(Trix);
71 
72   // Declared but not defined
73   //DBtrix(const Trix &obj);
74   //void operator = (const Trix &);
75 
76   // Block state
77   enum BlockState {
78     NOT_STARTED,
79     STARTED,
80     NODE_FAILURE,
81     IDLE,
82     BUSY
83   };
84 
85   BlockState c_blockState;
86 
87   // Node data needed when communicating with remote TRIX:es
88   struct NodeRecord {
NodeRecordTrix::NodeRecord89     NodeRecord() {}
90     bool alive;
91     BlockReference trixRef;
92     union {
93       Uint32 nextPool;
94       Uint32 nextList;
95     };
96     Uint32 prevList;
97   };
98 
99   typedef Ptr<NodeRecord> NodeRecPtr;
100 
101   /**
102    * The pool of node records
103    */
104   ArrayPool<NodeRecord> c_theNodeRecPool;
105 
106   /**
107    * The list of other NDB nodes
108    */
109   DLList<NodeRecord> c_theNodes;
110 
111   Uint32 c_masterNodeId;
112   BlockReference c_masterTrixRef;
113   Uint16 c_noNodesFailed;
114   Uint16 c_noActiveNodes;
115 
116   AttrOrderBuffer::DataBufferPool c_theAttrOrderBufferPool;
117 
118   struct SubscriptionRecord {
SubscriptionRecordTrix::SubscriptionRecord119     SubscriptionRecord(AttrOrderBuffer::DataBufferPool & aop):
120       attributeOrder(aop)
121     {}
122     enum RequestFlags {
123       RF_WAIT_GCP = 0x1
124       ,RF_NO_DISK = 0x2
125       ,RF_TUP_ORDER = 0x4
126     };
127     Uint32 m_flags;
128     RequestType requestType;
129     BlockReference userReference; // For user
130     Uint32 connectionPtr; // For user
131     Uint32 subscriptionId; // For Suma
132     Uint32 schemaTransId;
133     Uint32 subscriptionKey; // For Suma
134     Uint32 prepareId; // For DbUtil
135     Uint32 indexType;
136     Uint32 sourceTableId;
137     Uint32 targetTableId;
138     AttrOrderBuffer attributeOrder;
139     Uint32 noOfIndexColumns;
140     Uint32 noOfKeyColumns;
141     Uint32 parallelism;
142     Uint32 fragCount;
143     Uint32 fragId;
144     Uint32 syncPtr;
145     BuildIndxRef::ErrorCode errorCode;
146     bool subscriptionCreated;
147     bool pendingSubSyncContinueConf;
148     Uint32 expectedConf; // Count in n UTIL_EXECUTE_CONF + 1 SUB_SYNC_CONF
149     Uint64 m_rows_processed;
150     Uint64 m_gci;
151     Uint32 m_statPtrI;
152     union {
153       Uint32 nextPool;
154       Uint32 nextList;
155     };
156     Uint32 prevList;
157   };
158 
159   typedef Ptr<SubscriptionRecord> SubscriptionRecPtr;
160 
161   /**
162    * The pool of node records
163    */
164   ArrayPool<SubscriptionRecord> c_theSubscriptionRecPool;
165   RSS_AP_SNAPSHOT(c_theSubscriptionRecPool);
166 
167   /**
168    * The list of other subscriptions
169    */
170   DLList<SubscriptionRecord> c_theSubscriptions;
171 
172   /*
173    * Ordered index stats.  Implements sub-ops of DBDICT index stat
174    * schema op.  Each sub-op is a simple REQ which seizes and releases
175    * a stat op here before returning CONF or REF.  A stat op always has
176    * an associated SubscriptionRecord.  It is used for SUMA index scans
177    * and as proxy for PK ops to DBUTIL.
178    */
179 
180   bool c_statGetMetaDone;
181   struct SysColumn {
182     Uint32 pos;
183     const char* name;
184     bool keyFlag;
185   };
186   struct SysTable {
187     const char* name;
188     mutable Uint32 tableId;
189     const Uint32 columnCount;
190     const SysColumn* columnList;
191   };
192   struct SysIndex {
193     const char* name;
194     mutable Uint32 tableId;
195     mutable Uint32 indexId;
196   };
197   static const SysColumn g_statMetaHead_column[];
198   static const SysColumn g_statMetaSample_column[];
199   static const SysTable g_statMetaHead;
200   static const SysTable g_statMetaSample;
201   static const SysIndex g_statMetaSampleX1;
202 
203   struct StatOp {
204     struct Meta {
205       GetTabInfoConf m_conf;
206       Callback m_cb;
207     };
208     struct Data {
209       Int32 m_head_found;
210       Uint32 m_indexId;
211       Uint32 m_indexVersion;
212       Uint32 m_tableId;
213       Uint32 m_fragCount;
214       Uint32 m_valueFormat;
215       Uint32 m_sampleVersion;
216       Uint32 m_loadTime;
217       Uint32 m_sampleCount;
218       Uint32 m_keyBytes;
219       Uint32* m_statKey;
220       Uint32* m_statValue;
DataTrix::StatOp::Data221       Data() {
222         m_head_found = -1;
223         m_sampleVersion = 0;
224       }
225     };
226     struct Attr {
227       Uint32* m_attr;
228       Uint32 m_attrMax;
229       Uint32 m_attrSize;
230       Uint32* m_data;
231       Uint32 m_dataMax;
232       Uint32 m_dataSize;
AttrTrix::StatOp::Attr233       Attr() {}
234     };
235     struct Util {
236       Uint32 m_prepareId;
237       bool m_not_found;
238       Callback m_cb;
UtilTrix::StatOp::Util239       Util() {
240         m_prepareId = RNIL;
241         m_not_found = false; // read + ZNOT_FOUND
242       };
243     };
244     struct Clean {
245       Uint32 m_cleanCount;
246       // bounds on index_id, index_version, sample_version
247       Uint32 m_bound[3 * 3];
248       Uint32 m_boundCount;
249       Uint32 m_boundSize;
CleanTrix::StatOp::Clean250       Clean() {}
251     };
252     struct Scan {
253       Uint32 m_sampleCount;
254       Uint32 m_keyBytes;
ScanTrix::StatOp::Scan255       Scan() {}
256     };
257     struct Drop {
258     };
259     struct Send {
260       const SysTable* m_sysTable;
261       Uint32 m_operationType;     // UtilPrepareReq::OperationTypeValue
262       Uint32 m_prepareId;
SendTrix::StatOp::Send263       Send() {}
264     };
265     IndexStatImplReq m_req;
266     Uint32 m_requestType;
267     const char* m_requestName;
268     Uint32 m_subRecPtrI;
269     Meta m_meta;
270     Data m_data;
271     Attr m_attr;
272     Util m_util;
273     Clean m_clean;
274     Scan m_scan;
275     Drop m_drop;
276     Send m_send;
277     Uint32 m_errorCode;
278     Uint32 m_errorLine;
279     union {
280       Uint32 m_ownPtrI;
281       Uint32 nextPool;
282     };
StatOpTrix::StatOp283     StatOp() {
284       m_subRecPtrI = RNIL;
285       m_errorCode = 0;
286       m_errorLine = 0;
287     };
288   };
289   typedef Ptr<StatOp> StatOpPtr;
290   ArrayPool<StatOp> c_statOpPool;
291   RSS_AP_SNAPSHOT(c_statOpPool);
292 
293   // System start
294   void execREAD_CONFIG_REQ(Signal* signal);
295   void execSTTOR(Signal* signal);
296   void execNDB_STTOR(Signal* signal);
297 
298   // Node management
299   void execREAD_NODESCONF(Signal* signal);
300   void execREAD_NODESREF(Signal* signal);
301   void execNODE_FAILREP(Signal* signal);
302   void execINCL_NODEREQ(Signal* signal);
303   // Debugging
304   void execDUMP_STATE_ORD(Signal* signal);
305 
306   void execDBINFO_SCANREQ(Signal* signal);
307 
308   // Build index
309   void execBUILD_INDX_IMPL_REQ(Signal* signal);
310   void execBUILD_INDX_IMPL_CONF(Signal* signal);
311   void execBUILD_INDX_IMPL_REF(Signal* signal);
312 
313   void execCOPY_DATA_IMPL_REQ(Signal* signal);
314 
315   void execUTIL_PREPARE_CONF(Signal* signal);
316   void execUTIL_PREPARE_REF(Signal* signal);
317   void execUTIL_EXECUTE_CONF(Signal* signal);
318   void execUTIL_EXECUTE_REF(Signal* signal);
319   void execUTIL_RELEASE_CONF(Signal* signal);
320   void execUTIL_RELEASE_REF(Signal* signal);
321 
322   // Suma signals
323   void execSUB_CREATE_CONF(Signal* signal);
324   void execSUB_CREATE_REF(Signal* signal);
325   void execSUB_REMOVE_CONF(Signal* signal);
326   void execSUB_REMOVE_REF(Signal* signal);
327   void execSUB_SYNC_CONF(Signal* signal);
328   void execSUB_SYNC_REF(Signal* signal);
329   void execSUB_SYNC_CONTINUE_REQ(Signal* signal);
330   void execSUB_TABLE_DATA(Signal* signal);
331 
332   // GCP
333   void execWAIT_GCP_REF(Signal*);
334   void execWAIT_GCP_CONF(Signal*);
335 
336   // Utility functions
337   void setupSubscription(Signal* signal, SubscriptionRecPtr subRecPtr);
338   void startTableScan(Signal* signal, SubscriptionRecPtr subRecPtr);
339   void prepareInsertTransactions(Signal* signal, SubscriptionRecPtr subRecPtr);
340   void executeBuildInsertTransaction(Signal* signal, SubscriptionRecPtr);
341   void executeReorgTransaction(Signal*, SubscriptionRecPtr, Uint32);
342   void buildComplete(Signal* signal, SubscriptionRecPtr subRecPtr);
343   void wait_gcp(Signal*, SubscriptionRecPtr subRecPtr, Uint32 delay = 0);
344   void buildFailed(Signal* signal,
345 		   SubscriptionRecPtr subRecPtr,
346 		   BuildIndxRef::ErrorCode);
347   void checkParallelism(Signal* signal, SubscriptionRecord* subRec);
348 
349   // index stats
350   StatOp& statOpGetPtr(Uint32 statPtrI);
351   bool statOpSeize(Uint32& statPtrI);
352   void statOpRelease(StatOp&);
353   void execINDEX_STAT_IMPL_REQ(Signal*);
354   // sys tables metadata
355   void statMetaGetHead(Signal*, StatOp&);
356   void statMetaGetHeadCB(Signal*, Uint32 statPtrI, Uint32 ret);
357   void statMetaGetSample(Signal*, StatOp&);
358   void statMetaGetSampleCB(Signal*, Uint32 statPtrI, Uint32 ret);
359   void statMetaGetSampleX1(Signal*, StatOp&);
360   void statMetaGetSampleX1CB(Signal*, Uint32 statPtrI, Uint32 ret);
361   void sendGetTabInfoReq(Signal*, StatOp&, const char* name);
362   void execGET_TABINFO_CONF(Signal*);
363   void execGET_TABINFO_REF(Signal*);
364   // continue
365   void statGetMetaDone(Signal*, StatOp&);
366   // head table ops
367   void statHeadRead(Signal*, StatOp&);
368   void statHeadReadCB(Signal*, Uint32 statPtrI, Uint32 ret);
369   void statHeadInsert(Signal*, StatOp&);
370   void statHeadInsertCB(Signal*, Uint32 statPtrI, Uint32 ret);
371   void statHeadUpdate(Signal*, StatOp&);
372   void statHeadUpdateCB(Signal*, Uint32 statPtrI, Uint32 ret);
373   void statHeadDelete(Signal*, StatOp&);
374   void statHeadDeleteCB(Signal*, Uint32 statPtrI, Uint32 ret);
375   // util
376   void statUtilPrepare(Signal*, StatOp&);
377   void statUtilPrepareConf(Signal*, Uint32 statPtrI);
378   void statUtilPrepareRef(Signal*, Uint32 statPtrI);
379   void statUtilExecute(Signal*, StatOp&);
380   void statUtilExecuteConf(Signal*, Uint32 statPtrI);
381   void statUtilExecuteRef(Signal*, Uint32 statPtrI);
382   void statUtilRelease(Signal*, StatOp&);
383   void statUtilReleaseConf(Signal*, Uint32 statPtrI);
384   // continue
385   void statReadHeadDone(Signal*, StatOp&);
386   void statInsertHeadDone(Signal*, StatOp&);
387   void statUpdateHeadDone(Signal*, StatOp&);
388   void statDeleteHeadDone(Signal*, StatOp&);
389   // clean
390   void statCleanBegin(Signal*, StatOp&);
391   void statCleanPrepare(Signal*, StatOp&);
392   void statCleanExecute(Signal*, StatOp&);
393   void statCleanRelease(Signal*, StatOp&);
394   void statCleanEnd(Signal*, StatOp&);
395   // scan
396   void statScanBegin(Signal*, StatOp&);
397   void statScanPrepare(Signal*, StatOp&);
398   void statScanExecute(Signal*, StatOp&);
399   void statScanRelease(Signal*, StatOp&);
400   void statScanEnd(Signal*, StatOp&);
401   // drop
402   void statDropBegin(Signal*, StatOp&);
403   void statDropEnd(Signal*, StatOp&);
404   // send
405   void statSendPrepare(Signal*, StatOp&);
406   void statSendExecute(Signal*, StatOp&);
407   void statSendRelease(Signal*, StatOp&);
408   // data
409   void statDataPtr(StatOp&, Uint32 i, Uint32*& dptr, Uint32& bytes);
410   void statDataOut(StatOp&, Uint32 i);
411   void statDataIn(StatOp&, Uint32 i);
412   // abort ongoing
413   void statAbortUtil(Signal*, StatOp&);
414   void statAbortUtilCB(Signal*, Uint32 statPtrI, Uint32 ret);
415   // conf and ref
416   void statOpSuccess(Signal*, StatOp&);
417   void statOpConf(Signal*, StatOp&);
418   void statOpError(Signal*, StatOp&, Uint32 errorCode, Uint32 errorLine,
419                    const Uint32 * supress = 0);
420   void statOpAbort(Signal*, StatOp&);
421   void statOpRef(Signal*, StatOp&);
422   void statOpRef(Signal*, const IndexStatImplReq*, Uint32 errorCode, Uint32 errorLine);
423   void statOpEvent(StatOp&, const char* level, const char* msg, ...);
424   // debug
425   friend class NdbOut& operator<<(NdbOut&, const StatOp& stat);
426 };
427 
428 #endif
429