MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DbtuxGen.cpp
1 /*
2  Copyright (C) 2003-2008 MySQL AB, 2008, 2009 Sun Microsystems, Inc.
3  All rights reserved. Use is subject to license terms.
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; version 2 of the License.
8 
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with this program; if not, write to the Free Software
16  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18 
19 #define DBTUX_GEN_CPP
20 #include "Dbtux.hpp"
21 
22 #include <signaldata/NodeStateSignalData.hpp>
23 
24 Dbtux::Dbtux(Block_context& ctx, Uint32 instanceNumber) :
25  SimulatedBlock(DBTUX, ctx, instanceNumber),
26  c_tup(0),
27  c_descPageList(RNIL),
28 #ifdef VM_TRACE
29  debugFile(0),
30  debugOut(*new NullOutputStream()),
31  debugFlags(0),
32 #endif
33  c_internalStartPhase(0),
34  c_typeOfStart(NodeState::ST_ILLEGAL_TYPE),
35  c_indexStatAutoUpdate(false),
36  c_indexStatSaveSize(0),
37  c_indexStatSaveScale(0),
38  c_indexStatTriggerPct(0),
39  c_indexStatTriggerScale(0),
40  c_indexStatUpdateDelay(0)
41 {
42  BLOCK_CONSTRUCTOR(Dbtux);
43  // verify size assumptions (also when release-compiled)
44  ndbrequire(
45  (sizeof(TreeEnt) & 0x3) == 0 &&
46  (sizeof(TreeNode) & 0x3) == 0 &&
47  (sizeof(DescHead) & 0x3) == 0 &&
48  (sizeof(KeyType) & 0x3) == 0
49  );
50  /*
51  * DbtuxGen.cpp
52  */
53  addRecSignal(GSN_CONTINUEB, &Dbtux::execCONTINUEB);
54  addRecSignal(GSN_STTOR, &Dbtux::execSTTOR);
55  addRecSignal(GSN_READ_CONFIG_REQ, &Dbtux::execREAD_CONFIG_REQ, true);
56  /*
57  * DbtuxMeta.cpp
58  */
59  addRecSignal(GSN_CREATE_TAB_REQ, &Dbtux::execCREATE_TAB_REQ);
60  addRecSignal(GSN_TUXFRAGREQ, &Dbtux::execTUXFRAGREQ);
61  addRecSignal(GSN_TUX_ADD_ATTRREQ, &Dbtux::execTUX_ADD_ATTRREQ);
62  addRecSignal(GSN_ALTER_INDX_IMPL_REQ, &Dbtux::execALTER_INDX_IMPL_REQ);
63  addRecSignal(GSN_DROP_TAB_REQ, &Dbtux::execDROP_TAB_REQ);
64  /*
65  * DbtuxMaint.cpp
66  */
67  addRecSignal(GSN_TUX_MAINT_REQ, &Dbtux::execTUX_MAINT_REQ);
68  /*
69  * DbtuxScan.cpp
70  */
71  addRecSignal(GSN_ACC_SCANREQ, &Dbtux::execACC_SCANREQ);
72  addRecSignal(GSN_TUX_BOUND_INFO, &Dbtux::execTUX_BOUND_INFO);
73  addRecSignal(GSN_NEXT_SCANREQ, &Dbtux::execNEXT_SCANREQ);
74  addRecSignal(GSN_ACC_CHECK_SCAN, &Dbtux::execACC_CHECK_SCAN);
75  addRecSignal(GSN_ACCKEYCONF, &Dbtux::execACCKEYCONF);
76  addRecSignal(GSN_ACCKEYREF, &Dbtux::execACCKEYREF);
77  addRecSignal(GSN_ACC_ABORTCONF, &Dbtux::execACC_ABORTCONF);
78  /*
79  * DbtuxStat.cpp
80  */
81  addRecSignal(GSN_READ_PSEUDO_REQ, &Dbtux::execREAD_PSEUDO_REQ);
82  addRecSignal(GSN_INDEX_STAT_REP, &Dbtux::execINDEX_STAT_REP);
83  addRecSignal(GSN_INDEX_STAT_IMPL_REQ, &Dbtux::execINDEX_STAT_IMPL_REQ);
84  /*
85  * DbtuxDebug.cpp
86  */
87  addRecSignal(GSN_DUMP_STATE_ORD, &Dbtux::execDUMP_STATE_ORD);
88 
89  addRecSignal(GSN_DBINFO_SCANREQ, &Dbtux::execDBINFO_SCANREQ);
90 
91  addRecSignal(GSN_NODE_STATE_REP, &Dbtux::execNODE_STATE_REP, true);
92 
93  addRecSignal(GSN_DROP_FRAG_REQ, &Dbtux::execDROP_FRAG_REQ);
94 }
95 
96 Dbtux::~Dbtux()
97 {
98 }
99 
100 void
101 Dbtux::execCONTINUEB(Signal* signal)
102 {
103  jamEntry();
104  const Uint32* data = signal->getDataPtr();
105  switch (data[0]) {
106  case TuxContinueB::DropIndex: // currently unused
107  {
108  IndexPtr indexPtr;
109  c_indexPool.getPtr(indexPtr, data[1]);
110  dropIndex(signal, indexPtr, data[2], data[3]);
111  }
112  break;
113  case TuxContinueB::StatMon:
114  {
115  Uint32 id = data[1];
116  ndbrequire(id == c_statMon.m_loopIndexId);
117  statMonExecContinueB(signal);
118  }
119  break;
120  default:
121  ndbrequire(false);
122  break;
123  }
124 }
125 
126 /*
127  * STTOR is sent to one block at a time. In NDBCNTR it triggers
128  * NDB_STTOR to the "old" blocks. STTOR carries start phase (SP) and
129  * NDB_STTOR carries internal start phase (ISP).
130  *
131  * SP ISP activities
132  * 1 none
133  * 2 1
134  * 3 2 recover metadata, activate indexes
135  * 4 3 recover data
136  * 5 4-6
137  * 6 skip
138  * 7 skip
139  * 8 7 build non-logged indexes on SR
140  *
141  * DBTUX catches type of start (IS, SR, NR, INR) at SP 3 and updates
142  * internal start phase at SP 7. These are used to prevent index
143  * maintenance operations caused by redo log at SR.
144  */
145 void
146 Dbtux::execSTTOR(Signal* signal)
147 {
148  jamEntry();
149  Uint32 startPhase = signal->theData[1];
150  switch (startPhase) {
151  case 1:
152  jam();
153  CLEAR_ERROR_INSERT_VALUE;
154  c_tup = (Dbtup*)globalData.getBlock(DBTUP, instance());
155  ndbrequire(c_tup != 0);
156  break;
157  case 3:
158  jam();
159  c_typeOfStart = signal->theData[7];
160  break;
161  return;
162  case 7:
163  c_internalStartPhase = 6;
164  /*
165  * config cannot yet be changed dynamically but we start the
166  * loop always anyway because the cost is minimal
167  */
168  c_statMon.m_loopIndexId = 0;
169  statMonSendContinueB(signal);
170  break;
171  default:
172  jam();
173  break;
174  }
175  signal->theData[0] = 0; // garbage
176  signal->theData[1] = 0; // garbage
177  signal->theData[2] = 0; // garbage
178  signal->theData[3] = 1;
179  signal->theData[4] = 3; // for c_typeOfStart
180  signal->theData[5] = 7; // for c_internalStartPhase
181  signal->theData[6] = 255;
182  BlockReference cntrRef = !isNdbMtLqh() ? NDBCNTR_REF : DBTUX_REF;
183  sendSignal(cntrRef, GSN_STTORRY, signal, 7, JBB);
184 }
185 
186 void
187 Dbtux::execNODE_STATE_REP(Signal* signal)
188 {
193  NodeStateRep* rep = (NodeStateRep*)signal->getDataPtr();
194  if (rep->nodeState.startLevel == NodeState::SL_STARTING)
195  {
196  c_typeOfStart = rep->nodeState.starting.restartType;
197  }
198  SimulatedBlock::execNODE_STATE_REP(signal);
199 }
200 
201 void
202 Dbtux::execREAD_CONFIG_REQ(Signal* signal)
203 {
204  jamEntry();
205 
206  const ReadConfigReq * req = (ReadConfigReq*)signal->getDataPtr();
207  Uint32 ref = req->senderRef;
208  Uint32 senderData = req->senderData;
209  ndbrequire(req->noOfParameters == 0);
210 
211  Uint32 nIndex;
212  Uint32 nFragment;
213  Uint32 nAttribute;
214  Uint32 nScanOp;
215  Uint32 nScanBatch;
216  Uint32 nStatAutoUpdate;
217  Uint32 nStatSaveSize;
218  Uint32 nStatSaveScale;
219  Uint32 nStatTriggerPct;
220  Uint32 nStatTriggerScale;
221  Uint32 nStatUpdateDelay;
222 
223  const ndb_mgm_configuration_iterator * p =
224  m_ctx.m_config.getOwnConfigIterator();
225  ndbrequire(p != 0);
226 
227  ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_TUX_INDEX, &nIndex));
228  ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_TUX_FRAGMENT, &nFragment));
229  ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_TUX_ATTRIBUTE, &nAttribute));
230  ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_TUX_SCAN_OP, &nScanOp));
231  ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_DB_BATCH_SIZE, &nScanBatch));
232 
233  nStatAutoUpdate = 0;
234  ndb_mgm_get_int_parameter(p, CFG_DB_INDEX_STAT_AUTO_UPDATE,
235  &nStatAutoUpdate);
236 
237  nStatSaveSize = 32768;
238  ndb_mgm_get_int_parameter(p, CFG_DB_INDEX_STAT_SAVE_SIZE,
239  &nStatSaveSize);
240 
241  nStatSaveScale = 100;
242  ndb_mgm_get_int_parameter(p, CFG_DB_INDEX_STAT_SAVE_SCALE,
243  &nStatSaveScale);
244 
245  nStatTriggerPct = 100;
246  ndb_mgm_get_int_parameter(p, CFG_DB_INDEX_STAT_TRIGGER_PCT,
247  &nStatTriggerPct);
248 
249  nStatTriggerScale = 100;
250  ndb_mgm_get_int_parameter(p, CFG_DB_INDEX_STAT_TRIGGER_SCALE,
251  &nStatTriggerScale);
252 
253  nStatUpdateDelay = 60;
254  ndb_mgm_get_int_parameter(p, CFG_DB_INDEX_STAT_UPDATE_DELAY,
255  &nStatUpdateDelay);
256 
257  const Uint32 nDescPage = (nIndex * DescHeadSize + nAttribute * KeyTypeSize + nAttribute * AttributeHeaderSize + DescPageSize - 1) / DescPageSize;
258  const Uint32 nScanBoundWords = nScanOp * ScanBoundSegmentSize * 4;
259  const Uint32 nScanLock = nScanOp * nScanBatch;
260  const Uint32 nStatOp = 8;
261 
262  c_indexPool.setSize(nIndex);
263  c_fragPool.setSize(nFragment);
264  c_descPagePool.setSize(nDescPage);
265  c_fragOpPool.setSize(MaxIndexFragments);
266  c_scanOpPool.setSize(nScanOp);
267  c_scanBoundPool.setSize(nScanBoundWords);
268  c_scanLockPool.setSize(nScanLock);
269  c_statOpPool.setSize(nStatOp);
270  c_indexStatAutoUpdate = nStatAutoUpdate;
271  c_indexStatSaveSize = nStatSaveSize;
272  c_indexStatSaveScale = nStatSaveScale;
273  c_indexStatTriggerPct = nStatTriggerPct;
274  c_indexStatTriggerScale = nStatTriggerScale;
275  c_indexStatUpdateDelay = nStatUpdateDelay;
276 
277  /*
278  * Index id is physical array index. We seize and initialize all
279  * index records now.
280  */
281  IndexPtr indexPtr;
282  while (1) {
283  jam();
285  c_indexPool.seize(indexPtr);
286  if (indexPtr.i == RNIL) {
287  jam();
288  break;
289  }
290  new (indexPtr.p) Index();
291  }
292  // allocate buffers
293  c_ctx.jamBuffer = jamBuffer();
294  c_ctx.c_searchKey = (Uint32*)allocRecord("c_searchKey", sizeof(Uint32), MaxAttrDataSize);
295  c_ctx.c_entryKey = (Uint32*)allocRecord("c_entryKey", sizeof(Uint32), MaxAttrDataSize);
296 
297  c_ctx.c_dataBuffer = (Uint32*)allocRecord("c_dataBuffer", sizeof(Uint64), (MaxXfrmDataSize + 1) >> 1);
298 
299 #ifdef VM_TRACE
300  c_ctx.c_debugBuffer = (char*)allocRecord("c_debugBuffer", sizeof(char), DebugBufferBytes);
301 #endif
302 
303  // ack
304  ReadConfigConf * conf = (ReadConfigConf*)signal->getDataPtrSend();
305  conf->senderRef = reference();
306  conf->senderData = senderData;
307  sendSignal(ref, GSN_READ_CONFIG_CONF, signal,
308  ReadConfigConf::SignalLength, JBB);
309 }
310 
311 // utils
312 
313 void
314 Dbtux::readKeyAttrs(TuxCtx& ctx, const Frag& frag, TreeEnt ent, KeyData& keyData, Uint32 count)
315 {
316  const Index& index = *c_indexPool.getPtr(frag.m_indexId);
317  const DescHead& descHead = getDescHead(index);
318  const AttributeHeader* keyAttrs = getKeyAttrs(descHead);
319  Uint32* const outputBuffer = ctx.c_dataBuffer;
320 
321 #ifdef VM_TRACE
322  ndbrequire(&keyData.get_spec() == &index.m_keySpec);
323  ndbrequire(keyData.get_spec().validate() == 0);
324  ndbrequire(count <= index.m_numAttrs);
325 #endif
326 
327  const TupLoc tupLoc = ent.m_tupLoc;
328  const Uint32 pageId = tupLoc.getPageId();
329  const Uint32 pageOffset = tupLoc.getPageOffset();
330  const Uint32 tupVersion = ent.m_tupVersion;
331  const Uint32 tableFragPtrI = frag.m_tupTableFragPtrI;
332  const Uint32* keyAttrs32 = (const Uint32*)&keyAttrs[0];
333 
334  int ret;
335  ret = c_tup->tuxReadAttrs(ctx.jamBuffer, tableFragPtrI, pageId, pageOffset, tupVersion, keyAttrs32, count, outputBuffer, false);
336  jamEntry();
337  ndbrequire(ret > 0);
338  keyData.reset();
339  Uint32 len;
340  ret = keyData.add_poai(outputBuffer, count, &len);
341  ndbrequire(ret == 0);
342  ret = keyData.finalize();
343  ndbrequire(ret == 0);
344 
345 #ifdef VM_TRACE
346  if (debugFlags & (DebugMaint | DebugScan)) {
347  debugOut << "readKeyAttrs: ";
348  debugOut << " ent:" << ent << " count:" << count;
349  debugOut << " data:" << keyData.print(ctx.c_debugBuffer, DebugBufferBytes);
350  debugOut << endl;
351  }
352 #endif
353 }
354 
355 void
356 Dbtux::readTablePk(const Frag& frag, TreeEnt ent, Uint32* pkData, unsigned& pkSize)
357 {
358  const Uint32 tableFragPtrI = frag.m_tupTableFragPtrI;
359  const TupLoc tupLoc = ent.m_tupLoc;
360  int ret = c_tup->tuxReadPk(tableFragPtrI, tupLoc.getPageId(), tupLoc.getPageOffset(), pkData, true);
361  jamEntry();
362  ndbrequire(ret > 0);
363  pkSize = ret;
364 }
365 
366 void
367 Dbtux::unpackBound(TuxCtx& ctx, const ScanBound& scanBound, KeyBoundC& searchBound)
368 {
369  // there is no const version of LocalDataBuffer
370  DataBuffer<ScanBoundSegmentSize>::Head head = scanBound.m_head;
371  LocalDataBuffer<ScanBoundSegmentSize> b(c_scanBoundPool, head);
373  // always use searchKey buffer
374  Uint32* const outputBuffer = ctx.c_searchKey;
375  b.first(iter);
376  const Uint32 n = b.getSize();
377  ndbrequire(n <= MaxAttrDataSize);
378  for (Uint32 i = 0; i < n; i++) {
379  outputBuffer[i] = *iter.data;
380  b.next(iter);
381  }
382  // set bound to the unpacked data buffer
383  KeyDataC& searchBoundData = searchBound.get_data();
384  searchBoundData.set_buf(outputBuffer, MaxAttrDataSize << 2, scanBound.m_cnt);
385  int ret = searchBound.finalize(scanBound.m_side);
386  ndbrequire(ret == 0);
387 }
388 
389 void
390 Dbtux::findFrag(const Index& index, Uint32 fragId, FragPtr& fragPtr)
391 {
392  const Uint32 numFrags = index.m_numFrags;
393  for (Uint32 i = 0; i < numFrags; i++) {
394  jam();
395  if (index.m_fragId[i] == fragId) {
396  jam();
397  fragPtr.i = index.m_fragPtrI[i];
398  c_fragPool.getPtr(fragPtr);
399  return;
400  }
401  }
402  fragPtr.i = RNIL;
403 }
404 
405 BLOCK_FUNCTIONS(Dbtux)