diff options
author | unknown <marko@hundin.mysql.fi> | 2004-10-27 13:33:11 +0300 |
---|---|---|
committer | unknown <marko@hundin.mysql.fi> | 2004-10-27 13:33:11 +0300 |
commit | 743597ea96cbf227c2c5dd34b9837802d62ad834 (patch) | |
tree | 811cd8122c4f67f06ae87f7dde570b7aea9d484d /innobase/trx | |
parent | 9abe7d272bcd75ef4eb83a33f31a3c9b756317a1 (diff) | |
download | mariadb-git-743597ea96cbf227c2c5dd34b9837802d62ad834.tar.gz |
Backport innodb_max_purge_lag from 4.1
innobase/include/srv0srv.h:
Add configuration parameter srv_max_purge_lag.
Add global variable srv_dml_needed_delay.
innobase/include/trx0sys.h:
Add trx_sys->rseg_history_len
innobase/row/row0mysql.c:
Add row_mysql_delay_if_needed() for delaying INSERTs, UPDATEs and
DELETEs for srv_dml_needed_delay microseconds.
innobase/srv/srv0srv.c:
Define global variable srv_dml_needed_delay.
Define configuration parameter srv_max_purge_lag.
innobase/trx/trx0purge.c:
Update trx_sys->rseg_history_len.
trx_purge(): Compute srv_dml_needed_delay from srv_max_purge_lag
and trx_sys->rseg_history_len.
innobase/trx/trx0rseg.c:
Initialize trx_sys->rseg_history_len at InnoDB start-up.
sql/ha_innodb.h:
Add configuration parameter srv_max_purge_lag.
sql/mysqld.cc:
Add startup option innodb_max_purge_lag,
with default value 0 (meaning infinite, disabling the feature).
sql/set_var.cc:
Add global variable innodb_max_purge_lag.
Diffstat (limited to 'innobase/trx')
-rw-r--r-- | innobase/trx/trx0purge.c | 38 | ||||
-rw-r--r-- | innobase/trx/trx0rseg.c | 7 |
2 files changed, 44 insertions, 1 deletions
diff --git a/innobase/trx/trx0purge.c b/innobase/trx/trx0purge.c index a8b6b9fcc21..d772af47b29 100644 --- a/innobase/trx/trx0purge.c +++ b/innobase/trx/trx0purge.c @@ -295,6 +295,9 @@ trx_purge_add_update_undo_to_history( /* Add the log as the first in the history list */ flst_add_first(rseg_header + TRX_RSEG_HISTORY, undo_header + TRX_UNDO_HISTORY_NODE, mtr); + mutex_enter(&kernel_mutex); + trx_sys->rseg_history_len++; + mutex_exit(&kernel_mutex); /* Write the trx number to the undo log header */ mlog_write_dulint(undo_header + TRX_UNDO_TRX_NO, trx->no, mtr); @@ -386,6 +389,12 @@ loop: flst_cut_end(rseg_hdr + TRX_RSEG_HISTORY, log_hdr + TRX_UNDO_HISTORY_NODE, n_removed_logs, &mtr); + + mutex_enter(&kernel_mutex); + ut_ad(trx_sys->rseg_history_len >= n_removed_logs); + trx_sys->rseg_history_len -= n_removed_logs; + mutex_exit(&kernel_mutex); + freed = FALSE; while (!freed) { @@ -470,6 +479,11 @@ loop: } if (cmp >= 0) { + mutex_enter(&kernel_mutex); + ut_a(trx_sys->rseg_history_len >= n_removed_logs); + trx_sys->rseg_history_len -= n_removed_logs; + mutex_exit(&kernel_mutex); + flst_truncate_end(rseg_hdr + TRX_RSEG_HISTORY, log_hdr + TRX_UNDO_HISTORY_NODE, n_removed_logs, &mtr); @@ -1031,6 +1045,30 @@ trx_purge(void) purge_sys->view = NULL; mem_heap_empty(purge_sys->heap); + /* Determine how much data manipulation language (DML) statements + need to be delayed in order to reduce the lagging of the purge + thread. */ + srv_dml_needed_delay = 0; /* in microseconds; default: no delay */ + + /* If we cannot advance the 'purge view' because of an old + 'consistent read view', then the DML statements cannot be delayed. + Also, srv_max_purge_lag <= 0 means 'infinity'. */ + if (srv_max_purge_lag > 0 + && !UT_LIST_GET_LAST(trx_sys->view_list)) { + float ratio = (float) trx_sys->rseg_history_len + / srv_max_purge_lag; + if (ratio > ULINT_MAX / 10000) { + /* Avoid overflow: maximum delay is 4295 seconds */ + srv_dml_needed_delay = ULINT_MAX; + } else if (ratio > 1) { + /* If the history list length exceeds the + innodb_max_purge_lag, the + data manipulation statements are delayed + by at least 5000 microseconds. */ + srv_dml_needed_delay = (ulint) ((ratio - .5) * 10000); + } + } + purge_sys->view = read_view_oldest_copy_or_open_new(NULL, purge_sys->heap); mutex_exit(&kernel_mutex); diff --git a/innobase/trx/trx0rseg.c b/innobase/trx/trx0rseg.c index e3885c86def..a01d4bb835d 100644 --- a/innobase/trx/trx0rseg.c +++ b/innobase/trx/trx0rseg.c @@ -135,6 +135,7 @@ trx_rseg_mem_create( trx_ulogf_t* undo_log_hdr; fil_addr_t node_addr; ulint sum_of_undo_sizes; + ulint len; #ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); @@ -166,7 +167,9 @@ trx_rseg_mem_create( MLOG_4BYTES, mtr) + 1 + sum_of_undo_sizes; - if (flst_get_len(rseg_header + TRX_RSEG_HISTORY, mtr) > 0) { + len = flst_get_len(rseg_header + TRX_RSEG_HISTORY, mtr); + if (len > 0) { + trx_sys->rseg_history_len += len; node_addr = trx_purge_get_log_from_hist( flst_get_last(rseg_header + TRX_RSEG_HISTORY, @@ -206,6 +209,8 @@ trx_rseg_list_and_array_init( UT_LIST_INIT(trx_sys->rseg_list); + trx_sys->rseg_history_len = 0; + for (i = 0; i < TRX_SYS_N_RSEGS; i++) { page_no = trx_sysf_rseg_get_page_no(sys_header, i, mtr); |