summaryrefslogtreecommitdiff
path: root/storage/xtradb/trx
diff options
context:
space:
mode:
Diffstat (limited to 'storage/xtradb/trx')
-rw-r--r--storage/xtradb/trx/trx0i_s.c39
-rw-r--r--storage/xtradb/trx/trx0purge.c124
-rw-r--r--storage/xtradb/trx/trx0rec.c4
-rw-r--r--storage/xtradb/trx/trx0roll.c74
-rw-r--r--storage/xtradb/trx/trx0rseg.c43
-rw-r--r--storage/xtradb/trx/trx0sys.c92
-rw-r--r--storage/xtradb/trx/trx0trx.c46
-rw-r--r--storage/xtradb/trx/trx0undo.c2
8 files changed, 387 insertions, 37 deletions
diff --git a/storage/xtradb/trx/trx0i_s.c b/storage/xtradb/trx/trx0i_s.c
index 90b73ad9e07..e7646c99227 100644
--- a/storage/xtradb/trx/trx0i_s.c
+++ b/storage/xtradb/trx/trx0i_s.c
@@ -60,7 +60,7 @@ Created July 17, 2007 Vasil Dimov
/** @brief The maximum number of chunks to allocate for a table cache.
The rows of a table cache are stored in a set of chunks. When a new
-row is added a new chunk is allocated if necessary. Assuming that the
+row is added a new chunk is allocated if necessary. Assuming that the
first one is 1024 rows (TABLE_CACHE_INITIAL_ROWSNUM) and each
subsequent is N/2 where N is the number of rows we have allocated till
now, then 39th chunk would accommodate 1677416425 rows and all chunks
@@ -238,6 +238,27 @@ table_cache_init(
}
/*******************************************************************//**
+Frees a table cache. */
+static
+void
+table_cache_free(
+/*=============*/
+ i_s_table_cache_t* table_cache) /*!< in/out: table cache */
+{
+ ulint i;
+
+ for (i = 0; i < MEM_CHUNKS_IN_TABLE_CACHE; i++) {
+
+ /* the memory is actually allocated in
+ table_cache_create_empty_row() */
+ if (table_cache->chunks[i].base) {
+ mem_free(table_cache->chunks[i].base);
+ table_cache->chunks[i].base = NULL;
+ }
+ }
+}
+
+/*******************************************************************//**
Returns an empty row from a table cache. The row is allocated if no more
empty rows are available. The number of used rows is incremented.
If the memory limit is hit then NULL is returned and nothing is
@@ -1252,6 +1273,22 @@ trx_i_s_cache_init(
}
/*******************************************************************//**
+Free the INFORMATION SCHEMA trx related cache. */
+UNIV_INTERN
+void
+trx_i_s_cache_free(
+/*===============*/
+ trx_i_s_cache_t* cache) /*!< in, own: cache to free */
+{
+ hash_table_free(cache->locks_hash);
+ ha_storage_free(cache->storage);
+ table_cache_free(&cache->innodb_trx);
+ table_cache_free(&cache->innodb_locks);
+ table_cache_free(&cache->innodb_lock_waits);
+ memset(cache, 0, sizeof *cache);
+}
+
+/*******************************************************************//**
Issue a shared/read lock on the tables cache. */
UNIV_INTERN
void
diff --git a/storage/xtradb/trx/trx0purge.c b/storage/xtradb/trx/trx0purge.c
index cd79fd1c315..41e16b35e85 100644
--- a/storage/xtradb/trx/trx0purge.c
+++ b/storage/xtradb/trx/trx0purge.c
@@ -184,8 +184,9 @@ this query graph.
@return own: the query graph */
static
que_t*
-trx_purge_graph_build(void)
+trx_purge_graph_build(
/*=======================*/
+ trx_t* trx)
{
mem_heap_t* heap;
que_fork_t* fork;
@@ -194,7 +195,7 @@ trx_purge_graph_build(void)
heap = mem_heap_create(512);
fork = que_fork_create(NULL, NULL, QUE_FORK_PURGE, heap);
- fork->trx = purge_sys->trx;
+ fork->trx = trx;
thr = que_thr_create(fork, heap);
@@ -243,10 +244,73 @@ trx_purge_sys_create(void)
ut_a(trx_start_low(purge_sys->trx, ULINT_UNDEFINED));
- purge_sys->query = trx_purge_graph_build();
+ purge_sys->query = trx_purge_graph_build(purge_sys->trx);
purge_sys->view = read_view_oldest_copy_or_open_new(ut_dulint_zero,
purge_sys->heap);
+
+ purge_sys->n_worker = 0;
+ if (srv_use_purge_thread > 1) {
+ /* Use worker threads */
+ ulint i;
+
+ purge_sys->n_worker = srv_use_purge_thread - 1;
+
+ purge_sys->sess_arr = mem_alloc(sizeof(sess_t*) * purge_sys->n_worker);
+ purge_sys->trx_arr = mem_alloc(sizeof(trx_t*) * purge_sys->n_worker);
+ purge_sys->query_arr = mem_alloc(sizeof(que_t*) * purge_sys->n_worker);
+
+ purge_sys->worker_event = os_event_create(NULL);
+ os_event_reset(purge_sys->worker_event);
+
+ for (i = 0; i < purge_sys->n_worker; i++) {
+ purge_sys->sess_arr[i] = sess_open();
+
+ purge_sys->trx_arr[i] = purge_sys->sess_arr[i]->trx;
+ purge_sys->trx_arr[i]->is_purge = 1;
+ ut_a(trx_start_low(purge_sys->trx_arr[i], ULINT_UNDEFINED));
+
+ purge_sys->query_arr[i] = trx_purge_graph_build(purge_sys->trx_arr[i]);
+ }
+ }
+}
+
+/************************************************************************
+Frees the global purge system control structure. */
+UNIV_INTERN
+void
+trx_purge_sys_close(void)
+/*======================*/
+{
+ ut_ad(!mutex_own(&kernel_mutex));
+
+ que_graph_free(purge_sys->query);
+
+ ut_a(purge_sys->sess->trx->is_purge);
+ purge_sys->sess->trx->conc_state = TRX_NOT_STARTED;
+ sess_close(purge_sys->sess);
+ purge_sys->sess = NULL;
+
+ if (purge_sys->view != NULL) {
+ /* Because acquiring the kernel mutex is a pre-condition
+ of read_view_close(). We don't really need it here. */
+ mutex_enter(&kernel_mutex);
+
+ read_view_close(purge_sys->view);
+ purge_sys->view = NULL;
+
+ mutex_exit(&kernel_mutex);
+ }
+
+ trx_undo_arr_free(purge_sys->arr);
+
+ rw_lock_free(&purge_sys->latch);
+ mutex_free(&purge_sys->mutex);
+
+ mem_heap_free(purge_sys->heap);
+ mem_free(purge_sys);
+
+ purge_sys = NULL;
}
/*================ UNDO LOG HISTORY LIST =============================*/
@@ -1110,7 +1174,7 @@ trx_purge(void)
/* Handle at most 20 undo log pages in one purge batch */
- purge_sys->handle_limit = purge_sys->n_pages_handled + 20;
+ purge_sys->handle_limit = purge_sys->n_pages_handled + 20 * (srv_use_purge_thread + 1);
old_pages_handled = purge_sys->n_pages_handled;
@@ -1129,6 +1193,9 @@ trx_purge(void)
mutex_exit(&kernel_mutex);
+ if (purge_sys->n_worker)
+ os_event_set(purge_sys->worker_event);
+
/* srv_que_task_enqueue(thr2); */
if (srv_print_thread_releases) {
@@ -1138,6 +1205,9 @@ trx_purge(void)
que_run_threads(thr);
+ if (purge_sys->n_worker)
+ os_event_reset(purge_sys->worker_event);
+
if (srv_print_thread_releases) {
fprintf(stderr,
@@ -1148,6 +1218,52 @@ trx_purge(void)
return(purge_sys->n_pages_handled - old_pages_handled);
}
+/**********************************************************************
+This function runs a purge worker batch */
+UNIV_INTERN
+void
+trx_purge_worker(
+/*=============*/
+ ulint worker_id)
+{
+ que_thr_t* thr;
+
+ mutex_enter(&kernel_mutex);
+
+ thr = que_fork_start_command(purge_sys->query_arr[worker_id]);
+
+ ut_ad(thr);
+
+ mutex_exit(&kernel_mutex);
+
+ que_run_threads(thr);
+
+ if (purge_sys->state == TRX_STOP_PURGE) { /* optimistic */
+ os_event_reset(purge_sys->worker_event);
+ }
+}
+
+/**********************************************************************
+This function waits the event for worker batch */
+UNIV_INTERN
+void
+trx_purge_worker_wait(void)
+/*=======================*/
+{
+ os_event_wait(purge_sys->worker_event);
+}
+
+/**********************************************************************
+This function wakes the waiting worker batch */
+UNIV_INTERN
+void
+trx_purge_worker_wake(void)
+/*=======================*/
+{
+ if (purge_sys->n_worker)
+ os_event_set(purge_sys->worker_event);
+}
+
/******************************************************************//**
Prints information of the purge system to stderr. */
UNIV_INTERN
diff --git a/storage/xtradb/trx/trx0rec.c b/storage/xtradb/trx/trx0rec.c
index 36911c9df85..5097cf18dcd 100644
--- a/storage/xtradb/trx/trx0rec.c
+++ b/storage/xtradb/trx/trx0rec.c
@@ -1333,7 +1333,7 @@ trx_undo_get_undo_rec_low(
ulint rseg_id;
ulint page_no;
ulint offset;
- page_t* undo_page;
+ const page_t* undo_page;
trx_rseg_t* rseg;
ibool is_insert;
mtr_t mtr;
@@ -1572,7 +1572,7 @@ trx_undo_prev_version_build(
/* We have to set the appropriate extern storage bits in the
old version of the record: the extern bits in rec for those
- fields that update does NOT update, as well as the the bits for
+ fields that update does NOT update, as well as the bits for
those fields that update updates to become externally stored
fields. Store the info: */
diff --git a/storage/xtradb/trx/trx0roll.c b/storage/xtradb/trx/trx0roll.c
index 51d17192d5b..c925478cdf4 100644
--- a/storage/xtradb/trx/trx0roll.c
+++ b/storage/xtradb/trx/trx0roll.c
@@ -66,9 +66,9 @@ int
trx_general_rollback_for_mysql(
/*===========================*/
trx_t* trx, /*!< in: transaction handle */
- ibool partial,/*!< in: TRUE if partial rollback requested */
trx_savept_t* savept) /*!< in: pointer to savepoint undo number, if
- partial rollback requested */
+ partial rollback requested, or NULL for
+ complete rollback */
{
mem_heap_t* heap;
que_thr_t* thr;
@@ -85,9 +85,8 @@ trx_general_rollback_for_mysql(
roll_node = roll_node_create(heap);
- roll_node->partial = partial;
-
- if (partial) {
+ if (savept) {
+ roll_node->partial = TRUE;
roll_node->savept = *savept;
}
@@ -145,7 +144,7 @@ trx_rollback_for_mysql(
the transaction object does not have an InnoDB session object, and we
set a dummy session that we use for all MySQL transactions. */
- err = trx_general_rollback_for_mysql(trx, FALSE, NULL);
+ err = trx_general_rollback_for_mysql(trx, NULL);
trx->op_info = "";
@@ -170,8 +169,7 @@ trx_rollback_last_sql_stat_for_mysql(
trx->op_info = "rollback of SQL statement";
- err = trx_general_rollback_for_mysql(trx, TRUE,
- &(trx->last_sql_stat_start));
+ err = trx_general_rollback_for_mysql(trx, &trx->last_sql_stat_start);
/* The following call should not be needed, but we play safe: */
trx_mark_sql_stat_end(trx);
@@ -282,7 +280,7 @@ trx_rollback_to_savepoint_for_mysql(
trx->op_info = "rollback to a savepoint";
- err = trx_general_rollback_for_mysql(trx, TRUE, &(savep->savept));
+ err = trx_general_rollback_for_mysql(trx, &savep->savept);
/* Store the current undo_no of the transaction so that we know where
to roll back if we have to roll back the next SQL statement: */
@@ -534,28 +532,26 @@ trx_rollback_active(
Rollback or clean up any incomplete transactions which were
encountered in crash recovery. If the transaction already was
committed, then we clean up a possible insert undo log. If the
-transaction was not yet committed, then we roll it back.
-Note: this is done in a background thread.
-@return a dummy parameter */
+transaction was not yet committed, then we roll it back. */
UNIV_INTERN
-os_thread_ret_t
-trx_rollback_or_clean_all_recovered(
-/*================================*/
- void* arg __attribute__((unused)))
- /*!< in: a dummy parameter required by
- os_thread_create */
+void
+trx_rollback_or_clean_recovered(
+/*============================*/
+ ibool all) /*!< in: FALSE=roll back dictionary transactions;
+ TRUE=roll back all non-PREPARED transactions */
{
trx_t* trx;
mutex_enter(&kernel_mutex);
- if (UT_LIST_GET_FIRST(trx_sys->trx_list)) {
+ if (!UT_LIST_GET_FIRST(trx_sys->trx_list)) {
+ goto leave_function;
+ }
+ if (all) {
fprintf(stderr,
"InnoDB: Starting in background the rollback"
" of uncommitted transactions\n");
- } else {
- goto leave_function;
}
mutex_exit(&kernel_mutex);
@@ -584,18 +580,42 @@ loop:
goto loop;
case TRX_ACTIVE:
- mutex_exit(&kernel_mutex);
- trx_rollback_active(trx);
- goto loop;
+ if (all || trx_get_dict_operation(trx)
+ != TRX_DICT_OP_NONE) {
+ mutex_exit(&kernel_mutex);
+ trx_rollback_active(trx);
+ goto loop;
+ }
}
}
- ut_print_timestamp(stderr);
- fprintf(stderr,
- " InnoDB: Rollback of non-prepared transactions completed\n");
+ if (all) {
+ ut_print_timestamp(stderr);
+ fprintf(stderr,
+ " InnoDB: Rollback of non-prepared"
+ " transactions completed\n");
+ }
leave_function:
mutex_exit(&kernel_mutex);
+}
+
+/*******************************************************************//**
+Rollback or clean up any incomplete transactions which were
+encountered in crash recovery. If the transaction already was
+committed, then we clean up a possible insert undo log. If the
+transaction was not yet committed, then we roll it back.
+Note: this is done in a background thread.
+@return a dummy parameter */
+UNIV_INTERN
+os_thread_ret_t
+trx_rollback_or_clean_all_recovered(
+/*================================*/
+ void* arg __attribute__((unused)))
+ /*!< in: a dummy parameter required by
+ os_thread_create */
+{
+ trx_rollback_or_clean_recovered(TRUE);
/* We count the number of threads in os_thread_exit(). A created
thread should always use that to exit and not use return() to exit. */
diff --git a/storage/xtradb/trx/trx0rseg.c b/storage/xtradb/trx/trx0rseg.c
index 580762e8716..8d754788e2a 100644
--- a/storage/xtradb/trx/trx0rseg.c
+++ b/storage/xtradb/trx/trx0rseg.c
@@ -132,6 +132,49 @@ trx_rseg_header_create(
}
/***********************************************************************//**
+Free's an instance of the rollback segment in memory. */
+UNIV_INTERN
+void
+trx_rseg_mem_free(
+/*==============*/
+ trx_rseg_t* rseg) /* in, own: instance to free */
+{
+ trx_undo_t* undo;
+
+ mutex_free(&rseg->mutex);
+
+ /* There can't be any active transactions. */
+ ut_a(UT_LIST_GET_LEN(rseg->update_undo_list) == 0);
+ ut_a(UT_LIST_GET_LEN(rseg->insert_undo_list) == 0);
+
+ undo = UT_LIST_GET_FIRST(rseg->update_undo_cached);
+
+ while (undo != NULL) {
+ trx_undo_t* prev_undo = undo;
+
+ undo = UT_LIST_GET_NEXT(undo_list, undo);
+ UT_LIST_REMOVE(undo_list, rseg->update_undo_cached, prev_undo);
+
+ trx_undo_mem_free(prev_undo);
+ }
+
+ undo = UT_LIST_GET_FIRST(rseg->insert_undo_cached);
+
+ while (undo != NULL) {
+ trx_undo_t* prev_undo = undo;
+
+ undo = UT_LIST_GET_NEXT(undo_list, undo);
+ UT_LIST_REMOVE(undo_list, rseg->insert_undo_cached, prev_undo);
+
+ trx_undo_mem_free(prev_undo);
+ }
+
+ trx_sys_set_nth_rseg(trx_sys, rseg->id, NULL);
+
+ mem_free(rseg);
+}
+
+/***************************************************************************
Creates and initializes a rollback segment object. The values for the
fields are read from the header. The object is inserted to the rseg
list of the trx system object and a pointer is inserted in the rseg
diff --git a/storage/xtradb/trx/trx0sys.c b/storage/xtradb/trx/trx0sys.c
index 81c614c8323..8ea34a8c81c 100644
--- a/storage/xtradb/trx/trx0sys.c
+++ b/storage/xtradb/trx/trx0sys.c
@@ -39,7 +39,9 @@ Created 3/26/1996 Heikki Tuuri
#include "srv0srv.h"
#include "trx0purge.h"
#include "log0log.h"
+#include "log0recv.h"
#include "os0file.h"
+#include "read0read.h"
/** The file format tag structure with id and name. */
struct file_format_struct {
@@ -552,6 +554,12 @@ trx_sys_doublewrite_init_or_restore_pages(
zip_size ? zip_size : UNIV_PAGE_SIZE,
read_buf, NULL);
+ if (srv_recovery_stats && recv_recovery_is_on()) {
+ mutex_enter(&(recv_sys->mutex));
+ recv_sys->stats_doublewrite_check_pages++;
+ mutex_exit(&(recv_sys->mutex));
+ }
+
/* Check if the page is corrupt */
if (UNIV_UNLIKELY
@@ -599,6 +607,13 @@ trx_sys_doublewrite_init_or_restore_pages(
zip_size, page_no, 0,
zip_size ? zip_size : UNIV_PAGE_SIZE,
page, NULL);
+
+ if (srv_recovery_stats && recv_recovery_is_on()) {
+ mutex_enter(&(recv_sys->mutex));
+ recv_sys->stats_doublewrite_overwrite_pages++;
+ mutex_exit(&(recv_sys->mutex));
+ }
+
fprintf(stderr,
"InnoDB: Recovered the page from"
" the doublewrite buffer.\n");
@@ -1592,3 +1607,80 @@ trx_sys_file_format_id_to_name(
}
#endif /* !UNIV_HOTBACKUP */
+
+/*********************************************************************
+Shutdown/Close the transaction system. */
+UNIV_INTERN
+void
+trx_sys_close(void)
+/*===============*/
+{
+ trx_rseg_t* rseg;
+ read_view_t* view;
+
+ ut_ad(trx_sys != NULL);
+
+ /* Check that all read views are closed except read view owned
+ by a purge. */
+
+ if (UT_LIST_GET_LEN(trx_sys->view_list) > 1) {
+ fprintf(stderr,
+ "InnoDB: Error: all read views were not closed"
+ " before shutdown:\n"
+ "InnoDB: %lu read views open \n",
+ UT_LIST_GET_LEN(trx_sys->view_list) - 1);
+ }
+
+ sess_close(trx_dummy_sess);
+ trx_dummy_sess = NULL;
+
+ trx_purge_sys_close();
+
+ mutex_enter(&kernel_mutex);
+
+ /* Free the double write data structures. */
+ ut_a(trx_doublewrite != NULL);
+ ut_free(trx_doublewrite->write_buf_unaligned);
+ trx_doublewrite->write_buf_unaligned = NULL;
+
+ mem_free(trx_doublewrite->buf_block_arr);
+ trx_doublewrite->buf_block_arr = NULL;
+
+ mutex_free(&trx_doublewrite->mutex);
+ mem_free(trx_doublewrite);
+ trx_doublewrite = NULL;
+
+ /* There can't be any active transactions. */
+ rseg = UT_LIST_GET_FIRST(trx_sys->rseg_list);
+
+ while (rseg != NULL) {
+ trx_rseg_t* prev_rseg = rseg;
+
+ rseg = UT_LIST_GET_NEXT(rseg_list, prev_rseg);
+ UT_LIST_REMOVE(rseg_list, trx_sys->rseg_list, prev_rseg);
+
+ trx_rseg_mem_free(prev_rseg);
+ }
+
+ view = UT_LIST_GET_FIRST(trx_sys->view_list);
+
+ while (view != NULL) {
+ read_view_t* prev_view = view;
+
+ view = UT_LIST_GET_NEXT(view_list, prev_view);
+
+ /* Views are allocated from the trx_sys->global_read_view_heap.
+ So, we simply remove the element here. */
+ UT_LIST_REMOVE(view_list, trx_sys->view_list, prev_view);
+ }
+
+ ut_a(UT_LIST_GET_LEN(trx_sys->trx_list) == 0);
+ ut_a(UT_LIST_GET_LEN(trx_sys->rseg_list) == 0);
+ ut_a(UT_LIST_GET_LEN(trx_sys->view_list) == 0);
+ ut_a(UT_LIST_GET_LEN(trx_sys->mysql_trx_list) == 0);
+
+ mem_free(trx_sys);
+
+ trx_sys = NULL;
+ mutex_exit(&kernel_mutex);
+}
diff --git a/storage/xtradb/trx/trx0trx.c b/storage/xtradb/trx/trx0trx.c
index 12253c131a8..69bc5c6b18b 100644
--- a/storage/xtradb/trx/trx0trx.c
+++ b/storage/xtradb/trx/trx0trx.c
@@ -178,6 +178,15 @@ trx_create(
trx->global_read_view = NULL;
trx->read_view = NULL;
+ trx->io_reads = 0;
+ trx->io_read = 0;
+ trx->io_reads_wait_timer = 0;
+ trx->lock_que_wait_timer = 0;
+ trx->innodb_que_wait_timer = 0;
+ trx->distinct_page_access = 0;
+ trx->distinct_page_access_hash = NULL;
+ trx->take_stats = FALSE;
+
/* Set X/Open XA transaction identification to NULL */
memset(&trx->xid, 0, sizeof(trx->xid));
trx->xid.formatID = -1;
@@ -215,6 +224,11 @@ trx_allocate_for_mysql(void)
trx->mysql_process_no = os_proc_get_number();
+ if (innobase_get_slow_log() && trx->take_stats) {
+ trx->distinct_page_access_hash = mem_alloc(DPAH_SIZE);
+ memset(trx->distinct_page_access_hash, 0, DPAH_SIZE);
+ }
+
return(trx);
}
@@ -346,6 +360,12 @@ trx_free_for_mysql(
/*===============*/
trx_t* trx) /*!< in, own: trx object */
{
+ if (trx->distinct_page_access_hash)
+ {
+ mem_free(trx->distinct_page_access_hash);
+ trx->distinct_page_access_hash= NULL;
+ }
+
mutex_enter(&kernel_mutex);
UT_LIST_REMOVE(mysql_trx_list, trx_sys->mysql_trx_list, trx);
@@ -367,6 +387,12 @@ trx_free_for_background(
/*====================*/
trx_t* trx) /*!< in, own: trx object */
{
+ if (trx->distinct_page_access_hash)
+ {
+ mem_free(trx->distinct_page_access_hash);
+ trx->distinct_page_access_hash= NULL;
+ }
+
mutex_enter(&kernel_mutex);
trx_free(trx);
@@ -820,7 +846,7 @@ trx_commit_off_kernel(
in exactly the same order as commit lsn's, if the transactions
have different rollback segments. To get exactly the same
order we should hold the kernel mutex up to this point,
- adding to to the contention of the kernel mutex. However, if
+ adding to the contention of the kernel mutex. However, if
a transaction T2 is able to see modifications made by
a transaction T1, T2 will always get a bigger transaction
number and a bigger commit lsn than T1. */
@@ -967,7 +993,7 @@ trx_commit_off_kernel(
/****************************************************************//**
Cleans up a transaction at database startup. The cleanup is needed if
the transaction already got to the middle of a commit when the database
-crashed, andf we cannot roll it back. */
+crashed, and we cannot roll it back. */
UNIV_INTERN
void
trx_cleanup_at_db_startup(
@@ -1072,6 +1098,9 @@ trx_end_lock_wait(
trx_t* trx) /*!< in: transaction */
{
que_thr_t* thr;
+ ulint sec;
+ ulint ms;
+ ib_uint64_t now;
ut_ad(mutex_own(&kernel_mutex));
ut_ad(trx->que_state == TRX_QUE_LOCK_WAIT);
@@ -1086,6 +1115,11 @@ trx_end_lock_wait(
thr = UT_LIST_GET_FIRST(trx->wait_thrs);
}
+ if (innobase_get_slow_log() && trx->take_stats) {
+ ut_usectime(&sec, &ms);
+ now = (ib_uint64_t)sec * 1000000 + ms;
+ trx->lock_que_wait_timer += (ulint)(now - trx->lock_que_wait_ustarted);
+ }
trx->que_state = TRX_QUE_RUNNING;
}
@@ -1099,6 +1133,9 @@ trx_lock_wait_to_suspended(
trx_t* trx) /*!< in: transaction in the TRX_QUE_LOCK_WAIT state */
{
que_thr_t* thr;
+ ulint sec;
+ ulint ms;
+ ib_uint64_t now;
ut_ad(mutex_own(&kernel_mutex));
ut_ad(trx->que_state == TRX_QUE_LOCK_WAIT);
@@ -1113,6 +1150,11 @@ trx_lock_wait_to_suspended(
thr = UT_LIST_GET_FIRST(trx->wait_thrs);
}
+ if (innobase_get_slow_log() && trx->take_stats) {
+ ut_usectime(&sec, &ms);
+ now = (ib_uint64_t)sec * 1000000 + ms;
+ trx->lock_que_wait_timer += (ulint)(now - trx->lock_que_wait_ustarted);
+ }
trx->que_state = TRX_QUE_RUNNING;
}
diff --git a/storage/xtradb/trx/trx0undo.c b/storage/xtradb/trx/trx0undo.c
index 99672d4eb81..063a2f2b8a6 100644
--- a/storage/xtradb/trx/trx0undo.c
+++ b/storage/xtradb/trx/trx0undo.c
@@ -1560,7 +1560,7 @@ trx_undo_mem_init_for_reuse(
/********************************************************************//**
Frees an undo log memory copy. */
-static
+UNIV_INTERN
void
trx_undo_mem_free(
/*==============*/