Skip to content

Commit

Permalink
Merge branch '5.6-ps-bug1651657' into 5.7-ps-bug1651657
Browse files Browse the repository at this point in the history
  • Loading branch information
ihanick committed Mar 21, 2017
2 parents 75a1f89 + 4d70ecc commit 8103a23
Show file tree
Hide file tree
Showing 7 changed files with 119 additions and 70 deletions.
10 changes: 10 additions & 0 deletions mysql-test/suite/innodb/r/percona_bug1651657.result
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
include/assert.inc [Small buffer pool instances should use legacy]
call mtr.add_suppression("InnoDB: innodb_empty_free_list_algorithm = 'backoff' requires at least 20MB buffer pool instances.");
SET GLOBAL innodb_empty_free_list_algorithm="backoff";
ERROR 42000: Variable 'innodb_empty_free_list_algorithm' can't be set to the value of 'backoff'
include/assert.inc [Small buffer pool instances should use legacy]
SET @@GLOBAL.innodb_buffer_pool_size = 1189085184;
SET GLOBAL innodb_empty_free_list_algorithm="backoff";
SET @@GLOBAL.innodb_buffer_pool_size = 1075838976;
ERROR 42000: Variable 'innodb_buffer_pool_size' can't be set to the value of '1075838976'
SET GLOBAL innodb_empty_free_list_algorithm="legacy";
1 change: 1 addition & 0 deletions mysql-test/suite/innodb/t/percona_bug1651657-master.opt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
--innodb-buffer-pool-size=1026M --innodb-buffer-pool-instances=54 --innodb-empty-free-list-algorithm=backoff --innodb_buffer_pool_chunk_size=1048576
44 changes: 44 additions & 0 deletions mysql-test/suite/innodb/t/percona_bug1651657.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
--source include/have_innodb.inc
--let $assert_text= Small buffer pool instances should use legacy
--let $assert_cond= @@innodb_empty_free_list_algorithm = "legacy"
--source include/assert.inc

call mtr.add_suppression("InnoDB: innodb_empty_free_list_algorithm = 'backoff' requires at least 20MB buffer pool instances.");
--error 1231
SET GLOBAL innodb_empty_free_list_algorithm="backoff";
--let $assert_text= Small buffer pool instances should use legacy
--let $assert_cond= @@innodb_empty_free_list_algorithm = "legacy"
--source include/assert.inc

# Test buffer pool expand and shink with backoff algorithm.
let $wait_timeout = 180;
let $wait_condition =
SELECT SUBSTR(variable_value, 1, 34) = 'Completed resizing buffer pool at '
FROM information_schema.global_status
WHERE LOWER(variable_name) = 'innodb_buffer_pool_resize_status';
--disable_query_log
set @old_innodb_buffer_pool_size = @@innodb_buffer_pool_size;
if (`select (version() like '%debug%') > 0`)
{
set @old_innodb_disable_resize = @@innodb_disable_resize_buffer_pool_debug;
set global innodb_disable_resize_buffer_pool_debug = OFF;
}
--enable_query_log

SET @@GLOBAL.innodb_buffer_pool_size = 1189085184;
--source include/wait_condition.inc
SET GLOBAL innodb_empty_free_list_algorithm="backoff";

--error 1231
SET @@GLOBAL.innodb_buffer_pool_size = 1075838976;

SET GLOBAL innodb_empty_free_list_algorithm="legacy";

--disable_query_log
set global innodb_buffer_pool_size = @old_innodb_buffer_pool_size;
if (`select (version() like '%debug%') > 0`)
{
set global innodb_disable_resize_buffer_pool_debug = @old_innodb_disable_resize;
}
--enable_query_log
--source include/wait_condition.inc
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ COUNT(@@GLOBAL.innodb_buffer_pool_size)
1
1 Expected
'#---------------------BS_STVARS_022_02----------------------#'
SET @@GLOBAL.innodb_buffer_pool_size=10485760;
SET @@GLOBAL.innodb_buffer_pool_size=20971520;
Expected succeeded
SELECT COUNT(@@GLOBAL.innodb_buffer_pool_size);
COUNT(@@GLOBAL.innodb_buffer_pool_size)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ SELECT COUNT(@@GLOBAL.innodb_buffer_pool_size);
# Check if Value can set #
####################################################################

