Commit 2bf3e416 authored by Jan Lindström's avatar Jan Lindström

MDEV-6932: Enable Lazy Flushing

Merge Facebook commit 4f3e0343fd2ac3fc7311d0ec9739a8f668274f0d
authored by Steaphan Greene from https://github.com/facebook/mysql-5.6

Adds innodb_idle_flush_pct to enable tuning of the page flushing rate
when the system is relatively idle. We care about this, since doing
extra unnecessary flash writes shortens the lifespan of the flash.
parent 58888e2c
SET @start_global_value = @@global.innodb_idle_flush_pct;
SELECT @start_global_value;
@start_global_value
100
Valid values are between 0 and 100
select @@global.innodb_idle_flush_pct between 0 and 100;
@@global.innodb_idle_flush_pct between 0 and 100
1
select @@global.innodb_idle_flush_pct;
@@global.innodb_idle_flush_pct
100
select @@session.innodb_idle_flush_pct;
ERROR HY000: Variable 'innodb_idle_flush_pct' is a GLOBAL variable
show global variables like 'innodb_idle_flush_pct';
Variable_name Value
innodb_idle_flush_pct 100
show session variables like 'innodb_idle_flush_pct';
Variable_name Value
innodb_idle_flush_pct 100
select * from information_schema.global_variables where variable_name='innodb_idle_flush_pct';
VARIABLE_NAME VARIABLE_VALUE
INNODB_IDLE_FLUSH_PCT 100
select * from information_schema.session_variables where variable_name='innodb_idle_flush_pct';
VARIABLE_NAME VARIABLE_VALUE
INNODB_IDLE_FLUSH_PCT 100
set global innodb_idle_flush_pct=10;
select @@global.innodb_idle_flush_pct;
@@global.innodb_idle_flush_pct
10
select * from information_schema.global_variables where variable_name='innodb_idle_flush_pct';
VARIABLE_NAME VARIABLE_VALUE
INNODB_IDLE_FLUSH_PCT 10
select * from information_schema.session_variables where variable_name='innodb_idle_flush_pct';
VARIABLE_NAME VARIABLE_VALUE
INNODB_IDLE_FLUSH_PCT 10
set session innodb_idle_flush_pct=1;
ERROR HY000: Variable 'innodb_idle_flush_pct' is a GLOBAL variable and should be set with SET GLOBAL
set global innodb_idle_flush_pct=1.1;
ERROR 42000: Incorrect argument type to variable 'innodb_idle_flush_pct'
set global innodb_idle_flush_pct=1e1;
ERROR 42000: Incorrect argument type to variable 'innodb_idle_flush_pct'
set global innodb_idle_flush_pct="bar";
ERROR 42000: Incorrect argument type to variable 'innodb_idle_flush_pct'
set global innodb_idle_flush_pct=-7;
Warnings:
Warning 1292 Truncated incorrect innodb_idle_flush_pct value: '-7'
select @@global.innodb_idle_flush_pct;
@@global.innodb_idle_flush_pct
0
select * from information_schema.global_variables where variable_name='innodb_idle_flush_pct';
VARIABLE_NAME VARIABLE_VALUE
INNODB_IDLE_FLUSH_PCT 0
set global innodb_idle_flush_pct=106;
Warnings:
Warning 1292 Truncated incorrect innodb_idle_flush_pct value: '106'
select @@global.innodb_idle_flush_pct;
@@global.innodb_idle_flush_pct
100
select * from information_schema.global_variables where variable_name='innodb_idle_flush_pct';
VARIABLE_NAME VARIABLE_VALUE
INNODB_IDLE_FLUSH_PCT 100
set global innodb_idle_flush_pct=0;
select @@global.innodb_idle_flush_pct;
@@global.innodb_idle_flush_pct
0
set global innodb_idle_flush_pct=100;
select @@global.innodb_idle_flush_pct;
@@global.innodb_idle_flush_pct
100
set global innodb_idle_flush_pct=DEFAULT;
select @@global.innodb_idle_flush_pct;
@@global.innodb_idle_flush_pct
100
SET @@global.innodb_idle_flush_pct = @start_global_value;
SELECT @@global.innodb_idle_flush_pct;
@@global.innodb_idle_flush_pct
100
......@@ -1027,6 +1027,20 @@ NUMERIC_BLOCK_SIZE NULL
ENUM_VALUE_LIST NULL
READ_ONLY NO
COMMAND_LINE_ARGUMENT OPTIONAL
VARIABLE_NAME INNODB_IDLE_FLUSH_PCT
SESSION_VALUE NULL
GLOBAL_VALUE 100
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 100
VARIABLE_SCOPE GLOBAL
VARIABLE_TYPE BIGINT UNSIGNED
VARIABLE_COMMENT Up to what percentage of dirty pages should be flushed when innodb finds it has spare resources to do so.
NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 100
NUMERIC_BLOCK_SIZE 0
ENUM_VALUE_LIST NULL
READ_ONLY NO
COMMAND_LINE_ARGUMENT REQUIRED
VARIABLE_NAME INNODB_IO_CAPACITY
SESSION_VALUE NULL
GLOBAL_VALUE 200
......
#
# 2013-04-01 - Added
#
--source include/have_innodb.inc
SET @start_global_value = @@global.innodb_idle_flush_pct;
SELECT @start_global_value;
#
# exists as global only
#
--echo Valid values are between 0 and 100
select @@global.innodb_idle_flush_pct between 0 and 100;
select @@global.innodb_idle_flush_pct;
--error ER_INCORRECT_GLOBAL_LOCAL_VAR
select @@session.innodb_idle_flush_pct;
show global variables like 'innodb_idle_flush_pct';
show session variables like 'innodb_idle_flush_pct';
select * from information_schema.global_variables where variable_name='innodb_idle_flush_pct';
select * from information_schema.session_variables where variable_name='innodb_idle_flush_pct';
#
# show that it's writable
#
set global innodb_idle_flush_pct=10;
select @@global.innodb_idle_flush_pct;
select * from information_schema.global_variables where variable_name='innodb_idle_flush_pct';
select * from information_schema.session_variables where variable_name='innodb_idle_flush_pct';
--error ER_GLOBAL_VARIABLE
set session innodb_idle_flush_pct=1;
#
# incorrect types
#
--error ER_WRONG_TYPE_FOR_VAR
set global innodb_idle_flush_pct=1.1;
--error ER_WRONG_TYPE_FOR_VAR
set global innodb_idle_flush_pct=1e1;
--error ER_WRONG_TYPE_FOR_VAR
set global innodb_idle_flush_pct="bar";
set global innodb_idle_flush_pct=-7;
select @@global.innodb_idle_flush_pct;
select * from information_schema.global_variables where variable_name='innodb_idle_flush_pct';
set global innodb_idle_flush_pct=106;
select @@global.innodb_idle_flush_pct;
select * from information_schema.global_variables where variable_name='innodb_idle_flush_pct';
#
# min/max/DEFAULT values
#
set global innodb_idle_flush_pct=0;
select @@global.innodb_idle_flush_pct;
set global innodb_idle_flush_pct=100;
select @@global.innodb_idle_flush_pct;
set global innodb_idle_flush_pct=DEFAULT;
select @@global.innodb_idle_flush_pct;
SET @@global.innodb_idle_flush_pct = @start_global_value;
SELECT @@global.innodb_idle_flush_pct;
......@@ -2444,27 +2444,17 @@ DECLARE_THREAD(buf_flush_page_cleaner_thread)(
while (srv_shutdown_state == SRV_SHUTDOWN_NONE) {
/* The page_cleaner skips sleep if the server is
idle and there are no pending IOs in the buffer pool
and there is work to do. */
if (srv_check_activity(last_activity)
|| buf_get_n_pending_read_ios()
|| n_flushed == 0) {
page_cleaner_sleep_if_needed(next_loop_time);
}
page_cleaner_sleep_if_needed(next_loop_time);
next_loop_time = ut_time_ms() + 1000;
if (srv_check_activity(last_activity)) {
last_activity = srv_get_activity_count();
/* Flush pages from end of LRU if required */
n_flushed = buf_flush_LRU_tail();
/* Flush pages from flush_list if required */
n_flushed += page_cleaner_flush_pages_if_needed();
} else {
} else if (srv_idle_flush_pct) {
n_flushed = page_cleaner_do_flush_batch(
PCT_IO(100),
LSN_MAX);
......@@ -2477,6 +2467,9 @@ DECLARE_THREAD(buf_flush_page_cleaner_thread)(
n_flushed);
}
}
/* Flush pages from end of LRU if required */
buf_flush_LRU_tail();
}
ut_ad(srv_shutdown_state > 0);
......
......@@ -17891,6 +17891,13 @@ static MYSQL_SYSVAR_ULONG(io_capacity_max, srv_max_io_capacity,
SRV_MAX_IO_CAPACITY_DUMMY_DEFAULT, 100,
SRV_MAX_IO_CAPACITY_LIMIT, 0);
static MYSQL_SYSVAR_ULONG(idle_flush_pct,
srv_idle_flush_pct,
PLUGIN_VAR_RQCMDARG,
"Up to what percentage of dirty pages should be flushed when innodb "
"finds it has spare resources to do so.",
NULL, NULL, 100, 0, 100, 0);
#ifdef UNIV_DEBUG
static MYSQL_SYSVAR_BOOL(purge_run_now, innodb_purge_run_now,
PLUGIN_VAR_OPCMDARG,
......@@ -18920,6 +18927,7 @@ static struct st_mysql_sys_var* innobase_system_variables[]= {
MYSQL_SYSVAR(read_only),
MYSQL_SYSVAR(io_capacity),
MYSQL_SYSVAR(io_capacity_max),
MYSQL_SYSVAR(idle_flush_pct),
MYSQL_SYSVAR(monitor_enable),
MYSQL_SYSVAR(monitor_disable),
MYSQL_SYSVAR(monitor_reset),
......
......@@ -359,6 +359,8 @@ extern double srv_defragment_fill_factor;
extern uint srv_defragment_frequency;
extern ulonglong srv_defragment_interval;
extern ulint srv_idle_flush_pct;
/* Number of IO operations per second the server can do */
extern ulong srv_io_capacity;
......
......@@ -257,6 +257,8 @@ UNIV_INTERN ulint srv_buf_pool_curr_size = 0;
UNIV_INTERN ulint srv_mem_pool_size = ULINT_MAX;
UNIV_INTERN ulint srv_lock_table_size = ULINT_MAX;
UNIV_INTERN ulint srv_idle_flush_pct = 100;
/* This parameter is deprecated. Use srv_n_io_[read|write]_threads
instead. */
UNIV_INTERN ulint srv_n_file_io_threads = ULINT_MAX;
......
......@@ -2736,14 +2736,7 @@ DECLARE_THREAD(buf_flush_page_cleaner_thread)(
srv_current_thread_priority = srv_cleaner_thread_priority;
/* The page_cleaner skips sleep if the server is
idle and there are no pending IOs in the buffer pool
and there is work to do. */
if (srv_check_activity(last_activity)
|| buf_get_n_pending_read_ios()
|| n_flushed == 0) {
page_cleaner_sleep_if_needed(next_loop_time);
}
page_cleaner_sleep_if_needed(next_loop_time);
page_cleaner_sleep_time
= page_cleaner_adapt_flush_sleep_time();
......@@ -2761,8 +2754,8 @@ DECLARE_THREAD(buf_flush_page_cleaner_thread)(
}
/* Flush pages from flush_list if required */
n_flushed += page_cleaner_flush_pages_if_needed();
} else {
page_cleaner_flush_pages_if_needed();
} else if (srv_idle_flush_pct) {
n_flushed = page_cleaner_do_flush_batch(
PCT_IO(100),
LSN_MAX);
......@@ -2775,6 +2768,9 @@ DECLARE_THREAD(buf_flush_page_cleaner_thread)(
n_flushed);
}
}
/* Flush pages from end of LRU if required */
buf_flush_LRU_tail();
}
ut_ad(srv_shutdown_state > 0);
......
......@@ -18970,6 +18970,13 @@ static MYSQL_SYSVAR_ULONG(io_capacity_max, srv_max_io_capacity,
SRV_MAX_IO_CAPACITY_DUMMY_DEFAULT, 100,
SRV_MAX_IO_CAPACITY_LIMIT, 0);
static MYSQL_SYSVAR_ULONG(idle_flush_pct,
srv_idle_flush_pct,
PLUGIN_VAR_RQCMDARG,
"Up to what percentage of dirty pages should be flushed when innodb "
"finds it has spare resources to do so.",
NULL, NULL, 100, 0, 100, 0);
#ifdef UNIV_DEBUG
static MYSQL_SYSVAR_BOOL(purge_run_now, innodb_purge_run_now,
PLUGIN_VAR_OPCMDARG,
......@@ -20224,6 +20231,7 @@ static struct st_mysql_sys_var* innobase_system_variables[]= {
MYSQL_SYSVAR(read_only),
MYSQL_SYSVAR(io_capacity),
MYSQL_SYSVAR(io_capacity_max),
MYSQL_SYSVAR(idle_flush_pct),
MYSQL_SYSVAR(monitor_enable),
MYSQL_SYSVAR(monitor_disable),
MYSQL_SYSVAR(monitor_reset),
......
......@@ -424,6 +424,8 @@ extern double srv_defragment_fill_factor;
extern uint srv_defragment_frequency;
extern ulonglong srv_defragment_interval;
extern ulint srv_idle_flush_pct;
/* Number of IO operations per second the server can do */
extern ulong srv_io_capacity;
......
......@@ -341,6 +341,8 @@ UNIV_INTERN ulong srv_cleaner_lsn_age_factor
UNIV_INTERN ulong srv_empty_free_list_algorithm
= SRV_EMPTY_FREE_LIST_BACKOFF;
UNIV_INTERN ulint srv_idle_flush_pct = 100;
/* This parameter is deprecated. Use srv_n_io_[read|write]_threads
instead. */
UNIV_INTERN ulint srv_n_file_io_threads = ULINT_MAX;
......
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