1
/*****************************************************************************
3
Copyright (c) 2007, 2009, Innobase Oy. All Rights Reserved.
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.
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.
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
17
*****************************************************************************/
21
#include "data_dictionary.h"
23
#include "drizzled/current_session.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 */
33
#include "handler0vars.h"
35
using namespace drizzled;
38
* Fill the dynamic table data_dictionary.INNODB_CMP and INNODB_CMP_RESET
41
CmpTool::CmpTool(bool in_reset) :
42
plugin::TableFunction("DATA_DICTIONARY", in_reset ? "INNODB_CMP_RESET" : "INNODB_CMP"),
45
add_field("PAGE_SIZE", plugin::TableFunction::NUMBER);
46
add_field("COMPRESS_OPS", plugin::TableFunction::NUMBER);
47
add_field("COMPRESS_OPS_OK", plugin::TableFunction::NUMBER);
48
add_field("COMPRESS_TIME", plugin::TableFunction::NUMBER);
49
add_field("UNCOMPRESS_OPS", plugin::TableFunction::NUMBER);
50
add_field("UNCOMPRESS_TIME", plugin::TableFunction::NUMBER);
53
CmpTool::Generator::Generator(Field **arg, bool in_reset) :
54
plugin::TableFunction::Generator(arg),
60
bool CmpTool::Generator::populate()
62
if (record_number == (PAGE_ZIP_NUM_SSIZE - 1))
67
page_zip_stat_t* zip_stat = &page_zip_stat[record_number];
69
push(static_cast<uint64_t>(PAGE_ZIP_MIN_SIZE << record_number));
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
77
push(zip_stat->compressed);
78
push(zip_stat->compressed_ok);
79
push(zip_stat->compressed_usec / 1000000);
80
push(zip_stat->decompressed);
81
push(zip_stat->decompressed_usec / 1000000);
85
memset(zip_stat, 0, sizeof *zip_stat);
94
* Fill the dynamic table data_dictionary.INNODB_CMPMEM and INNODB_CMPMEM_RESET
97
CmpmemTool::CmpmemTool(bool in_reset) :
98
plugin::TableFunction("DATA_DICTIONARY", in_reset ? "INNODB_CMPMEM_RESET" : "INNODB_CMPMEM"),
101
add_field("PAGE_SIZE", plugin::TableFunction::NUMBER);
102
add_field("PAGES_USED", plugin::TableFunction::NUMBER);
103
add_field("PAGES_FREE", plugin::TableFunction::NUMBER);
104
add_field("RELOCATION_OPS", plugin::TableFunction::NUMBER);
105
add_field("RELOCATION_TIME", plugin::TableFunction::NUMBER);
108
CmpmemTool::Generator::Generator(Field **arg, bool in_reset) :
109
plugin::TableFunction::Generator(arg),
111
inner_reset(in_reset)
113
buf_pool_mutex_enter();
116
CmpmemTool::Generator::~Generator()
118
buf_pool_mutex_exit();
121
bool CmpmemTool::Generator::populate()
123
if (record_number > BUF_BUDDY_SIZES)
128
buf_buddy_stat_t* buddy_stat = &buf_buddy_stat[record_number];
130
push(static_cast<uint64_t>(BUF_BUDDY_LOW << record_number));
131
push(buddy_stat->used);
132
push(UNIV_LIKELY(record_number < BUF_BUDDY_SIZES)
133
? UT_LIST_GET_LEN(buf_pool->zip_free[record_number]) : 0);
135
push(buddy_stat->relocated);
136
push(buddy_stat->relocated_usec / 1000000);
141
buddy_stat->relocated = 0;
142
buddy_stat->relocated_usec = 0;
151
* Fill the dynamic table data_dictionary.INNODB_TRX INNODB_LOCKS INNODB_LOCK_WAITS
154
InnodbTrxTool::InnodbTrxTool(const char* in_table_name) :
155
plugin::TableFunction("DATA_DICTIONARY", in_table_name),
156
table_name(in_table_name)
158
if (innobase_strcasecmp(table_name, "INNODB_TRX") == 0)
161
add_field("TRX_STATE");
162
add_field("TRX_STARTED", plugin::TableFunction::NUMBER);
163
add_field("TRX_REQUESTED_LOCK_ID");
164
add_field("TRX_WAIT_STARTED", plugin::TableFunction::NUMBER);
165
add_field("TRX_WEIGHT", plugin::TableFunction::NUMBER);
166
add_field("TRX_DRIZZLE_THREAD_ID", plugin::TableFunction::NUMBER);
167
add_field("TRX_QUERY");
169
else if (innobase_strcasecmp(table_name, "INNODB_LOCKS") == 0)
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);
178
add_field("LOCK_PAGE", plugin::TableFunction::NUMBER);
179
add_field("LOCK_REC", plugin::TableFunction::NUMBER);
180
add_field("LOCK_DATA");
182
else if (innobase_strcasecmp(table_name, "INNODB_LOCK_WAITS") == 0)
184
add_field("REQUESTING_TRX_ID");
185
add_field("REQUESTED_LOCK_ID");
186
add_field("BLOCKING_TRX_ID");
187
add_field("BLOCKING_LOCK_ID");
191
InnodbTrxTool::Generator::Generator(Field **arg, const char* in_table_name) :
192
plugin::TableFunction::Generator(arg),
193
table_name(in_table_name)
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);
200
if (trx_i_s_cache_is_truncated(trx_i_s_cache))
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);
206
trx_i_s_cache_start_read(trx_i_s_cache);
208
number_rows= trx_i_s_cache_get_rows_used(trx_i_s_cache, I_S_INNODB_TRX);
213
InnodbTrxTool::Generator::~Generator()
215
trx_i_s_cache_end_read(trx_i_s_cache);
218
bool InnodbTrxTool::Generator::populate()
220
if (record_number == number_rows)
225
if (innobase_strcasecmp(table_name, "INNODB_TRX") == 0)
227
populate_innodb_trx();
229
else if (innobase_strcasecmp(table_name, "INNODB_LOCKS") == 0)
231
populate_innodb_locks();
233
else if (innobase_strcasecmp(table_name, "INNODB_LOCK_WAITS") == 0)
235
populate_innodb_lock_waits();
246
void InnodbTrxTool::Generator::populate_innodb_locks()
249
char lock_id[TRX_I_S_LOCK_ID_MAX_LEN + 1];
250
i_s_locks_row_t* row;
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
262
char buf[2 * NAME_LEN + 14];
265
char lock_trx_id[TRX_ID_MAX_LEN + 1];
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);
272
trx_i_s_create_lock_id(row, lock_id, sizeof(lock_id));
275
ut_snprintf(lock_trx_id, sizeof(lock_trx_id),
276
TRX_ID_FMT, row->lock_trx_id);
279
push(row->lock_mode);
280
push(row->lock_type);
282
bufend = innobase_convert_name(buf, sizeof(buf),
284
strlen(row->lock_table),
285
current_session, TRUE);
288
if (row->lock_index != NULL)
290
bufend = innobase_convert_name(buf, sizeof(buf),
292
strlen(row->lock_index),
293
current_session, FALSE);
301
push(row->lock_space);
302
push(row->lock_page);
304
push(row->lock_data);
307
void InnodbTrxTool::Generator::populate_innodb_trx()
309
char lock_id[TRX_I_S_LOCK_ID_MAX_LEN + 1];
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);
315
ut_snprintf(trx_id, sizeof(trx_id), TRX_ID_FMT, row->trx_id);
318
push(row->trx_state);
319
push(row->trx_started);
321
if (row->trx_wait_started != 0)
323
push(trx_i_s_create_lock_id(row->requested_lock_row, lock_id, sizeof(lock_id)));
324
push(row->trx_wait_started);
328
push(static_cast<uint64_t>(0));
329
push(static_cast<uint64_t>(0));
332
push(static_cast<int64_t>(row->trx_weight));
333
push(row->trx_mysql_thread_id);
334
push(row->trx_query);
337
void InnodbTrxTool::Generator::populate_innodb_lock_waits()
339
char requested_lock_id[TRX_I_S_LOCK_ID_MAX_LEN + 1];
340
char blocking_lock_id[TRX_I_S_LOCK_ID_MAX_LEN + 1];
342
i_s_lock_waits_row_t* row;
344
char requesting_trx_id[TRX_ID_MAX_LEN + 1];
345
char blocking_trx_id[TRX_ID_MAX_LEN + 1];
347
row = (i_s_lock_waits_row_t*)
348
trx_i_s_cache_get_nth_row(
349
trx_i_s_cache, I_S_INNODB_LOCK_WAITS, record_number);
351
ut_snprintf(requesting_trx_id, sizeof(requesting_trx_id),
352
TRX_ID_FMT, row->requested_lock_row->lock_trx_id);
353
push(requesting_trx_id);
355
push(trx_i_s_create_lock_id(row->requested_lock_row, requested_lock_id,
356
sizeof(requested_lock_id)));
358
ut_snprintf(blocking_trx_id, sizeof(blocking_trx_id),
359
TRX_ID_FMT, row->blocking_lock_row->lock_trx_id);
360
push(blocking_trx_id);
362
push(trx_i_s_create_lock_id(row->blocking_lock_row, blocking_lock_id,
363
sizeof(blocking_lock_id)));