Commit b100a45f authored by vasil's avatar vasil

branches/zip:

Fix Mantis Issue#244 fix bug in linear read ahead (no check on access pattern)

The changes are:

1) Take into account access pattern when deciding whether or not to do linear
  read ahead.
2) Expose a knob innodb_read_ahead_factor = [0-64] default (8), dynamic,
  global to control linear read ahead behvior
3) Disable random read ahead. Keep the code for now.

Submitted by:	Inaam (rb://122)
Approved by:	Heikki (rb://122)
parent 06069a93
...@@ -456,11 +456,12 @@ buf_LRU_get_recent_limit(void) ...@@ -456,11 +456,12 @@ buf_LRU_get_recent_limit(void)
bpage = UT_LIST_GET_FIRST(buf_pool->LRU); bpage = UT_LIST_GET_FIRST(buf_pool->LRU);
limit = buf_page_get_LRU_position(bpage) - len / BUF_LRU_INITIAL_RATIO; limit = buf_page_get_LRU_position(bpage);
len /= BUF_LRU_INITIAL_RATIO;
buf_pool_mutex_exit(); buf_pool_mutex_exit();
return(limit); return(limit > len ? (limit - len) : 0);
} }
/********************************************************************//** /********************************************************************//**
......
...@@ -44,14 +44,11 @@ the accessed pages when deciding whether to read-ahead */ ...@@ -44,14 +44,11 @@ the accessed pages when deciding whether to read-ahead */
/** There must be at least this many pages in buf_pool in the area to start /** There must be at least this many pages in buf_pool in the area to start
a random read-ahead */ a random read-ahead */
#define BUF_READ_AHEAD_RANDOM_THRESHOLD (5 + buf_read_ahead_random_area / 8) #define BUF_READ_AHEAD_RANDOM_THRESHOLD (1 + BUF_READ_AHEAD_RANDOM_AREA / 2)
/** The linear read-ahead area size */ /** The linear read-ahead area size */
#define BUF_READ_AHEAD_LINEAR_AREA BUF_READ_AHEAD_AREA #define BUF_READ_AHEAD_LINEAR_AREA BUF_READ_AHEAD_AREA
/** The linear read-ahead threshold */
#define LINEAR_AREA_THRESHOLD_COEF 5 / 8
/** If there are buf_pool->curr_size per the number below pending reads, then /** If there are buf_pool->curr_size per the number below pending reads, then
read-ahead is not done: this is to prevent flooding the buffer pool with read-ahead is not done: this is to prevent flooding the buffer pool with
i/o-fixed buffer blocks */ i/o-fixed buffer blocks */
...@@ -199,6 +196,9 @@ buf_read_ahead_random( ...@@ -199,6 +196,9 @@ buf_read_ahead_random(
ulint i; ulint i;
ulint buf_read_ahead_random_area; ulint buf_read_ahead_random_area;
/* We have currently disabled random readahead */
return(0);
if (srv_startup_is_before_trx_rollback_phase) { if (srv_startup_is_before_trx_rollback_phase) {
/* No read-ahead to avoid thread deadlocks */ /* No read-ahead to avoid thread deadlocks */
return(0); return(0);
...@@ -423,6 +423,7 @@ buf_read_ahead_linear( ...@@ -423,6 +423,7 @@ buf_read_ahead_linear(
ulint i; ulint i;
const ulint buf_read_ahead_linear_area const ulint buf_read_ahead_linear_area
= BUF_READ_AHEAD_LINEAR_AREA; = BUF_READ_AHEAD_LINEAR_AREA;
ulint threshold;
if (UNIV_UNLIKELY(srv_startup_is_before_trx_rollback_phase)) { if (UNIV_UNLIKELY(srv_startup_is_before_trx_rollback_phase)) {
/* No read-ahead to avoid thread deadlocks */ /* No read-ahead to avoid thread deadlocks */
...@@ -482,6 +483,10 @@ buf_read_ahead_linear( ...@@ -482,6 +483,10 @@ buf_read_ahead_linear(
asc_or_desc = -1; asc_or_desc = -1;
} }
/* How many out of order accessed pages can we ignore
when working out the access pattern for linear readahead */
threshold = ut_min(srv_read_ahead_factor, BUF_READ_AHEAD_AREA);
fail_count = 0; fail_count = 0;
for (i = low; i < high; i++) { for (i = low; i < high; i++) {
...@@ -491,25 +496,25 @@ buf_read_ahead_linear( ...@@ -491,25 +496,25 @@ buf_read_ahead_linear(
/* Not accessed */ /* Not accessed */
fail_count++; fail_count++;
} else if (pred_bpage } else if (pred_bpage) {
&& (ut_ulint_cmp( int res = (ut_ulint_cmp(
buf_page_get_LRU_position(bpage), buf_page_get_LRU_position(bpage),
buf_page_get_LRU_position(pred_bpage)) buf_page_get_LRU_position(pred_bpage)));
!= asc_or_desc)) {
/* Accesses not in the right order */ /* Accesses not in the right order */
if (res != 0 && res != asc_or_desc) {
fail_count++; fail_count++;
pred_bpage = bpage; }
} }
}
if (fail_count > buf_read_ahead_linear_area
* LINEAR_AREA_THRESHOLD_COEF) {
/* Too many failures: return */
buf_pool_mutex_exit(); if (fail_count > threshold) {
/* Too many failures: return */
buf_pool_mutex_exit();
return(0);
}
return(0); if (bpage && buf_page_is_accessed(bpage)) {
pred_bpage = bpage;
}
} }
/* If we got this far, we know that enough pages in the area have /* If we got this far, we know that enough pages in the area have
......
...@@ -9735,6 +9735,14 @@ static MYSQL_SYSVAR_STR(change_buffering, innobase_change_buffering, ...@@ -9735,6 +9735,14 @@ static MYSQL_SYSVAR_STR(change_buffering, innobase_change_buffering,
innodb_change_buffering_validate, innodb_change_buffering_validate,
innodb_change_buffering_update, NULL); innodb_change_buffering_update, NULL);
static MYSQL_SYSVAR_ULONG(read_ahead_factor, srv_read_ahead_factor,
PLUGIN_VAR_RQCMDARG,
"Number of pages that may be accessed out of order and InnoDB "
"will still issue a readahead."
"The higher the value the more relaxed the condition for starting "
"readahead.",
NULL, NULL, 8, 0, 64, 0);
static struct st_mysql_sys_var* innobase_system_variables[]= { static struct st_mysql_sys_var* innobase_system_variables[]= {
MYSQL_SYSVAR(additional_mem_pool_size), MYSQL_SYSVAR(additional_mem_pool_size),
MYSQL_SYSVAR(autoextend_increment), MYSQL_SYSVAR(autoextend_increment),
...@@ -9784,6 +9792,7 @@ static struct st_mysql_sys_var* innobase_system_variables[]= { ...@@ -9784,6 +9792,7 @@ static struct st_mysql_sys_var* innobase_system_variables[]= {
MYSQL_SYSVAR(version), MYSQL_SYSVAR(version),
MYSQL_SYSVAR(use_sys_malloc), MYSQL_SYSVAR(use_sys_malloc),
MYSQL_SYSVAR(change_buffering), MYSQL_SYSVAR(change_buffering),
MYSQL_SYSVAR(read_ahead_factor),
NULL NULL
}; };
......
...@@ -125,6 +125,7 @@ extern ulint srv_mem_pool_size; ...@@ -125,6 +125,7 @@ extern ulint srv_mem_pool_size;
extern ulint srv_lock_table_size; extern ulint srv_lock_table_size;
extern ulint srv_n_file_io_threads; extern ulint srv_n_file_io_threads;
extern ulint srv_read_ahead_factor;
#ifdef UNIV_LOG_ARCHIVE #ifdef UNIV_LOG_ARCHIVE
extern ibool srv_log_archive_on; extern ibool srv_log_archive_on;
......
...@@ -175,6 +175,13 @@ UNIV_INTERN ulint srv_lock_table_size = ULINT_MAX; ...@@ -175,6 +175,13 @@ UNIV_INTERN ulint srv_lock_table_size = ULINT_MAX;
UNIV_INTERN ulint srv_n_file_io_threads = ULINT_MAX; UNIV_INTERN ulint srv_n_file_io_threads = ULINT_MAX;
/* User settable value of the number of pages that InnoDB will tolerate
within a 64 page extent even if they are accessed out of order or have
not been accessed at all. This number (which varies from 0 to 64) is
indicative of the slack that we have when deciding about linear
readahead. */
UNIV_INTERN ulint srv_read_ahead_factor = 8;
#ifdef UNIV_LOG_ARCHIVE #ifdef UNIV_LOG_ARCHIVE
UNIV_INTERN ibool srv_log_archive_on = FALSE; UNIV_INTERN ibool srv_log_archive_on = FALSE;
UNIV_INTERN ibool srv_archive_recovery = 0; UNIV_INTERN ibool srv_archive_recovery = 0;
......
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