Commit 60a68fdf authored by Marko Mäkelä's avatar Marko Mäkelä

Clarify the access to trx_sys.rseg_history_len

trx_sys_t::rseg_history_len: Make private, and clarify the
documentation.

trx_sys_t::history_size(): Read rseg_history_len.

trx_sys_t::history_insert(), trx_sys_t::history_remove(),
trx_sys_t::history_add(): Update rseg_history_len.
parent d23fcc42
...@@ -1166,7 +1166,7 @@ btr_cur_search_to_nth_level_func( ...@@ -1166,7 +1166,7 @@ btr_cur_search_to_nth_level_func(
Free blocks and read IO bandwidth should be prior Free blocks and read IO bandwidth should be prior
for them, when the history list is glowing huge. */ for them, when the history list is glowing huge. */
if (lock_intention == BTR_INTENTION_DELETE if (lock_intention == BTR_INTENTION_DELETE
&& trx_sys.rseg_history_len > BTR_CUR_FINE_HISTORY_LENGTH && trx_sys.history_size() > BTR_CUR_FINE_HISTORY_LENGTH
&& buf_get_n_pending_read_ios()) { && buf_get_n_pending_read_ios()) {
mtr_x_lock(dict_index_get_lock(index), mtr); mtr_x_lock(dict_index_get_lock(index), mtr);
} else if (dict_index_is_spatial(index) } else if (dict_index_is_spatial(index)
...@@ -2305,7 +2305,7 @@ btr_cur_open_at_index_side_func( ...@@ -2305,7 +2305,7 @@ btr_cur_open_at_index_side_func(
Free blocks and read IO bandwidth should be prior Free blocks and read IO bandwidth should be prior
for them, when the history list is glowing huge. */ for them, when the history list is glowing huge. */
if (lock_intention == BTR_INTENTION_DELETE if (lock_intention == BTR_INTENTION_DELETE
&& trx_sys.rseg_history_len > BTR_CUR_FINE_HISTORY_LENGTH && trx_sys.history_size() > BTR_CUR_FINE_HISTORY_LENGTH
&& buf_get_n_pending_read_ios()) { && buf_get_n_pending_read_ios()) {
mtr_x_lock(dict_index_get_lock(index), mtr); mtr_x_lock(dict_index_get_lock(index), mtr);
} else { } else {
...@@ -2651,7 +2651,7 @@ btr_cur_open_at_rnd_pos_func( ...@@ -2651,7 +2651,7 @@ btr_cur_open_at_rnd_pos_func(
Free blocks and read IO bandwidth should be prior Free blocks and read IO bandwidth should be prior
for them, when the history list is glowing huge. */ for them, when the history list is glowing huge. */
if (lock_intention == BTR_INTENTION_DELETE if (lock_intention == BTR_INTENTION_DELETE
&& trx_sys.rseg_history_len > BTR_CUR_FINE_HISTORY_LENGTH && trx_sys.history_size() > BTR_CUR_FINE_HISTORY_LENGTH
&& buf_get_n_pending_read_ios()) { && buf_get_n_pending_read_ios()) {
mtr_x_lock(dict_index_get_lock(index), mtr); mtr_x_lock(dict_index_get_lock(index), mtr);
} else { } else {
......
...@@ -817,6 +817,11 @@ class trx_sys_t ...@@ -817,6 +817,11 @@ class trx_sys_t
MY_ALIGNED(CACHE_LINE_SIZE) trx_id_t m_rw_trx_hash_version; MY_ALIGNED(CACHE_LINE_SIZE) trx_id_t m_rw_trx_hash_version;
/**
TRX_RSEG_HISTORY list length (number of committed transactions to purge)
*/
MY_ALIGNED(CACHE_LINE_SIZE) int32 rseg_history_len;
/** Active views. */ /** Active views. */
MY_ALIGNED(CACHE_LINE_SIZE) UT_LIST_BASE_NODE_T(ReadView) m_views; MY_ALIGNED(CACHE_LINE_SIZE) UT_LIST_BASE_NODE_T(ReadView) m_views;
...@@ -850,11 +855,6 @@ class trx_sys_t ...@@ -850,11 +855,6 @@ class trx_sys_t
single-threaded mode; not protected single-threaded mode; not protected
by any mutex, because it is read-only by any mutex, because it is read-only
during multi-threaded operation */ during multi-threaded operation */
ulint rseg_history_len;
/*!< Length of the TRX_RSEG_HISTORY
list (update undo logs for committed
transactions), protected by
rseg->mutex */
/** /**
...@@ -1122,6 +1122,20 @@ class trx_sys_t ...@@ -1122,6 +1122,20 @@ class trx_sys_t
return count; return count;
} }
/** @return number of committed transactions waiting for purge */
ulint history_size() const
{
return uint32(my_atomic_load32(&rseg_history_len));
}
/** Add to the TRX_RSEG_HISTORY length (on database startup). */
void history_add(int32 len)
{
my_atomic_add32(&rseg_history_len, len);
}
/** Register a committed transaction. */
void history_insert() { history_add(1); }
/** Note that a committed transaction was purged. */
void history_remove() { history_add(-1); }
private: private:
static my_bool get_min_trx_id_callback(rw_trx_hash_element_t *element, static my_bool get_min_trx_id_callback(rw_trx_hash_element_t *element,
......
...@@ -5294,7 +5294,7 @@ lock_print_info_summary( ...@@ -5294,7 +5294,7 @@ lock_print_info_summary(
fprintf(file, "\n"); fprintf(file, "\n");
fprintf(file, fprintf(file,
"History list length " ULINTPF "\n", trx_sys.rseg_history_len); "History list length " ULINTPF "\n", trx_sys.history_size());
#ifdef PRINT_NUM_OF_LOCK_STRUCTS #ifdef PRINT_NUM_OF_LOCK_STRUCTS
fprintf(file, fprintf(file,
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
Copyright (c) 2010, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2010, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc. Copyright (c) 2012, Facebook Inc.
Copyright (c) 2013, 2017, MariaDB Corporation. Copyright (c) 2013, 2018, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software the terms of the GNU General Public License as published by the Free Software
...@@ -1952,7 +1952,7 @@ srv_mon_process_existing_counter( ...@@ -1952,7 +1952,7 @@ srv_mon_process_existing_counter(
break; break;
case MONITOR_RSEG_HISTORY_LEN: case MONITOR_RSEG_HISTORY_LEN:
value = trx_sys.rseg_history_len; value = trx_sys.history_size();
break; break;
case MONITOR_RSEG_CUR_SIZE: case MONITOR_RSEG_CUR_SIZE:
......
...@@ -1975,7 +1975,7 @@ srv_wake_purge_thread_if_not_active() ...@@ -1975,7 +1975,7 @@ srv_wake_purge_thread_if_not_active()
if (purge_sys->state == PURGE_STATE_RUN if (purge_sys->state == PURGE_STATE_RUN
&& !my_atomic_loadlint(&srv_sys.n_threads_active[SRV_PURGE]) && !my_atomic_loadlint(&srv_sys.n_threads_active[SRV_PURGE])
&& my_atomic_loadlint(&trx_sys.rseg_history_len)) { && trx_sys.history_size()) {
srv_release_threads(SRV_PURGE, 1); srv_release_threads(SRV_PURGE, 1);
} }
...@@ -2614,7 +2614,7 @@ srv_do_purge(ulint* n_total_purged) ...@@ -2614,7 +2614,7 @@ srv_do_purge(ulint* n_total_purged)
} }
do { do {
if (trx_sys.rseg_history_len > rseg_history_len if (trx_sys.history_size() > rseg_history_len
|| (srv_max_purge_lag > 0 || (srv_max_purge_lag > 0
&& rseg_history_len > srv_max_purge_lag)) { && rseg_history_len > srv_max_purge_lag)) {
...@@ -2643,7 +2643,7 @@ srv_do_purge(ulint* n_total_purged) ...@@ -2643,7 +2643,7 @@ srv_do_purge(ulint* n_total_purged)
ut_a(n_use_threads <= n_threads); ut_a(n_use_threads <= n_threads);
/* Take a snapshot of the history list before purge. */ /* Take a snapshot of the history list before purge. */
if ((rseg_history_len = trx_sys.rseg_history_len) == 0) { if (!(rseg_history_len = trx_sys.history_size())) {
break; break;
} }
...@@ -2698,7 +2698,7 @@ srv_purge_coordinator_suspend( ...@@ -2698,7 +2698,7 @@ srv_purge_coordinator_suspend(
/* We don't wait right away on the the non-timed wait because /* We don't wait right away on the the non-timed wait because
we want to signal the thread that wants to suspend purge. */ we want to signal the thread that wants to suspend purge. */
const bool wait = stop const bool wait = stop
|| rseg_history_len <= trx_sys.rseg_history_len; || rseg_history_len <= trx_sys.history_size();
const bool timeout = srv_resume_thread( const bool timeout = srv_resume_thread(
slot, sig_count, wait, slot, sig_count, wait,
stop ? 0 : SRV_PURGE_MAX_TIMEOUT); stop ? 0 : SRV_PURGE_MAX_TIMEOUT);
...@@ -2715,8 +2715,8 @@ srv_purge_coordinator_suspend( ...@@ -2715,8 +2715,8 @@ srv_purge_coordinator_suspend(
purge_sys->running = true; purge_sys->running = true;
if (timeout if (timeout
&& rseg_history_len == trx_sys.rseg_history_len && rseg_history_len < 5000
&& trx_sys.rseg_history_len < 5000) { && rseg_history_len == trx_sys.history_size()) {
/* No new records were added since the /* No new records were added since the
wait started. Simply wait for new wait started. Simply wait for new
records. The magic number 5000 is an records. The magic number 5000 is an
...@@ -2777,7 +2777,7 @@ DECLARE_THREAD(srv_purge_coordinator_thread)( ...@@ -2777,7 +2777,7 @@ DECLARE_THREAD(srv_purge_coordinator_thread)(
slot = srv_reserve_slot(SRV_PURGE); slot = srv_reserve_slot(SRV_PURGE);
ulint rseg_history_len = trx_sys.rseg_history_len; ulint rseg_history_len = trx_sys.history_size();
do { do {
/* If there are no records to purge or the last /* If there are no records to purge or the last
......
...@@ -324,8 +324,6 @@ trx_purge_add_undo_to_history(const trx_t* trx, trx_undo_t*& undo, mtr_t* mtr) ...@@ -324,8 +324,6 @@ trx_purge_add_undo_to_history(const trx_t* trx, trx_undo_t*& undo, mtr_t* mtr)
flst_add_first(rseg_header + TRX_RSEG_HISTORY, flst_add_first(rseg_header + TRX_RSEG_HISTORY,
undo_header + TRX_UNDO_HISTORY_NODE, mtr); undo_header + TRX_UNDO_HISTORY_NODE, mtr);
my_atomic_addlint(&trx_sys.rseg_history_len, 1);
mlog_write_ull(undo_header + TRX_UNDO_TRX_NO, trx->no, mtr); mlog_write_ull(undo_header + TRX_UNDO_TRX_NO, trx->no, mtr);
/* This is needed for upgrading old undo log pages from /* This is needed for upgrading old undo log pages from
before MariaDB 10.3.1. */ before MariaDB 10.3.1. */
...@@ -342,6 +340,8 @@ trx_purge_add_undo_to_history(const trx_t* trx, trx_undo_t*& undo, mtr_t* mtr) ...@@ -342,6 +340,8 @@ trx_purge_add_undo_to_history(const trx_t* trx, trx_undo_t*& undo, mtr_t* mtr)
rseg->needs_purge = true; rseg->needs_purge = true;
} }
trx_sys.history_insert();
if (undo->state == TRX_UNDO_CACHED) { if (undo->state == TRX_UNDO_CACHED) {
UT_LIST_ADD_FIRST(rseg->undo_cached, undo); UT_LIST_ADD_FIRST(rseg->undo_cached, undo);
MONITOR_INC(MONITOR_NUM_UNDO_SLOT_CACHED); MONITOR_INC(MONITOR_NUM_UNDO_SLOT_CACHED);
...@@ -366,7 +366,7 @@ trx_purge_remove_log_hdr( ...@@ -366,7 +366,7 @@ trx_purge_remove_log_hdr(
{ {
flst_remove(rseg_hdr + TRX_RSEG_HISTORY, flst_remove(rseg_hdr + TRX_RSEG_HISTORY,
log_hdr + TRX_UNDO_HISTORY_NODE, mtr); log_hdr + TRX_UNDO_HISTORY_NODE, mtr);
my_atomic_addlint(&trx_sys.rseg_history_len, -1); trx_sys.history_remove();
} }
/** Free an undo log segment, and remove the header from the history list. /** Free an undo log segment, and remove the header from the history list.
...@@ -1539,7 +1539,7 @@ trx_purge_dml_delay(void) ...@@ -1539,7 +1539,7 @@ trx_purge_dml_delay(void)
if (srv_max_purge_lag > 0) { if (srv_max_purge_lag > 0) {
float ratio; float ratio;
ratio = float(trx_sys.rseg_history_len) / srv_max_purge_lag; ratio = float(trx_sys.history_size()) / srv_max_purge_lag;
if (ratio > 1.0) { if (ratio > 1.0) {
/* If the history list length exceeds the /* If the history list length exceeds the
......
...@@ -213,7 +213,7 @@ trx_rseg_mem_restore(trx_rseg_t* rseg, trx_id_t& max_trx_id, mtr_t* mtr) ...@@ -213,7 +213,7 @@ trx_rseg_mem_restore(trx_rseg_t* rseg, trx_id_t& max_trx_id, mtr_t* mtr)
+ 1 + trx_undo_lists_init(rseg, max_trx_id, rseg_header); + 1 + trx_undo_lists_init(rseg, max_trx_id, rseg_header);
if (ulint len = flst_get_len(rseg_header + TRX_RSEG_HISTORY)) { if (ulint len = flst_get_len(rseg_header + TRX_RSEG_HISTORY)) {
my_atomic_addlint(&trx_sys.rseg_history_len, len); trx_sys.history_add(int32(len));
fil_addr_t node_addr = trx_purge_get_log_from_hist( fil_addr_t node_addr = trx_purge_get_log_from_hist(
flst_get_last(rseg_header + TRX_RSEG_HISTORY, mtr)); flst_get_last(rseg_header + TRX_RSEG_HISTORY, mtr));
......
...@@ -402,6 +402,7 @@ trx_sys_t::create() ...@@ -402,6 +402,7 @@ trx_sys_t::create()
mutex_create(LATCH_ID_TRX_SYS, &mutex); mutex_create(LATCH_ID_TRX_SYS, &mutex);
UT_LIST_INIT(mysql_trx_list, &trx_t::mysql_trx_list); UT_LIST_INIT(mysql_trx_list, &trx_t::mysql_trx_list);
UT_LIST_INIT(m_views, &ReadView::m_view_list); UT_LIST_INIT(m_views, &ReadView::m_view_list);
my_atomic_store32(&rseg_history_len, 0);
rw_trx_hash.init(); rw_trx_hash.init();
} }
...@@ -529,8 +530,6 @@ trx_sys_t::close() ...@@ -529,8 +530,6 @@ trx_sys_t::close()
ut_a(UT_LIST_GET_LEN(mysql_trx_list) == 0); ut_a(UT_LIST_GET_LEN(mysql_trx_list) == 0);
ut_ad(UT_LIST_GET_LEN(m_views) == 0); ut_ad(UT_LIST_GET_LEN(m_views) == 0);
/* We used placement new to create this mutex. Call the destructor. */
mutex_free(&mutex); mutex_free(&mutex);
m_initialised = false; m_initialised = false;
} }
......
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