Skip to content

Commit b0723f6

Browse files
committed
Merge branch '10.9' into 10.10
2 parents 91b31ce + be19f81 commit b0723f6

File tree

4 files changed

+64
-64
lines changed

4 files changed

+64
-64
lines changed

storage/innobase/include/trx0sys.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1053,7 +1053,7 @@ class trx_sys_t
10531053
void close();
10541054

10551055
/** @return total number of active (non-prepared) transactions */
1056-
ulint any_active_transactions();
1056+
size_t any_active_transactions(size_t *prepared= nullptr);
10571057

10581058

10591059
/**

storage/innobase/srv/srv0srv.cc

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1409,7 +1409,7 @@ void srv_master_callback(void*)
14091409
}
14101410

14111411
/** @return whether purge should exit due to shutdown */
1412-
static bool srv_purge_should_exit()
1412+
static bool srv_purge_should_exit(size_t old_history_size)
14131413
{
14141414
ut_ad(srv_shutdown_state <= SRV_SHUTDOWN_CLEANUP);
14151415

@@ -1420,8 +1420,12 @@ static bool srv_purge_should_exit()
14201420
return true;
14211421

14221422
/* Slow shutdown was requested. */
1423+
size_t prepared, active= trx_sys.any_active_transactions(&prepared);
14231424
const size_t history_size= trx_sys.history_size();
1424-
if (history_size)
1425+
1426+
if (!history_size);
1427+
else if (!active && history_size == old_history_size && prepared);
1428+
else
14251429
{
14261430
static time_t progress_time;
14271431
time_t now= time(NULL);
@@ -1438,7 +1442,7 @@ static bool srv_purge_should_exit()
14381442
return false;
14391443
}
14401444

1441-
return !trx_sys.any_active_transactions();
1445+
return !active;
14421446
}
14431447

14441448
/*********************************************************************//**
@@ -1581,7 +1585,7 @@ inline void purge_coordinator_state::do_purge()
15811585
break;
15821586
}
15831587

1584-
if (!srv_purge_should_exit())
1588+
if (!srv_purge_should_exit(history_size))
15851589
goto loop;
15861590
}
15871591

@@ -1777,15 +1781,19 @@ ulint srv_get_task_queue_length()
17771781
/** Shut down the purge threads. */
17781782
void srv_purge_shutdown()
17791783
{
1780-
if (purge_sys.enabled()) {
1781-
if (!srv_fast_shutdown && !opt_bootstrap)
1782-
srv_update_purge_thread_count(innodb_purge_threads_MAX);
1783-
while(!srv_purge_should_exit()) {
1784-
ut_a(!purge_sys.paused());
1785-
srv_wake_purge_thread_if_not_active();
1786-
purge_coordinator_task.wait();
1787-
}
1788-
purge_sys.coordinator_shutdown();
1789-
srv_shutdown_purge_tasks();
1790-
}
1784+
if (purge_sys.enabled())
1785+
{
1786+
if (!srv_fast_shutdown && !opt_bootstrap)
1787+
srv_update_purge_thread_count(innodb_purge_threads_MAX);
1788+
size_t history_size= trx_sys.history_size();
1789+
while (!srv_purge_should_exit(history_size))
1790+
{
1791+
history_size= trx_sys.history_size();
1792+
ut_a(!purge_sys.paused());
1793+
srv_wake_purge_thread_if_not_active();
1794+
purge_coordinator_task.wait();
1795+
}
1796+
purge_sys.coordinator_shutdown();
1797+
srv_shutdown_purge_tasks();
1798+
}
17911799
}

storage/innobase/trx/trx0purge.cc

Lines changed: 21 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -369,19 +369,6 @@ trx_purge_add_undo_to_history(const trx_t* trx, trx_undo_t*& undo, mtr_t* mtr)
369369
undo = NULL;
370370
}
371371

