MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DblqhProxy.hpp
1 /* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
2 
3  This program is free software; you can redistribute it and/or modify
4  it under the terms of the GNU General Public License as published by
5  the Free Software Foundation; version 2 of the License.
6 
7  This program is distributed in the hope that it will be useful,
8  but WITHOUT ANY WARRANTY; without even the implied warranty of
9  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  GNU General Public License for more details.
11 
12  You should have received a copy of the GNU General Public License
13  along with this program; if not, write to the Free Software
14  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
15 
16 #ifndef NDB_DBLQH_PROXY_HPP
17 #define NDB_DBLQH_PROXY_HPP
18 
19 #include <LocalProxy.hpp>
20 #include <signaldata/CreateTab.hpp>
21 #include <signaldata/LqhFrag.hpp>
22 #include <signaldata/TabCommit.hpp>
23 #include <signaldata/LCP.hpp>
24 #include <signaldata/GCP.hpp>
25 #include <signaldata/PrepDropTab.hpp>
26 #include <signaldata/DropTab.hpp>
27 #include <signaldata/AlterTab.hpp>
28 #include <signaldata/StartRec.hpp>
29 #include <signaldata/LqhTransReq.hpp>
30 #include <signaldata/LqhTransConf.hpp>
31 #include <signaldata/EmptyLcp.hpp>
32 
33 class DblqhProxy : public LocalProxy {
34 public:
36  virtual ~DblqhProxy();
37  BLOCK_DEFINES(DblqhProxy);
38 
39 protected:
40  virtual SimulatedBlock* newWorker(Uint32 instanceNo);
41 
42  // system info
43  Uint32 c_tableRecSize;
44  Uint8* c_tableRec; // bool => table exists
45 
46  // GSN_NDB_STTOR
47  virtual void callNDB_STTOR(Signal*);
48  virtual void callREAD_CONFIG_REQ(Signal*);
49 
50  // GSN_CREATE_TAB_REQ
52  CreateTabReq m_req;
53  Uint32 m_lqhConnectPtr[MaxWorkers];
55  m_sendREQ = (SsFUNCREQ)&DblqhProxy::sendCREATE_TAB_REQ;
56  m_sendCONF = (SsFUNCREP)&DblqhProxy::sendCREATE_TAB_CONF;
57  }
58  enum { poolSize = 1 };
59  static SsPool<Ss_CREATE_TAB_REQ>& pool(LocalProxy* proxy) {
60  return ((DblqhProxy*)proxy)->c_ss_CREATE_TAB_REQ;
61  }
62  };
63  SsPool<Ss_CREATE_TAB_REQ> c_ss_CREATE_TAB_REQ;
64  void execCREATE_TAB_REQ(Signal*);
65  void sendCREATE_TAB_REQ(Signal*, Uint32 ssId, SectionHandle*);
66  void execCREATE_TAB_CONF(Signal*);
67  void execCREATE_TAB_REF(Signal*);
68  void sendCREATE_TAB_CONF(Signal*, Uint32 ssId);
69 
70  // GSN_LQHADDATTREQ [ sub-op ]
72  LqhAddAttrReq m_req;
73  Uint32 m_reqlength;
74  Ss_LQHADDATTREQ() {
75  m_sendREQ = (SsFUNCREQ)&DblqhProxy::sendLQHADDATTREQ;
76  m_sendCONF = (SsFUNCREP)&DblqhProxy::sendLQHADDATTCONF;
77  }
78  enum { poolSize = 1 };
79  static SsPool<Ss_LQHADDATTREQ>& pool(LocalProxy* proxy) {
80  return ((DblqhProxy*)proxy)->c_ss_LQHADDATTREQ;
81  }
82  };
83  SsPool<Ss_LQHADDATTREQ> c_ss_LQHADDATTREQ;
84  void execLQHADDATTREQ(Signal*);
85  void sendLQHADDATTREQ(Signal*, Uint32 ssId, SectionHandle*);
86  void execLQHADDATTCONF(Signal*);
87  void execLQHADDATTREF(Signal*);
88  void sendLQHADDATTCONF(Signal*, Uint32 ssId);
89 
90  // GSN_LQHFRAGREQ [ pass-through ]
91  void execLQHFRAGREQ(Signal*);
92 
93  // GSN_TAB_COMMITREQ [ sub-op ]
95  TabCommitReq m_req;
97  m_sendREQ = (SsFUNCREQ)&DblqhProxy::sendTAB_COMMITREQ;
98  m_sendCONF = (SsFUNCREP)&DblqhProxy::sendTAB_COMMITCONF;
99  }
100  enum { poolSize = 1 };
101  static SsPool<Ss_TAB_COMMITREQ>& pool(LocalProxy* proxy) {
102  return ((DblqhProxy*)proxy)->c_ss_TAB_COMMITREQ;
103  }
104  };
105  SsPool<Ss_TAB_COMMITREQ> c_ss_TAB_COMMITREQ;
106  void execTAB_COMMITREQ(Signal*);
107  void sendTAB_COMMITREQ(Signal*, Uint32 ssId, SectionHandle*);
108  void execTAB_COMMITCONF(Signal*);
109  void execTAB_COMMITREF(Signal*);
110  void sendTAB_COMMITCONF(Signal*, Uint32 ssId);
111 
112  // GSN_GCP_SAVEREQ
114  static const char* name() { return "GCP_SAVEREQ"; }
115  GCPSaveReq m_req;
116  Ss_GCP_SAVEREQ() {
117  m_sendREQ = (SsFUNCREQ)&DblqhProxy::sendGCP_SAVEREQ;
118  m_sendCONF = (SsFUNCREP)&DblqhProxy::sendGCP_SAVECONF;
119  }
120  enum { poolSize = 1 };
121  static SsPool<Ss_GCP_SAVEREQ>& pool(LocalProxy* proxy) {
122  return ((DblqhProxy*)proxy)->c_ss_GCP_SAVEREQ;
123  }
124  };
125  SsPool<Ss_GCP_SAVEREQ> c_ss_GCP_SAVEREQ;
126  Uint32 getSsId(const GCPSaveReq* req) {
127  return SsIdBase | (req->gci & 0xFFFF);
128  }
129  Uint32 getSsId(const GCPSaveConf* conf) {
130  return SsIdBase | (conf->gci & 0xFFFF);
131  }
132  Uint32 getSsId(const GCPSaveRef* ref) {
133  return SsIdBase | (ref->gci & 0xFFFF);
134  }
135  void execGCP_SAVEREQ(Signal*);
136  void sendGCP_SAVEREQ(Signal*, Uint32 ssId, SectionHandle*);
137  void execGCP_SAVECONF(Signal*);
138  void execGCP_SAVEREF(Signal*);
139  void sendGCP_SAVECONF(Signal*, Uint32 ssId);
140 
141  // GSN_SUB_GCP_COMPLETE_REP
142  void execSUB_GCP_COMPLETE_REP(Signal*);
143 
144  // GSN_PREP_DROP_TAB_REQ
146  PrepDropTabReq m_req;
148  m_sendREQ = (SsFUNCREQ)&DblqhProxy::sendPREP_DROP_TAB_REQ;
149  m_sendCONF = (SsFUNCREP)&DblqhProxy::sendPREP_DROP_TAB_CONF;
150  }
151  enum { poolSize = 1 };
152  static SsPool<Ss_PREP_DROP_TAB_REQ>& pool(LocalProxy* proxy) {
153  return ((DblqhProxy*)proxy)->c_ss_PREP_DROP_TAB_REQ;
154  }
155  };
156  SsPool<Ss_PREP_DROP_TAB_REQ> c_ss_PREP_DROP_TAB_REQ;
157  Uint32 getSsId(const PrepDropTabReq* req) {
158  return SsIdBase | req->tableId;
159  }
160  Uint32 getSsId(const PrepDropTabConf* conf) {
161  return SsIdBase | conf->tableId;
162  }
163  Uint32 getSsId(const PrepDropTabRef* ref) {
164  return SsIdBase | ref->tableId;
165  }
166  void execPREP_DROP_TAB_REQ(Signal*);
167  void sendPREP_DROP_TAB_REQ(Signal*, Uint32 ssId, SectionHandle*);
168  void execPREP_DROP_TAB_CONF(Signal*);
169  void execPREP_DROP_TAB_REF(Signal*);
170  void sendPREP_DROP_TAB_CONF(Signal*, Uint32 ssId);
171 
172  // GSN_DROP_TAB_REQ
174  DropTabReq m_req;
175  Ss_DROP_TAB_REQ() {
176  m_sendREQ = (SsFUNCREQ)&DblqhProxy::sendDROP_TAB_REQ;
177  m_sendCONF = (SsFUNCREP)&DblqhProxy::sendDROP_TAB_CONF;
178  }
179  enum { poolSize = 1 };
180  static SsPool<Ss_DROP_TAB_REQ>& pool(LocalProxy* proxy) {
181  return ((DblqhProxy*)proxy)->c_ss_DROP_TAB_REQ;
182  }
183  };
184  SsPool<Ss_DROP_TAB_REQ> c_ss_DROP_TAB_REQ;
185  Uint32 getSsId(const DropTabReq* req) {
186  return SsIdBase | req->tableId;
187  }
188  Uint32 getSsId(const DropTabConf* conf) {
189  return SsIdBase | conf->tableId;
190  }
191  Uint32 getSsId(const DropTabRef* ref) {
192  return SsIdBase | ref->tableId;
193  }
194  void execDROP_TAB_REQ(Signal*);
195  void sendDROP_TAB_REQ(Signal*, Uint32 ssId, SectionHandle*);
196  void execDROP_TAB_CONF(Signal*);
197  void execDROP_TAB_REF(Signal*);
198  void sendDROP_TAB_CONF(Signal*, Uint32 ssId);
199 
200  // GSN_ALTER_TAB_REQ
202  AlterTabReq m_req;
203  Ss_ALTER_TAB_REQ() {
204  m_sendREQ = (SsFUNCREQ)&DblqhProxy::sendALTER_TAB_REQ;
205  m_sendCONF = (SsFUNCREP)&DblqhProxy::sendALTER_TAB_CONF;
206  }
207  enum { poolSize = 1 };
208  static SsPool<Ss_ALTER_TAB_REQ>& pool(LocalProxy* proxy) {
209  return ((DblqhProxy*)proxy)->c_ss_ALTER_TAB_REQ;
210  }
211  };
212  SsPool<Ss_ALTER_TAB_REQ> c_ss_ALTER_TAB_REQ;
213  Uint32 getSsId(const AlterTabReq* req) {
214  return SsIdBase | req->tableId;
215  }
216  Uint32 getSsId(const AlterTabConf* conf) {
217  return conf->senderData;
218  }
219  Uint32 getSsId(const AlterTabRef* ref) {
220  return ref->senderData;
221  }
222  void execALTER_TAB_REQ(Signal*);
223  void sendALTER_TAB_REQ(Signal*, Uint32 ssId, SectionHandle*);
224  void execALTER_TAB_CONF(Signal*);
225  void execALTER_TAB_REF(Signal*);
226  void sendALTER_TAB_CONF(Signal*, Uint32 ssId);
227 
232  void execSTART_FRAGREQ(Signal*);
233 
234  // GSN_START_RECREQ
236  /*
237  * The proxy is also proxy for signals from workers to global
238  * blocks LGMAN, TSMAN. These are run (sequentially) using
239  * the sub-op START_RECREQ_2.
240  */
241  static const char* name() { return "START_RECREQ"; }
242  StartRecReq m_req;
243  // pointers to START_RECREQ_2 for LGMAN, TSMAN
244  enum { m_req2cnt = 2 };
245  struct {
246  Uint32 m_blockNo;
247  Uint32 m_ssId;
248  } m_req2[m_req2cnt];
249  Ss_START_RECREQ() {
250  m_sendREQ = (SsFUNCREQ)&DblqhProxy::sendSTART_RECREQ;
251  m_sendCONF = (SsFUNCREP)&DblqhProxy::sendSTART_RECCONF;
252  m_req2[0].m_blockNo = LGMAN;
253  m_req2[1].m_blockNo = TSMAN;
254  }
255  enum { poolSize = 1 };
256  static SsPool<Ss_START_RECREQ>& pool(LocalProxy* proxy) {
257  return ((DblqhProxy*)proxy)->c_ss_START_RECREQ;
258  }
259  };
260  SsPool<Ss_START_RECREQ> c_ss_START_RECREQ;
261  void execSTART_RECREQ(Signal*);
262  void sendSTART_RECREQ(Signal*, Uint32 ssId, SectionHandle*);
263  void execSTART_RECCONF(Signal*);
264  void sendSTART_RECCONF(Signal*, Uint32 ssId);
265 
266  // GSN_START_RECREQ_2 [ sub-op, fictional gsn ]
268  static const char* name() { return "START_RECREQ_2"; }
269  struct Req {
270  enum { SignalLength = 2 };
271  Uint32 lcpId;
272  Uint32 proxyBlockNo;
273  };
274  // senderData is unnecessary as signal is unique per proxyBlockNo
275  struct Conf {
276  enum { SignalLength = 1 };
277  Uint32 senderRef;
278  };
279  Req m_req;
280  Conf m_conf;
282  // reversed sendREQ/sendCONF
283  m_sendREQ = (SsFUNCREQ)&DblqhProxy::sendSTART_RECCONF_2;
284  m_sendCONF = (SsFUNCREP)&DblqhProxy::sendSTART_RECREQ_2;
285  }
286  enum { poolSize = 2 };
287  static SsPool<Ss_START_RECREQ_2>& pool(LocalProxy* proxy) {
288  return ((DblqhProxy*)proxy)->c_ss_START_RECREQ_2;
289  }
290  };
291  SsPool<Ss_START_RECREQ_2> c_ss_START_RECREQ_2;
292  Uint32 getSsId(const Ss_START_RECREQ_2::Req* req) {
293  return SsIdBase | req->proxyBlockNo;
294  }
295  Uint32 getSsId(const Ss_START_RECREQ_2::Conf* conf) {
296  return SsIdBase | refToBlock(conf->senderRef);
297  }
298  void execSTART_RECREQ_2(Signal*);
299  void sendSTART_RECREQ_2(Signal*, Uint32 ssId);
300  void execSTART_RECCONF_2(Signal*);
301  void sendSTART_RECCONF_2(Signal*, Uint32 ssId, SectionHandle*);
302 
303  // GSN_LQH_TRANSREQ
305  static const char* name() { return "LQH_TRANSREQ"; }
310  bool m_valid;
311  LqhTransReq m_req;
312  LqhTransConf m_conf; // latest conf
313  Ss_LQH_TRANSREQ() {
314  m_valid = true;
315  m_sendREQ = (SsFUNCREQ)&DblqhProxy::sendLQH_TRANSREQ;
316  m_sendCONF = (SsFUNCREP)&DblqhProxy::sendLQH_TRANSCONF;
317  }
318  enum { poolSize = MAX_NDB_NODES };
319  static SsPool<Ss_LQH_TRANSREQ>& pool(LocalProxy* proxy) {
320  return ((DblqhProxy*)proxy)->c_ss_LQH_TRANSREQ;
321  }
322  };
323  SsPool<Ss_LQH_TRANSREQ> c_ss_LQH_TRANSREQ;
324  void execLQH_TRANSREQ(Signal*);
325  void sendLQH_TRANSREQ(Signal*, Uint32 ssId, SectionHandle*);
326  void execLQH_TRANSCONF(Signal*);
327  void sendLQH_TRANSCONF(Signal*, Uint32 ssId);
328 
329  // GSN_EXEC_SR_1 [ fictional gsn ]
331  /*
332  * Handle EXEC_SRREQ and EXEC_SRCONF. These are broadcast
333  * signals (not REQ/CONF). EXEC_SR_1 receives one signal and
334  * sends it to its workers. EXEC_SR_2 waits for signal from
335  * all workers and broadcasts it to all nodes. These are
336  * required to handle mixed versions (non-mt, mt-lqh-1,2,4).
337  */
338  static const char* name() { return "EXEC_SR_1"; }
339  struct Sig {
340  enum { SignalLength = 1 };
341  Uint32 nodeId;
342  };
343  GlobalSignalNumber m_gsn;
344  Sig m_sig;
345  Ss_EXEC_SR_1() {
346  m_sendREQ = (SsFUNCREQ)&DblqhProxy::sendEXEC_SR_1;
347  m_sendCONF = (SsFUNCREP)0;
348  m_gsn = 0;
349  };
350  enum { poolSize = 1 };
351  static SsPool<Ss_EXEC_SR_1>& pool(LocalProxy* proxy) {
352  return ((DblqhProxy*)proxy)->c_ss_EXEC_SR_1;
353  }
354  };
355  SsPool<Ss_EXEC_SR_1> c_ss_EXEC_SR_1;
356  Uint32 getSsId(const Ss_EXEC_SR_1::Sig* sig) {
357  return SsIdBase | refToNode(sig->nodeId);
358  };
359  void execEXEC_SRREQ(Signal*);
360  void execEXEC_SRCONF(Signal*);
361  void execEXEC_SR_1(Signal*, GlobalSignalNumber gsn);
362  void sendEXEC_SR_1(Signal*, Uint32 ssId, SectionHandle*);
363 
364  // GSN_EXEC_SR_2 [ fictional gsn ]
366  static const char* name() { return "EXEC_SR_2"; }
367  struct Sig {
368  enum { SignalLength = 1 + NdbNodeBitmask::Size };
369  Uint32 nodeId;
370  Uint32 sr_nodes[NdbNodeBitmask::Size]; // local signal so ok to add
371  };
372  GlobalSignalNumber m_gsn;
373  Uint32 m_sigcount;
374  Sig m_sig; // all signals must be identical
375  Ss_EXEC_SR_2() {
376  // reversed roles
377  m_sendREQ = (SsFUNCREQ)0;
378  m_sendCONF = (SsFUNCREP)&DblqhProxy::sendEXEC_SR_2;
379  m_gsn = 0;
380  m_sigcount = 0;
381  };
382  enum { poolSize = 1 };
383  static SsPool<Ss_EXEC_SR_2>& pool(LocalProxy* proxy) {
384  return ((DblqhProxy*)proxy)->c_ss_EXEC_SR_2;
385  }
386  };
387  SsPool<Ss_EXEC_SR_2> c_ss_EXEC_SR_2;
388  Uint32 getSsId(const Ss_EXEC_SR_2::Sig* sig) {
389  return SsIdBase | refToNode(sig->nodeId);
390  };
391  void execEXEC_SR_2(Signal*, GlobalSignalNumber gsn);
392  void sendEXEC_SR_2(Signal*, Uint32 ssId);
393 
399  void execEXEC_FRAGREQ(Signal*);
400  void execEXEC_FRAGCONF(Signal*);
401 
402  // GSN_DROP_FRAG_REQ
404  DropFragReq m_req;
405  Ss_DROP_FRAG_REQ() {
406  m_sendREQ = (SsFUNCREQ)&DblqhProxy::sendDROP_FRAG_REQ;
407  m_sendCONF = (SsFUNCREP)&DblqhProxy::sendDROP_FRAG_CONF;
408  }
409  enum { poolSize = 1 };
410  static SsPool<Ss_DROP_FRAG_REQ>& pool(LocalProxy* proxy) {
411  return ((DblqhProxy*)proxy)->c_ss_DROP_FRAG_REQ;
412  }
413  };
414  SsPool<Ss_DROP_FRAG_REQ> c_ss_DROP_FRAG_REQ;
415  Uint32 getSsId(const DropFragReq* req) {
416  return SsIdBase | (req->tableId ^ req->fragId);
417  }
418  Uint32 getSsId(const DropFragConf* conf) {
419  return SsIdBase | (conf->tableId ^ conf->fragId);
420  }
421  Uint32 getSsId(const DropFragRef* ref) {
422  return SsIdBase | (ref->tableId ^ ref->fragId);
423  }
424  void execDROP_FRAG_REQ(Signal*);
425  void sendDROP_FRAG_REQ(Signal*, Uint32 ssId, SectionHandle*);
426  void execDROP_FRAG_CONF(Signal*);
427  void execDROP_FRAG_REF(Signal*);
428  void sendDROP_FRAG_CONF(Signal*, Uint32 ssId);
429 
430  // LCP handling
431  void execEMPTY_LCP_REQ(Signal*);
432  void execLCP_FRAG_ORD(Signal*);
433  void execLCP_FRAG_REP(Signal*);
434  void execEND_LCP_CONF(Signal*);
435  void execLCP_COMPLETE_REP(Signal*);
436 
437  struct LcpRecord {
438  enum {
439  L_IDLE = 0,
440  L_STARTING = 1,
441  L_RUNNING = 2,
442  L_COMPLETING_1 = 3,
443  L_COMPLETING_2 = 4,
444  L_COMPLETING_3 = 5
445  } m_state;
446  Uint32 m_lcpId;
447  Uint32 m_lcp_frag_ord_cnt; // No of LCP_FRAG_ORD received
448  Uint32 m_lcp_frag_rep_cnt; // No of LCP_FRAG_REP sent
449  Uint32 m_complete_outstanding; // Outstanding END_LCP_REQ
450  NdbNodeBitmask m_empty_lcp_req;// Nodes waiting for EMPTY_LCP_CONF
451  LcpFragOrd m_last_lcp_frag_ord;// Last received LCP_FRAG_ORD
452  bool m_lastFragmentFlag;
453 
454  LcpRecord(){
455  m_state = L_IDLE;
456  m_lcpId = 0;
457  m_lcp_frag_ord_cnt = 0;
458  m_lcp_frag_rep_cnt = 0;
459  m_lastFragmentFlag = false;
460  };
461  };
462  LcpRecord c_lcpRecord;
463  Uint32 getNoOfOutstanding(const LcpRecord&) const;
464  void completeLCP_1(Signal* signal);
465  void completeLCP_2(Signal* signal);
466  void completeLCP_3(Signal* signal);
467  void sendLCP_COMPLETE_REP(Signal*);
468 
469  void checkSendEMPTY_LCP_CONF_impl(Signal* signal);
470  void checkSendEMPTY_LCP_CONF(Signal* signal) {
471  if (c_lcpRecord.m_empty_lcp_req.isclear())
472  return;
474  }
475 };
476 
477 #endif