~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/innobase/handler/data_dictionary.cc

  • Committer: Monty Taylor
  • Date: 2008-10-09 22:38:27 UTC
  • mto: This revision was merged to the branch mainline in revision 497.
  • Revision ID: monty@inaugust.com-20081009223827-bc9gvpiplsmvpwyq
Moved test() to its own file.
Made a new function to possibly replace int10_to_str.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*****************************************************************************
2
 
 
3
 
Copyright (c) 2007, 2009, Innobase Oy. All Rights Reserved.
4
 
 
5
 
This program is free software; you can redistribute it and/or modify it under
6
 
the terms of the GNU General Public License as published by the Free Software
7
 
Foundation; version 2 of the License.
8
 
 
9
 
This program is distributed in the hope that it will be useful, but WITHOUT
10
 
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11
 
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12
 
 
13
 
You should have received a copy of the GNU General Public License along with
14
 
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
15
 
Place, Suite 330, Boston, MA 02111-1307 USA
16
 
 
17
 
*****************************************************************************/
18
 
 
19
 
#include "config.h"
20
 
 
21
 
#include "data_dictionary.h"
22
 
 
23
 
#include "drizzled/current_session.h"
24
 
 
25
 
extern "C" {
26
 
#include "trx0i_s.h"
27
 
#include "trx0trx.h" /* for TRX_QUE_STATE_STR_MAX_LEN */
28
 
#include "buf0buddy.h" /* for i_s_cmpmem */
29
 
#include "buf0buf.h" /* for buf_pool and PAGE_ZIP_MIN_SIZE */
30
 
#include "ha_prototypes.h" /* for innobase_convert_name() */
31
 
#include "srv0start.h" /* for srv_was_started */
32
 
}
33
 
#include "handler0vars.h"
34
 
 
35
 
using namespace drizzled;
36
 
 
37
 
/*
38
 
 * Fill the dynamic table data_dictionary.INNODB_CMP and INNODB_CMP_RESET
39
 
 *
40
 
 */
41
 
CmpTool::CmpTool(bool in_reset) :
42
 
  plugin::TableFunction("DATA_DICTIONARY", in_reset ? "INNODB_CMP_RESET" : "INNODB_CMP"),
43
 
  outer_reset(in_reset)
44
 
{
45
 
  add_field("PAGE_SIZE", plugin::TableFunction::NUMBER, 0, false);
46
 
  add_field("COMPRESS_OPS", plugin::TableFunction::NUMBER, 0, false);
47
 
  add_field("COMPRESS_OPS_OK", plugin::TableFunction::NUMBER, 0, false);
48
 
  add_field("COMPRESS_TIME", plugin::TableFunction::NUMBER, 0, false);
49
 
  add_field("UNCOMPRESS_OPS", plugin::TableFunction::NUMBER, 0, false);
50
 
  add_field("UNCOMPRESS_TIME", plugin::TableFunction::NUMBER, 0, false);
51
 
}
52
 
 
53
 
CmpTool::Generator::Generator(Field **arg, bool in_reset) :
54
 
  plugin::TableFunction::Generator(arg),
55
 
  record_number(0),
56
 
  inner_reset(in_reset)
57
 
{
58
 
}
59
 
 
60
 
bool CmpTool::Generator::populate()
61
 
{
62
 
  if (record_number == (PAGE_ZIP_NUM_SSIZE - 1))
63
 
  {
64
 
    return false;
65
 
  }
66
 
 
67
 
  page_zip_stat_t*        zip_stat = &page_zip_stat[record_number];
68
 
 
69
 
  push(static_cast<uint64_t>(PAGE_ZIP_MIN_SIZE << record_number));
70
 
 
71
 
  /* The cumulated counts are not protected by any
72
 
     mutex.  Thus, some operation in page0zip.c could
73
 
     increment a counter between the time we read it and
74
 
     clear it.  We could introduce mutex protection, but it
75
 
     could cause a measureable performance hit in
76
 
     page0zip.c. */
77
 
  push(static_cast<uint64_t>(zip_stat->compressed));
78
 
  push(static_cast<uint64_t>(zip_stat->compressed_ok));
79
 
  push(zip_stat->compressed_usec / 1000000);
80
 
  push(static_cast<uint64_t>(zip_stat->decompressed));
81
 
  push(zip_stat->decompressed_usec / 1000000);
82
 
 
83
 
  if (inner_reset)
84
 
  {
85
 
    memset(zip_stat, 0, sizeof *zip_stat);
86
 
  }
87
 
 
88
 
  record_number++;
89
 
 
90
 
  return true;
91
 
}
92
 
 
93
 
