Commit 6a6d7a9b authored by vasil's avatar vasil

branches/zip:

* Change terminology:
  wait lock -> requested lock
  waited lock -> blocking lock
  new: requesting transaction (the trx what owns the requested lock)
  new: blocking transaction (the trx that owns the blocking lock)

* Add transaction ids to INFORMATION_SCHEMA.INNODB_LOCK_WAITS. This is
  somewhat redundant because transaction ids can be found in INNODB_LOCKS
  (which can be joined with INNODB_LOCK_WAITS) but would help users to
  write shorter joins (one table less) in some cases where they want to
  find which transaction is blocking which.

Suggested by:	Ken
Approved by:	Heikki
parent 5784e7de
...@@ -224,8 +224,8 @@ static ST_FIELD_INFO innodb_trx_fields_info[] = ...@@ -224,8 +224,8 @@ static ST_FIELD_INFO innodb_trx_fields_info[] =
STRUCT_FLD(old_name, ""), STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
#define IDX_TRX_WAIT_LOCK_ID 4 #define IDX_TRX_REQUESTED_LOCK_ID 4
{STRUCT_FLD(field_name, "trx_wait_lock_id"), {STRUCT_FLD(field_name, "trx_requested_lock_id"),
STRUCT_FLD(field_length, TRX_I_S_LOCK_ID_MAX_LEN), STRUCT_FLD(field_length, TRX_I_S_LOCK_ID_MAX_LEN),
STRUCT_FLD(field_type, MYSQL_TYPE_STRING), STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
STRUCT_FLD(value, 0), STRUCT_FLD(value, 0),
...@@ -310,14 +310,14 @@ fill_innodb_trx_from_cache( ...@@ -310,14 +310,14 @@ fill_innodb_trx_from_cache(
OK(field_store_time_t(fields[IDX_TRX_STARTED], OK(field_store_time_t(fields[IDX_TRX_STARTED],
(time_t) row->trx_started)); (time_t) row->trx_started));
/* trx_wait_lock_id */ /* trx_requested_lock_id */
/* trx_wait_started */ /* trx_wait_started */
if (row->trx_wait_started != 0) { if (row->trx_wait_started != 0) {
OK(field_store_string( OK(field_store_string(
fields[IDX_TRX_WAIT_LOCK_ID], fields[IDX_TRX_REQUESTED_LOCK_ID],
trx_i_s_create_lock_id( trx_i_s_create_lock_id(
row->wait_lock_row, row->requested_lock_row,
lock_id, sizeof(lock_id)))); lock_id, sizeof(lock_id))));
/* field_store_string() sets it no notnull */ /* field_store_string() sets it no notnull */
...@@ -327,7 +327,7 @@ fill_innodb_trx_from_cache( ...@@ -327,7 +327,7 @@ fill_innodb_trx_from_cache(
fields[IDX_TRX_WAIT_STARTED]->set_notnull(); fields[IDX_TRX_WAIT_STARTED]->set_notnull();
} else { } else {
fields[IDX_TRX_WAIT_LOCK_ID]->set_null(); fields[IDX_TRX_REQUESTED_LOCK_ID]->set_null();
fields[IDX_TRX_WAIT_STARTED]->set_null(); fields[IDX_TRX_WAIT_STARTED]->set_null();
} }
...@@ -694,8 +694,17 @@ struct st_mysql_plugin i_s_innodb_locks = ...@@ -694,8 +694,17 @@ struct st_mysql_plugin i_s_innodb_locks =
/* Fields of the dynamic table INFORMATION_SCHEMA.innodb_lock_waits */ /* Fields of the dynamic table INFORMATION_SCHEMA.innodb_lock_waits */
static ST_FIELD_INFO innodb_lock_waits_fields_info[] = static ST_FIELD_INFO innodb_lock_waits_fields_info[] =
{ {
#define IDX_WAIT_LOCK_ID 0 #define IDX_REQUESTING_TRX_ID 0
{STRUCT_FLD(field_name, "wait_lock_id"), {STRUCT_FLD(field_name, "requesting_trx_id"),
STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
#define IDX_REQUESTED_LOCK_ID 1
{STRUCT_FLD(field_name, "requested_lock_id"),
STRUCT_FLD(field_length, TRX_I_S_LOCK_ID_MAX_LEN), STRUCT_FLD(field_length, TRX_I_S_LOCK_ID_MAX_LEN),
STRUCT_FLD(field_type, MYSQL_TYPE_STRING), STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
STRUCT_FLD(value, 0), STRUCT_FLD(value, 0),
...@@ -703,8 +712,17 @@ static ST_FIELD_INFO innodb_lock_waits_fields_info[] = ...@@ -703,8 +712,17 @@ static ST_FIELD_INFO innodb_lock_waits_fields_info[] =
STRUCT_FLD(old_name, ""), STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
#define IDX_WAITED_LOCK_ID 1 #define IDX_BLOCKING_TRX_ID 2
{STRUCT_FLD(field_name, "waited_lock_id"), {STRUCT_FLD(field_name, "blocking_trx_id"),
STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
#define IDX_BLOCKING_LOCK_ID 3
{STRUCT_FLD(field_name, "blocking_lock_id"),
STRUCT_FLD(field_length, TRX_I_S_LOCK_ID_MAX_LEN), STRUCT_FLD(field_length, TRX_I_S_LOCK_ID_MAX_LEN),
STRUCT_FLD(field_type, MYSQL_TYPE_STRING), STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
STRUCT_FLD(value, 0), STRUCT_FLD(value, 0),
...@@ -730,8 +748,8 @@ fill_innodb_lock_waits_from_cache( ...@@ -730,8 +748,8 @@ fill_innodb_lock_waits_from_cache(
{ {
Field** fields; Field** fields;
ulint rows_num; ulint rows_num;
char wait_lock_id[TRX_I_S_LOCK_ID_MAX_LEN]; char requested_lock_id[TRX_I_S_LOCK_ID_MAX_LEN];
char waited_lock_id[TRX_I_S_LOCK_ID_MAX_LEN]; char blocking_lock_id[TRX_I_S_LOCK_ID_MAX_LEN];
ulint i; ulint i;
DBUG_ENTER("fill_innodb_lock_waits_from_cache"); DBUG_ENTER("fill_innodb_lock_waits_from_cache");
...@@ -749,21 +767,29 @@ fill_innodb_lock_waits_from_cache( ...@@ -749,21 +767,29 @@ fill_innodb_lock_waits_from_cache(
trx_i_s_cache_get_nth_row( trx_i_s_cache_get_nth_row(
cache, I_S_INNODB_LOCK_WAITS, i); cache, I_S_INNODB_LOCK_WAITS, i);
/* wait_lock_id */ /* requesting_trx_id */
OK(fields[IDX_REQUESTING_TRX_ID]->store(
row->requested_lock_row->lock_trx_id));
/* requested_lock_id */
OK(field_store_string( OK(field_store_string(
fields[IDX_WAIT_LOCK_ID], fields[IDX_REQUESTED_LOCK_ID],
trx_i_s_create_lock_id( trx_i_s_create_lock_id(
row->wait_lock_row, row->requested_lock_row,
wait_lock_id, requested_lock_id,
sizeof(wait_lock_id)))); sizeof(requested_lock_id))));
/* blocking_trx_id */
OK(fields[IDX_BLOCKING_TRX_ID]->store(
row->blocking_lock_row->lock_trx_id));
/* waited_lock_id */ /* blocking_lock_id */
OK(field_store_string( OK(field_store_string(
fields[IDX_WAITED_LOCK_ID], fields[IDX_BLOCKING_LOCK_ID],
trx_i_s_create_lock_id( trx_i_s_create_lock_id(
row->waited_lock_row, row->blocking_lock_row,
waited_lock_id, blocking_lock_id,
sizeof(waited_lock_id)))); sizeof(blocking_lock_id))));
OK(schema_table_store_record(thd, table)); OK(schema_table_store_record(thd, table));
} }
......
...@@ -61,7 +61,7 @@ typedef struct i_s_trx_row_struct { ...@@ -61,7 +61,7 @@ typedef struct i_s_trx_row_struct {
ullint trx_weight; ullint trx_weight;
const char* trx_state; const char* trx_state;
ib_time_t trx_started; ib_time_t trx_started;
const i_s_locks_row_t* wait_lock_row; const i_s_locks_row_t* requested_lock_row;
ib_time_t trx_wait_started; ib_time_t trx_wait_started;
ulint trx_mysql_thread_id; ulint trx_mysql_thread_id;
const char* trx_query; const char* trx_query;
...@@ -69,8 +69,8 @@ typedef struct i_s_trx_row_struct { ...@@ -69,8 +69,8 @@ typedef struct i_s_trx_row_struct {
/* This structure represents INFORMATION_SCHEMA.innodb_lock_waits row */ /* This structure represents INFORMATION_SCHEMA.innodb_lock_waits row */
typedef struct i_s_lock_waits_row_struct { typedef struct i_s_lock_waits_row_struct {
const i_s_locks_row_t* wait_lock_row; const i_s_locks_row_t* requested_lock_row;
const i_s_locks_row_t* waited_lock_row; const i_s_locks_row_t* blocking_lock_row;
} i_s_lock_waits_row_t; } i_s_lock_waits_row_t;
/* This type is opaque and is defined in trx/trx0i_s.c */ /* This type is opaque and is defined in trx/trx0i_s.c */
......
...@@ -361,7 +361,7 @@ fill_trx_row( ...@@ -361,7 +361,7 @@ fill_trx_row(
that's filled */ that's filled */
const trx_t* trx, /* in: transaction to const trx_t* trx, /* in: transaction to
get data from */ get data from */
const i_s_locks_row_t* wait_lock_row, /* in: pointer to the const i_s_locks_row_t* requested_lock_row,/* in: pointer to the
corresponding row in corresponding row in
innodb_locks if trx is innodb_locks if trx is
waiting or NULL if trx waiting or NULL if trx
...@@ -377,15 +377,15 @@ fill_trx_row( ...@@ -377,15 +377,15 @@ fill_trx_row(
if (trx->wait_lock != NULL) { if (trx->wait_lock != NULL) {
ut_a(wait_lock_row != NULL); ut_a(requested_lock_row != NULL);
row->wait_lock_row = wait_lock_row; row->requested_lock_row = requested_lock_row;
row->trx_wait_started = (ib_time_t) trx->wait_started; row->trx_wait_started = (ib_time_t) trx->wait_started;
} else { } else {
ut_a(wait_lock_row == NULL); ut_a(requested_lock_row == NULL);
row->wait_lock_row = NULL; row->requested_lock_row = NULL;
row->trx_wait_started = 0; row->trx_wait_started = 0;
} }
...@@ -677,15 +677,15 @@ fill_lock_waits_row( ...@@ -677,15 +677,15 @@ fill_lock_waits_row(
that's filled */ that's filled */
i_s_lock_waits_row_t* row, /* out: result object i_s_lock_waits_row_t* row, /* out: result object
that's filled */ that's filled */
const i_s_locks_row_t* wait_lock_row, /* in: pointer to the const i_s_locks_row_t* requested_lock_row,/* in: pointer to the
relevant wait-lock relevant requested lock
row in innodb_locks */ row in innodb_locks */
const i_s_locks_row_t* waited_lock_row)/* in: pointer to the const i_s_locks_row_t* blocking_lock_row)/* in: pointer to the
relevant waited-lock relevant blocking lock
row in innodb_locks */ row in innodb_locks */
{ {
row->wait_lock_row = wait_lock_row; row->requested_lock_row = requested_lock_row;
row->waited_lock_row = waited_lock_row; row->blocking_lock_row = blocking_lock_row;
return(row); return(row);
} }
...@@ -899,11 +899,11 @@ add_lock_wait_to_cache( ...@@ -899,11 +899,11 @@ add_lock_wait_to_cache(
/* out: FALSE if /* out: FALSE if
allocation fails */ allocation fails */
trx_i_s_cache_t* cache, /* in/out: cache */ trx_i_s_cache_t* cache, /* in/out: cache */
const i_s_locks_row_t* wait_lock_row, /* in: pointer to the const i_s_locks_row_t* requested_lock_row,/* in: pointer to the
relevant wait-lock relevant requested lock
row in innodb_locks */ row in innodb_locks */
const i_s_locks_row_t* waited_lock_row)/* in: pointer to the const i_s_locks_row_t* blocking_lock_row)/* in: pointer to the
relevant waited-lock relevant blocking lock
row in innodb_locks */ row in innodb_locks */
{ {
i_s_lock_waits_row_t* dst_row; i_s_lock_waits_row_t* dst_row;
...@@ -918,7 +918,7 @@ add_lock_wait_to_cache( ...@@ -918,7 +918,7 @@ add_lock_wait_to_cache(
return(FALSE); return(FALSE);
} }
fill_lock_waits_row(dst_row, wait_lock_row, waited_lock_row); fill_lock_waits_row(dst_row, requested_lock_row, blocking_lock_row);
return(TRUE); return(TRUE);
} }
...@@ -927,9 +927,9 @@ add_lock_wait_to_cache( ...@@ -927,9 +927,9 @@ add_lock_wait_to_cache(
Adds transaction's relevant (important) locks to cache. Adds transaction's relevant (important) locks to cache.
If the transaction is waiting, then the wait lock is added to If the transaction is waiting, then the wait lock is added to
innodb_locks and a pointer to the added row is returned in innodb_locks and a pointer to the added row is returned in
wait_lock_row, otherwise wait_lock_row is set to NULL. requested_lock_row, otherwise requested_lock_row is set to NULL.
If rows can not be allocated then FALSE is returned and the value of If rows can not be allocated then FALSE is returned and the value of
wait_lock_row is undefined. */ requested_lock_row is undefined. */
static static
ibool ibool
add_trx_relevant_locks_to_cache( add_trx_relevant_locks_to_cache(
...@@ -937,8 +937,9 @@ add_trx_relevant_locks_to_cache( ...@@ -937,8 +937,9 @@ add_trx_relevant_locks_to_cache(
/* out: FALSE if allocation fails */ /* out: FALSE if allocation fails */
trx_i_s_cache_t* cache, /* in/out: cache */ trx_i_s_cache_t* cache, /* in/out: cache */
const trx_t* trx, /* in: transaction */ const trx_t* trx, /* in: transaction */
i_s_locks_row_t** wait_lock_row)/* out: pointer to the i_s_locks_row_t** requested_lock_row)/* out: pointer to the
wait lock row, or NULL */ requested lock row, or NULL or
undefined */
{ {
/* If transaction is waiting we add the wait lock and all locks /* If transaction is waiting we add the wait lock and all locks
from another transactions that are blocking the wait lock. */ from another transactions that are blocking the wait lock. */
...@@ -946,7 +947,7 @@ add_trx_relevant_locks_to_cache( ...@@ -946,7 +947,7 @@ add_trx_relevant_locks_to_cache(
const lock_t* curr_lock; const lock_t* curr_lock;
ulint wait_lock_heap_no; ulint wait_lock_heap_no;
i_s_locks_row_t* waited_lock_row; i_s_locks_row_t* blocking_lock_row;
lock_queue_iterator_t iter; lock_queue_iterator_t iter;
ut_a(trx->wait_lock != NULL); ut_a(trx->wait_lock != NULL);
...@@ -954,13 +955,13 @@ add_trx_relevant_locks_to_cache( ...@@ -954,13 +955,13 @@ add_trx_relevant_locks_to_cache(
wait_lock_heap_no wait_lock_heap_no
= wait_lock_get_heap_no(trx->wait_lock); = wait_lock_get_heap_no(trx->wait_lock);
/* add the wait lock */ /* add the requested lock */
*wait_lock_row *requested_lock_row
= add_lock_to_cache(cache, trx->wait_lock, = add_lock_to_cache(cache, trx->wait_lock,
wait_lock_heap_no); wait_lock_heap_no);
/* memory could not be allocated */ /* memory could not be allocated */
if (*wait_lock_row == NULL) { if (*requested_lock_row == NULL) {
return(FALSE); return(FALSE);
} }
...@@ -977,9 +978,9 @@ add_trx_relevant_locks_to_cache( ...@@ -977,9 +978,9 @@ add_trx_relevant_locks_to_cache(
if (lock_has_to_wait(trx->wait_lock, if (lock_has_to_wait(trx->wait_lock,
curr_lock)) { curr_lock)) {
/* add the lock that trx->wait_lock is /* add the lock that is
waiting for */ blocking trx->wait_lock */
waited_lock_row blocking_lock_row
= add_lock_to_cache( = add_lock_to_cache(
cache, curr_lock, cache, curr_lock,
/* heap_no is the same /* heap_no is the same
...@@ -988,7 +989,7 @@ add_trx_relevant_locks_to_cache( ...@@ -988,7 +989,7 @@ add_trx_relevant_locks_to_cache(
wait_lock_heap_no); wait_lock_heap_no);
/* memory could not be allocated */ /* memory could not be allocated */
if (waited_lock_row == NULL) { if (blocking_lock_row == NULL) {
return(FALSE); return(FALSE);
} }
...@@ -996,8 +997,8 @@ add_trx_relevant_locks_to_cache( ...@@ -996,8 +997,8 @@ add_trx_relevant_locks_to_cache(
/* add the relation between both locks /* add the relation between both locks
to innodb_lock_waits */ to innodb_lock_waits */
if (!add_lock_wait_to_cache( if (!add_lock_wait_to_cache(
cache, *wait_lock_row, cache, *requested_lock_row,
waited_lock_row)) { blocking_lock_row)) {
/* memory could not be allocated */ /* memory could not be allocated */
return(FALSE); return(FALSE);
...@@ -1008,7 +1009,7 @@ add_trx_relevant_locks_to_cache( ...@@ -1008,7 +1009,7 @@ add_trx_relevant_locks_to_cache(
} }
} else { } else {
*wait_lock_row = NULL; *requested_lock_row = NULL;
} }
return(TRUE); return(TRUE);
...@@ -1079,7 +1080,7 @@ fetch_data_into_cache( ...@@ -1079,7 +1080,7 @@ fetch_data_into_cache(
{ {
trx_t* trx; trx_t* trx;
i_s_trx_row_t* trx_row; i_s_trx_row_t* trx_row;
i_s_locks_row_t* wait_lock_row; i_s_locks_row_t* requested_lock_row;
trx_i_s_cache_clear(cache); trx_i_s_cache_clear(cache);
...@@ -1093,7 +1094,7 @@ fetch_data_into_cache( ...@@ -1093,7 +1094,7 @@ fetch_data_into_cache(
trx = UT_LIST_GET_NEXT(trx_list, trx)) { trx = UT_LIST_GET_NEXT(trx_list, trx)) {
if (!add_trx_relevant_locks_to_cache(cache, trx, if (!add_trx_relevant_locks_to_cache(cache, trx,
&wait_lock_row)) { &requested_lock_row)) {
cache->is_truncated = TRUE; cache->is_truncated = TRUE;
return; return;
...@@ -1110,7 +1111,7 @@ fetch_data_into_cache( ...@@ -1110,7 +1111,7 @@ fetch_data_into_cache(
return; return;
} }
if (!fill_trx_row(trx_row, trx, wait_lock_row, cache)) { if (!fill_trx_row(trx_row, trx, requested_lock_row, cache)) {
/* memory could not be allocated */ /* memory could not be allocated */
cache->innodb_trx.rows_used--; cache->innodb_trx.rows_used--;
......
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