1
/* Copyright (C) 2003 MySQL AB
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.
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.
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 */
18
#define DBTUP_DEBUG_CPP
20
#include <RefConvert.hpp>
21
#include <ndb_limits.h>
23
#include <signaldata/DropTab.hpp>
24
#include <signaldata/DumpStateOrd.hpp>
25
#include <signaldata/EventReport.hpp>
28
/* **************************************************************** */
29
/* ---------------------------------------------------------------- */
30
/* ------------------------ DEBUG MODULE -------------------------- */
31
/* ---------------------------------------------------------------- */
32
/* **************************************************************** */
33
void Dbtup::execDEBUG_SIG(Signal* signal)
37
regPagePtr.i = signal->theData[0];
38
c_page_pool.getPtr(regPagePtr);
39
}//Dbtup::execDEBUG_SIG()
44
void startTimer(struct timespec *tp)
46
clock_gettime(CLOCK_REALTIME, tp);
49
int stopTimer(struct timespec *tp)
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;
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);
78
extern Uint32 fc_left, fc_right, fc_remove;
82
Dbtup::execDUMP_STATE_ORD(Signal* signal)
84
Uint32 type = signal->theData[0];
85
if(type == DumpStateOrd::DumpPageMemory && signal->getLength() == 1){
86
reportMemoryUsage(signal, 0);
89
DumpStateOrd * const dumpState = (DumpStateOrd *)&signal->theData[0];
93
RelTabMemReq * const req = (RelTabMemReq *)signal->getDataPtrSend();
94
req->primaryTableId = 2;
95
req->secondaryTableId = RNIL;
97
req->userRef = DBDICT_REF;
98
sendSignal(cownref, GSN_REL_TABMEMREQ, signal,
99
RelTabMemReq::SignalLength, JBB);
103
RelTabMemReq * const req = (RelTabMemReq *)signal->getDataPtrSend();
104
req->primaryTableId = 4;
105
req->secondaryTableId = 5;
107
req->userRef = DBDICT_REF;
108
sendSignal(cownref, GSN_REL_TABMEMREQ, signal,
109
RelTabMemReq::SignalLength, JBB);
113
RelTabMemReq * const req = (RelTabMemReq *)signal->getDataPtrSend();
114
req->primaryTableId = 6;
115
req->secondaryTableId = 8;
117
req->userRef = DBDICT_REF;
118
sendSignal(cownref, GSN_REL_TABMEMREQ, signal,
119
RelTabMemReq::SignalLength, JBB);
123
DropTabFileReq * const req = (DropTabFileReq *)signal->getDataPtrSend();
124
req->primaryTableId = 2;
125
req->secondaryTableId = RNIL;
127
req->userRef = DBDICT_REF;
128
sendSignal(cownref, GSN_DROP_TABFILEREQ, signal,
129
DropTabFileReq::SignalLength, JBB);
133
DropTabFileReq * const req = (DropTabFileReq *)signal->getDataPtrSend();
134
req->primaryTableId = 4;
135
req->secondaryTableId = 5;
137
req->userRef = DBDICT_REF;
138
sendSignal(cownref, GSN_DROP_TABFILEREQ, signal,
139
DropTabFileReq::SignalLength, JBB);
143
DropTabFileReq * const req = (DropTabFileReq *)signal->getDataPtrSend();
144
req->primaryTableId = 6;
145
req->secondaryTableId = 8;
147
req->userRef = DBDICT_REF;
148
sendSignal(cownref, GSN_DROP_TABFILEREQ, signal,
149
DropTabFileReq::SignalLength, JBB);
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);
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);
170
Vector<Chunk> chunks;
171
const Uint32 LOOPS = 1000;
176
for(Uint32 i = 0; i<LOOPS; i++){
179
Uint32 c = (rand() % 3);
180
const Uint32 free = c_page_pool.getSize() - cnoOfAllocatedPages;
187
alloc = 1 + (rand() % (free - 1));
189
if(chunks.size() == 0 && c == 0){
194
ndbout_c("loop=%d case=%d free=%d alloc=%d", i, c, free, alloc);
199
alloc = 2 + (sum_conf >> 3) + (sum_conf >> 4);
203
const int ch = rand() % chunks.size();
204
Chunk chunk = chunks[ch];
206
returnCommonArea(chunk.pageId, chunk.pageCount);
209
case 2: { // Seize(n) - fail
215
case 1: { // Seize(n) (success)
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) {
225
ndbout_c(" Tried to allocate %d - only allocated %d - free: %d",
226
alloc, chunk.pageCount, free);
229
ndbout_c(" Failed to alloc %d pages with %d pages free",
233
sum_conf += chunk.pageCount;
234
Uint32 tot = fc_left + fc_right + fc_remove;
239
for(Uint32 i = 0; i<chunk.pageCount; i++){
241
pagePtr.i = chunk.pageId + i;
242
c_page_pool.getPtr(pagePtr);
243
pagePtr.p->page_state = ~ZFREE_COMMON;
246
if(alloc == 1 && free > 0)
247
ndbrequire(chunk.pageCount == alloc);
252
while(chunks.size() > 0){
253
Chunk chunk = chunks.back();
254
returnCommonArea(chunk.pageId, chunk.pageCount);
255
chunks.erase(chunks.size() - 1);
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,
263
}//Dbtup::execDUMP_STATE_ORD()
265
/* ---------------------------------------------------------------- */
266
/* --------- MEMORY CHECK ----------------------- */
267
/* ---------------------------------------------------------------- */
268
void Dbtup::execMEMCHECKREQ(Signal* signal)
270
TablerecPtr regTabPtr;
272
ptrCheckGuard(regTabPtr, cnoOfTablerec, tablerec);
273
if(tablerec && regTabPtr.p->tableStatus == DEFINED)
274
validate_page(regTabPtr.p, 0);
277
const Dbtup::Tablerec& tab = *tup->tabptr.p;
280
Uint32* data = &signal->theData[0];
283
BlockReference blockref = signal->theData[0];
285
for (i = 0; i < 25; i++) {
289
for (i = 0; i < 16; i++) {
290
regPagePtr.i = cfreepageList[i];
292
while (regPagePtr.i != RNIL) {
294
ptrCheckGuard(regPagePtr, cnoOfPage, cpage);
295
regPagePtr.i = regPagePtr.p->next_page;
299
sendSignal(blockref, GSN_MEMCHECKCONF, signal, 25, JBB);
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)
311
FragrecordPtr tmpFragP;
312
TablerecPtr tmpTableP;
314
c_page_pool.getPtr(tmpPageP, pageid);
317
ptrCheckGuard(tmpFragP, cnoOfFragrec, fragrecord);
319
tmpTableP.i = tmpFragP.p->fragTableId;
320
ptrCheckGuard(tmpTableP, cnoOfTablerec, tablerec);
322
ndbout << "Fragid: " << fragid << " Pageid: " << pageid << endl
323
<< "----------------------------------------" << endl;
325
ndbout << "PageHead : ";
327
}//Dbtup::printoutTuplePage
331
operator<<(NdbOut& out, const Dbtup::Operationrec& op)
333
out << "[Operationrec " << hex << &op;
335
out << " [fragmentPtr " << hex << op.fragmentPtr << "]";
337
out << " [op_type " << dec << op.op_struct.op_type << "]";
338
out << " [delete_insert_flag " << dec;
339
out << op.op_struct.delete_insert_flag << "]";
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 << "]";
345
out << " [prevActiveOp " << hex << op.prevActiveOp << "]";
346
out << " [nextActiveOp " << hex << op.nextActiveOp << "]";
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 << "]";
355
// uses global tabptr
357
operator<<(NdbOut& out, const Dbtup::Th& th)
360
Dbtup* tup = (Dbtup*)globalData.getBlock(DBTUP);
361
const Dbtup::Tablerec& tab = *tup->tabptr.p;
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++] << "]";
369
for (unsigned j = 0; j < tab.m_offsets[Dbtup::MM].m_null_words; j++)
370
out << " " << hex << th.data[i++];
373
while (i < tab.m_offsets[Dbtup::MM].m_fix_header_size)
374
out << " " << hex << th.data[i++];
382
template class Vector<Chunk>;
384
// uses global tabptr
387
operator<<(NdbOut& out, const Local_key & key)
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 << "]";
397
operator<<(NdbOut& out, const Dbtup::Tablerec::Tuple_offsets& off)
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
410
operator<<(NdbOut& out, const Dbtup::Tablerec& tab)
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 << "]"
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 << "]"
428
operator<<(NdbOut& out, const AttributeDescriptor& off)
431
memcpy(&word, &off, 4);
435
#include "AttributeOffset.hpp"
438
operator<<(NdbOut& out, const AttributeOffset& off)
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);