Commit babc9f5d authored by unknown's avatar unknown

InnoDB: Print more than 300 characters of queries in various error conditions,

most notably deadlocked ones in SHOW INNODB STATUS. Fixes bug #7819.


innobase/btr/btr0pcur.c:
  Adapt to changes in trx_print.
innobase/include/trx0trx.h:
  Add max_query_len parameter to trx_print.
innobase/lock/lock0lock.c:
  Adapt to changes in trx_print.
innobase/row/row0ins.c:
  Adapt to changes in trx_print.
innobase/row/row0sel.c:
  Adapt to changes in trx_print.
innobase/row/row0umod.c:
  Adapt to changes in trx_print.
innobase/row/row0upd.c:
  Adapt to changes in trx_print.
innobase/srv/srv0srv.c:
  Adapt to changes in trx_print.
innobase/trx/trx0trx.c:
  Add max_query_len parameter to trx_print.
sql/ha_innodb.cc:
  Add max_query_len parameter to innobase_mysql_print_thd.
parent 5329be86
......@@ -210,7 +210,7 @@ btr_pcur_restore_position(
&& cursor->pos_state != BTR_PCUR_IS_POSITIONED)) {
ut_print_buf(stderr, (const byte*)cursor, sizeof(btr_pcur_t));
if (cursor->trx_if_known) {
trx_print(stderr, cursor->trx_if_known);
trx_print(stderr, cursor->trx_if_known, 0);
}
ut_error;
......
......@@ -329,17 +329,20 @@ trx_commit_step(
/*============*/
/* out: query thread to run next, or NULL */
que_thr_t* thr); /* in: query thread */
/**************************************************************************
Prints info about a transaction to the standard output. The caller must
own the kernel mutex and must have called
innobase_mysql_prepare_print_arbitrary_thd(), unless he knows that MySQL or
InnoDB cannot meanwhile change the info printed here. */
Prints info about a transaction to the given file. The caller must own the
kernel mutex and must have called
innobase_mysql_prepare_print_arbitrary_thd(), unless he knows that MySQL
or InnoDB cannot meanwhile change the info printed here. */
void
trx_print(
/*======*/
FILE* f, /* in: output stream */
trx_t* trx); /* in: transaction */
FILE* f, /* in: output stream */
trx_t* trx, /* in: transaction */
uint max_query_len); /* in: max query length to print, or 0 to
use the default max length */
#ifndef UNIV_HOTBACKUP
/**************************************************************************
......
......@@ -3297,7 +3297,7 @@ lock_deadlock_recursive(
fputs("\n*** (1) TRANSACTION:\n", ef);
trx_print(ef, wait_lock->trx);
trx_print(ef, wait_lock->trx, 3000);
fputs(
"*** (1) WAITING FOR THIS LOCK TO BE GRANTED:\n", ef);
......@@ -3310,7 +3310,7 @@ lock_deadlock_recursive(
fputs("*** (2) TRANSACTION:\n", ef);
trx_print(ef, lock->trx);
trx_print(ef, lock->trx, 3000);
fputs("*** (2) HOLDS THE LOCK(S):\n", ef);
......@@ -4207,7 +4207,7 @@ lock_print_info_all_transactions(
while (trx) {
if (trx->conc_state == TRX_NOT_STARTED) {
fputs("---", file);
trx_print(file, trx);
trx_print(file, trx, 600);
}
trx = UT_LIST_GET_NEXT(mysql_trx_list, trx);
......@@ -4239,7 +4239,7 @@ lock_print_info_all_transactions(
if (nth_lock == 0) {
fputs("---", file);
trx_print(file, trx);
trx_print(file, trx, 600);
if (trx->read_view) {
fprintf(file,
......
......@@ -602,7 +602,7 @@ row_ins_foreign_report_err(
rewind(ef);
ut_print_timestamp(ef);
fputs(" Transaction:\n", ef);
trx_print(ef, trx);
trx_print(ef, trx, 600);
fputs("Foreign key constraint fails for table ", ef);
ut_print_name(ef, trx, foreign->foreign_table_name);
......@@ -653,7 +653,7 @@ row_ins_foreign_report_add_err(
rewind(ef);
ut_print_timestamp(ef);
fputs(" Transaction:\n", ef);
trx_print(ef, trx);
trx_print(ef, trx, 600);
fputs("Foreign key constraint fails for table ", ef);
ut_print_name(ef, trx, foreign->foreign_table_name);
fputs(":\n", ef);
......@@ -1228,7 +1228,7 @@ row_ins_check_foreign_constraint(
rewind(ef);
ut_print_timestamp(ef);
fputs(" Transaction:\n", ef);
trx_print(ef, trx);
trx_print(ef, trx, 600);
fputs("Foreign key constraint fails for table ", ef);
ut_print_name(ef, trx, foreign->foreign_table_name);
fputs(":\n", ef);
......
......@@ -2685,7 +2685,7 @@ row_sel_get_clust_rec_for_mysql(
"InnoDB: clust index record ", stderr);
rec_print(stderr, clust_rec, clust_index);
putc('\n', stderr);
trx_print(stderr, trx);
trx_print(stderr, trx, 600);
fputs("\n"
"InnoDB: Submit a detailed bug report to http://bugs.mysql.com\n", stderr);
......@@ -3128,7 +3128,7 @@ row_search_for_mysql(
"InnoDB: Error: MySQL is trying to perform a SELECT\n"
"InnoDB: but it has not locked any tables in ::external_lock()!\n",
stderr);
trx_print(stderr, trx);
trx_print(stderr, trx, 600);
fputc('\n', stderr);
}
......@@ -3455,7 +3455,7 @@ row_search_for_mysql(
fputs(
"InnoDB: Error: MySQL is trying to perform a consistent read\n"
"InnoDB: but the read view is not assigned!\n", stderr);
trx_print(stderr, trx);
trx_print(stderr, trx, 600);
fputc('\n', stderr);
ut_a(0);
}
......
......@@ -431,7 +431,7 @@ row_undo_mod_del_unmark_sec_and_undo_update(
"InnoDB: record ", stderr);
rec_print(stderr, btr_pcur_get_rec(&pcur), index);
putc('\n', stderr);
trx_print(stderr, trx);
trx_print(stderr, trx, 0);
fputs("\n"
"InnoDB: Submit a detailed bug report to http://bugs.mysql.com\n", stderr);
} else {
......
......@@ -1279,7 +1279,7 @@ row_upd_sec_index_entry(
rec_print(stderr, rec, index);
putc('\n', stderr);
trx_print(stderr, trx);
trx_print(stderr, trx, 0);
fputs("\n"
"InnoDB: Submit a detailed bug report to http://bugs.mysql.com\n", stderr);
......
......@@ -999,7 +999,7 @@ srv_conc_enter_innodb(
fputs(
" InnoDB: Error: trying to declare trx to enter InnoDB, but\n"
"InnoDB: it already is declared.\n", stderr);
trx_print(stderr, trx);
trx_print(stderr, trx, 0);
putc('\n', stderr);
os_fast_mutex_unlock(&srv_conc_mutex);
......
......@@ -30,8 +30,9 @@ Created 3/26/1996 Heikki Tuuri
copy MUST be equal to the one in mysql/sql/ha_innodb.cc ! */
void innobase_mysql_print_thd(
FILE* f,
void* thd);
FILE* f,
void* thd,
uint max_query_len);
/* Dummy session used currently in MySQL interface */
sess_t* trx_dummy_sess = NULL;
......@@ -262,7 +263,7 @@ trx_free(
fputs(
" InnoDB: Error: Freeing a trx which is declared to be processing\n"
"InnoDB: inside InnoDB.\n", stderr);
trx_print(stderr, trx);
trx_print(stderr, trx, 600);
putc('\n', stderr);
}
......@@ -277,7 +278,7 @@ trx_free(
(ulong)trx->n_mysql_tables_in_use,
(ulong)trx->mysql_n_tables_locked);
trx_print(stderr, trx);
trx_print(stderr, trx, 600);
ut_print_buf(stderr, (byte*)trx, sizeof(trx_t));
}
......@@ -1651,16 +1652,18 @@ trx_mark_sql_stat_end(
}
/**************************************************************************
Prints info about a transaction to the standard output. The caller must
own the kernel mutex and must have called
innobase_mysql_prepare_print_arbitrary_thd(), unless he knows that MySQL or
InnoDB cannot meanwhile change the info printed here. */
Prints info about a transaction to the given file. The caller must own the
kernel mutex and must have called
innobase_mysql_prepare_print_arbitrary_thd(), unless he knows that MySQL
or InnoDB cannot meanwhile change the info printed here. */
void
trx_print(
/*======*/
FILE* f, /* in: output stream */
trx_t* trx) /* in: transaction */
FILE* f, /* in: output stream */
trx_t* trx, /* in: transaction */
uint max_query_len) /* in: max query length to print, or 0 to
use the default max length */
{
ibool newline;
......@@ -1755,7 +1758,7 @@ trx_print(
}
if (trx->mysql_thd != NULL) {
innobase_mysql_print_thd(f, trx->mysql_thd);
innobase_mysql_print_thd(f, trx->mysql_thd, max_query_len);
}
}
......
......@@ -550,19 +550,20 @@ innobase_mysql_end_print_arbitrary_thd(void)
}
/*****************************************************************
Prints info of a THD object (== user session thread) to the
standard output. NOTE that /mysql/innobase/trx/trx0trx.c must contain
the prototype for this function! */
Prints info of a THD object (== user session thread) to the given file.
NOTE that /mysql/innobase/trx/trx0trx.c must contain the prototype for
this function! */
extern "C"
void
innobase_mysql_print_thd(
/*=====================*/
FILE* f, /* in: output stream */
void* input_thd)/* in: pointer to a MySQL THD object */
FILE* f, /* in: output stream */
void* input_thd, /* in: pointer to a MySQL THD object */
uint max_query_len) /* in: max query length to print, or 0 to
use the default max length */
{
const THD* thd;
const char* s;
char buf[301];
thd = (const THD*) input_thd;
......@@ -589,25 +590,47 @@ innobase_mysql_print_thd(
}
if ((s = thd->query)) {
/* determine the length of the query string */
uint32 i, len;
/* 3100 is chosen because currently 3000 is the maximum
max_query_len we ever give this. */
char buf[3100];
uint len;
/* If buf is too small, we dynamically allocate storage
in this. */
char* dyn_str = NULL;
/* Points to buf or dyn_str. */
char* str = buf;
len = thd->query_length;
if (len > 300) {
len = 300; /* ADDITIONAL SAFETY: print at most
300 chars to reduce the probability of
a seg fault if there is a race in
thd->query_length in MySQL; after
May 14, 2004 probably no race any more,
but better be safe */
if (max_query_len == 0)
{
/* ADDITIONAL SAFETY: the default is to print at
most 300 chars to reduce the probability of a
seg fault if there is a race in
thd->query_length in MySQL; after May 14, 2004
probably no race any more, but better be
safe */
max_query_len = 300;
}
len = min(thd->query_length, max_query_len);
/* Use strmake to reduce the timeframe
for a race, compared to fwrite() */
i= (uint) (strmake(buf, s, len) - buf);
if (len > (sizeof(buf) - 1))
{
dyn_str = my_malloc(len + 1, MYF(0));
str = dyn_str;
}
/* Use strmake to reduce the timeframe for a race,
compared to fwrite() */
len = (uint) (strmake(str, s, len) - str);
putc('\n', f);
fwrite(buf, 1, i, f);
fwrite(str, 1, len, f);
if (dyn_str)
{
my_free(dyn_str, MYF(0));
}
}
putc('\n', f);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment