summaryrefslogtreecommitdiff
path: root/innobase
diff options
context:
space:
mode:
authorheikki@hundin.mysql.fi <>2002-07-08 19:34:49 +0300
committerheikki@hundin.mysql.fi <>2002-07-08 19:34:49 +0300
commit7390d81f43c5c02004039a27bff27e558639aab0 (patch)
treeb4e7fbd4d1817aa205132578bc6b11e6dd0fad86 /innobase
parent3135924745a221a579f5a49aaee4b112a3a1bb4c (diff)
downloadmariadb-git-7390d81f43c5c02004039a27bff27e558639aab0.tar.gz
Many files:
Merge InnoDB-3.23.52b
Diffstat (limited to 'innobase')
-rw-r--r--innobase/btr/btr0btr.c3
-rw-r--r--innobase/btr/btr0cur.c2
-rw-r--r--innobase/btr/btr0sea.c85
-rw-r--r--innobase/buf/buf0buf.c36
-rw-r--r--innobase/ha/ha0ha.c43
-rw-r--r--innobase/ibuf/ibuf0ibuf.c16
-rw-r--r--innobase/include/btr0cur.h2
-rw-r--r--innobase/include/buf0buf.h8
-rw-r--r--innobase/include/ha0ha.h2
-rw-r--r--innobase/include/ibuf0ibuf.h6
-rw-r--r--innobase/include/lock0lock.h10
-rw-r--r--innobase/include/log0log.h6
-rw-r--r--innobase/include/os0file.h6
-rw-r--r--innobase/include/rem0rec.ic2
-rw-r--r--innobase/include/srv0srv.h8
-rw-r--r--innobase/include/sync0arr.h2
-rw-r--r--innobase/include/sync0sync.h12
-rw-r--r--innobase/include/trx0trx.h4
-rw-r--r--innobase/lock/lock0lock.c128
-rw-r--r--innobase/log/log0log.c15
-rw-r--r--innobase/os/os0file.c48
-rw-r--r--innobase/row/row0mysql.c8
-rw-r--r--innobase/row/row0umod.c5
-rw-r--r--innobase/row/row0upd.c7
-rw-r--r--innobase/srv/srv0srv.c201
-rw-r--r--innobase/srv/srv0start.c2
-rw-r--r--innobase/sync/sync0arr.c78
-rw-r--r--innobase/sync/sync0sync.c33
-rw-r--r--innobase/trx/trx0trx.c49
29 files changed, 579 insertions, 248 deletions
diff --git a/innobase/btr/btr0btr.c b/innobase/btr/btr0btr.c
index 88472d6dbe0..15642e6ccbc 100644
--- a/innobase/btr/btr0btr.c
+++ b/innobase/btr/btr0btr.c
@@ -2076,8 +2076,7 @@ btr_discard_page(
btr_search_drop_page_hash_index(page);
- if ((left_page_no == FIL_NULL)
- && (btr_page_get_level(page, mtr) > 0)) {
+ if (left_page_no == FIL_NULL && btr_page_get_level(page, mtr) > 0) {
/* We have to mark the leftmost node pointer on the right
side page as the predefined minimum record */
diff --git a/innobase/btr/btr0cur.c b/innobase/btr/btr0cur.c
index f3aebb7f96f..50f9584e86d 100644
--- a/innobase/btr/btr0cur.c
+++ b/innobase/btr/btr0cur.c
@@ -44,6 +44,8 @@ ulint btr_cur_rnd = 0;
ulint btr_cur_n_non_sea = 0;
ulint btr_cur_n_sea = 0;
+ulint btr_cur_n_non_sea_old = 0;
+ulint btr_cur_n_sea_old = 0;
/* In the optimistic insert, if the insert does not fit, but this much space
can be released by page reorganize, then it is reorganized */
diff --git a/innobase/btr/btr0sea.c b/innobase/btr/btr0sea.c
index 5e1c8401e28..5db737561aa 100644
--- a/innobase/btr/btr0sea.c
+++ b/innobase/btr/btr0sea.c
@@ -451,7 +451,9 @@ btr_search_info_update_slow(
rw_lock_x_unlock(&btr_search_latch);
}
- if (build_index) {
+ if (build_index) {
+ ut_a(block->n_fields + block->n_bytes > 0);
+
btr_search_build_page_hash_index(block->frame,
block->n_fields,
block->n_bytes,
@@ -676,6 +678,9 @@ btr_search_guess_on_hash(
rw_lock_s_lock(&btr_search_latch);
}
+ ut_a(btr_search_latch.writer != RW_LOCK_EX);
+ ut_a(btr_search_latch.reader_count > 0);
+
rec = ha_search_and_get_data(btr_search_sys->hash_index, fold);
if (!rec) {
@@ -902,7 +907,7 @@ btr_search_drop_page_hash_index(
fold = rec_fold(rec, n_fields, n_bytes, tree_id);
- if ((fold == prev_fold) && (prev_fold != 0)) {
+ if (fold == prev_fold && prev_fold != 0) {
goto next_rec;
}
@@ -914,6 +919,7 @@ btr_search_drop_page_hash_index(
n_cached++;
next_rec:
rec = page_rec_get_next(rec);
+ prev_fold = fold;
}
rw_lock_x_lock(&btr_search_latch);
@@ -954,7 +960,7 @@ btr_search_drop_page_hash_when_freed(
mtr_start(&mtr);
/* We assume that if the caller has a latch on the page,
- then the caller has already drooped the hash index for the page,
+ then the caller has already dropped the hash index for the page,
and we never get here. Therefore we can acquire the s-latch to
the page without fearing a deadlock. */
@@ -1177,6 +1183,8 @@ btr_search_move_or_delete_hash_entries(
rw_lock_s_unlock(&btr_search_latch);
+ ut_a(n_fields + n_bytes > 0);
+
btr_search_build_page_hash_index(new_page, n_fields, n_bytes,
side);
ut_a(n_fields == block->curr_n_fields);
@@ -1217,9 +1225,11 @@ btr_search_update_hash_on_delete(
return;
}
+ ut_a(block->curr_n_fields + block->curr_n_bytes > 0);
+
table = btr_search_sys->hash_index;
- tree_id = ((cursor->index)->tree)->id;
+ tree_id = cursor->index->tree->id;
fold = rec_fold(rec, block->curr_n_fields, block->curr_n_bytes,
tree_id);
@@ -1336,7 +1346,6 @@ btr_search_update_hash_on_insert(
if (rec != page_get_infimum_rec(page)) {
fold = rec_fold(rec, n_fields, n_bytes, tree_id);
-
} else {
if (side == BTR_SEARCH_LEFT_SIDE) {
@@ -1421,7 +1430,7 @@ btr_search_print_info(void)
rw_lock_x_lock(&btr_search_latch);
- ha_print_info(btr_search_sys->hash_index);
+/* ha_print_info(btr_search_sys->hash_index); */
rw_lock_x_unlock(&btr_search_latch);
}
@@ -1487,11 +1496,71 @@ btr_search_validate(void)
/*=====================*/
/* out: TRUE if ok */
{
+ buf_block_t* block;
+ page_t* page;
+ ha_node_t* node;
+ ulint n_page_dumps = 0;
+ ibool ok = TRUE;
+ ulint i;
+ char rec_str[500];
+
rw_lock_x_lock(&btr_search_latch);
+
+ for (i = 0; i < hash_get_n_cells(btr_search_sys->hash_index); i++) {
+ node = hash_get_nth_cell(btr_search_sys->hash_index, i)->node;
+
+ while (node != NULL) {
+ block = buf_block_align(node->data);
+ page = buf_frame_align(node->data);
+
+ if (!block->is_hashed
+ || node->fold != rec_fold((rec_t*)(node->data),
+ block->curr_n_fields,
+ block->curr_n_bytes,
+ btr_page_get_index_id(page))) {
+ ok = FALSE;
+ ut_print_timestamp(stderr);
+
+ fprintf(stderr,
+" InnoDB: Error in an adaptive hash index pointer to page %lu\n"
+"ptr mem address %lu index id %lu %lu, node fold %lu, rec fold %lu\n",
+ buf_frame_get_page_no(page),
+ (ulint)(node->data),
+ ut_dulint_get_high(btr_page_get_index_id(page)),
+ ut_dulint_get_low(btr_page_get_index_id(page)),
+ node->fold, rec_fold((rec_t*)(node->data),
+ block->curr_n_fields,
+ block->curr_n_bytes,
+ btr_page_get_index_id(page)));
+
+ rec_sprintf(rec_str, 450, (rec_t*)(node->data));
+
+ fprintf(stderr,
+ "InnoDB: Record %s\n"
+ "InnoDB: on that page.", rec_str);
+
+ fprintf(stderr,
+"Page mem address %lu, is hashed %lu, n fields %lu, n bytes %lu\n"
+"side %lu\n",
+ (ulint)page, block->is_hashed, block->curr_n_fields,
+ block->curr_n_bytes, block->curr_side);
+
+ if (n_page_dumps < 20) {
+ buf_page_print(page);
+ n_page_dumps++;
+ }
+ }
+
+ node = node->next;
+ }
+ }
- ut_a(ha_validate(btr_search_sys->hash_index));
+ if (!ha_validate(btr_search_sys->hash_index)) {
+
+ ok = FALSE;
+ }
rw_lock_x_unlock(&btr_search_latch);
- return(TRUE);
+ return(ok);
}
diff --git a/innobase/buf/buf0buf.c b/innobase/buf/buf0buf.c
index 7d001a6953d..80e89e16588 100644
--- a/innobase/buf/buf0buf.c
+++ b/innobase/buf/buf0buf.c
@@ -1798,8 +1798,10 @@ buf_get_n_pending_ios(void)
Prints info of the buffer i/o. */
void
-buf_print_io(void)
-/*==============*/
+buf_print_io(
+/*=========*/
+ char* buf, /* in/out: buffer where to print */
+ char* buf_end)/* in: buffer end */
{
time_t current_time;
double time_elapsed;
@@ -1807,19 +1809,28 @@ buf_print_io(void)
ut_ad(buf_pool);
+ if (buf_end - buf < 400) {
+
+ return;
+ }
+
size = buf_pool_get_curr_size() / UNIV_PAGE_SIZE;
mutex_enter(&(buf_pool->mutex));
- printf("Free list length %lu \n", UT_LIST_GET_LEN(buf_pool->free));
- printf("LRU list length %lu \n", UT_LIST_GET_LEN(buf_pool->LRU));
- printf("Flush list length %lu \n",
+ buf += sprintf(buf,
+ "Free list length %lu \n", UT_LIST_GET_LEN(buf_pool->free));
+ buf += sprintf(buf,
+ "LRU list length %lu \n", UT_LIST_GET_LEN(buf_pool->LRU));
+ buf += sprintf(buf,
+ "Flush list length %lu \n",
UT_LIST_GET_LEN(buf_pool->flush_list));
- printf("Buffer pool size %lu\n", size);
+ buf += sprintf(buf, "Buffer pool size %lu\n", size);
- printf("Pending reads %lu \n", buf_pool->n_pend_reads);
+ buf += sprintf(buf, "Pending reads %lu \n", buf_pool->n_pend_reads);
- printf("Pending writes: LRU %lu, flush list %lu, single page %lu\n",
+ buf += sprintf(buf,
+ "Pending writes: LRU %lu, flush list %lu, single page %lu\n",
buf_pool->n_flush[BUF_FLUSH_LRU],
buf_pool->n_flush[BUF_FLUSH_LIST],
buf_pool->n_flush[BUF_FLUSH_SINGLE_PAGE]);
@@ -1829,10 +1840,10 @@ buf_print_io(void)
buf_pool->last_printout_time = current_time;
- printf("Pages read %lu, created %lu, written %lu\n",
+ buf += sprintf(buf, "Pages read %lu, created %lu, written %lu\n",
buf_pool->n_pages_read, buf_pool->n_pages_created,
buf_pool->n_pages_written);
- printf("%.2f reads/s, %.2f creates/s, %.2f writes/s\n",
+ buf += sprintf(buf, "%.2f reads/s, %.2f creates/s, %.2f writes/s\n",
(buf_pool->n_pages_read - buf_pool->n_pages_read_old)
/ time_elapsed,
(buf_pool->n_pages_created - buf_pool->n_pages_created_old)
@@ -1841,13 +1852,14 @@ buf_print_io(void)
/ time_elapsed);
if (buf_pool->n_page_gets > buf_pool->n_page_gets_old) {
- printf("Buffer pool hit rate %lu / 1000\n",
+ buf += sprintf(buf, "Buffer pool hit rate %lu / 1000\n",
1000
- ((1000 *
(buf_pool->n_pages_read - buf_pool->n_pages_read_old))
/ (buf_pool->n_page_gets - buf_pool->n_page_gets_old)));
} else {
- printf("No buffer pool activity since the last printout\n");
+ buf += sprintf(buf,
+ "No buffer pool activity since the last printout\n");
}
buf_pool->n_page_gets_old = buf_pool->n_page_gets;
diff --git a/innobase/ha/ha0ha.c b/innobase/ha/ha0ha.c
index 3e4473126cf..c3ad6cdca76 100644
--- a/innobase/ha/ha0ha.c
+++ b/innobase/ha/ha0ha.c
@@ -194,7 +194,7 @@ ha_delete(
node = ha_search_with_data(table, fold, data);
- ut_ad(node);
+ ut_a(node);
ha_delete_hash_node(table, node);
}
@@ -232,6 +232,16 @@ ha_remove_all_nodes_to_page(
node = ha_chain_get_next(table, node);
}
}
+
+ /* Check that all nodes really got deleted */
+
+ node = ha_chain_get_first(table, fold);
+
+ while (node) {
+ ut_a(buf_frame_align(ha_node_get_data(node)) != page);
+
+ node = ha_chain_get_next(table, node);
+ }
}
/*****************************************************************
@@ -245,6 +255,7 @@ ha_validate(
{
hash_cell_t* cell;
ha_node_t* node;
+ ibool ok = TRUE;
ulint i;
for (i = 0; i < hash_get_n_cells(table); i++) {
@@ -254,13 +265,21 @@ ha_validate(
node = cell->node;
while (node) {
- ut_a(hash_calc_hash(node->fold, table) == i);
+ if (hash_calc_hash(node->fold, table) != i) {
+ ut_print_timestamp(stderr);
+ fprintf(stderr,
+"InnoDB: Error: hash table node fold value %lu does not\n"
+"InnoDB: match with the cell number %lu.\n",
+ node->fold, i);
+
+ ok = FALSE;
+ }
node = node->next;
}
}
- return(TRUE);
+ return(ok);
}
/*****************************************************************
@@ -269,16 +288,22 @@ Prints info of a hash table. */
void
ha_print_info(
/*==========*/
+ char* buf, /* in/out: buffer where to print */
+ char* buf_end,/* in: buffer end */
hash_table_t* table) /* in: hash table */
{
hash_cell_t* cell;
- ha_node_t* node;
+/* ha_node_t* node; */
ulint nodes = 0;
ulint cells = 0;
ulint len = 0;
ulint max_len = 0;
ulint i;
+ if (buf_end - buf < 200) {
+ return;
+ }
+
for (i = 0; i < hash_get_n_cells(table); i++) {
cell = hash_get_nth_cell(table, i);
@@ -286,7 +311,7 @@ ha_print_info(
if (cell->node) {
cells++;
-
+/*
len = 0;
node = cell->node;
@@ -306,12 +331,10 @@ ha_print_info(
if (len > max_len) {
max_len = len;
}
+*/
}
}
- printf("Hash table size %lu, used cells %lu, nodes %lu\n",
- hash_get_n_cells(table), cells, nodes);
- printf("max chain length %lu\n", max_len);
-
- ut_a(ha_validate(table));
+ buf += sprintf(buf, "Hash table size %lu, used cells %lu\n",
+ hash_get_n_cells(table), cells);
}
diff --git a/innobase/ibuf/ibuf0ibuf.c b/innobase/ibuf/ibuf0ibuf.c
index f51a924c87f..2cbffadf6a9 100644
--- a/innobase/ibuf/ibuf0ibuf.c
+++ b/innobase/ibuf/ibuf0ibuf.c
@@ -2703,22 +2703,30 @@ ibuf_validate_low(void)
Prints info of ibuf. */
void
-ibuf_print(void)
-/*============*/
+ibuf_print(
+/*=======*/
+ char* buf, /* in/out: buffer where to print */
+ char* buf_end)/* in: buffer end */
{
ibuf_data_t* data;
#ifdef UNIV_IBUF_DEBUG
ulint i;
#endif
+ if (buf_end - buf < 500) {
+ return;
+ }
+
mutex_enter(&ibuf_mutex);
data = UT_LIST_GET_FIRST(ibuf->data_list);
while (data) {
- printf(
+ buf += sprintf(buf,
"Ibuf for space %lu: size %lu, free list len %lu, seg size %lu,\n",
data->space, data->size, data->free_list_len, data->seg_size);
- printf("%lu inserts, %lu merged recs, %lu merges\n",
+
+ buf += sprintf(buf,
+ "%lu inserts, %lu merged recs, %lu merges\n",
data->n_inserts, data->n_merged_recs, data->n_merges);
#ifdef UNIV_IBUF_DEBUG
for (i = 0; i < IBUF_COUNT_N_PAGES; i++) {
diff --git a/innobase/include/btr0cur.h b/innobase/include/btr0cur.h
index 7af34deb30f..b01cbd9a875 100644
--- a/innobase/include/btr0cur.h
+++ b/innobase/include/btr0cur.h
@@ -710,6 +710,8 @@ allowed to free an inherited external field. */
extern ulint btr_cur_n_non_sea;
extern ulint btr_cur_n_sea;
+extern ulint btr_cur_n_non_sea_old;
+extern ulint btr_cur_n_sea_old;
#ifndef UNIV_NONINL
#include "btr0cur.ic"
diff --git a/innobase/include/buf0buf.h b/innobase/include/buf0buf.h
index ca0692f1e17..b80ed96f54c 100644
--- a/innobase/include/buf0buf.h
+++ b/innobase/include/buf0buf.h
@@ -448,7 +448,7 @@ Prints info of the buffer pool data structure. */
void
buf_print(void);
-/*===========*/
+/*============*/
/*************************************************************************
Returns the number of pending buf pool ios. */
@@ -459,8 +459,10 @@ buf_get_n_pending_ios(void);
Prints info of the buffer i/o. */
void
-buf_print_io(void);
-/*==============*/
+buf_print_io(
+/*=========*/
+ char* buf, /* in/out: buffer where to print */
+ char* buf_end);/* in: buffer end */
/*************************************************************************
Checks that all file pages in the buffer are in a replaceable state. */
diff --git a/innobase/include/ha0ha.h b/innobase/include/ha0ha.h
index aeed7c32eff..945b1198a41 100644
--- a/innobase/include/ha0ha.h
+++ b/innobase/include/ha0ha.h
@@ -127,6 +127,8 @@ Prints info of a hash table. */
void
ha_print_info(
/*==========*/
+ char* buf, /* in/out: buffer where to print */
+ char* buf_end,/* in: buffer end */
hash_table_t* table); /* in: hash table */
diff --git a/innobase/include/ibuf0ibuf.h b/innobase/include/ibuf0ibuf.h
index fac28461be4..a290e90e4db 100644
--- a/innobase/include/ibuf0ibuf.h
+++ b/innobase/include/ibuf0ibuf.h
@@ -269,8 +269,10 @@ ibuf_count_get(
Prints info of ibuf. */
void
-ibuf_print(void);
-/*============*/
+ibuf_print(
+/*=======*/
+ char* buf, /* in/out: buffer where to print */
+ char* buf_end);/* in: buffer end */
#define IBUF_HEADER_PAGE_NO FSP_IBUF_HEADER_PAGE_NO
#define IBUF_TREE_ROOT_PAGE_NO FSP_IBUF_TREE_ROOT_PAGE_NO
diff --git a/innobase/include/lock0lock.h b/innobase/include/lock0lock.h
index 5a15b78b869..80afba97416 100644
--- a/innobase/include/lock0lock.h
+++ b/innobase/include/lock0lock.h
@@ -460,6 +460,8 @@ Prints info of a table lock. */
void
lock_table_print(
/*=============*/
+ char* buf, /* in/out: buffer where to print, must be at least
+ 500 bytes */
lock_t* lock); /* in: table type lock */
/*************************************************************************
Prints info of a record lock. */
@@ -467,13 +469,17 @@ Prints info of a record lock. */
void
lock_rec_print(
/*===========*/
+ char* buf, /* in/out: buffer where to print, must be at least
+ 500 bytes */
lock_t* lock); /* in: record type lock */
/*************************************************************************
Prints info of locks for all transactions. */
void
-lock_print_info(void);
-/*=================*/
+lock_print_info(
+/*============*/
+ char* buf, /* in/out: buffer where to print */
+ char* buf_end);/* in: buffer end */
/*************************************************************************
Validates the lock queue on a table. */
diff --git a/innobase/include/log0log.h b/innobase/include/log0log.h
index d4bd0036c5a..5d848b85658 100644
--- a/innobase/include/log0log.h
+++ b/innobase/include/log0log.h
@@ -493,8 +493,10 @@ log_block_convert_lsn_to_no(
Prints info of the log. */
void
-log_print(void);
-/*===========*/
+log_print(
+/*======*/
+ char* buf, /* in/out: buffer where to print */
+ char* buf_end);/* in: buffer end */
extern log_t* log_sys;
diff --git a/innobase/include/os0file.h b/innobase/include/os0file.h
index d4d12e4a9d9..b7911c5014a 100644
--- a/innobase/include/os0file.h
+++ b/innobase/include/os0file.h
@@ -403,8 +403,10 @@ os_aio_validate(void);
Prints info of the aio arrays. */
void
-os_aio_print(void);
-/*==============*/
+os_aio_print(
+/*=========*/
+ char* buf, /* in/out: buffer where to print */
+ char* buf_end);/* in: buffer end */
/**************************************************************************
Checks that all slots in the system have been freed, that is, there are
no pending io operations. */
diff --git a/innobase/include/rem0rec.ic b/innobase/include/rem0rec.ic
index 6b96e3056fa..aaa3c58a003 100644
--- a/innobase/include/rem0rec.ic
+++ b/innobase/include/rem0rec.ic
@@ -970,8 +970,6 @@ rec_fold(
ut_ad(n_fields <= rec_get_n_fields(rec));
ut_ad((n_fields < rec_get_n_fields(rec)) || (n_bytes == 0));
ut_ad(n_fields + n_bytes > 0);
- /* Only the page supremum and infimum records have 1 field: */
- ut_ad(rec_get_n_fields(rec) > 1);
n_fields_rec = rec_get_n_fields(rec);
diff --git a/innobase/include/srv0srv.h b/innobase/include/srv0srv.h
index 903dd9afc90..1f76974b03d 100644
--- a/innobase/include/srv0srv.h
+++ b/innobase/include/srv0srv.h
@@ -356,6 +356,14 @@ srv_error_monitor_thread(
/* out: a dummy parameter */
void* arg); /* in: a dummy parameter required by
os_thread_create */
+/**********************************************************************
+Sprintfs to a buffer the output of the InnoDB Monitor. */
+
+void
+srv_sprintf_innodb_monitor(
+/*=======================*/
+ char* buf, /* in/out: buffer which must be at least 4 kB */
+ ulint len); /* in: length of the buffer */
/* Types for the threads existing in the system. Threads of types 4 - 9
diff --git a/innobase/include/sync0arr.h b/innobase/include/sync0arr.h
index f0134894997..765ad33afea 100644
--- a/innobase/include/sync0arr.h
+++ b/innobase/include/sync0arr.h
@@ -114,6 +114,8 @@ Prints info of the wait array. */
void
sync_array_print_info(
/*==================*/
+ char* buf, /* in/out: buffer where to print */
+ char* buf_end,/* in: buffer end */
sync_array_t* arr); /* in: wait array */
diff --git a/innobase/include/sync0sync.h b/innobase/include/sync0sync.h
index 4f55709a5d7..5bfa0bc2d48 100644
--- a/innobase/include/sync0sync.h
+++ b/innobase/include/sync0sync.h
@@ -117,14 +117,18 @@ FUNCTION PROTOTYPES FOR DEBUGGING */
Prints wait info of the sync system. */
void
-sync_print_wait_info(void);
-/*======================*/
+sync_print_wait_info(
+/*=================*/
+ char* buf, /* in/out: buffer where to print */
+ char* buf_end); /* in: buffer end */
/***********************************************************************
Prints info of the sync system. */
void
-sync_print(void);
-/*============*/
+sync_print(
+/*=======*/
+ char* buf, /* in/out: buffer where to print */
+ char* buf_end); /* in: buffer end */
/**********************************************************************
Checks that the mutex has been initialized. */
diff --git a/innobase/include/trx0trx.h b/innobase/include/trx0trx.h
index 090473f3a5a..83789966514 100644
--- a/innobase/include/trx0trx.h
+++ b/innobase/include/trx0trx.h
@@ -261,7 +261,9 @@ own the kernel mutex. */
void
trx_print(
/*======*/
- trx_t* trx); /* in: transaction */
+ char* buf, /* in/out: buffer where to print, must be at least
+ 500 bytes */
+ trx_t* trx); /* in: transaction */
/* Signal to a transaction */
diff --git a/innobase/lock/lock0lock.c b/innobase/lock/lock0lock.c
index 1bdbf72bda6..f7ba49004d7 100644
--- a/innobase/lock/lock0lock.c
+++ b/innobase/lock/lock0lock.c
@@ -3326,34 +3326,37 @@ Prints info of a table lock. */
void
lock_table_print(
/*=============*/
+ char* buf, /* in/out: buffer where to print, must be at least
+ 500 bytes */
lock_t* lock) /* in: table type lock */
{
ut_ad(mutex_own(&kernel_mutex));
ut_a(lock_get_type(lock) == LOCK_TABLE);
- printf("TABLE LOCK table %s trx id %lu %lu",
+ buf += sprintf(buf, "TABLE LOCK table %s trx id %lu %lu",
lock->un_member.tab_lock.table->name,
(lock->trx)->id.high, (lock->trx)->id.low);
if (lock_get_mode(lock) == LOCK_S) {
- printf(" lock mode S");
+ buf += sprintf(buf, " lock mode S");
} else if (lock_get_mode(lock) == LOCK_X) {
- printf(" lock_mode X");
+ buf += sprintf(buf, " lock_mode X");
} else if (lock_get_mode(lock) == LOCK_IS) {
- printf(" lock_mode IS");
+ buf += sprintf(buf, " lock_mode IS");
} else if (lock_get_mode(lock) == LOCK_IX) {
- printf(" lock_mode IX");
+ buf += sprintf(buf, " lock_mode IX");
} else if (lock_get_mode(lock) == LOCK_AUTO_INC) {
- printf(" lock_mode AUTO-INC");
+ buf += sprintf(buf, " lock_mode AUTO-INC");
} else {
- printf(" unknown lock_mode %lu", lock_get_mode(lock));
+ buf += sprintf(buf,
+ " unknown lock_mode %lu", lock_get_mode(lock));
}
if (lock_get_wait(lock)) {
- printf(" waiting");
+ buf += sprintf(buf, " waiting");
}
- printf("\n");
+ buf += sprintf(buf, "\n");
}
/*************************************************************************
@@ -3362,6 +3365,8 @@ Prints info of a record lock. */
void
lock_rec_print(
/*===========*/
+ char* buf, /* in/out: buffer where to print, must be at least
+ 500 bytes */
lock_t* lock) /* in: record type lock */
{
page_t* page;
@@ -3369,8 +3374,7 @@ lock_rec_print(
ulint page_no;
ulint i;
ulint count = 0;
- ulint len;
- char buf[200];
+ char* buf_start = buf;
mtr_t mtr;
ut_ad(mutex_own(&kernel_mutex));
@@ -3379,32 +3383,32 @@ lock_rec_print(
space = lock->un_member.rec_lock.space;
page_no = lock->un_member.rec_lock.page_no;
- printf("RECORD LOCKS space id %lu page no %lu n bits %lu",
+ buf += sprintf(buf, "RECORD LOCKS space id %lu page no %lu n bits %lu",
space, page_no, lock_rec_get_n_bits(lock));
- printf(" table %s index %s trx id %lu %lu",
+ buf += sprintf(buf, " table %s index %s trx id %lu %lu",
lock->index->table->name, lock->index->name,
(lock->trx)->id.high, (lock->trx)->id.low);
if (lock_get_mode(lock) == LOCK_S) {
- printf(" lock mode S");
+ buf += sprintf(buf, " lock mode S");
} else if (lock_get_mode(lock) == LOCK_X) {
- printf(" lock_mode X");
+ buf += sprintf(buf, " lock_mode X");
} else {
ut_error;
}
if (lock_rec_get_gap(lock)) {
- printf(" gap type lock");
+ buf += sprintf(buf, " gap type lock");
}
if (lock_get_wait(lock)) {
- printf(" waiting");
+ buf += sprintf(buf, " waiting");
}
mtr_start(&mtr);
- printf("\n");
+ buf += sprintf(buf, "\n");
/* If the page is not in the buffer pool, we cannot load it
because we have the kernel mutex and ibuf operations would
@@ -3423,28 +3427,28 @@ lock_rec_print(
for (i = 0; i < lock_rec_get_n_bits(lock); i++) {
+ if (buf - buf_start > 300) {
+
+ buf += sprintf(buf,
+ "Suppressing further record lock prints for this page\n");
+ return;
+ }
+
if (lock_rec_get_nth_bit(lock, i)) {
- printf("Record lock, heap no %lu ", i);
+ buf += sprintf(buf, "Record lock, heap no %lu ", i);
if (page) {
- len = rec_sprintf(buf, 190,
+ buf += rec_sprintf(buf, 120,
page_find_rec_with_heap_no(page, i));
- buf[len] = '\0';
- printf("%s", buf);
+ *buf = '\0';
}
- printf("\n");
+ buf += sprintf(buf, "\n");
count++;
}
-
- if (count >= 3) {
- printf(
- "3 LOCKS PRINTED FOR THIS TRX AND PAGE: SUPPRESSING FURTHER PRINTS\n");
- goto end_prints;
- }
}
-end_prints:
+
mtr_commit(&mtr);
}
@@ -3479,8 +3483,10 @@ lock_get_n_rec_locks(void)
Prints info of locks for all transactions. */
void
-lock_print_info(void)
-/*=================*/
+lock_print_info(
+/*============*/
+ char* buf, /* in/out: buffer where to print */
+ char* buf_end)/* in: buffer end */
{
lock_t* lock;
trx_t* trx;
@@ -3493,11 +3499,15 @@ lock_print_info(void)
ulint i;
mtr_t mtr;
- printf("Trx id counter %lu %lu\n",
+ if (buf_end - buf < 600) {
+ return;
+ }
+
+ buf += sprintf(buf, "Trx id counter %lu %lu\n",
ut_dulint_get_high(trx_sys->max_trx_id),
ut_dulint_get_low(trx_sys->max_trx_id));
- printf(
+ buf += sprintf(buf,
"Purge done for trx's n:o < %lu %lu undo n:o < %lu %lu\n",
ut_dulint_get_high(purge_sys->purge_trx_no),
ut_dulint_get_low(purge_sys->purge_trx_no),
@@ -3506,7 +3516,8 @@ lock_print_info(void)
lock_mutex_enter_kernel();
- printf("Total number of lock structs in row lock hash table %lu\n",
+ buf += sprintf(buf,
+ "Total number of lock structs in row lock hash table %lu\n",
lock_get_n_rec_locks());
/* First print info on non-active transactions */
@@ -3514,9 +3525,15 @@ lock_print_info(void)
trx = UT_LIST_GET_FIRST(trx_sys->mysql_trx_list);
while (trx) {
+ if (buf_end - buf < 600) {
+ return;
+ }
+
if (trx->conc_state == TRX_NOT_STARTED) {
- printf("---");
- trx_print(trx);
+ buf += sprintf(buf, "---");
+ trx_print(buf, trx);
+
+ buf += strlen(buf);
}
trx = UT_LIST_GET_NEXT(mysql_trx_list, trx);
@@ -3545,12 +3562,22 @@ loop:
return;
}
+ if (buf_end - buf < 600) {
+ return;
+ }
+
if (nth_lock == 0) {
- printf("---");
- trx_print(trx);
+ buf += sprintf(buf, "---");
+ trx_print(buf, trx);
+ buf += strlen(buf);
+
+ if (buf_end - buf < 500) {
+ return;
+ }
+
if (trx->read_view) {
- printf(
+ buf += sprintf(buf,
"Trx read view will not see trx with id >= %lu %lu, sees < %lu %lu\n",
ut_dulint_get_high(trx->read_view->low_limit_id),
ut_dulint_get_low(trx->read_view->low_limit_id),
@@ -3559,16 +3586,17 @@ loop:
}
if (trx->que_state == TRX_QUE_LOCK_WAIT) {
- printf(
+ buf += sprintf(buf,
"------------------TRX IS WAITING FOR THE LOCK:\n");
if (lock_get_type(trx->wait_lock) == LOCK_REC) {
- lock_rec_print(trx->wait_lock);
+ lock_rec_print(buf, trx->wait_lock);
} else {
- lock_table_print(trx->wait_lock);
+ lock_table_print(buf, trx->wait_lock);
}
- printf(
+ buf += strlen(buf);
+ buf += sprintf(buf,
"------------------\n");
}
}
@@ -3597,6 +3625,10 @@ loop:
goto loop;
}
+ if (buf_end - buf < 500) {
+ return;
+ }
+
if (lock_get_type(lock) == LOCK_REC) {
space = lock->un_member.rec_lock.space;
page_no = lock->un_member.rec_lock.page_no;
@@ -3617,19 +3649,21 @@ loop:
goto loop;
}
- lock_rec_print(lock);
+ lock_rec_print(buf, lock);
} else {
ut_ad(lock_get_type(lock) == LOCK_TABLE);
- lock_table_print(lock);
+ lock_table_print(buf, lock);
}
+ buf += strlen(buf);
+
load_page_first = TRUE;
nth_lock++;
if (nth_lock >= 10) {
- printf(
+ buf += sprintf(buf,
"10 LOCKS PRINTED FOR THIS TRX: SUPPRESSING FURTHER PRINTS\n");
nth_trx++;
diff --git a/innobase/log/log0log.c b/innobase/log/log0log.c
index d6e9deaa151..9d79c19a586 100644
--- a/innobase/log/log0log.c
+++ b/innobase/log/log0log.c
@@ -3081,15 +3081,22 @@ log_check_log_recs(
Prints info of the log. */
void
-log_print(void)
-/*===========*/
+log_print(
+/*======*/
+ char* buf, /* in/out: buffer where to print */
+ char* buf_end)/* in: buffer end */
{
double time_elapsed;
time_t current_time;
+ if (buf_end - buf < 300) {
+
+ return;
+ }
+
mutex_enter(&(log_sys->mutex));
- printf("Log sequence number %lu %lu\n"
+ buf += sprintf(buf, "Log sequence number %lu %lu\n"
"Log flushed up to %lu %lu\n"
"Last checkpoint at %lu %lu\n",
ut_dulint_get_high(log_sys->lsn),
@@ -3103,7 +3110,7 @@ log_print(void)
time_elapsed = difftime(current_time, log_sys->last_printout_time);
- printf(
+ buf += sprintf(buf,
"%lu pending log writes, %lu pending chkp writes\n"
"%lu log i/o's done, %.2f log i/o's/second\n",
log_sys->n_pending_writes,
diff --git a/innobase/os/os0file.c b/innobase/os/os0file.c
index e98b9e95cf7..34e13b80c58 100644
--- a/innobase/os/os0file.c
+++ b/innobase/os/os0file.c
@@ -1094,7 +1094,9 @@ os_file_write(
fprintf(stderr,
" InnoDB: Error: File pointer positioning to file %s failed at\n"
-"InnoDB: offset %lu %lu. Operating system error number %lu.\n",
+"InnoDB: offset %lu %lu. Operating system error number %lu.\n"
+"InnoDB: Look from section 13.2 at http://www.innodb.com/ibman.html\n"
+"InnoDB: what the error number means.\n",
name, offset_high, offset,
(ulint)GetLastError());
@@ -1125,8 +1127,10 @@ os_file_write(
" InnoDB: Error: Write to file %s failed at offset %lu %lu.\n"
"InnoDB: %lu bytes should have been written, only %lu were written.\n"
"InnoDB: Operating system error number %lu.\n"
+"InnoDB: Look from section 13.2 at http://www.innodb.com/ibman.html\n"
+"InnoDB: what the error number means.\n"
"InnoDB: Check that your OS and file system support files of this size.\n"
-"InnoDB: Check also the disk is not full or a disk quota exceeded.\n",
+"InnoDB: Check also that the disk is not full or a disk quota exceeded.\n",
name, offset_high, offset, n, len,
(ulint)GetLastError());
@@ -1152,8 +1156,10 @@ os_file_write(
" InnoDB: Error: Write to file %s failed at offset %lu %lu.\n"
"InnoDB: %lu bytes should have been written, only %lu were written.\n"
"InnoDB: Operating system error number %lu.\n"
+"InnoDB: Look from section 13.2 at http://www.innodb.com/ibman.html\n"
+"InnoDB: what the error number means or use the perror program of MySQL.\n"
"InnoDB: Check that your OS and file system support files of this size.\n"
-"InnoDB: Check also the disk is not full or a disk quota exceeded.\n",
+"InnoDB: Check also that the disk is not full or a disk quota exceeded.\n",
name, offset_high, offset, n, (ulint)ret,
(ulint)errno);
os_has_said_disk_full = TRUE;
@@ -1744,7 +1750,6 @@ os_aio(
ut_ad(buf);
ut_ad(n > 0);
ut_ad(n % OS_FILE_LOG_BLOCK_SIZE == 0);
- ut_ad((ulint)buf % OS_FILE_LOG_BLOCK_SIZE == 0)
ut_ad(offset % OS_FILE_LOG_BLOCK_SIZE == 0);
ut_ad(os_aio_validate());
@@ -2388,8 +2393,10 @@ os_aio_validate(void)
Prints info of the aio arrays. */
void
-os_aio_print(void)
-/*==============*/
+os_aio_print(
+/*=========*/
+ char* buf, /* in/out: buffer where to print */
+ char* buf_end)/* in: buffer end */
{
os_aio_array_t* array;
os_aio_slot_t* slot;
@@ -2399,12 +2406,17 @@ os_aio_print(void)
double avg_bytes_read;
ulint i;
+ if (buf_end - buf < 1000) {
+
+ return;
+ }
+
for (i = 0; i < srv_n_file_io_threads; i++) {
- printf("I/O thread %lu state: %s\n", i,
+ buf += sprintf(buf, "I/O thread %lu state: %s\n", i,
srv_io_thread_op_info[i]);
}
- printf("Pending normal aio reads:");
+ buf += sprintf(buf, "Pending normal aio reads:");
array = os_aio_read_array;
loop:
@@ -2431,12 +2443,12 @@ loop:
ut_a(array->n_reserved == n_reserved);
- printf(" %lu", n_reserved);
+ buf += sprintf(buf, " %lu", n_reserved);
os_mutex_exit(array->mutex);
if (array == os_aio_read_array) {
- printf(", aio writes:");
+ buf += sprintf(buf, ", aio writes:");
array = os_aio_write_array;
@@ -2444,34 +2456,36 @@ loop:
}
if (array == os_aio_write_array) {
- printf(",\n ibuf aio reads:");
+ buf += sprintf(buf, ",\n ibuf aio reads:");
array = os_aio_ibuf_array;
goto loop;
}
if (array == os_aio_ibuf_array) {
- printf(", log i/o's:");
+ buf += sprintf(buf, ", log i/o's:");
array = os_aio_log_array;
goto loop;
}
if (array == os_aio_log_array) {
- printf(", sync i/o's:");
+ buf += sprintf(buf, ", sync i/o's:");
array = os_aio_sync_array;
goto loop;
}
- printf("\n");
+ buf += sprintf(buf, "\n");
current_time = time(NULL);
time_elapsed = difftime(current_time, os_last_printout);
- printf("Pending flushes (fsync) log: %lu; buffer pool: %lu\n",
+ buf += sprintf(buf,
+ "Pending flushes (fsync) log: %lu; buffer pool: %lu\n",
fil_n_pending_log_flushes, fil_n_pending_tablespace_flushes);
- printf("%lu OS file reads, %lu OS file writes, %lu OS fsyncs\n",
+ buf += sprintf(buf,
+ "%lu OS file reads, %lu OS file writes, %lu OS fsyncs\n",
os_n_file_reads, os_n_file_writes, os_n_fsyncs);
if (os_n_file_reads == os_n_file_reads_old) {
@@ -2481,7 +2495,7 @@ loop:
(os_n_file_reads - os_n_file_reads_old);
}
- printf(
+ buf += sprintf(buf,
"%.2f reads/s, %lu avg bytes/read, %.2f writes/s, %.2f fsyncs/s\n",
(os_n_file_reads - os_n_file_reads_old)
/ time_elapsed,
diff --git a/innobase/row/row0mysql.c b/innobase/row/row0mysql.c
index b05476e0a3d..638df1b6380 100644
--- a/innobase/row/row0mysql.c
+++ b/innobase/row/row0mysql.c
@@ -2416,6 +2416,14 @@ row_check_table_for_mysql(
index = dict_table_get_next_index(index);
}
+ /* We validate also the whole adaptive hash index for all tables
+ at every CHECK TABLE */
+
+ if (!btr_search_validate()) {
+
+ ret = DB_ERROR;
+ }
+
prebuilt->trx->op_info = "";
return(ret);
diff --git a/innobase/row/row0umod.c b/innobase/row/row0umod.c
index 9e8ba87fc2f..bbffda39352 100644
--- a/innobase/row/row0umod.c
+++ b/innobase/row/row0umod.c
@@ -437,11 +437,12 @@ row_undo_mod_del_unmark_sec(
rec_sprintf(err_buf, 900, btr_pcur_get_rec(&pcur));
fprintf(stderr, "InnoDB: record %s\n", err_buf);
+ trx_print(err_buf, thr_get_trx(thr));
fprintf(stderr,
- "InnoDB: Make a detailed bug report and send it\n");
+ "%s\nInnoDB: Make a detailed bug report and send it\n",
+ err_buf);
fprintf(stderr, "InnoDB: to mysql@lists.mysql.com\n");
- trx_print(thr_get_trx(thr));
} else {
btr_cur = btr_pcur_get_btr_cur(&pcur);
diff --git a/innobase/row/row0upd.c b/innobase/row/row0upd.c
index 77af2390786..6eaab79060e 100644
--- a/innobase/row/row0upd.c
+++ b/innobase/row/row0upd.c
@@ -1095,11 +1095,12 @@ row_upd_sec_index_entry(
rec_sprintf(err_buf, 900, rec);
fprintf(stderr, "InnoDB: record %s\n", err_buf);
+ trx_print(err_buf, thr_get_trx(thr));
+
fprintf(stderr,
- "InnoDB: Make a detailed bug report and send it\n");
+ "%s\nInnoDB: Make a detailed bug report and send it\n",
+ err_buf);
fprintf(stderr, "InnoDB: to mysql@lists.mysql.com\n");
-
- trx_print(thr_get_trx(thr));
} else {
/* Delete mark the old index record; it can already be
delete marked if we return after a lock wait in
diff --git a/innobase/srv/srv0srv.c b/innobase/srv/srv0srv.c
index 19e2b08d5a6..81b3333cbe8 100644
--- a/innobase/srv/srv0srv.c
+++ b/innobase/srv/srv0srv.c
@@ -272,6 +272,8 @@ i/o handler thread */
char* srv_io_thread_op_info[SRV_MAX_N_IO_THREADS];
+time_t srv_last_monitor_time;
+
/*
IMPLEMENTATION OF THE SERVER MAIN PROGRAM
=========================================
@@ -2131,106 +2133,106 @@ srv_release_mysql_thread_if_suspended(
/* not found */
}
-/*************************************************************************
-A thread which wakes up threads whose lock wait may have lasted too long.
-This also prints the info output by various InnoDB monitors. */
+/**********************************************************************
+Sprintfs to a buffer the output of the InnoDB Monitor. */
-#ifndef __WIN__
-void*
-#else
-ulint
-#endif
-srv_lock_timeout_and_monitor_thread(
-/*================================*/
- /* out: a dummy parameter */
- void* arg) /* in: a dummy parameter required by
- os_thread_create */
+void
+srv_sprintf_innodb_monitor(
+/*=======================*/
+ char* buf, /* in/out: buffer which must be at least 4 kB */
+ ulint len) /* in: length of the buffer */
{
- srv_slot_t* slot;
- double time_elapsed;
- time_t current_time;
- time_t last_monitor_time;
- time_t last_table_monitor_time;
- ibool some_waits;
- double wait_time;
- ulint i;
+ char* buf_end = buf + len - 2000;
+ double time_elapsed;
+ time_t current_time;
- UT_NOT_USED(arg);
- last_monitor_time = time(NULL);
- last_table_monitor_time = time(NULL);
-loop:
- srv_lock_timeout_and_monitor_active = TRUE;
-
- /* When someone is waiting for a lock, we wake up every second
- and check if a timeout has passed for a lock wait */
-
- os_thread_sleep(1000000);
+ current_time = time(NULL);
- /* In case mutex_exit is not a memory barrier, it is
- theoretically possible some threads are left waiting though
- the semaphore is already released. Wake up those threads: */
-
- sync_arr_wake_threads_if_sema_free();
+ time_elapsed = difftime(current_time, srv_last_monitor_time);
- current_time = time(NULL);
+ srv_last_monitor_time = time(NULL);
- time_elapsed = difftime(current_time, last_monitor_time);
-
- if (time_elapsed > 15) {
+ ut_a(len >= 4096);
- if (srv_print_innodb_monitor) {
+ buf += sprintf(buf, "\n=====================================\n");
- last_monitor_time = time(NULL);
+ ut_sprintf_timestamp(buf);
+ buf = buf + strlen(buf);
- printf("=====================================\n");
- ut_print_timestamp(stdout);
-
- printf(" INNODB MONITOR OUTPUT\n"
+ buf += sprintf(buf, " INNODB MONITOR OUTPUT\n"
"=====================================\n");
- printf("----------\n"
+
+ buf += sprintf(buf,
+"Per second values calculated from the last %lu seconds\n",
+ (ulint)time_elapsed);
+
+ buf += sprintf(buf, "----------\n"
"SEMAPHORES\n"
"----------\n");
- sync_print();
- printf("------------\n"
+ sync_print(buf, buf_end);
+
+ buf = buf + strlen(buf);
+
+ buf += sprintf(buf, "------------\n"
"TRANSACTIONS\n"
"------------\n");
- lock_print_info();
- printf("--------\n"
+ lock_print_info(buf, buf_end);
+ buf = buf + strlen(buf);
+
+ buf += sprintf(buf, "--------\n"
"FILE I/O\n"
"--------\n");
- os_aio_print();
- printf("-------------------------------------\n"
+ os_aio_print(buf, buf_end);
+ buf = buf + strlen(buf);
+
+ buf += sprintf(buf, "-------------------------------------\n"
"INSERT BUFFER AND ADAPTIVE HASH INDEX\n"
"-------------------------------------\n");
- ibuf_print();
- printf("Successful hash searches %lu, non-hash searches %lu\n",
- btr_cur_n_sea, btr_cur_n_non_sea);
- printf("---\n"
+ ibuf_print(buf, buf_end);
+ buf = buf + strlen(buf);
+
+ ha_print_info(buf, buf_end, btr_search_sys->hash_index);
+ buf = buf + strlen(buf);
+
+ buf += sprintf(buf,
+ "%.2f hash searches/s, %.2f non-hash searches/s\n",
+ (btr_cur_n_sea - btr_cur_n_sea_old)
+ / time_elapsed,
+ (btr_cur_n_non_sea - btr_cur_n_non_sea_old)
+ / time_elapsed);
+ btr_cur_n_sea_old = btr_cur_n_sea;
+ btr_cur_n_non_sea_old = btr_cur_n_non_sea;
+
+ buf += sprintf(buf,"---\n"
"LOG\n"
"---\n");
- log_print();
- printf("----------------------\n"
+ log_print(buf, buf_end);
+ buf = buf + strlen(buf);
+
+ buf += sprintf(buf, "----------------------\n"
"BUFFER POOL AND MEMORY\n"
"----------------------\n");
- printf(
+ buf += sprintf(buf,
"Total memory allocated %lu; in additional pool allocated %lu\n",
ut_total_allocated_memory,
mem_pool_get_reserved(mem_comm_pool));
- buf_print_io();
- printf("--------------\n"
+ buf_print_io(buf, buf_end);
+ buf = buf + strlen(buf);
+
+ buf += sprintf(buf, "--------------\n"
"ROW OPERATIONS\n"
"--------------\n");
- printf(
+ buf += sprintf(buf,
"%ld queries inside InnoDB, %ld queries in queue; main thread: %s\n",
srv_conc_n_threads, srv_conc_n_waiting_threads,
srv_main_thread_op_info);
- printf(
+ buf += sprintf(buf,
"Number of rows inserted %lu, updated %lu, deleted %lu, read %lu\n",
srv_n_rows_inserted,
srv_n_rows_updated,
srv_n_rows_deleted,
srv_n_rows_read);
- printf(
+ buf += sprintf(buf,
"%.2f inserts/s, %.2f updates/s, %.2f deletes/s, %.2f reads/s\n",
(srv_n_rows_inserted - srv_n_rows_inserted_old)
/ time_elapsed,
@@ -2246,9 +2248,70 @@ loop:
srv_n_rows_deleted_old = srv_n_rows_deleted;
srv_n_rows_read_old = srv_n_rows_read;
- printf("----------------------------\n"
+ buf += sprintf(buf, "----------------------------\n"
"END OF INNODB MONITOR OUTPUT\n"
"============================\n");
+}
+
+/*************************************************************************
+A thread which wakes up threads whose lock wait may have lasted too long.
+This also prints the info output by various InnoDB monitors. */
+
+#ifndef __WIN__
+void*
+#else
+ulint
+#endif
+srv_lock_timeout_and_monitor_thread(
+/*================================*/
+ /* out: a dummy parameter */
+ void* arg) /* in: a dummy parameter required by
+ os_thread_create */
+{
+ srv_slot_t* slot;
+ double time_elapsed;
+ time_t current_time;
+ time_t last_table_monitor_time;
+ time_t last_monitor_time;
+ ibool some_waits;
+ double wait_time;
+ char* buf;
+ ulint i;
+
+ UT_NOT_USED(arg);
+ srv_last_monitor_time = time(NULL);
+ last_table_monitor_time = time(NULL);
+ last_monitor_time = time(NULL);
+loop:
+ srv_lock_timeout_and_monitor_active = TRUE;
+
+ /* When someone is waiting for a lock, we wake up every second
+ and check if a timeout has passed for a lock wait */
+
+ os_thread_sleep(1000000);
+
+ /* In case mutex_exit is not a memory barrier, it is
+ theoretically possible some threads are left waiting though
+ the semaphore is already released. Wake up those threads: */
+
+ sync_arr_wake_threads_if_sema_free();
+
+ current_time = time(NULL);
+
+ time_elapsed = difftime(current_time, last_monitor_time);
+
+ if (time_elapsed > 15) {
+ last_monitor_time = time(NULL);
+
+ if (srv_print_innodb_monitor) {
+
+ buf = mem_alloc(100000);
+
+ srv_sprintf_innodb_monitor(buf, 100000);
+
+ printf("%s", buf);
+
+ mem_free(buf);
}
if (srv_print_innodb_tablespace_monitor
@@ -2380,7 +2443,13 @@ loop:
srv_error_monitor_active = TRUE;
os_thread_sleep(10000000);
+ /*
+ printf("Validating has index\n");
+
+ btr_search_validate();
+ printf("Hash index validated\n");
+ */
sync_array_print_long_waits();
/* Flush stdout and stderr so that a database user gets their output
diff --git a/innobase/srv/srv0start.c b/innobase/srv/srv0start.c
index ff4c4f021b0..9768d484ce6 100644
--- a/innobase/srv/srv0start.c
+++ b/innobase/srv/srv0start.c
@@ -896,7 +896,7 @@ test_measure_cont(
"Mutex res. l %lu, p %lu, k %lu s x %lu s s %lu s mut %lu of %lu\n",
lcount, pcount, kcount, s_xcount, s_scount, s_mcount, j);
- sync_print_wait_info();
+/* sync_print_wait_info(); */
fprintf(stderr,
"log i/o %lu n non sea %lu n succ %lu n h fail %lu\n",
diff --git a/innobase/sync/sync0arr.c b/innobase/sync/sync0arr.c
index 7788b104120..81b5b7de195 100644
--- a/innobase/sync/sync0arr.c
+++ b/innobase/sync/sync0arr.c
@@ -441,7 +441,8 @@ static
void
sync_array_cell_print(
/*==================*/
- FILE* file, /* in: file where to print */
+ char* buf, /* in: buffer where to print, must be
+ at least 400 characters */
sync_cell_t* cell) /* in: sync cell */
{
mutex_t* mutex;
@@ -451,7 +452,7 @@ sync_array_cell_print(
type = cell->request_type;
- fprintf(file,
+ buf += sprintf(buf,
"--Thread %lu has waited at %s line %lu for %.2f seconds the semaphore:\n",
(ulint)cell->thread, cell->file, cell->line,
difftime(time(NULL), cell->reservation_time));
@@ -461,54 +462,58 @@ sync_array_cell_print(
been freed meanwhile */
mutex = cell->old_wait_mutex;
- fprintf(file,
+ buf += sprintf(buf,
"Mutex at %lx created file %s line %lu, lock var %lu\n",
(ulint)mutex, mutex->cfile_name, mutex->cline,
mutex->lock_word);
- fprintf(file,
+ buf += sprintf(buf,
"Last time reserved in file %s line %lu, waiters flag %lu\n",
mutex->file_name, mutex->line, mutex->waiters);
} else if (type == RW_LOCK_EX || type == RW_LOCK_SHARED) {
if (type == RW_LOCK_EX) {
- fprintf(file, "X-lock on");
+ buf += sprintf(buf, "X-lock on");
} else {
- fprintf(file, "S-lock on");
+ buf += sprintf(buf, "S-lock on");
}
rwlock = cell->old_wait_rw_lock;
- fprintf(file, " RW-latch at %lx created in file %s line %lu\n",
+ buf += sprintf(buf,
+ " RW-latch at %lx created in file %s line %lu\n",
(ulint)rwlock, rwlock->cfile_name, rwlock->cline);
if (rwlock->writer != RW_LOCK_NOT_LOCKED) {
- fprintf(file,
+ buf += sprintf(buf,
"a writer (thread id %lu) has reserved it in mode",
(ulint)rwlock->writer_thread);
if (rwlock->writer == RW_LOCK_EX) {
- fprintf(file, " exclusive\n");
+ buf += sprintf(buf, " exclusive\n");
} else {
- fprintf(file, " wait exclusive\n");
+ buf += sprintf(buf, " wait exclusive\n");
}
}
- fprintf(file, "number of readers %lu, waiters flag %lu\n",
+ buf += sprintf(buf,
+ "number of readers %lu, waiters flag %lu\n",
rwlock->reader_count, rwlock->waiters);
- fprintf(file, "Last time read locked in file %s line %lu\n",
+ buf += sprintf(buf,
+ "Last time read locked in file %s line %lu\n",
rwlock->last_s_file_name, rwlock->last_s_line);
- fprintf(file, "Last time write locked in file %s line %lu\n",
+ buf += sprintf(buf,
+ "Last time write locked in file %s line %lu\n",
rwlock->last_x_file_name, rwlock->last_x_line);
} else {
ut_error;
}
if (!cell->waiting) {
- fprintf(file, "wait has ended\n");
+ buf += sprintf(buf, "wait has ended\n");
}
if (cell->event_set) {
- fprintf(file, "wait is ending\n");
+ buf += sprintf(buf, "wait is ending\n");
}
}
@@ -610,6 +615,7 @@ sync_array_detect_deadlock(
os_thread_id_t thread;
ibool ret;
rw_lock_debug_t* debug;
+ char buf[500];
ut_a(arr && start && cell);
ut_ad(cell->wait_object);
@@ -642,11 +648,12 @@ sync_array_detect_deadlock(
ret = sync_array_deadlock_step(arr, start, thread, 0,
depth);
if (ret) {
+ sync_array_cell_print(buf, cell);
printf(
- "Mutex %lx owned by thread %lu file %s line %lu\n",
+ "Mutex %lx owned by thread %lu file %s line %lu\n%s",
(ulint)mutex, mutex->thread_id,
- mutex->file_name, mutex->line);
- sync_array_cell_print(stdout, cell);
+ mutex->file_name, mutex->line,
+ buf);
return(TRUE);
}
}
@@ -678,9 +685,9 @@ sync_array_detect_deadlock(
debug->pass,
depth);
if (ret) {
- printf("rw-lock %lx ", (ulint) lock);
+ sync_array_cell_print(buf, cell);
+ printf("rw-lock %lx %s ", (ulint) lock, buf);
rw_lock_debug_print(debug);
- sync_array_cell_print(stdout, cell);
return(TRUE);
}
@@ -711,9 +718,9 @@ sync_array_detect_deadlock(
debug->pass,
depth);
if (ret) {
- printf("rw-lock %lx ", (ulint) lock);
+ sync_array_cell_print(buf, cell);
+ printf("rw-lock %lx %s ", (ulint) lock, buf);
rw_lock_debug_print(debug);
- sync_array_cell_print(stdout, cell);
return(TRUE);
}
@@ -898,6 +905,7 @@ sync_array_print_long_waits(void)
sync_cell_t* cell;
ibool old_val;
ibool noticed = FALSE;
+ char buf[500];
ulint i;
for (i = 0; i < sync_primary_wait_array->n_cells; i++) {
@@ -907,9 +915,10 @@ sync_array_print_long_waits(void)
if (cell->wait_object != NULL
&& difftime(time(NULL), cell->reservation_time) > 240) {
+ sync_array_cell_print(buf, cell);
+
fprintf(stderr,
- "InnoDB: Warning: a long semaphore wait:\n");
- sync_array_cell_print(stderr, cell);
+ "InnoDB: Warning: a long semaphore wait:\n%s", buf);
noticed = TRUE;
}
@@ -948,6 +957,8 @@ static
void
sync_array_output_info(
/*===================*/
+ char* buf, /* in/out: buffer where to print */
+ char* buf_end,/* in: buffer end */
sync_array_t* arr) /* in: wait array; NOTE! caller must own the
mutex */
{
@@ -955,18 +966,29 @@ sync_array_output_info(
ulint count;
ulint i;
- printf("OS WAIT ARRAY INFO: reservation count %ld, signal count %ld\n",
+ if (buf_end - buf < 500) {
+ return;
+ }
+
+ buf += sprintf(buf,
+ "OS WAIT ARRAY INFO: reservation count %ld, signal count %ld\n",
arr->res_count, arr->sg_count);
i = 0;
count = 0;
while (count < arr->n_reserved) {
+ if (buf_end - buf < 500) {
+ return;
+ }
+
cell = sync_array_get_nth_cell(arr, i);
if (cell->wait_object != NULL) {
count++;
- sync_array_cell_print(stdout, cell);
+ sync_array_cell_print(buf, cell);
+
+ buf = buf + strlen(buf);
}
i++;
@@ -979,11 +1001,13 @@ Prints info of the wait array. */
void
sync_array_print_info(
/*==================*/
+ char* buf, /* in/out: buffer where to print */
+ char* buf_end,/* in: buffer end */
sync_array_t* arr) /* in: wait array */
{
sync_array_enter(arr);
- sync_array_output_info(arr);
+ sync_array_output_info(buf, buf_end, arr);
sync_array_exit(arr);
}
diff --git a/innobase/sync/sync0sync.c b/innobase/sync/sync0sync.c
index f5b4e35e8d2..c070e97f692 100644
--- a/innobase/sync/sync0sync.c
+++ b/innobase/sync/sync0sync.c
@@ -874,6 +874,7 @@ sync_thread_levels_empty_gen(
sync_level_t* slot;
rw_lock_t* lock;
mutex_t* mutex;
+ char* buf;
ulint i;
if (!sync_order_checks_on) {
@@ -907,7 +908,9 @@ sync_thread_levels_empty_gen(
mutex = slot->latch;
mutex_exit(&sync_thread_mutex);
- sync_print();
+ buf = mem_alloc(20000);
+
+ sync_print(buf, buf + 18000);
ut_error;
return(FALSE);
@@ -1243,14 +1246,21 @@ sync_close(void)
Prints wait info of the sync system. */
void
-sync_print_wait_info(void)
-/*======================*/
+sync_print_wait_info(
+/*=================*/
+ char* buf, /* in/out: buffer where to print */
+ char* buf_end) /* in: buffer end */
{
#ifdef UNIV_SYNC_DEBUG
printf("Mutex exits %lu, rws exits %lu, rwx exits %lu\n",
mutex_exit_count, rw_s_exit_count, rw_x_exit_count);
#endif
- printf(
+ if (buf_end - buf < 500) {
+
+ return;
+ }
+
+ sprintf(buf,
"Mutex spin waits %lu, rounds %lu, OS waits %lu\n"
"RW-shared spins %lu, OS waits %lu; RW-excl spins %lu, OS waits %lu\n",
mutex_spin_wait_count, mutex_spin_round_count,
@@ -1263,11 +1273,18 @@ sync_print_wait_info(void)
Prints info of the sync system. */
void
-sync_print(void)
-/*============*/
+sync_print(
+/*=======*/
+ char* buf, /* in/out: buffer where to print */
+ char* buf_end) /* in: buffer end */
{
mutex_list_print_info();
+
rw_lock_list_print_info();
- sync_array_print_info(sync_primary_wait_array);
- sync_print_wait_info();
+
+ sync_array_print_info(buf, buf_end, sync_primary_wait_array);
+
+ buf = buf + strlen(buf);
+
+ sync_print_wait_info(buf, buf_end);
}
diff --git a/innobase/trx/trx0trx.c b/innobase/trx/trx0trx.c
index 9c49abbd287..c2d99424d33 100644
--- a/innobase/trx/trx0trx.c
+++ b/innobase/trx/trx0trx.c
@@ -26,9 +26,11 @@ Created 3/26/1996 Heikki Tuuri
/* Copy of the prototype for innobase_mysql_print_thd: this
-copy must be equal to the one in mysql/sql/ha_innobase.cc ! */
+copy MUST be equal to the one in mysql/sql/ha_innobase.cc ! */
-void innobase_mysql_print_thd(void* thd);
+void innobase_mysql_print_thd(
+ char* buf,
+ void* thd);
/* Dummy session used currently in MySQL interface */
sess_t* trx_dummy_sess = NULL;
@@ -1459,54 +1461,63 @@ own the kernel mutex. */
void
trx_print(
/*======*/
+ char* buf, /* in/out: buffer where to print, must be at least
+ 500 bytes */
trx_t* trx) /* in: transaction */
{
- printf("TRANSACTION %lu %lu, OS thread id %lu",
+ buf += sprintf(buf, "TRANSACTION %lu %lu, OS thread id %lu",
ut_dulint_get_high(trx->id),
ut_dulint_get_low(trx->id),
(ulint)trx->mysql_thread_id);
if (ut_strlen(trx->op_info) > 0) {
- printf(" %s", trx->op_info);
+ buf += sprintf(buf, " %s", trx->op_info);
}
if (trx->type != TRX_USER) {
- printf(" purge trx");
+ buf += sprintf(buf, " purge trx");
}
switch (trx->conc_state) {
- case TRX_NOT_STARTED: printf(", not started"); break;
- case TRX_ACTIVE: printf(", active"); break;
- case TRX_COMMITTED_IN_MEMORY: printf(", committed in memory");
+ case TRX_NOT_STARTED: buf += sprintf(buf,
+ ", not started"); break;
+ case TRX_ACTIVE: buf += sprintf(buf,
+ ", active"); break;
+ case TRX_COMMITTED_IN_MEMORY: buf += sprintf(buf,
+ ", committed in memory");
break;
- default: printf(" state %lu", trx->conc_state);
+ default: buf += sprintf(buf, " state %lu", trx->conc_state);
}
switch (trx->que_state) {
- case TRX_QUE_RUNNING: printf(", runs or sleeps"); break;
- case TRX_QUE_LOCK_WAIT: printf(", lock wait"); break;
- case TRX_QUE_ROLLING_BACK: printf(", rolling back"); break;
- case TRX_QUE_COMMITTING: printf(", committing"); break;
- default: printf(" que state %lu", trx->que_state);
+ case TRX_QUE_RUNNING: buf += sprintf(buf,
+ ", runs or sleeps"); break;
+ case TRX_QUE_LOCK_WAIT: buf += sprintf(buf,
+ ", lock wait"); break;
+ case TRX_QUE_ROLLING_BACK: buf += sprintf(buf,
+ ", rolling back"); break;
+ case TRX_QUE_COMMITTING: buf += sprintf(buf,
+ ", committing"); break;
+ default: buf += sprintf(buf, " que state %lu", trx->que_state);
}
if (0 < UT_LIST_GET_LEN(trx->trx_locks)) {
- printf(", has %lu lock struct(s)",
+ buf += sprintf(buf, ", has %lu lock struct(s)",
UT_LIST_GET_LEN(trx->trx_locks));
}
if (trx->has_search_latch) {
- printf(", holds adaptive hash latch");
+ buf += sprintf(buf, ", holds adaptive hash latch");
}
if (ut_dulint_cmp(trx->undo_no, ut_dulint_zero) != 0) {
- printf(", undo log entries %lu",
+ buf += sprintf(buf, ", undo log entries %lu",
ut_dulint_get_low(trx->undo_no));
}
- printf("\n");
+ buf += sprintf(buf, "\n");
if (trx->mysql_thd != NULL) {
- innobase_mysql_print_thd(trx->mysql_thd);
+ innobase_mysql_print_thd(buf, trx->mysql_thd);
}
}