~ubuntu-branches/ubuntu/precise/mysql-5.1/precise

« back to all changes in this revision

Viewing changes to storage/ndb/src/kernel/blocks/dbtup/DbtupDebug.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Norbert Tretkowski
  • Date: 2010-03-17 14:56:02 UTC
  • Revision ID: james.westby@ubuntu.com-20100317145602-x7e30l1b2sb5s6w6
Tags: upstream-5.1.45
ImportĀ upstreamĀ versionĀ 5.1.45

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (C) 2003 MySQL AB
 
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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
 
15
 
 
16
 
 
17
#define DBTUP_C
 
18
#define DBTUP_DEBUG_CPP
 
19
#include "Dbtup.hpp"
 
20
#include <RefConvert.hpp>
 
21
#include <ndb_limits.h>
 
22
#include <pc.hpp>
 
23
#include <signaldata/DropTab.hpp>
 
24
#include <signaldata/DumpStateOrd.hpp>
 
25
#include <signaldata/EventReport.hpp>
 
26
#include <Vector.hpp>
 
27
 
 
28
/* **************************************************************** */
 
29
/* ---------------------------------------------------------------- */
 
30
/* ------------------------ DEBUG MODULE -------------------------- */
 
31
/* ---------------------------------------------------------------- */
 
32
/* **************************************************************** */
 
33
void Dbtup::execDEBUG_SIG(Signal* signal) 
 
34
{
 
35
  PagePtr regPagePtr;
 
36
  jamEntry();
 
37
  regPagePtr.i = signal->theData[0];
 
38
  c_page_pool.getPtr(regPagePtr);
 
39
}//Dbtup::execDEBUG_SIG()
 
40
 
 
41
#ifdef TEST_MR
 
42
#include <time.h>
 
43
 
 
44
void startTimer(struct timespec *tp)
 
45
{
 
46
  clock_gettime(CLOCK_REALTIME, tp);
 
47
}//startTimer()
 
48
 
 
49
int stopTimer(struct timespec *tp)
 
50
{
 
51
  double timer_count;
 
52
  struct timespec theStopTime;
 
53
  clock_gettime(CLOCK_REALTIME, &theStopTime);
 
54
  timer_count = (double)(1000000*((double)theStopTime.tv_sec - (double)tp->tv_sec)) + 
 
55
                (double)((double)((double)theStopTime.tv_nsec - (double)tp->tv_nsec)/(double)1000);
 
56
  return (int)timer_count;
 
57
}//stopTimer()
 
58
 
 
59
#endif // end TEST_MR
 
60
 
 
61
struct Chunk {
 
62
  Uint32 pageId;
 
63
  Uint32 pageCount;
 
64
};
 
65
 
 
66
void
 
67
Dbtup::reportMemoryUsage(Signal* signal, int incDec){
 
68
  signal->theData[0] = NDB_LE_MemoryUsage;
 
69
  signal->theData[1] = incDec;
 
70
  signal->theData[2] = sizeof(Page);
 
71
  signal->theData[3] = cnoOfAllocatedPages;
 
72
  signal->theData[4] = c_page_pool.getSize();
 
73
  signal->theData[5] = DBTUP;
 
74
  sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 6, JBB);
 
75
}
 
76
 
 
77
#ifdef VM_TRACE
 
78
extern Uint32 fc_left, fc_right, fc_remove;
 
79
#endif
 
80
 
 
81
void
 
82
Dbtup::execDUMP_STATE_ORD(Signal* signal)
 