372-
MY_ATTRIBUTE((nonnull, warn_unused_result))
373-
/** Remove undo log header from the history list.
374-
@param[in,out] rseg rollback segment header page
375-
@param[in] log undo log segment header page
376-
@param[in] offset byte offset in the undo log segment header page
377-
@param[in,out] mtr mini-transaction */
378-
static dberr_t trx_purge_remove_log_hdr(buf_block_t *rseg, buf_block_t* log,
379-
uint16_t offset, mtr_t *mtr)
380-
{
381-
return flst_remove(rseg, TRX_RSEG + TRX_RSEG_HISTORY, log,
382-
uint16_t(offset + TRX_UNDO_HISTORY_NODE), mtr);
383-
}
384-
385372
/** Free an undo log segment.
386373
@param block rollback segment header page
387374
@param mtr mini-transaction */
@@ -391,7 +378,7 @@ static void trx_purge_free_segment(buf_block_t *block, mtr_t &mtr)
391378
block->page.frame, &mtr))
392379
{
393380
block->fix();
394-
const page_id_t id{block->page.id()};
381+
ut_d(const page_id_t id{block->page.id()});
395382
mtr.commit();
396383
/* NOTE: If the server is killed after the log that was produced
397384
up to this point was written, and before the log from the mtr.commit()
@@ -403,29 +390,22 @@ static void trx_purge_free_segment(buf_block_t *block, mtr_t &mtr)
403390
log_free_check();
404391
mtr.start();
405392
block->page.lock.x_lock();
406-
if (UNIV_UNLIKELY(block->page.id() != id))
407-
{
408-
block->unfix();
409-
block->page.lock.x_unlock();
410-
block= buf_page_get_gen(id, 0, RW_X_LATCH, nullptr, BUF_GET, &mtr);
411-
if (!block)
412-
return;
413-
}
414-
else
415-
mtr.memo_push(block, MTR_MEMO_PAGE_X_MODIFY);
393+
ut_ad(block->page.id() == id);
394+
mtr.memo_push(block, MTR_MEMO_PAGE_X_MODIFY);
416395
}
417396

418397
while (!fseg_free_step(TRX_UNDO_SEG_HDR + TRX_UNDO_FSEG_HEADER +
419398
block->page.frame, &mtr));
420399
}
421400

422401
/** Remove unnecessary history data from a rollback segment.
423-
@param[in,out] rseg rollback segment
424-
@param[in] limit truncate anything before this
402+
@param rseg rollback segment
403+
@param limit truncate anything before this
404+
@param all whether everything can be truncated
425405
@return error code */
426406
static dberr_t
427-
trx_purge_truncate_rseg_history(trx_rseg_t& rseg,
428-
const purge_sys_t::iterator& limit)
407+
trx_purge_truncate_rseg_history(trx_rseg_t &rseg,
408+
const purge_sys_t::iterator &limit, bool all)
429409
{
430410
fil_addr_t hdr_addr;
431411
mtr_t mtr;
@@ -434,7 +414,6 @@ trx_purge_truncate_rseg_history(trx_rseg_t& rseg,
434414
mtr.start();
435415

436416
dberr_t err;
437-
reget:
438417
buf_block_t *rseg_hdr= rseg.get(&mtr, &err);
439418
if (!rseg_hdr)
440419
{
@@ -469,23 +448,24 @@ trx_purge_truncate_rseg_history(trx_rseg_t& rseg,
469448
goto func_exit;
470449
}
471450

451+
if (!all)
452+
goto func_exit;
453+
472454
fil_addr_t prev_hdr_addr=
473455
flst_get_prev_addr(b->page.frame + hdr_addr.boffset +
474456
TRX_UNDO_HISTORY_NODE);
475457
prev_hdr_addr.boffset= static_cast<uint16_t>(prev_hdr_addr.boffset -
476458
TRX_UNDO_HISTORY_NODE);
477-
err= trx_purge_remove_log_hdr(rseg_hdr, b, hdr_addr.boffset, &mtr);
459+
460+
err= flst_remove(rseg_hdr, TRX_RSEG + TRX_RSEG_HISTORY, b,
461+
uint16_t(hdr_addr.boffset + TRX_UNDO_HISTORY_NODE), &mtr);
478462
if (UNIV_UNLIKELY(err != DB_SUCCESS))
479463
goto func_exit;
480464

481465
rseg_hdr->fix();
482466

483-
if (mach_read_from_2(b->page.frame + hdr_addr.boffset + TRX_UNDO_NEXT_LOG) ||
484-
rseg.is_referenced() ||
485-
rseg.needs_purge > (purge_sys.head.trx_no
486-
? purge_sys.head.trx_no
487-
: purge_sys.tail.trx_no))
488-
/* We cannot free the entire undo page. */;
467+
if (mach_read_from_2(b->page.frame + hdr_addr.boffset + TRX_UNDO_NEXT_LOG))
468+
/* We cannot free the entire undo log segment. */;
489469
else
490470
{
491471
const uint32_t seg_size=
@@ -535,12 +515,7 @@ trx_purge_truncate_rseg_history(trx_rseg_t& rseg,
535515
log_free_check();
536516
mtr.start();
537517
rseg_hdr->page.lock.x_lock();
538-
if (UNIV_UNLIKELY(rseg_hdr->page.id() != rseg.page_id()))
539-
{
540-
rseg_hdr->unfix();
541-
rseg_hdr->page.lock.x_unlock();
542-
goto reget;
543-
}
518+
ut_ad(rseg_hdr->page.id() == rseg.page_id());
544519
mtr.memo_push(rseg_hdr, MTR_MEMO_PAGE_X_MODIFY);
545520

546521
goto loop;
@@ -613,7 +588,10 @@ TRANSACTIONAL_TARGET static void trx_purge_truncate_history()
613588
{
614589
ut_ad(rseg.is_persistent());
615590
rseg.latch.wr_lock(SRW_LOCK_CALL);
616-
if (dberr_t e= trx_purge_truncate_rseg_history(rseg, head))
591+
if (dberr_t e=
592+
trx_purge_truncate_rseg_history(rseg, head,
593+
!rseg.is_referenced() &&
594+
rseg.needs_purge <= head.trx_no))
617595
err= e;
618596
rseg.latch.wr_unlock();
619597
}

storage/innobase/trx/trx0sys.cc

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -343,15 +343,29 @@ trx_sys_t::close()
343343
}
344344

345345
/** @return total number of active (non-prepared) transactions */
346-
ulint trx_sys_t::any_active_transactions()
346+
size_t trx_sys_t::any_active_transactions(size_t *prepared)
347347
{
348-
uint32_t total_trx= 0;
348+
size_t total_trx= 0, prepared_trx= 0;
349349

350-
trx_sys.trx_list.for_each([&total_trx](const trx_t &trx) {
351-
if (trx.state == TRX_STATE_COMMITTED_IN_MEMORY ||
352-
(trx.state == TRX_STATE_ACTIVE && trx.id))
350+
trx_sys.trx_list.for_each([&](const trx_t &trx) {
351+
switch (trx.state) {
352+
case TRX_STATE_NOT_STARTED:
353+
break;
354+
case TRX_STATE_ACTIVE:
355+
if (!trx.id)
356+
break;
357+
/* fall through */
358+
case TRX_STATE_COMMITTED_IN_MEMORY:
353359
total_trx++;
360+
break;
361+
case TRX_STATE_PREPARED:
362+
case TRX_STATE_PREPARED_RECOVERED:
363+
prepared_trx++;
364+
}
354365
});
355366

367+
if (prepared)
368+
*prepared= prepared_trx;
369+
356370
return total_trx;
357371
}

0 commit comments

Comments
 (0)