Commit 37492960 authored by Marko Mäkelä's avatar Marko Mäkelä

Merge 10.5 into 10.6

parents a24f2bb5 e0084b9d
...@@ -1053,7 +1053,7 @@ class trx_sys_t ...@@ -1053,7 +1053,7 @@ class trx_sys_t
void close(); void close();
/** @return total number of active (non-prepared) transactions */ /** @return total number of active (non-prepared) transactions */
ulint any_active_transactions(); size_t any_active_transactions(size_t *prepared= nullptr);
/** /**
......
...@@ -1545,7 +1545,7 @@ void srv_master_callback(void*) ...@@ -1545,7 +1545,7 @@ void srv_master_callback(void*)
} }
/** @return whether purge should exit due to shutdown */ /** @return whether purge should exit due to shutdown */
static bool srv_purge_should_exit() static bool srv_purge_should_exit(size_t old_history_size)
{ {
ut_ad(srv_shutdown_state <= SRV_SHUTDOWN_CLEANUP); ut_ad(srv_shutdown_state <= SRV_SHUTDOWN_CLEANUP);
...@@ -1556,8 +1556,12 @@ static bool srv_purge_should_exit() ...@@ -1556,8 +1556,12 @@ static bool srv_purge_should_exit()
return true; return true;
/* Slow shutdown was requested. */ /* Slow shutdown was requested. */
size_t prepared, active= trx_sys.any_active_transactions(&prepared);
const size_t history_size= trx_sys.history_size(); const size_t history_size= trx_sys.history_size();
if (history_size)
if (!history_size);
else if (!active && history_size == old_history_size && prepared);
else
{ {
static time_t progress_time; static time_t progress_time;
time_t now= time(NULL); time_t now= time(NULL);
...@@ -1574,7 +1578,7 @@ static bool srv_purge_should_exit() ...@@ -1574,7 +1578,7 @@ static bool srv_purge_should_exit()
return false; return false;
} }
return !trx_sys.any_active_transactions(); return !active;
} }
/*********************************************************************//** /*********************************************************************//**
...@@ -1716,7 +1720,7 @@ inline void purge_coordinator_state::do_purge() ...@@ -1716,7 +1720,7 @@ inline void purge_coordinator_state::do_purge()
break; break;
} }
if (!srv_purge_should_exit()) if (!srv_purge_should_exit(history_size))
goto loop; goto loop;
} }
...@@ -1912,15 +1916,19 @@ ulint srv_get_task_queue_length() ...@@ -1912,15 +1916,19 @@ ulint srv_get_task_queue_length()
/** Shut down the purge threads. */ /** Shut down the purge threads. */
void srv_purge_shutdown() void srv_purge_shutdown()
{ {
if (purge_sys.enabled()) { if (purge_sys.enabled())
if (!srv_fast_shutdown && !opt_bootstrap) {
srv_update_purge_thread_count(innodb_purge_threads_MAX); if (!srv_fast_shutdown && !opt_bootstrap)
while(!srv_purge_should_exit()) { srv_update_purge_thread_count(innodb_purge_threads_MAX);
ut_a(!purge_sys.paused()); size_t history_size= trx_sys.history_size();
srv_wake_purge_thread_if_not_active(); while (!srv_purge_should_exit(history_size))
purge_coordinator_task.wait(); {
} history_size= trx_sys.history_size();
purge_sys.coordinator_shutdown(); ut_a(!purge_sys.paused());
srv_shutdown_purge_tasks(); srv_wake_purge_thread_if_not_active();
} purge_coordinator_task.wait();
}
purge_sys.coordinator_shutdown();
srv_shutdown_purge_tasks();
}
} }
...@@ -369,19 +369,6 @@ trx_purge_add_undo_to_history(const trx_t* trx, trx_undo_t*& undo, mtr_t* mtr) ...@@ -369,19 +369,6 @@ trx_purge_add_undo_to_history(const trx_t* trx, trx_undo_t*& undo, mtr_t* mtr)
undo = NULL; undo = NULL;
} }
MY_ATTRIBUTE((nonnull, warn_unused_result))
/** Remove undo log header from the history list.
@param[in,out] rseg rollback segment header page
@param[in] log undo log segment header page
@param[in] offset byte offset in the undo log segment header page
@param[in,out] mtr mini-transaction */
static dberr_t trx_purge_remove_log_hdr(buf_block_t *rseg, buf_block_t* log,
uint16_t offset, mtr_t *mtr)
{
return flst_remove(rseg, TRX_RSEG + TRX_RSEG_HISTORY, log,
uint16_t(offset + TRX_UNDO_HISTORY_NODE), mtr);
}
/** Free an undo log segment. /** Free an undo log segment.
@param block rollback segment header page @param block rollback segment header page
@param mtr mini-transaction */ @param mtr mini-transaction */
...@@ -474,18 +461,16 @@ trx_purge_truncate_rseg_history(trx_rseg_t& rseg, ...@@ -474,18 +461,16 @@ trx_purge_truncate_rseg_history(trx_rseg_t& rseg,
TRX_UNDO_HISTORY_NODE); TRX_UNDO_HISTORY_NODE);
prev_hdr_addr.boffset= static_cast<uint16_t>(prev_hdr_addr.boffset - prev_hdr_addr.boffset= static_cast<uint16_t>(prev_hdr_addr.boffset -
TRX_UNDO_HISTORY_NODE); TRX_UNDO_HISTORY_NODE);
err= trx_purge_remove_log_hdr(rseg_hdr, b, hdr_addr.boffset, &mtr);
err= flst_remove(rseg_hdr, TRX_RSEG + TRX_RSEG_HISTORY, b,
uint16_t(hdr_addr.boffset + TRX_UNDO_HISTORY_NODE), &mtr);
if (UNIV_UNLIKELY(err != DB_SUCCESS)) if (UNIV_UNLIKELY(err != DB_SUCCESS))
goto func_exit; goto func_exit;
rseg_hdr->fix(); rseg_hdr->fix();
if (mach_read_from_2(b->page.frame + hdr_addr.boffset + TRX_UNDO_NEXT_LOG) || if (mach_read_from_2(b->page.frame + hdr_addr.boffset + TRX_UNDO_NEXT_LOG))
rseg.is_referenced() || /* We cannot free the entire undo log segment. */;
rseg.needs_purge > (purge_sys.head.trx_no
? purge_sys.head.trx_no
: purge_sys.tail.trx_no))
/* We cannot free the entire undo page. */;
else else
{ {
const uint32_t seg_size= const uint32_t seg_size=
...@@ -613,8 +598,9 @@ TRANSACTIONAL_TARGET static void trx_purge_truncate_history() ...@@ -613,8 +598,9 @@ TRANSACTIONAL_TARGET static void trx_purge_truncate_history()
{ {
ut_ad(rseg.is_persistent()); ut_ad(rseg.is_persistent());
rseg.latch.wr_lock(SRW_LOCK_CALL); rseg.latch.wr_lock(SRW_LOCK_CALL);
if (dberr_t e= trx_purge_truncate_rseg_history(rseg, head)) if (!rseg.is_referenced() && rseg.needs_purge <= head.trx_no)
err= e; if (dberr_t e= trx_purge_truncate_rseg_history(rseg, head))
err= e;
rseg.latch.wr_unlock(); rseg.latch.wr_unlock();
} }
......
...@@ -343,15 +343,29 @@ trx_sys_t::close() ...@@ -343,15 +343,29 @@ trx_sys_t::close()
} }
/** @return total number of active (non-prepared) transactions */ /** @return total number of active (non-prepared) transactions */
ulint trx_sys_t::any_active_transactions() size_t trx_sys_t::any_active_transactions(size_t *prepared)
{ {
uint32_t total_trx= 0; size_t total_trx= 0, prepared_trx= 0;
trx_sys.trx_list.for_each([&total_trx](const trx_t &trx) { trx_sys.trx_list.for_each([&](const trx_t &trx) {
if (trx.state == TRX_STATE_COMMITTED_IN_MEMORY || switch (trx.state) {
(trx.state == TRX_STATE_ACTIVE && trx.id)) case TRX_STATE_NOT_STARTED:
break;
case TRX_STATE_ACTIVE:
if (!trx.id)
break;
/* fall through */
case TRX_STATE_COMMITTED_IN_MEMORY:
total_trx++; total_trx++;
break;
case TRX_STATE_PREPARED:
case TRX_STATE_PREPARED_RECOVERED:
prepared_trx++;
}
}); });
if (prepared)
*prepared= prepared_trx;
return total_trx; return total_trx;
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment