diff options
author | Jan Lindström <jan.lindstrom@mariadb.com> | 2015-12-15 09:30:13 +0200 |
---|---|---|
committer | Jan Lindström <jan.lindstrom@mariadb.com> | 2015-12-15 09:35:22 +0200 |
commit | b63bf7368b4881789bef931f90d4719b358cf507 (patch) | |
tree | 7542a8a4b0a7170e6664502004e141b9ecd3d92c /storage/xtradb | |
parent | af3c67056d3f9f7f348c612f9ce48e83c8a456d6 (diff) | |
download | mariadb-git-b63bf7368b4881789bef931f90d4719b358cf507.tar.gz |
MDEV-8923: port innodb_buffer_pool_dump_pct from MySQL
Backport pull request #125 from grooverdan/MDEV-8923_innodb_buffer_pool_dump_pct to 10.0
WL#6504 InnoDB buffer pool dump/load enchantments
This patch consists of two parts:
1. Dump only the hottest N% of the buffer pool(s)
2. Prevent hogging the server duing BP load
From MySQL - commit b409342c43ce2edb68807100a77001367c7e6b8e
Add testcases for innodb_buffer_pool_dump_pct_basic.
Part of the code authored by Daniel Black
Diffstat (limited to 'storage/xtradb')
-rw-r--r-- | storage/xtradb/buf/buf0dump.cc | 88 | ||||
-rw-r--r-- | storage/xtradb/handler/ha_innodb.cc | 6 | ||||
-rw-r--r-- | storage/xtradb/include/srv0srv.h | 2 | ||||
-rw-r--r-- | storage/xtradb/srv/srv0srv.cc | 2 |
4 files changed, 95 insertions, 3 deletions
diff --git a/storage/xtradb/buf/buf0dump.cc b/storage/xtradb/buf/buf0dump.cc index 090e8cac63b..2b3b506a457 100644 --- a/storage/xtradb/buf/buf0dump.cc +++ b/storage/xtradb/buf/buf0dump.cc @@ -230,6 +230,16 @@ buf_dump( continue; } + if (srv_buf_pool_dump_pct != 100) { + ut_ad(srv_buf_pool_dump_pct < 100); + + n_pages = n_pages * srv_buf_pool_dump_pct / 100; + + if (n_pages == 0) { + n_pages = 1; + } + } + dump = static_cast<buf_dump_t*>( ut_malloc(n_pages * sizeof(*dump))) ; @@ -244,9 +254,9 @@ buf_dump( return; } - for (bpage = UT_LIST_GET_LAST(buf_pool->LRU), j = 0; - bpage != NULL; - bpage = UT_LIST_GET_PREV(LRU, bpage), j++) { + for (bpage = UT_LIST_GET_FIRST(buf_pool->LRU), j = 0; + bpage != NULL && j < n_pages; + bpage = UT_LIST_GET_NEXT(LRU, bpage), j++) { ut_a(buf_page_in_file(bpage)); @@ -361,6 +371,72 @@ buf_dump_sort( } /*****************************************************************//** +Artificially delay the buffer pool loading if necessary. The idea of +this function is to prevent hogging the server with IO and slowing down +too much normal client queries. */ +UNIV_INLINE +void +buf_load_throttle_if_needed( +/*========================*/ + ulint* last_check_time, /*!< in/out: miliseconds since epoch + of the last time we did check if + throttling is needed, we do the check + every srv_io_capacity IO ops. */ + ulint* last_activity_count, + ulint n_io) /*!< in: number of IO ops done since + buffer pool load has started */ +{ + if (n_io % srv_io_capacity < srv_io_capacity - 1) { + return; + } + + if (*last_check_time == 0 || *last_activity_count == 0) { + *last_check_time = ut_time_ms(); + *last_activity_count = srv_get_activity_count(); + return; + } + + /* srv_io_capacity IO operations have been performed by buffer pool + load since the last time we were here. */ + + /* If no other activity, then keep going without any delay. */ + if (srv_get_activity_count() == *last_activity_count) { + return; + } + + /* There has been other activity, throttle. */ + + ulint now = ut_time_ms(); + ulint elapsed_time = now - *last_check_time; + + /* Notice that elapsed_time is not the time for the last + srv_io_capacity IO operations performed by BP load. It is the + time elapsed since the last time we detected that there has been + other activity. This has a small and acceptable deficiency, e.g.: + 1. BP load runs and there is no other activity. + 2. Other activity occurs, we run N IO operations after that and + enter here (where 0 <= N < srv_io_capacity). + 3. last_check_time is very old and we do not sleep at this time, but + only update last_check_time and last_activity_count. + 4. We run srv_io_capacity more IO operations and call this function + again. + 5. There has been more other activity and thus we enter here. + 6. Now last_check_time is recent and we sleep if necessary to prevent + more than srv_io_capacity IO operations per second. + The deficiency is that we could have slept at 3., but for this we + would have to update last_check_time before the + "cur_activity_count == *last_activity_count" check and calling + ut_time_ms() that often may turn out to be too expensive. */ + + if (elapsed_time < 1000 /* 1 sec (1000 mili secs) */) { + os_thread_sleep((1000 - elapsed_time) * 1000 /* micro secs */); + } + + *last_check_time = ut_time_ms(); + *last_activity_count = srv_get_activity_count(); +} + +/*****************************************************************//** Perform a buffer pool load from the file specified by innodb_buffer_pool_filename. If any errors occur then the value of innodb_buffer_pool_load_status will be set accordingly, see buf_load_status(). @@ -521,6 +597,9 @@ buf_load() ut_free(dump_tmp); + ulint last_check_time = 0; + ulint last_activity_cnt = 0; + for (i = 0; i < dump_n && !SHUTTING_DOWN(); i++) { buf_read_page_async(BUF_DUMP_SPACE(dump[i]), @@ -544,6 +623,9 @@ buf_load() "Buffer pool(s) load aborted on request"); return; } + + buf_load_throttle_if_needed( + &last_check_time, &last_activity_cnt, i); } ut_free(dump); diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc index 348e7107009..e30727b93d1 100644 --- a/storage/xtradb/handler/ha_innodb.cc +++ b/storage/xtradb/handler/ha_innodb.cc @@ -17840,6 +17840,11 @@ static MYSQL_SYSVAR_BOOL(buffer_pool_dump_at_shutdown, srv_buffer_pool_dump_at_s "Dump the buffer pool into a file named @@innodb_buffer_pool_filename", NULL, NULL, FALSE); +static MYSQL_SYSVAR_ULONG(buffer_pool_dump_pct, srv_buf_pool_dump_pct, + PLUGIN_VAR_RQCMDARG, + "Dump only the hottest N% of each buffer pool, defaults to 100", + NULL, NULL, 100, 1, 100, 0); + #ifdef UNIV_DEBUG static MYSQL_SYSVAR_STR(buffer_pool_evict, srv_buffer_pool_evict, PLUGIN_VAR_RQCMDARG, @@ -18382,6 +18387,7 @@ static struct st_mysql_sys_var* innobase_system_variables[]= { MYSQL_SYSVAR(buffer_pool_filename), MYSQL_SYSVAR(buffer_pool_dump_now), MYSQL_SYSVAR(buffer_pool_dump_at_shutdown), + MYSQL_SYSVAR(buffer_pool_dump_pct), #ifdef UNIV_DEBUG MYSQL_SYSVAR(buffer_pool_evict), #endif /* UNIV_DEBUG */ diff --git a/storage/xtradb/include/srv0srv.h b/storage/xtradb/include/srv0srv.h index 981bcd0797a..aabc9c7f434 100644 --- a/storage/xtradb/include/srv0srv.h +++ b/storage/xtradb/include/srv0srv.h @@ -335,6 +335,8 @@ extern ulong srv_flush_neighbors; /*!< whether or not to flush neighbors of a block */ extern ulint srv_buf_pool_old_size; /*!< previously requested size */ extern ulint srv_buf_pool_curr_size; /*!< current size in bytes */ +extern ulong srv_buf_pool_dump_pct; /*!< dump that may % of each buffer + pool during BP dump */ extern ulint srv_mem_pool_size; extern ulint srv_lock_table_size; diff --git a/storage/xtradb/srv/srv0srv.cc b/storage/xtradb/srv/srv0srv.cc index c92aa0eaf2a..ffded97755e 100644 --- a/storage/xtradb/srv/srv0srv.cc +++ b/storage/xtradb/srv/srv0srv.cc @@ -260,6 +260,8 @@ UNIV_INTERN ulong srv_flush_neighbors = 1; UNIV_INTERN ulint srv_buf_pool_old_size; /* current size in kilobytes */ UNIV_INTERN ulint srv_buf_pool_curr_size = 0; +/* dump that may % of each buffer pool during BP dump */ +UNIV_INTERN ulong srv_buf_pool_dump_pct; /* size in bytes */ UNIV_INTERN ulint srv_mem_pool_size = ULINT_MAX; UNIV_INTERN ulint srv_lock_table_size = ULINT_MAX; |