summaryrefslogtreecommitdiff
path: root/storage/xtradb/trx
diff options
context:
space:
mode:
authorSachin Setiya <sachin.setiya@mariadb.com>2017-03-17 02:05:20 +0530
committerSachin Setiya <sachin.setiya@mariadb.com>2017-03-17 02:05:20 +0530
commitf66395f7c06f357e7ace74317e6563a1e5dbc3ae (patch)
treed1669b069aa722c9c73abe52e5924b7bbba41b39 /storage/xtradb/trx
parentc401773c8dd97bd9f6bf6cff9fcafdf24fbd0ee1 (diff)
parentc4f3e64c23fe7f7fd18c0a79f87f9771df15fe9f (diff)
downloadmariadb-git-f66395f7c06f357e7ace74317e6563a1e5dbc3ae.tar.gz
Merge tag 'mariadb-10.0.30' into bb-sachin-10.0-galera-merge
Signed-off-by: Sachin Setiya <sachin.setiya@mariadb.com>
Diffstat (limited to 'storage/xtradb/trx')
-rw-r--r--storage/xtradb/trx/trx0purge.cc20
-rw-r--r--storage/xtradb/trx/trx0sys.cc70
-rw-r--r--storage/xtradb/trx/trx0trx.cc6
-rw-r--r--storage/xtradb/trx/trx0undo.cc29
4 files changed, 100 insertions, 25 deletions
diff --git a/storage/xtradb/trx/trx0purge.cc b/storage/xtradb/trx/trx0purge.cc
index d9e40c5d6f5..6b7b7df4cd8 100644
--- a/storage/xtradb/trx/trx0purge.cc
+++ b/storage/xtradb/trx/trx0purge.cc
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2017, MariaDB Corporation. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -172,13 +173,9 @@ trx_purge_sys_close(void)
sess_close(purge_sys->sess);
- purge_sys->sess = NULL;
-
read_view_free(purge_sys->prebuilt_view);
read_view_free(purge_sys->prebuilt_clone);
- purge_sys->view = NULL;
-
rw_lock_free(&purge_sys->latch);
mutex_free(&purge_sys->bh_mutex);
@@ -187,9 +184,6 @@ trx_purge_sys_close(void)
ib_bh_free(purge_sys->ib_bh);
os_event_free(purge_sys->event);
-
- purge_sys->event = NULL;
-
mem_free(purge_sys);
purge_sys = NULL;
@@ -1306,20 +1300,16 @@ void
trx_purge_stop(void)
/*================*/
{
- purge_state_t state;
- ib_int64_t sig_count = os_event_reset(purge_sys->event);
-
ut_a(srv_n_purge_threads > 0);
rw_lock_x_lock(&purge_sys->latch);
- ut_a(purge_sys->state != PURGE_STATE_INIT);
- ut_a(purge_sys->state != PURGE_STATE_EXIT);
- ut_a(purge_sys->state != PURGE_STATE_DISABLED);
+ const ib_int64_t sig_count = os_event_reset(purge_sys->event);
+ const purge_state_t state = purge_sys->state;
- ++purge_sys->n_stop;
+ ut_a(state == PURGE_STATE_RUN || state == PURGE_STATE_STOP);
- state = purge_sys->state;
+ ++purge_sys->n_stop;
if (state == PURGE_STATE_RUN) {
ib_logf(IB_LOG_LEVEL_INFO, "Stopping purge");
diff --git a/storage/xtradb/trx/trx0sys.cc b/storage/xtradb/trx/trx0sys.cc
index 6f524718052..5126711fb82 100644
--- a/storage/xtradb/trx/trx0sys.cc
+++ b/storage/xtradb/trx/trx0sys.cc
@@ -1333,7 +1333,9 @@ trx_sys_close(void)
ut_a(UT_LIST_GET_LEN(trx_sys->ro_trx_list) == 0);
/* Only prepared transactions may be left in the system. Free them. */
- ut_a(UT_LIST_GET_LEN(trx_sys->rw_trx_list) == trx_sys->n_prepared_trx);
+ ut_a(UT_LIST_GET_LEN(trx_sys->rw_trx_list) == trx_sys->n_prepared_trx
+ || srv_read_only_mode
+ || srv_force_recovery >= SRV_FORCE_NO_TRX_UNDO);
while ((trx = UT_LIST_GET_FIRST(trx_sys->rw_trx_list)) != NULL) {
trx_free_prepared(trx);
@@ -1379,6 +1381,33 @@ trx_sys_close(void)
trx_sys = NULL;
}
+/** @brief Convert an undo log to TRX_UNDO_PREPARED state on shutdown.
+
+If any prepared ACTIVE transactions exist, and their rollback was
+prevented by innodb_force_recovery, we convert these transactions to
+XA PREPARE state in the main-memory data structures, so that shutdown
+will proceed normally. These transactions will again recover as ACTIVE
+on the next restart, and they will be rolled back unless
+innodb_force_recovery prevents it again.
+
+@param[in] trx transaction
+@param[in,out] undo undo log to convert to TRX_UNDO_PREPARED */
+static
+void
+trx_undo_fake_prepared(
+ const trx_t* trx,
+ trx_undo_t* undo)
+{
+ ut_ad(srv_force_recovery >= SRV_FORCE_NO_TRX_UNDO);
+ ut_ad(trx_state_eq(trx, TRX_STATE_ACTIVE));
+ ut_ad(trx->is_recovered);
+
+ if (undo != NULL) {
+ ut_ad(undo->state == TRX_UNDO_ACTIVE);
+ undo->state = TRX_UNDO_PREPARED;
+ }
+}
+
/*********************************************************************
Check if there are any active (non-prepared) transactions.
@return total number of active transactions or 0 if none */
@@ -1387,15 +1416,42 @@ ulint
trx_sys_any_active_transactions(void)
/*=================================*/
{
- ulint total_trx = 0;
-
mutex_enter(&trx_sys->mutex);
- total_trx = UT_LIST_GET_LEN(trx_sys->rw_trx_list)
- + UT_LIST_GET_LEN(trx_sys->mysql_trx_list);
+ ulint total_trx = UT_LIST_GET_LEN(trx_sys->mysql_trx_list);
+
+ if (total_trx == 0) {
+ total_trx = UT_LIST_GET_LEN(trx_sys->rw_trx_list);
+ ut_a(total_trx >= trx_sys->n_prepared_trx);
+
+ if (total_trx > trx_sys->n_prepared_trx
+ && srv_force_recovery >= SRV_FORCE_NO_TRX_UNDO) {
+ for (trx_t* trx = UT_LIST_GET_FIRST(
+ trx_sys->rw_trx_list);
+ trx != NULL;
+ trx = UT_LIST_GET_NEXT(trx_list, trx)) {
+ if (!trx_state_eq(trx, TRX_STATE_ACTIVE)
+ || !trx->is_recovered) {
+ continue;
+ }
+ /* This was a recovered transaction
+ whose rollback was disabled by
+ the innodb_force_recovery setting.
+ Pretend that it is in XA PREPARE
+ state so that shutdown will work. */
+ trx_undo_fake_prepared(
+ trx, trx->insert_undo);
+ trx_undo_fake_prepared(
+ trx, trx->update_undo);
+ trx->state = TRX_STATE_PREPARED;
+ trx_sys->n_prepared_trx++;
+ trx_sys->n_prepared_recovered_trx++;
+ }
+ }
- ut_a(total_trx >= trx_sys->n_prepared_trx);
- total_trx -= trx_sys->n_prepared_trx;
+ ut_a(total_trx >= trx_sys->n_prepared_trx);
+ total_trx -= trx_sys->n_prepared_trx;
+ }
mutex_exit(&trx_sys->mutex);
diff --git a/storage/xtradb/trx/trx0trx.cc b/storage/xtradb/trx/trx0trx.cc
index 97d1f264235..07e122e54ee 100644
--- a/storage/xtradb/trx/trx0trx.cc
+++ b/storage/xtradb/trx/trx0trx.cc
@@ -476,7 +476,11 @@ trx_free_prepared(
/*==============*/
trx_t* trx) /*!< in, own: trx object */
{
- ut_a(trx_state_eq(trx, TRX_STATE_PREPARED));
+ ut_a(trx_state_eq(trx, TRX_STATE_PREPARED)
+ || (trx_state_eq(trx, TRX_STATE_ACTIVE)
+ && trx->is_recovered
+ && (srv_read_only_mode
+ || srv_force_recovery >= SRV_FORCE_NO_TRX_UNDO)));
ut_a(trx->magic_n == TRX_MAGIC_N);
lock_trx_release_locks(trx);
diff --git a/storage/xtradb/trx/trx0undo.cc b/storage/xtradb/trx/trx0undo.cc
index cdd23726f2e..220589dd9ff 100644
--- a/storage/xtradb/trx/trx0undo.cc
+++ b/storage/xtradb/trx/trx0undo.cc
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2014, 2017, MariaDB Corporation. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -2011,13 +2012,37 @@ trx_undo_free_prepared(
ut_ad(srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS);
if (trx->update_undo) {
- ut_a(trx->update_undo->state == TRX_UNDO_PREPARED);
+ switch (trx->update_undo->state) {
+ case TRX_UNDO_PREPARED:
+ break;
+ case TRX_UNDO_ACTIVE:
+ /* lock_trx_release_locks() assigns
+ trx->is_recovered=false */
+ ut_a(srv_read_only_mode
+ || srv_force_recovery >= SRV_FORCE_NO_TRX_UNDO);
+ break;
+ default:
+ ut_error;
+ }
+
UT_LIST_REMOVE(undo_list, trx->rseg->update_undo_list,
trx->update_undo);
trx_undo_mem_free(trx->update_undo);
}
if (trx->insert_undo) {
- ut_a(trx->insert_undo->state == TRX_UNDO_PREPARED);
+ switch (trx->insert_undo->state) {
+ case TRX_UNDO_PREPARED:
+ break;
+ case TRX_UNDO_ACTIVE:
+ /* lock_trx_release_locks() assigns
+ trx->is_recovered=false */
+ ut_a(srv_read_only_mode
+ || srv_force_recovery >= SRV_FORCE_NO_TRX_UNDO);
+ break;
+ default:
+ ut_error;
+ }
+
UT_LIST_REMOVE(undo_list, trx->rseg->insert_undo_list,
trx->insert_undo);
trx_undo_mem_free(trx->insert_undo);