83
{
 
84
  Uint32 type = signal->theData[0];
 
85
  if(type == DumpStateOrd::DumpPageMemory && signal->getLength() == 1){
 
86
    reportMemoryUsage(signal, 0);
 
87
    return;
 
88
  }
 
89
  DumpStateOrd * const dumpState = (DumpStateOrd *)&signal->theData[0];
 
90
 
 
91
#if 0
 
92
  if (type == 100) {
 
93
    RelTabMemReq * const req = (RelTabMemReq *)signal->getDataPtrSend();
 
94
    req->primaryTableId = 2;
 
95
    req->secondaryTableId = RNIL;
 
96
    req->userPtr = 2;
 
97
    req->userRef = DBDICT_REF;
 
98
    sendSignal(cownref, GSN_REL_TABMEMREQ, signal,
 
99
               RelTabMemReq::SignalLength, JBB);
 
100
    return;
 
101
  }//if
 
102
  if (type == 101) {
 
103
    RelTabMemReq * const req = (RelTabMemReq *)signal->getDataPtrSend();
 
104
    req->primaryTableId = 4;
 
105
    req->secondaryTableId = 5;
 
106
    req->userPtr = 4;
 
107
    req->userRef = DBDICT_REF;
 
108
    sendSignal(cownref, GSN_REL_TABMEMREQ, signal,
 
109
               RelTabMemReq::SignalLength, JBB);
 
110
    return;
 
111
  }//if
 
112
  if (type == 102) {
 
113
    RelTabMemReq * const req = (RelTabMemReq *)signal->getDataPtrSend();
 
114
    req->primaryTableId = 6;
 
115
    req->secondaryTableId = 8;
 
116
    req->userPtr = 6;
 
117
    req->userRef = DBDICT_REF;
 
118
    sendSignal(cownref, GSN_REL_TABMEMREQ, signal,
 
119
               RelTabMemReq::SignalLength, JBB);
 
120
    return;
 
121
  }//if
 
122
  if (type == 103) {
 
123
    DropTabFileReq * const req = (DropTabFileReq *)signal->getDataPtrSend();
 
124
    req->primaryTableId = 2;
 
125
    req->secondaryTableId = RNIL;
 
126
    req->userPtr = 2;
 
127
    req->userRef = DBDICT_REF;
 
128
    sendSignal(cownref, GSN_DROP_TABFILEREQ, signal,
 
129
               DropTabFileReq::SignalLength, JBB);
 
130
    return;
 
131
  }//if
 
132
  if (type == 104) {
 
133
    DropTabFileReq * const req = (DropTabFileReq *)signal->getDataPtrSend();
 
134
    req->primaryTableId = 4;
 
135
    req->secondaryTableId = 5;
 
136
    req->userPtr = 4;
 
137
    req->userRef = DBDICT_REF;
 
138
    sendSignal(cownref, GSN_DROP_TABFILEREQ, signal,
 
139
               DropTabFileReq::SignalLength, JBB);
 
140
    return;
 
141
  }//if
 
142
  if (type == 105) {
 
143
    DropTabFileReq * const req = (DropTabFileReq *)signal->getDataPtrSend();
 
144
    req->primaryTableId = 6;
 
145
    req->secondaryTableId = 8;
 
146
    req->userPtr = 6;
 
147
    req->userRef = DBDICT_REF;
 
148
    sendSignal(cownref, GSN_DROP_TABFILEREQ, signal,
 
149
               DropTabFileReq::SignalLength, JBB);
 
150
    return;
 
151
  }//if
 
152
#endif
 
153
#ifdef ERROR_INSERT
 
154
  if (type == DumpStateOrd::EnableUndoDelayDataWrite) {
 
155
    ndbout << "Dbtup:: delay write of datapages for table = " 
 
156
           << dumpState->args[1]<< endl;
 
157
    c_errorInsert4000TableId = dumpState->args[1];
 
158
    SET_ERROR_INSERT_VALUE(4000);
 
159
    return;
 
160
  }//if
 
161
#endif
 
162
#if defined VM_TRACE
 
163
  if (type == 1211 || type == 1212 || type == 1213){
 
164
    Uint32 seed = time(0);
 
165
    if (signal->getLength() > 1)
 
166
      seed = signal->theData[1];
 
167
    ndbout_c("Startar modul test av Page Manager (seed: 0x%x)", seed);
 
168
    srand(seed);
 
169
 
 
170
    Vector<Chunk> chunks;
 
171
    const Uint32 LOOPS = 1000;
 
172
    Uint32 sum_req = 0;
 
173
    Uint32 sum_conf = 0;
 
174
    Uint32 sum_loop = 0;
 
175
    Uint32 max_loop = 0;
 
176
    for(Uint32 i = 0; i<LOOPS; i++){
 
177
 
 
178
      // Case
 
179
      Uint32 c = (rand() % 3);
 
180
      const Uint32 free = c_page_pool.getSize() - cnoOfAllocatedPages;
 
181
      
 
182
      Uint32 alloc = 0;
 
183
      if(free <= 1){
 
184
        c = 0;
 
185
        alloc = 1;
 
186
      } else 
 
187
        alloc = 1 + (rand() % (free - 1));
 
188
      
 
189
      if(chunks.size() == 0 && c == 0){
 
190
        c = 1 + rand() % 2;
 
191
      }
 
192
      
 
193
      if (type == 1211)
 
194
        ndbout_c("loop=%d case=%d free=%d alloc=%d", i, c, free, alloc);
 
195
 
 
196
      if (type == 1213)
 
197
      {
 
198
        c = 1;
 
199
        alloc = 2 + (sum_conf >> 3) + (sum_conf >> 4);
 
200
      }
 
201
      switch(c){ 
 
202
      case 0:{ // Release
 
203
        const int ch = rand() % chunks.size();
 
204
        Chunk chunk = chunks[ch];
 
205
        chunks.erase(ch);
 
206
        returnCommonArea(chunk.pageId, chunk.pageCount);
 
207
      }
 
208
        break;
 
209
      case 2: { // Seize(n) - fail
 
210
        alloc += free;
 
211
        // Fall through
 
212
        sum_req += free;
 
213
        goto doalloc;
 
214
      }
 
215
      case 1: { // Seize(n) (success)
 
216
        sum_req += alloc;
 
217
    doalloc:
 
218
        Chunk chunk;
 
219
        allocConsPages(alloc, chunk.pageCount, chunk.pageId);
 
220
        ndbrequire(chunk.pageCount <= alloc);
 
221
        if(chunk.pageCount != 0){
 
222
          chunks.push_back(chunk);
 
223
          if(chunk.pageCount != alloc) {
 
224
            if (type == 1211)
 
225
              ndbout_c("  Tried to allocate %d - only allocated %d - free: %d",
 
226
                       alloc, chunk.pageCount, free);
 
227
          }
 
228
        } else {
 
229
          ndbout_c("  Failed to alloc %d pages with %d pages free",
 
230
                   alloc, free);
 
231
        }
 
232
        
 
233
        sum_conf += chunk.pageCount;
 
234
        Uint32 tot = fc_left + fc_right + fc_remove;
 
235
        sum_loop += tot;
 
236
        if (tot > max_loop)
 
237
          max_loop = tot;
 
238
 
 
239
        for(Uint32 i = 0; i<chunk.pageCount; i++){
 
240
          PagePtr pagePtr;
 
241
          pagePtr.i = chunk.pageId + i;
 
242
          c_page_pool.getPtr(pagePtr);
 
243
          pagePtr.p->page_state = ~ZFREE_COMMON;
 
244
        }
 
245
 
 
246
        if(alloc == 1 && free > 0)
 
247
          ndbrequire(chunk.pageCount == alloc);
 
248
      }
 
249
        break;
 
250
      }
 
251
    }
 
252
    while(chunks.size() > 0){
 
253
      Chunk chunk = chunks.back();
 
254
      returnCommonArea(chunk.pageId, chunk.pageCount);      
 
255
      chunks.erase(chunks.size() - 1);
 
256
    }
 
257
 
 
258
    ndbout_c("Got %u%% of requested allocs, loops : %u 100*avg: %u max: %u",
 
259
             (100 * sum_conf) / sum_req, sum_loop, 100*sum_loop / LOOPS,
 
260
             max_loop);
 
261
  }
 
262
#endif
 
263
}//Dbtup::execDUMP_STATE_ORD()
 
