summaryrefslogtreecommitdiff
path: root/storage/xtradb/trx
diff options
context:
space:
mode:
Diffstat (limited to 'storage/xtradb/trx')
-rw-r--r--storage/xtradb/trx/trx0purge.c17
-rw-r--r--storage/xtradb/trx/trx0rec.c20
-rw-r--r--storage/xtradb/trx/trx0trx.c6
3 files changed, 40 insertions, 3 deletions
diff --git a/storage/xtradb/trx/trx0purge.c b/storage/xtradb/trx/trx0purge.c
index 122aab119ba..b048dc66efe 100644
--- a/storage/xtradb/trx/trx0purge.c
+++ b/storage/xtradb/trx/trx0purge.c
@@ -61,6 +61,10 @@ UNIV_INTERN mysql_pfs_key_t trx_purge_latch_key;
UNIV_INTERN mysql_pfs_key_t purge_sys_bh_mutex_key;
#endif /* UNIV_PFS_MUTEX */
+#ifdef UNIV_DEBUG
+UNIV_INTERN my_bool srv_purge_view_update_only_debug;
+#endif /* UNIV_DEBUG */
+
/*****************************************************************//**
Checks if trx_id is >= purge_view: then it is guaranteed that its update
undo log still exists in the system.
@@ -236,6 +240,7 @@ trx_purge_sys_create(
purge_sys->purge_trx_no = 0;
purge_sys->purge_undo_no = 0;
purge_sys->next_stored = FALSE;
+ ut_d(purge_sys->done_trx_no = 0);
rw_lock_create(trx_purge_latch_key,
&purge_sys->latch, SYNC_PURGE_LATCH);
@@ -656,6 +661,12 @@ trx_purge_truncate_if_arr_empty(void)
{
static ulint count;
+#ifdef UNIV_DEBUG
+ if (purge_sys->arr->n_used == 0) {
+ purge_sys->done_trx_no = purge_sys->purge_trx_no;
+ }
+#endif /* UNIV_DEBUG */
+
if (!(++count % TRX_SYS_N_RSEGS) && purge_sys->arr->n_used == 0) {
trx_purge_truncate_history();
@@ -1172,6 +1183,12 @@ trx_purge(
rw_lock_x_unlock(&(purge_sys->latch));
+#ifdef UNIV_DEBUG
+ if (srv_purge_view_update_only_debug) {
+ return(0);
+ }
+#endif
+
purge_sys->state = TRX_PURGE_ON;
purge_sys->handle_limit = purge_sys->n_pages_handled + limit;
diff --git a/storage/xtradb/trx/trx0rec.c b/storage/xtradb/trx/trx0rec.c
index db4897c368d..ef42152aeb7 100644
--- a/storage/xtradb/trx/trx0rec.c
+++ b/storage/xtradb/trx/trx0rec.c
@@ -36,6 +36,7 @@ Created 3/26/1996 Heikki Tuuri
#ifndef UNIV_HOTBACKUP
#include "dict0dict.h"
#include "ut0mem.h"
+#include "read0read.h"
#include "row0ext.h"
#include "row0upd.h"
#include "que0que.h"
@@ -1647,6 +1648,25 @@ trx_undo_prev_version_build(
if (row_upd_changes_field_size_or_external(index, offsets, update)) {
ulint n_ext;
+ /* We should confirm the existence of disowned external data,
+ if the previous version record is delete marked. If the trx_id
+ of the previous record is seen by purge view, we should treat
+ it as missing history, because the disowned external data
+ might be purged already.
+
+ The inherited external data (BLOBs) can be freed (purged)
+ after trx_id was committed, provided that no view was started
+ before trx_id. If the purge view can see the committed
+ delete-marked record by trx_id, no transactions need to access
+ the BLOB. */
+
+ if ((update->info_bits & REC_INFO_DELETED_FLAG)
+ && read_view_sees_trx_id(purge_sys->view, trx_id)) {
+ /* treat as a fresh insert, not to
+ cause assertion error at the caller. */
+ return(DB_SUCCESS);
+ }
+
/* 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 bits for
diff --git a/storage/xtradb/trx/trx0trx.c b/storage/xtradb/trx/trx0trx.c
index 99b4276fbee..a17f8abdad0 100644
--- a/storage/xtradb/trx/trx0trx.c
+++ b/storage/xtradb/trx/trx0trx.c
@@ -235,7 +235,7 @@ trx_allocate_for_mysql(void)
mutex_exit(&kernel_mutex);
- if (innobase_get_slow_log() && trx->take_stats) {
+ if (UNIV_UNLIKELY(trx->take_stats)) {
trx->distinct_page_access_hash = mem_alloc(DPAH_SIZE);
memset(trx->distinct_page_access_hash, 0, DPAH_SIZE);
}
@@ -1269,7 +1269,7 @@ trx_end_lock_wait(
thr = UT_LIST_GET_FIRST(trx->wait_thrs);
}
- if (innobase_get_slow_log() && trx->take_stats) {
+ if (UNIV_UNLIKELY(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);
@@ -1304,7 +1304,7 @@ trx_lock_wait_to_suspended(
thr = UT_LIST_GET_FIRST(trx->wait_thrs);
}
- if (innobase_get_slow_log() && trx->take_stats) {
+ if (UNIV_UNLIKELY(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);