Merge bb-10.6-release into 10.6
This commit is contained in:
commit
347e22fbf8
@ -1053,7 +1053,7 @@ public:
|
||||
void close();
|
||||
|
||||
/** @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*)
|
||||
}
|
||||
|
||||
/** @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);
|
||||
|
||||
@ -1556,8 +1556,12 @@ static bool srv_purge_should_exit()
|
||||
return true;
|
||||
|
||||
/* Slow shutdown was requested. */
|
||||
size_t prepared, active= trx_sys.any_active_transactions(&prepared);
|
||||
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;
|
||||
time_t now= time(NULL);
|
||||
@ -1574,7 +1578,7 @@ static bool srv_purge_should_exit()
|
||||
return false;
|
||||
}
|
||||
|
||||
return !trx_sys.any_active_transactions();
|
||||
return !active;
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
@ -1716,7 +1720,7 @@ fewer_threads:
|
||||
break;
|
||||
}
|
||||
|
||||
if (!srv_purge_should_exit())
|
||||
if (!srv_purge_should_exit(history_size))
|
||||
goto loop;
|
||||
}
|
||||
|
||||
@ -1912,15 +1916,19 @@ ulint srv_get_task_queue_length()
|
||||
/** Shut down the purge threads. */
|
||||
void srv_purge_shutdown()
|
||||
{
|
||||
if (purge_sys.enabled()) {
|
||||
if (!srv_fast_shutdown && !opt_bootstrap)
|
||||
srv_update_purge_thread_count(innodb_purge_threads_MAX);
|
||||
while(!srv_purge_should_exit()) {
|
||||
ut_a(!purge_sys.paused());
|
||||
srv_wake_purge_thread_if_not_active();
|
||||
purge_coordinator_task.wait();
|
||||
}
|
||||
purge_sys.coordinator_shutdown();
|
||||
srv_shutdown_purge_tasks();
|
||||
}
|
||||
if (purge_sys.enabled())
|
||||
{
|
||||
if (!srv_fast_shutdown && !opt_bootstrap)
|
||||
srv_update_purge_thread_count(innodb_purge_threads_MAX);
|
||||
size_t history_size= trx_sys.history_size();
|
||||
while (!srv_purge_should_exit(history_size))
|
||||
{
|
||||
history_size= trx_sys.history_size();
|
||||
ut_a(!purge_sys.paused());
|
||||
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)
|
||||
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.
|
||||
@param block rollback segment header page
|
||||
@param mtr mini-transaction */
|
||||
@ -391,7 +378,7 @@ static void trx_purge_free_segment(buf_block_t *block, mtr_t &mtr)
|
||||
block->page.frame, &mtr))
|
||||
{
|
||||
block->fix();
|
||||
const page_id_t id{block->page.id()};
|
||||
ut_d(const page_id_t id{block->page.id()});
|
||||
mtr.commit();
|
||||
/* NOTE: If the server is killed after the log that was produced
|
||||
up to this point was written, and before the log from the mtr.commit()
|
||||
@ -403,16 +390,8 @@ static void trx_purge_free_segment(buf_block_t *block, mtr_t &mtr)
|
||||
log_free_check();
|
||||
mtr.start();
|
||||
block->page.lock.x_lock();
|
||||
if (UNIV_UNLIKELY(block->page.id() != id))
|
||||
{
|
||||
block->unfix();
|
||||
block->page.lock.x_unlock();
|
||||
block= buf_page_get_gen(id, 0, RW_X_LATCH, nullptr, BUF_GET, &mtr);
|
||||
if (!block)
|
||||
return;
|
||||
}
|
||||
else
|
||||
mtr.memo_push(block, MTR_MEMO_PAGE_X_MODIFY);
|
||||
ut_ad(block->page.id() == id);
|
||||
mtr.memo_push(block, MTR_MEMO_PAGE_X_MODIFY);
|
||||
}
|
||||
|
||||
while (!fseg_free_step(TRX_UNDO_SEG_HDR + TRX_UNDO_FSEG_HEADER +
|
||||
@ -434,7 +413,6 @@ trx_purge_truncate_rseg_history(trx_rseg_t& rseg,
|
||||
mtr.start();
|
||||
|
||||
dberr_t err;
|
||||
reget:
|
||||
buf_block_t *rseg_hdr= rseg.get(&mtr, &err);
|
||||
if (!rseg_hdr)
|
||||
{
|
||||
@ -474,18 +452,16 @@ loop:
|
||||
TRX_UNDO_HISTORY_NODE);
|
||||
prev_hdr_addr.boffset= static_cast<uint16_t>(prev_hdr_addr.boffset -
|
||||
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))
|
||||
goto func_exit;
|
||||
|
||||
rseg_hdr->fix();
|
||||
|
||||
if (mach_read_from_2(b->page.frame + hdr_addr.boffset + TRX_UNDO_NEXT_LOG) ||
|
||||
rseg.is_referenced() ||
|
||||
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. */;
|
||||
if (mach_read_from_2(b->page.frame + hdr_addr.boffset + TRX_UNDO_NEXT_LOG))
|
||||
/* We cannot free the entire undo log segment. */;
|
||||
else
|
||||
{
|
||||
const uint32_t seg_size=
|
||||
@ -535,12 +511,7 @@ loop:
|
||||
log_free_check();
|
||||
mtr.start();
|
||||
rseg_hdr->page.lock.x_lock();
|
||||
if (UNIV_UNLIKELY(rseg_hdr->page.id() != rseg.page_id()))
|
||||
{
|
||||
rseg_hdr->unfix();
|
||||
rseg_hdr->page.lock.x_unlock();
|
||||
goto reget;
|
||||
}
|
||||
ut_ad(rseg_hdr->page.id() == rseg.page_id());
|
||||
mtr.memo_push(rseg_hdr, MTR_MEMO_PAGE_X_MODIFY);
|
||||
|
||||
goto loop;
|
||||
@ -613,8 +584,9 @@ TRANSACTIONAL_TARGET static void trx_purge_truncate_history()
|
||||
{
|
||||
ut_ad(rseg.is_persistent());
|
||||
rseg.latch.wr_lock(SRW_LOCK_CALL);
|
||||
if (dberr_t e= trx_purge_truncate_rseg_history(rseg, head))
|
||||
err= e;
|
||||
if (!rseg.is_referenced() && rseg.needs_purge <= head.trx_no)
|
||||
if (dberr_t e= trx_purge_truncate_rseg_history(rseg, head))
|
||||
err= e;
|
||||
rseg.latch.wr_unlock();
|
||||
}
|
||||
|
||||
|
@ -343,15 +343,29 @@ trx_sys_t::close()
|
||||
}
|
||||
|
||||
/** @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) {
|
||||
if (trx.state == TRX_STATE_COMMITTED_IN_MEMORY ||
|
||||
(trx.state == TRX_STATE_ACTIVE && trx.id))
|
||||
trx_sys.trx_list.for_each([&](const trx_t &trx) {
|
||||
switch (trx.state) {
|
||||
case TRX_STATE_NOT_STARTED:
|
||||
break;
|
||||
case TRX_STATE_ACTIVE:
|
||||
if (!trx.id)
|
||||
break;
|
||||
/* fall through */
|
||||
case TRX_STATE_COMMITTED_IN_MEMORY:
|
||||
total_trx++;
|
||||
break;
|
||||
case TRX_STATE_PREPARED:
|
||||
case TRX_STATE_PREPARED_RECOVERED:
|
||||
prepared_trx++;
|
||||
}
|
||||
});
|
||||
|
||||
if (prepared)
|
||||
*prepared= prepared_trx;
|
||||
|
||||
return total_trx;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user