/*
94
 
 * Fill the dynamic table data_dictionary.INNODB_CMPMEM and INNODB_CMPMEM_RESET
95
 
 *
96
 
 */
97
 
CmpmemTool::CmpmemTool(bool in_reset) :
98
 
  plugin::TableFunction("DATA_DICTIONARY", in_reset ? "INNODB_CMPMEM_RESET" : "INNODB_CMPMEM"),
99
 
  outer_reset(in_reset)
100
 
{
101
 
  add_field("PAGE_SIZE", plugin::TableFunction::NUMBER, 0, false);
102
 
  add_field("PAGES_USED", plugin::TableFunction::NUMBER, 0, false);
103
 
  add_field("PAGES_FREE", plugin::TableFunction::NUMBER, 0, false);
104
 
  add_field("RELOCATION_OPS", plugin::TableFunction::NUMBER, 0, false);
105
 
  add_field("RELOCATION_TIME", plugin::TableFunction::NUMBER, 0, false);
106
 
}
107
 
 
108
 
CmpmemTool::Generator::Generator(Field **arg, bool in_reset) :
109
 
  plugin::TableFunction::Generator(arg),
110
 
  record_number(0),
111
 
  inner_reset(in_reset)
112
 
{
113
 
  buf_pool_mutex_enter();
114
 
}
115
 
 
116
 
CmpmemTool::Generator::~Generator()
117
 
{
118
 
  buf_pool_mutex_exit();
119
 
}
120
 
 
121
 
bool CmpmemTool::Generator::populate()
122
 
{
123
 
  if (record_number > BUF_BUDDY_SIZES)
124
 
  {
125
 
    return false;
126
 
  }
127
 
 
128
 
  buf_buddy_stat_t* buddy_stat = &buf_buddy_stat[record_number];
129
 
 
130
 
  push(static_cast<uint64_t>(BUF_BUDDY_LOW << record_number));
131
 
  push(static_cast<uint64_t>(buddy_stat->used));
132
 
  uint64_t pages_free= (UNIV_LIKELY(record_number < BUF_BUDDY_SIZES) ? UT_LIST_GET_LEN(buf_pool->zip_free[record_number]) : 0);
133
 
  push(pages_free);
134
 
 
135
 
  push(buddy_stat->relocated);
136
 
  push(buddy_stat->relocated_usec / 1000000);
137
 
 
138
 
 
139
 
  if (inner_reset)
140
 
  {
141
 
    buddy_stat->relocated = 0;
142
 
    buddy_stat->relocated_usec = 0;
143
 
  }
144
 
 
145
 
  record_number++;
146
 
 
147
 
  return true;
148
 
}
149
 
 
150
 
/*
151
 
 * Fill the dynamic table data_dictionary.INNODB_TRX INNODB_LOCKS INNODB_LOCK_WAITS
152
 
 *
153
 
 */
154
 
InnodbTrxTool::InnodbTrxTool(const char* in_table_name) :
155
 
  plugin::TableFunction("DATA_DICTIONARY", in_table_name),
156
 
  table_name(in_table_name)
157
 
{
158
 
  if (innobase_strcasecmp(table_name, "INNODB_TRX") == 0)
159
 
  {
160
 
    add_field("TRX_ID");
161
 
    add_field("TRX_STATE");
162
 
    add_field("TRX_STARTED", plugin::TableFunction::NUMBER, 0, false);
163
 
    add_field("TRX_REQUESTED_LOCK_ID");
164
 
    add_field("TRX_WAIT_STARTED", plugin::TableFunction::NUMBER, 0, false);
165
 
    add_field("TRX_WEIGHT", plugin::TableFunction::NUMBER, 0, false);
166
 
    add_field("TRX_DRIZZLE_THREAD_ID", plugin::TableFunction::NUMBER, 0, false);
167
 
    add_field("TRX_QUERY", plugin::TableFunction::STRING, TRX_I_S_TRX_QUERY_MAX_LEN, true);
168
 
  }
169
 
  else if (innobase_strcasecmp(table_name, "INNODB_LOCKS") == 0)
170
 
  {
171
 
    add_field("LOCK_ID");
172
 
    add_field("LOCK_TRX_ID");
173
 
    add_field("LOCK_MODE");
174
 
    add_field("LOCK_TYPE");
175
 
    add_field("LOCK_TABLE");
176
 
    add_field("LOCK_INDEX");
177
 
    add_field("LOCK_SPACE", plugin::TableFunction::NUMBER, 0, false);
178
 
    add_field("LOCK_PAGE", plugin::TableFunction::NUMBER, 0, false);
179
 
    add_field("LOCK_REC", plugin::TableFunction::NUMBER, 0, false);
180
 
    add_field("LOCK_DATA");
181
 
  }
182
 
  else if (innobase_strcasecmp(table_name, "INNODB_LOCK_WAITS") == 0)
183
 
  {
184
 
    add_field("REQUESTING_TRX_ID");  
185
 
    add_field("REQUESTED_LOCK_ID");
186
 
    add_field("BLOCKING_TRX_ID");
187
 
    add_field("BLOCKING_LOCK_ID");
188
 
  } 
189
 
}
190
 
 
191
 