264
 
 
265
/* ---------------------------------------------------------------- */
 
266
/* ---------      MEMORY       CHECK        ----------------------- */
 
267
/* ---------------------------------------------------------------- */
 
268
void Dbtup::execMEMCHECKREQ(Signal* signal) 
 
269
{
 
270
  TablerecPtr regTabPtr;
 
271
  regTabPtr.i = 2;
 
272
  ptrCheckGuard(regTabPtr, cnoOfTablerec, tablerec);
 
273
  if(tablerec && regTabPtr.p->tableStatus == DEFINED)
 
274
    validate_page(regTabPtr.p, 0);
 
275
 
 
276
#if 0
 
277
  const Dbtup::Tablerec& tab = *tup->tabptr.p;
 
278
 
 
279
  PagePtr regPagePtr;
 
280
  Uint32* data = &signal->theData[0];
 
281
 
 
282
  jamEntry();
 
283
  BlockReference blockref = signal->theData[0];
 
284
  Uint32 i;
 
285
  for (i = 0; i < 25; i++) {
 
286
    jam();
 
287
    data[i] = 0;
 
288
  }//for
 
289
  for (i = 0; i < 16; i++) {
 
290
    regPagePtr.i = cfreepageList[i];
 
291
    jam();
 
292
    while (regPagePtr.i != RNIL) {
 
293
      jam();
 
294
      ptrCheckGuard(regPagePtr, cnoOfPage, cpage);
 
295
      regPagePtr.i = regPagePtr.p->next_page;
 
296
      data[0]++;
 
297
    }//while
 
298
  }//for
 
299
  sendSignal(blockref, GSN_MEMCHECKCONF, signal, 25, JBB);
 
300
#endif
 
301
}//Dbtup::memCheck()
 
