Auto-tune effective_cache size to be 4x shared buffers

This commit is contained in:
Bruce Momjian 2013-10-08 12:12:24 -04:00
parent d29a031926
commit ee1e5662d8
8 changed files with 75 additions and 11 deletions

View File

@ -2758,7 +2758,7 @@ include 'filename'
<para>
Random access to mechanical disk storage is normally much more expensive
than four-times sequential access. However, a lower default is used
than four times sequential access. However, a lower default is used
(4.0) because the majority of random accesses to disk, such as indexed
reads, are assumed to be in cache. The default value can be thought of
as modeling random access as 40 times slower than sequential, while
@ -2841,9 +2841,17 @@ include 'filename'
<listitem>
<para>
Sets the planner's assumption about the effective size of the
disk cache that is available to a single query. This is
factored into estimates of the cost of using an index; a
higher value makes it more likely index scans will be used, a
disk cache that is available to a single query. The default
setting of -1 selects a size equal to four times the size of <xref
linkend="guc-shared-buffers">, but not less than the size of one
shared buffer page, typically <literal>8kB</literal>. This value
can be set manually if the automatic choice is too large or too
small.
</para>
<para>
This value is factored into estimates of the cost of using an index;
a higher value makes it more likely index scans will be used, a
lower value makes it more likely sequential scans will be
used. When setting this parameter you should consider both
<productname>PostgreSQL</productname>'s shared buffers and the
@ -2855,8 +2863,10 @@ include 'filename'
memory allocated by <productname>PostgreSQL</productname>, nor
does it reserve kernel disk cache; it is used only for estimation
purposes. The system also does not assume data remains in
the disk cache between queries. The default is 128 megabytes
(<literal>128MB</>).
the disk cache between queries. The auto-tuning
selected by the default setting of -1 should give reasonable
results if this database cluster is can utilize most of the memory
on this server.
</para>
</listitem>
</varlistentry>

View File

@ -87,6 +87,7 @@
#include "optimizer/planmain.h"
#include "optimizer/restrictinfo.h"
#include "parser/parsetree.h"
#include "utils/guc.h"
#include "utils/lsyscache.h"
#include "utils/selfuncs.h"
#include "utils/spccache.h"
@ -95,14 +96,13 @@
#define LOG2(x) (log(x) / 0.693147180559945)
double seq_page_cost = DEFAULT_SEQ_PAGE_COST;
double random_page_cost = DEFAULT_RANDOM_PAGE_COST;
double cpu_tuple_cost = DEFAULT_CPU_TUPLE_COST;
double cpu_index_tuple_cost = DEFAULT_CPU_INDEX_TUPLE_COST;
double cpu_operator_cost = DEFAULT_CPU_OPERATOR_COST;
int effective_cache_size = DEFAULT_EFFECTIVE_CACHE_SIZE;
int effective_cache_size = -1;
Cost disable_cost = 1.0e10;
@ -456,6 +456,52 @@ cost_index(IndexPath *path, PlannerInfo *root, double loop_count)
path->path.total_cost = startup_cost + run_cost;
}
void
set_default_effective_cache_size(void)
{
/*
* If the value of effective_cache_size is -1, use the preferred
* auto-tune value.
*/
if (effective_cache_size == -1)
{
char buf[32];
snprintf(buf, sizeof(buf), "%d", NBuffers * DEFAULT_EFFECTIVE_CACHE_SIZE_MULTI);
SetConfigOption("effective_cache_size", buf, PGC_POSTMASTER, PGC_S_OVERRIDE);
}
Assert(effective_cache_size > 0);
}
/*
* GUC check_hook for effective_cache_size
*/
bool
check_effective_cache_size(int *newval, void **extra, GucSource source)
{
/*
* -1 indicates a request for auto-tune.
*/
if (*newval == -1)
{
/*
* If we haven't yet changed the boot_val default of -1, just let it
* be. We'll fix it in index_pages_fetched
*/
if (effective_cache_size == -1)
return true;
/* Otherwise, substitute the auto-tune value */
*newval = NBuffers * DEFAULT_EFFECTIVE_CACHE_SIZE_MULTI;
}
/* set minimum? */
if (*newval < 1)
*newval = 1;
return true;
}
/*
* index_pages_fetched
* Estimate the number of pages actually fetched after accounting for

View File

@ -118,6 +118,7 @@
#include "utils/builtins.h"
#include "utils/datetime.h"
#include "utils/dynamic_loader.h"
#include "utils/guc.h"
#include "utils/memutils.h"
#include "utils/ps_status.h"
#include "utils/timeout.h"
@ -4475,6 +4476,8 @@ SubPostmasterMain(int argc, char *argv[])
memset(&port, 0, sizeof(Port));
read_backend_variables(argv[2], &port);
set_default_effective_cache_size();
/*
* Set reference point for stack-depth checking
*/

View File

@ -2410,8 +2410,8 @@ static struct config_int ConfigureNamesInt[] =
GUC_UNIT_BLOCKS,
},
&effective_cache_size,
DEFAULT_EFFECTIVE_CACHE_SIZE, 1, INT_MAX,
NULL, NULL, NULL
-1, -1, INT_MAX,
check_effective_cache_size, NULL, NULL
},
{

View File

@ -27,7 +27,7 @@
#define DEFAULT_CPU_INDEX_TUPLE_COST 0.005
#define DEFAULT_CPU_OPERATOR_COST 0.0025
#define DEFAULT_EFFECTIVE_CACHE_SIZE 16384 /* measured in pages */
#define DEFAULT_EFFECTIVE_CACHE_SIZE_MULTI 4
typedef enum
{

View File

@ -386,6 +386,8 @@ extern void assign_search_path(const char *newval, void *extra);
/* in access/transam/xlog.c */
extern bool check_wal_buffers(int *newval, void **extra, GucSource source);
extern bool check_effective_cache_size(int *newval, void **extra, GucSource source);
extern void set_default_effective_cache_size(void);
extern void assign_xlog_sync_method(int new_sync_method, void *extra);
#endif /* GUC_H */

View File

@ -2713,6 +2713,7 @@ where thousand = (q1 + q2);
--
-- test placement of movable quals in a parameterized join tree
--
set effective_cache_size = '128MB';
explain (costs off)
select * from tenk1 t1 left join
(tenk1 t2 join tenk1 t3 on t2.thousand = t3.unique2)

View File

@ -711,6 +711,8 @@ where thousand = (q1 + q2);
-- test placement of movable quals in a parameterized join tree
--
set effective_cache_size = '128MB';
explain (costs off)
select * from tenk1 t1 left join
(tenk1 t2 join tenk1 t3 on t2.thousand = t3.unique2)