InnodbTrxTool::Generator::Generator(Field **arg, const char* in_table_name) :
192
 
  plugin::TableFunction::Generator(arg),
193
 
  table_name(in_table_name)
194
 
{
195
 
  /* update the cache */
196
 
  trx_i_s_cache_start_write(trx_i_s_cache);
197
 
  trx_i_s_possibly_fetch_data_into_cache(trx_i_s_cache);
198
 
  trx_i_s_cache_end_write(trx_i_s_cache);
199
 
 
200
 
  if (trx_i_s_cache_is_truncated(trx_i_s_cache))
201
 
  {
202
 
    errmsg_printf(ERRMSG_LVL_ERROR, _("Warning: data in %s truncated due to memory limit of %d bytes\n"), 
203
 
                  table_name, TRX_I_S_MEM_LIMIT);
204
 
  } 
205
 
 
206
 
  trx_i_s_cache_start_read(trx_i_s_cache);
207
 
 
208
 
  number_rows= trx_i_s_cache_get_rows_used(trx_i_s_cache, I_S_INNODB_TRX);
209
 
 
210
 
  record_number= 0;
211
 
}
212
 
 
213
 
InnodbTrxTool::Generator::~Generator()
214
 
{
215
 
  trx_i_s_cache_end_read(trx_i_s_cache);
216
 
}
217
 
 
218
 
bool InnodbTrxTool::Generator::populate()
219
 
{
220
 
  if (record_number == number_rows)
221
 
  {
222
 
    return false;
223
 
  }
224
 
 
225
 
  if (innobase_strcasecmp(table_name, "INNODB_TRX") == 0)
226
 
  {
227
 
    populate_innodb_trx();
228
 
  }
229
 
  else if (innobase_strcasecmp(table_name, "INNODB_LOCKS") == 0)
230
 
  {
231
 
    populate_innodb_locks();
232
 
  }
233
 
  else if (innobase_strcasecmp(table_name, "INNODB_LOCK_WAITS") == 0)
234
 
  {
235
 
    populate_innodb_lock_waits();
236
 
  }
237
 
  else 
238
 
  {
239
 
    return false;
240
 
  }
241
 
  record_number++;
242
 
 
243
 
  return true;
244
 
}
245
 
 
246
 
void InnodbTrxTool::Generator::populate_innodb_locks()
247
 
{
248
 
 
249
 
  char lock_id[TRX_I_S_LOCK_ID_MAX_LEN + 1];
250
 
  i_s_locks_row_t* row;
251
 
 
252
 
  /* note that the decoded database or table name is
253
 
     never expected to be longer than NAME_LEN;
254
 
     NAME_LEN for database name
255
 
     2 for surrounding quotes around database name
256
 
     NAME_LEN for table name
257
 
     2 for surrounding quotes around table name
258
 
     1 for the separating dot (.)
259
 
     9 for the #mysql50# prefix 
260
 
  */
261
 
 
262
 
   char buf[2 * NAME_LEN + 14];
263
 
   const char* bufend;
264
 
 
265
 
   char lock_trx_id[TRX_ID_MAX_LEN + 1];
266
 
 
267
 
   row = (i_s_locks_row_t*)
268
 
          trx_i_s_cache_get_nth_row(
269
 
          trx_i_s_cache, I_S_INNODB_LOCKS, record_number);
270
 
 
271
 
 
272
 
   trx_i_s_create_lock_id(row, lock_id, sizeof(lock_id));
273
 
   push(lock_id);
274
 
 
275
 
   ut_snprintf(lock_trx_id, sizeof(lock_trx_id),
276
 
               TRX_ID_FMT, row->lock_trx_id);
277
 
   push(lock_trx_id);
278
 
 
279
 
   push(row->lock_mode);
280
 
   push(row->lock_type);
281
 
 
282
 
   bufend = innobase_convert_name(buf, sizeof(buf),
283
 
                                  row->lock_table,
284
 
                                  strlen(row->lock_table),
285
 
                                  current_session, TRUE);
286
 
   push(bufend);
287
 
 
288
 
   if (row->lock_index != NULL)
289
 
   {
290
 
     bufend = innobase_convert_name(buf, sizeof(buf),
291
 
                                    row->lock_index,
292
 
                                    strlen(row->lock_index),
293
 
                                    current_session, FALSE);
294
 
     push(bufend);     
295
 
   }
296
 
   else 
297
 
   {
298
 
     push("");
299
 
   }   
300
 
 
301
 
   push(static_cast<uint64_t>(row->lock_space));
302
 
   push(static_cast<uint64_t>(row->lock_page)); 
303
 
   push(static_cast<uint64_t>(row->lock_rec));
304
 
   push(row->lock_data);
305
 
}
306
 
 
307
 
