diff options
author | Sachin Setiya <sachin.setiya@mariadb.com> | 2017-03-17 02:05:20 +0530 |
---|---|---|
committer | Sachin Setiya <sachin.setiya@mariadb.com> | 2017-03-17 02:05:20 +0530 |
commit | f66395f7c06f357e7ace74317e6563a1e5dbc3ae (patch) | |
tree | d1669b069aa722c9c73abe52e5924b7bbba41b39 /storage/xtradb/trx | |
parent | c401773c8dd97bd9f6bf6cff9fcafdf24fbd0ee1 (diff) | |
parent | c4f3e64c23fe7f7fd18c0a79f87f9771df15fe9f (diff) | |
download | mariadb-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.cc | 20 | ||||
-rw-r--r-- | storage/xtradb/trx/trx0sys.cc | 70 | ||||
-rw-r--r-- | storage/xtradb/trx/trx0trx.cc | 6 | ||||
-rw-r--r-- | storage/xtradb/trx/trx0undo.cc | 29 |
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); |