302
 
 
303
// ------------------------------------------------------------------------
 
304
// Help function to be used when debugging. Prints out a tuple page.
 
305
// printLimit is the number of bytes that is printed out from the page. A 
 
306
// page is of size 32768 bytes as of March 2003.
 
307
// ------------------------------------------------------------------------
 
308
void Dbtup::printoutTuplePage(Uint32 fragid, Uint32 pageid, Uint32 printLimit) 
 
309
{
 
310
  PagePtr tmpPageP;
 
311
  FragrecordPtr tmpFragP;
 
312
  TablerecPtr tmpTableP;
 
313
 
 
314
  c_page_pool.getPtr(tmpPageP, pageid);
 
315
 
 
316
  tmpFragP.i = fragid;
 
317
  ptrCheckGuard(tmpFragP, cnoOfFragrec, fragrecord);
 
318
 
 
319
  tmpTableP.i = tmpFragP.p->fragTableId;
 
320
  ptrCheckGuard(tmpTableP, cnoOfTablerec, tablerec);
 
321
 
 
322
  ndbout << "Fragid: " << fragid << " Pageid: " << pageid << endl
 
323
         << "----------------------------------------" << endl;
 
324
 
 
325
  ndbout << "PageHead : ";
 
326
  ndbout << endl;
 
327
}//Dbtup::printoutTuplePage
 
328
 
 
329
#ifdef VM_TRACE
 
330
NdbOut&
 
331
operator<<(NdbOut& out, const Dbtup::Operationrec& op)
 
332
{
 
333
  out << "[Operationrec " << hex << &op;
 
334
  // table
 
335
  out << " [fragmentPtr " << hex << op.fragmentPtr << "]";
 
336
  // type
 
337
  out << " [op_type " << dec << op.op_struct.op_type << "]";
 
338
  out << " [delete_insert_flag " << dec;
 
339
  out << op.op_struct.delete_insert_flag << "]";
 
340
  // state
 
341
  out << " [tuple_state " << dec << op.op_struct.tuple_state << "]";
 
342
  out << " [trans_state " << dec << op.op_struct.trans_state << "]";
 
343
  out << " [in_active_list " << dec << op.op_struct.in_active_list << "]";
 
344
  // links
 
345
  out << " [prevActiveOp " << hex << op.prevActiveOp << "]";
 
346
  out << " [nextActiveOp " << hex << op.nextActiveOp << "]";
 
347
  // tuples
 
348
  out << " [tupVersion " << hex << op.tupVersion << "]";
 
349
  out << " [m_tuple_location " << op.m_tuple_location << "]";
 
350
  out << " [m_copy_tuple_location " << op.m_copy_tuple_location << "]";
 
351
  out << "]";
 
352
  return out;
 
353
}
 
354
 
 
355
// uses global tabptr
 
356
NdbOut&
 
357
operator<<(NdbOut& out, const Dbtup::Th& th)
 