SET @@GLOBAL.innodb_buffer_pool_size=10485760;
SET @@GLOBAL.innodb_buffer_pool_size=20971520;
--echo Expected succeeded
--source include/wait_condition.inc

Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
--innodb-buffer-pool-size=20M
--innodb-buffer-pool-size=20M --innodb_buffer_pool_instances=1
128 changes: 61 additions & 67 deletions storage/innobase/handler/ha_innodb.cc
Original file line number Diff line number Diff line change
Expand Up @@ -776,6 +776,37 @@ innodb_tmpdir_validate(
return(0);
}

/** Empty free list algorithm.
Checks if buffer pool is big enough to enable backoff algorithm.
InnoDB empty free list algorithm backoff requires free pages
from LRU for the best performance.
buf_LRU_buf_pool_running_out cancels query if 1/4 of
buffer pool belongs to LRU or freelist.
At the same time buf_flush_LRU_list_batch
keeps up to BUF_LRU_MIN_LEN in LRU.
In order to avoid deadlock baclkoff requires buffer pool
to be at least 4*BUF_LRU_MIN_LEN,
but flush peformance is bad because of trashing
and additional BUF_LRU_MIN_LEN pages are requested.
@param[in] algorithm desired algorithm from srv_empty_free_list_t
@param[in] new_buf_pool_sz requested buffer pool size
@return true if it's possible to enable backoff. */
static inline
bool
innodb_empty_free_list_algorithm_allowed(
srv_empty_free_list_t algorithm,
ulint new_buf_pool_sz = 0)
{
if (!new_buf_pool_sz)
new_buf_pool_sz = srv_buf_pool_size;

long long buf_pool_pages = new_buf_pool_sz / srv_page_size
/ srv_buf_pool_instances;

return(buf_pool_pages >= BUF_LRU_MIN_LEN * (4 + 1)
|| algorithm != SRV_EMPTY_FREE_LIST_BACKOFF);
}

/******************************************************************//**
Maps a MySQL trx isolation level code to the InnoDB isolation level code
@return InnoDB isolation level */
Expand Down Expand Up @@ -1383,28 +1414,6 @@ innobase_drop_zip_dict(
ulint* name_len);
/*!< in/out: zip dictionary name length */

/*************************************************************//**
Checks if buffer pool is big enough to enable backoff algorithm.
InnoDB empty free list algorithm backoff requires free pages
from LRU for the best performance.
buf_LRU_buf_pool_running_out cancels query if 1/4 of
buffer pool belongs to LRU or freelist.
At the same time buf_flush_LRU_list_batch
keeps up to BUF_LRU_MIN_LEN in LRU.
In order to avoid deadlock baclkoff requires buffer pool
to be at least 4*BUF_LRU_MIN_LEN,
but flush peformance is bad because of trashing
and additional BUF_LRU_MIN_LEN pages are requested.
@return true if it's possible to enable backoff. */
static
bool
innodb_empty_free_list_algorithm_backoff_allowed(
srv_empty_free_list_t
algorithm, /*!< in: desired algorithm
from srv_empty_free_list_t */
long long buf_pool_pages); /*!< in: total number
of pages inside buffer pool */

/****************************************************************//**
Parse and enable InnoDB monitor counters during server startup.
User can enable monitor counters/groups by specifying
Expand Down Expand Up @@ -4233,21 +4242,6 @@ innobase_init(

innobase_commit_concurrency_init_default();

/* Do not enable backoff algorithm for small buffer pool. */
if (!innodb_empty_free_list_algorithm_backoff_allowed(
static_cast<srv_empty_free_list_t>(
srv_empty_free_list_algorithm),
innobase_buffer_pool_size / srv_page_size)) {
sql_print_information(
"InnoDB: innodb_empty_free_list_algorithm "
"has been changed to legacy "
"because of small buffer pool size. "
"In order to use backoff, "
"increase buffer pool at least up to 20MB.\n");
srv_empty_free_list_algorithm
= SRV_EMPTY_FREE_LIST_LEGACY;
}

