Merge bb-10.6-release into 10.6

This commit is contained in:
Marko Mäkelä 2023-05-19 14:23:53 +03:00
commit 347e22fbf8
4 changed files with 55 additions and 61 deletions

View File

@ -1053,7 +1053,7 @@ public:
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);
/** /**

View File

@ -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()
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()
return false; return false;
} }
return !trx_sys.any_active_transactions(); return !active;
} }
/*********************************************************************//** /*********************************************************************//**
@ -1716,7 +1720,7 @@ fewer_threads:
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()
/** 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();
}
} }

View File

@ -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 */
@ -391,7 +378,7 @@ static void trx_purge_free_segment(buf_block_t *block, mtr_t &mtr)
block->page.frame, &mtr)) block->page.frame, &mtr))
{ {
block->fix(); block->fix();
const page_id_t id{block->page.id()}; ut_d(const page_id_t id{block->page.id()});
mtr.commit(); mtr.commit();
/* NOTE: If the server is killed after the log that was produced /* 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() 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(); log_free_check();
mtr.start(); mtr.start();
block->page.lock.x_lock(); block->page.lock.x_lock();
if (UNIV_UNLIKELY(block->page.id() != id)) ut_ad(block->page.id() == id);
{ mtr.memo_push(block, MTR_MEMO_PAGE_X_MODIFY);
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);
} }
while (!fseg_free_step(TRX_UNDO_SEG_HDR + TRX_UNDO_FSEG_HEADER + 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(); mtr.start();
dberr_t err; dberr_t err;
reget:
buf_block_t *rseg_hdr= rseg.get(&mtr, &err); buf_block_t *rseg_hdr= rseg.get(&mtr, &err);
if (!rseg_hdr) if (!rseg_hdr)
{ {
@ -474,18 +452,16 @@ loop:
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=
@ -535,12 +511,7 @@ loop:
log_free_check(); log_free_check();
mtr.start(); mtr.start();
rseg_hdr->page.lock.x_lock(); rseg_hdr->page.lock.x_lock();
if (UNIV_UNLIKELY(rseg_hdr->page.id() != rseg.page_id())) ut_ad(rseg_hdr->page.id() == rseg.page_id());
{
rseg_hdr->unfix();
rseg_hdr->page.lock.x_unlock();
goto reget;
}
mtr.memo_push(rseg_hdr, MTR_MEMO_PAGE_X_MODIFY); mtr.memo_push(rseg_hdr, MTR_MEMO_PAGE_X_MODIFY);
goto loop; goto loop;
@ -613,8 +584,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();
} }

View File

@ -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;
} }