void InnodbTrxTool::Generator::populate_innodb_trx()
308
 
{
309
 
    char lock_id[TRX_I_S_LOCK_ID_MAX_LEN + 1];
310
 
    i_s_trx_row_t* row;
311
 
    char trx_id[TRX_ID_MAX_LEN + 1];
312
 
    row = (i_s_trx_row_t*) trx_i_s_cache_get_nth_row(trx_i_s_cache, I_S_INNODB_TRX, record_number);
313
 
 
314
 
    /* trx_id */
315
 
    ut_snprintf(trx_id, sizeof(trx_id), TRX_ID_FMT, row->trx_id);
316
 
 
317
 
    push(trx_id);
318
 
    push(row->trx_state);
319
 
    push(static_cast<uint64_t>(row->trx_started));
320
 
 
321
 
    if (row->trx_wait_started != 0)
322
 
    {
323
 
      push(trx_i_s_create_lock_id(row->requested_lock_row, lock_id, sizeof(lock_id)));
324
 
      push(static_cast<uint64_t>(row->trx_wait_started));
325
 
    }
326
 
    else
327
 
    {
328
 
      push(static_cast<uint64_t>(0));
329
 
      push(static_cast<uint64_t>(0));
330
 
    }
331
 
 
332
 
    push(static_cast<int64_t>(row->trx_weight));
333
 
    push(static_cast<uint64_t>(row->trx_mysql_thread_id));
334
 
    if (row->trx_query)
335
 
    {
336
 
      push(row->trx_query);
337
 
    }
338
 
    else
339
 
    {
340
 
      push();
341
 
    }
342
 
}
343
 
 
344
 
void InnodbTrxTool::Generator::populate_innodb_lock_waits()
345
 
{
346
 
  char requested_lock_id[TRX_I_S_LOCK_ID_MAX_LEN + 1];
347
 
  char blocking_lock_id[TRX_I_S_LOCK_ID_MAX_LEN + 1];
348
 
 
349
 
  i_s_lock_waits_row_t* row;
350
 
 
351
 
  char requesting_trx_id[TRX_ID_MAX_LEN + 1];
352
 
  char blocking_trx_id[TRX_ID_MAX_LEN + 1];
353
 
 
354
 
  row = (i_s_lock_waits_row_t*)
355
 
         trx_i_s_cache_get_nth_row(
356
 
         trx_i_s_cache, I_S_INNODB_LOCK_WAITS, record_number);
357
 
 
358
 
  ut_snprintf(requesting_trx_id, sizeof(requesting_trx_id),
359
 
              TRX_ID_FMT, row->requested_lock_row->lock_trx_id);
360
 
  push(requesting_trx_id);
361
 
 
362
 
  push(trx_i_s_create_lock_id(row->requested_lock_row, requested_lock_id, 
363
 
       sizeof(requested_lock_id)));
364
 
 
365
 
  ut_snprintf(blocking_trx_id, sizeof(blocking_trx_id),
366
 
              TRX_ID_FMT, row->blocking_lock_row->lock_trx_id);
367
 
  push(blocking_trx_id);
368
 
 
369
 
  push(trx_i_s_create_lock_id(row->blocking_lock_row, blocking_lock_id, 
370
 
       sizeof(blocking_lock_id)));
371
 
}