diff --git a/storage/innobase/include/read0types.h b/storage/innobase/include/read0types.h index 4eaf1732aab..a585fdb91a9 100644 --- a/storage/innobase/include/read0types.h +++ b/storage/innobase/include/read0types.h @@ -231,6 +231,8 @@ class ReadView { @return true if there are no transaction ids in the snapshot */ bool empty() const { return (m_ids.empty()); } + void copy_from(const ReadView &other); + #ifdef UNIV_DEBUG /** @return the view low limit number */ diff --git a/storage/innobase/read/read0read.cc b/storage/innobase/read/read0read.cc index a918b11b06f..42e2185e011 100644 --- a/storage/innobase/read/read0read.cc +++ b/storage/innobase/read/read0read.cc @@ -36,6 +36,8 @@ this program; if not, write to the Free Software Foundation, Inc., #include "srv0srv.h" #include "trx0sys.h" +#include "current_thd.h" +#include /* ------------------------------------------------------------------------------- @@ -520,6 +522,11 @@ void MVCC::view_open(ReadView *&view, trx_t *trx) { if (trx_is_autocommit_non_locking(trx) && view->empty()) { view->m_closed = false; +#ifdef UNIV_DEBUG + if (current_thd) { + DEBUG_SYNC(current_thd, "simulate_stop_after_setting_m_closed"); + } +#endif if (view->m_low_limit_id == trx_sys_get_next_trx_id_or_no()) { return; @@ -699,3 +706,8 @@ void MVCC::view_close(ReadView *&view, bool own_mutex) { view = nullptr; } } + +void ReadView::copy_from(const ReadView &other) { + copy_prepare(other); + copy_complete(); +} diff --git a/storage/innobase/trx/trx0purge.cc b/storage/innobase/trx/trx0purge.cc index cbbac9eb59f..444522940e5 100644 --- a/storage/innobase/trx/trx0purge.cc +++ b/storage/innobase/trx/trx0purge.cc @@ -2393,6 +2393,8 @@ ulint trx_purge(ulint n_purge_threads, /*!< in: number of purge tasks { que_thr_t *thr = nullptr; ulint n_pages_handled; + ReadView last_view; + last_view.copy_from(purge_sys->view); ut_a(n_purge_threads > 0); @@ -2405,8 +2407,21 @@ ulint trx_purge(ulint n_purge_threads, /*!< in: number of purge tasks trx_sys->mvcc->clone_oldest_view(&purge_sys->view); + if (unlikely(purge_sys->view.low_limit_no() < last_view.low_limit_no())) { + purge_sys->view.copy_from(last_view); + } + rw_lock_x_unlock(&purge_sys->latch); + DBUG_EXECUTE_IF("simulate_stop_after_clone_oldest_view", { + bool end = false; + while (!end) { + std::this_thread::sleep_for(std::chrono::seconds(1)); + ib::info() << "[TXSQL] purge thread stopped after clone oldest view"; + DBUG_EXECUTE_IF("continue_to_purge", { end = true; }); + } + }); + #ifdef UNIV_DEBUG if (srv_purge_view_update_only_debug) { return (0);