358
{
 
359
  // ugly
 
360
  Dbtup* tup = (Dbtup*)globalData.getBlock(DBTUP);
 
361
  const Dbtup::Tablerec& tab = *tup->tabptr.p;
 
362
  unsigned i = 0;
 
363
  out << "[Th " << hex << &th;
 
364
  out << " [op " << hex << th.data[i++] << "]";
 
365
  out << " [version " << hex << (Uint16)th.data[i++] << "]";
 
366
  if (tab.m_bits & Dbtup::Tablerec::TR_Checksum)
 
367
    out << " [checksum " << hex << th.data[i++] << "]";
 
368
  out << " [nullbits";
 
369
  for (unsigned j = 0; j < tab.m_offsets[Dbtup::MM].m_null_words; j++)
 
370
    out << " " << hex << th.data[i++];
 
371
  out << "]";
 
372
  out << " [data";
 
373
  while (i < tab.m_offsets[Dbtup::MM].m_fix_header_size)
 
374
    out << " " << hex << th.data[i++];
 
375
  out << "]";
 
376
  out << "]";
 
377
  return out;
 
378
}
 
379
#endif
 
380
 
 
381
#ifdef VM_TRACE
 
382
template class Vector<Chunk>;
 
383
#endif
 
384
// uses global tabptr
 
385
 
 
386
NdbOut&
 
387
operator<<(NdbOut& out, const Local_key & key)
 
388
{
 
389
  out << "[ m_page_no: " << dec << key.m_page_no 
 
390
      << " m_file_no: " << dec << key.m_file_no 
 
391
      << " m_page_idx: " << dec << key.m_page_idx << "]";
 
392
  return out;
 
393
}
 
394
 
 
395
static
 
396
NdbOut&
 
397
operator<<(NdbOut& out, const Dbtup::Tablerec::Tuple_offsets& off)
 
398
{
 
399
  out << "[ null_words: " << (Uint32)off.m_null_words
 
400
      << " null off: " << (Uint32)off.m_null_offset
 
401
      << " disk_off: " << off.m_disk_ref_offset
 
402
      << " fixheadsz: " << off.m_fix_header_size
 
403
      << " max_var_off: " << off.m_max_var_offset
 
404
      << " ]";
 
405
 
 
406
  return out;
 
407
}
 
408
 
 
409
NdbOut&
 
410
operator<<(NdbOut& out, const Dbtup::Tablerec& tab)
 
411
{
 
412
  out << "[ total_rec_size: " << tab.total_rec_size
 
413
      << " checksum: " << !!(tab.m_bits & Dbtup::Tablerec::TR_Checksum)
 
414
      << " attr: " << tab.m_no_of_attributes
 
415
      << " disk: " << tab.m_no_of_disk_attributes 
 
416
      << " mm: " << tab.m_offsets[Dbtup::MM]
 
417
      << " [ fix: " << tab.m_attributes[Dbtup::MM].m_no_of_fixsize
 
418
      << " var: " << tab.m_attributes[Dbtup::MM].m_no_of_varsize << "]"
 
419
    
 
420
      << " dd: " << tab.m_offsets[Dbtup::DD]
 
421
      << " [ fix: " << tab.m_attributes[Dbtup::DD].m_no_of_fixsize
 
422
      << " var: " << tab.m_attributes[Dbtup::DD].m_no_of_varsize << "]"
 
423
      << " ]"  << endl;
 
424
  return out;
 
425
}
 
426
 
 
427
NdbOut&
 
428
operator<<(NdbOut& out, const AttributeDescriptor& off)
 
429
{
 
430
  Uint32 word;
 
431
  memcpy(&word, &off, 4);
 
432
  return out;
 
433
}
 
434
 
 
435
#include "AttributeOffset.hpp"
 
436
 
 
437
NdbOut&
 
438
operator<<(NdbOut& out, const AttributeOffset& off)
 
439
{
 
440
  Uint32 word;
 
441
  memcpy(&word, &off, 4);
 
442
  out << "[ offset: " << AttributeOffset::getOffset(word)
 
443
      << " nullpos: " << AttributeOffset::getNullFlagPos(word);
 
444
  if(AttributeOffset::getCharsetFlag(word))
 
445
    out << " charset: %d" << AttributeOffset::getCharsetPos(word);
 
446
  out << " ]";
 
447
  return out;
 
448
}
 
449