#ifdef HAVE_PSI_INTERFACE
/* Register keys with MySQL performance schema */
int count;
Expand Down Expand Up @@ -4314,6 +4308,20 @@ innobase_init(
DBUG_RETURN(innobase_init_abort());
}

/* Do not enable backoff algorithm for small buffer pool. */
if (!innodb_empty_free_list_algorithm_allowed(
static_cast<srv_empty_free_list_t>(
srv_empty_free_list_algorithm))) {
sql_print_information(
"InnoDB: innodb_empty_free_list_algorithm "
"has been changed to legacy "
"because of small buffer pool size. "
"In order to use backoff, "
"increase buffer pool at least up to 20MB.\n");
srv_empty_free_list_algorithm
= SRV_EMPTY_FREE_LIST_LEGACY;
}

/* Create mutex to protect encryption master_key_id. */
mutex_create(LATCH_ID_MASTER_KEY_ID_MUTEX, &master_key_id_mutex);

Expand Down Expand Up @@ -20346,32 +20354,6 @@ innodb_status_output_update(
os_event_set(lock_sys->timeout_event);
}

/*************************************************************//**
Empty free list algorithm.
Checks if buffer pool is big enough to enable backoff algorithm.
InnoDB empty free list algorithm backoff requires free pages
from LRU for the best performance.
buf_LRU_buf_pool_running_out cancels query if 1/4 of
buffer pool belongs to LRU or freelist.
At the same time buf_flush_LRU_list_batch
keeps up to BUF_LRU_MIN_LEN in LRU.
In order to avoid deadlock baclkoff requires buffer pool
to be at least 4*BUF_LRU_MIN_LEN,
but flush peformance is bad because of trashing
and additional BUF_LRU_MIN_LEN pages are requested.
@return true if it's possible to enable backoff. */
static
bool
innodb_empty_free_list_algorithm_backoff_allowed(
srv_empty_free_list_t algorithm, /*!< in: desired algorithm
from srv_empty_free_list_t */
long long buf_pool_pages) /*!< in: total number
of pages inside buffer pool */
{
return(buf_pool_pages >= BUF_LRU_MIN_LEN * (4 + 1)
|| algorithm != SRV_EMPTY_FREE_LIST_BACKOFF);
}

/*************************************************************//**
Empty free list algorithm. This function is registered as
a callback with MySQL.
Expand Down Expand Up @@ -20413,13 +20395,11 @@ innodb_srv_empty_free_list_algorithm_validate(
return(1);

algorithm = static_cast<srv_empty_free_list_t>(algo);
if (!innodb_empty_free_list_algorithm_backoff_allowed(
algorithm,
innobase_buffer_pool_size / srv_page_size)) {
if (!innodb_empty_free_list_algorithm_allowed(algorithm)) {
sql_print_warning(
"InnoDB: innodb_empty_free_list_algorithm "
"= 'backoff' requires at least"
" 20MB buffer pool.\n");
" 20MB buffer pool instances.\n");
return(1);
}

Expand Down Expand Up @@ -22635,6 +22615,20 @@ innodb_buffer_pool_size_validate(
return(1);
}

if (!innodb_empty_free_list_algorithm_allowed(
static_cast<srv_empty_free_list_t>(
srv_empty_free_list_algorithm),
intbuf
)) {
push_warning_printf(thd, Sql_condition::SL_WARNING,
ER_WRONG_ARGUMENTS,
"Cannot update innodb_buffer_pool_size"
" to less than 20MB per instance"
" innodb_empty_free_list_algorithm"
" = backoff.");
return(1);
}

ulint requested_buf_pool_size
= buf_pool_size_align(static_cast<ulint>(intbuf));

Expand Down

0 comments on commit 8103a23

Please sign in to comment.