Auto-tune effective_cache size to be 4x shared buffers
This commit is contained in:
parent
d29a031926
commit
ee1e5662d8
|
@ -2758,7 +2758,7 @@ include 'filename'
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
Random access to mechanical disk storage is normally much more expensive
|
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
|
(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
|
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
|
as modeling random access as 40 times slower than sequential, while
|
||||||
|
@ -2841,9 +2841,17 @@ include 'filename'
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Sets the planner's assumption about the effective size of the
|
Sets the planner's assumption about the effective size of the
|
||||||
disk cache that is available to a single query. This is
|
disk cache that is available to a single query. The default
|
||||||
factored into estimates of the cost of using an index; a
|
setting of -1 selects a size equal to four times the size of <xref
|
||||||
higher value makes it more likely index scans will be used, a
|
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
|
lower value makes it more likely sequential scans will be
|
||||||
used. When setting this parameter you should consider both
|
used. When setting this parameter you should consider both
|
||||||
<productname>PostgreSQL</productname>'s shared buffers and the
|
<productname>PostgreSQL</productname>'s shared buffers and the
|
||||||
|
@ -2855,8 +2863,10 @@ include 'filename'
|
||||||
memory allocated by <productname>PostgreSQL</productname>, nor
|
memory allocated by <productname>PostgreSQL</productname>, nor
|
||||||
does it reserve kernel disk cache; it is used only for estimation
|
does it reserve kernel disk cache; it is used only for estimation
|
||||||
purposes. The system also does not assume data remains in
|
purposes. The system also does not assume data remains in
|
||||||
the disk cache between queries. The default is 128 megabytes
|
the disk cache between queries. The auto-tuning
|
||||||
(<literal>128MB</>).
|
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>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
|
@ -87,6 +87,7 @@
|
||||||
#include "optimizer/planmain.h"
|
#include "optimizer/planmain.h"
|
||||||
#include "optimizer/restrictinfo.h"
|
#include "optimizer/restrictinfo.h"
|
||||||
#include "parser/parsetree.h"
|
#include "parser/parsetree.h"
|
||||||
|
#include "utils/guc.h"
|
||||||
#include "utils/lsyscache.h"
|
#include "utils/lsyscache.h"
|
||||||
#include "utils/selfuncs.h"
|
#include "utils/selfuncs.h"
|
||||||
#include "utils/spccache.h"
|
#include "utils/spccache.h"
|
||||||
|
@ -95,14 +96,13 @@
|
||||||
|
|
||||||
#define LOG2(x) (log(x) / 0.693147180559945)
|
#define LOG2(x) (log(x) / 0.693147180559945)
|
||||||
|
|
||||||
|
|
||||||
double seq_page_cost = DEFAULT_SEQ_PAGE_COST;
|
double seq_page_cost = DEFAULT_SEQ_PAGE_COST;
|
||||||
double random_page_cost = DEFAULT_RANDOM_PAGE_COST;
|
double random_page_cost = DEFAULT_RANDOM_PAGE_COST;
|
||||||
double cpu_tuple_cost = DEFAULT_CPU_TUPLE_COST;
|
double cpu_tuple_cost = DEFAULT_CPU_TUPLE_COST;
|
||||||
double cpu_index_tuple_cost = DEFAULT_CPU_INDEX_TUPLE_COST;
|
double cpu_index_tuple_cost = DEFAULT_CPU_INDEX_TUPLE_COST;
|
||||||
double cpu_operator_cost = DEFAULT_CPU_OPERATOR_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;
|
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;
|
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
|
* index_pages_fetched
|
||||||
* Estimate the number of pages actually fetched after accounting for
|
* Estimate the number of pages actually fetched after accounting for
|
||||||
|
|
|
@ -118,6 +118,7 @@
|
||||||
#include "utils/builtins.h"
|
#include "utils/builtins.h"
|
||||||
#include "utils/datetime.h"
|
#include "utils/datetime.h"
|
||||||
#include "utils/dynamic_loader.h"
|
#include "utils/dynamic_loader.h"
|
||||||
|
#include "utils/guc.h"
|
||||||
#include "utils/memutils.h"
|
#include "utils/memutils.h"
|
||||||
#include "utils/ps_status.h"
|
#include "utils/ps_status.h"
|
||||||
#include "utils/timeout.h"
|
#include "utils/timeout.h"
|
||||||
|
@ -4475,6 +4476,8 @@ SubPostmasterMain(int argc, char *argv[])
|
||||||
memset(&port, 0, sizeof(Port));
|
memset(&port, 0, sizeof(Port));
|
||||||
read_backend_variables(argv[2], &port);
|
read_backend_variables(argv[2], &port);
|
||||||
|
|
||||||
|
set_default_effective_cache_size();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set reference point for stack-depth checking
|
* Set reference point for stack-depth checking
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -2410,8 +2410,8 @@ static struct config_int ConfigureNamesInt[] =
|
||||||
GUC_UNIT_BLOCKS,
|
GUC_UNIT_BLOCKS,
|
||||||
},
|
},
|
||||||
&effective_cache_size,
|
&effective_cache_size,
|
||||||
DEFAULT_EFFECTIVE_CACHE_SIZE, 1, INT_MAX,
|
-1, -1, INT_MAX,
|
||||||
NULL, NULL, NULL
|
check_effective_cache_size, NULL, NULL
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
#define DEFAULT_CPU_INDEX_TUPLE_COST 0.005
|
#define DEFAULT_CPU_INDEX_TUPLE_COST 0.005
|
||||||
#define DEFAULT_CPU_OPERATOR_COST 0.0025
|
#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
|
typedef enum
|
||||||
{
|
{
|
||||||
|
|
|
@ -386,6 +386,8 @@ extern void assign_search_path(const char *newval, void *extra);
|
||||||
|
|
||||||
/* in access/transam/xlog.c */
|
/* in access/transam/xlog.c */
|
||||||
extern bool check_wal_buffers(int *newval, void **extra, GucSource source);
|
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);
|
extern void assign_xlog_sync_method(int new_sync_method, void *extra);
|
||||||
|
|
||||||
#endif /* GUC_H */
|
#endif /* GUC_H */
|
||||||
|
|
|
@ -2713,6 +2713,7 @@ where thousand = (q1 + q2);
|
||||||
--
|
--
|
||||||
-- test placement of movable quals in a parameterized join tree
|
-- test placement of movable quals in a parameterized join tree
|
||||||
--
|
--
|
||||||
|
set effective_cache_size = '128MB';
|
||||||
explain (costs off)
|
explain (costs off)
|
||||||
select * from tenk1 t1 left join
|
select * from tenk1 t1 left join
|
||||||
(tenk1 t2 join tenk1 t3 on t2.thousand = t3.unique2)
|
(tenk1 t2 join tenk1 t3 on t2.thousand = t3.unique2)
|
||||||
|
|
|
@ -711,6 +711,8 @@ where thousand = (q1 + q2);
|
||||||
-- test placement of movable quals in a parameterized join tree
|
-- test placement of movable quals in a parameterized join tree
|
||||||
--
|
--
|
||||||
|
|
||||||
|
set effective_cache_size = '128MB';
|
||||||
|
|
||||||
explain (costs off)
|
explain (costs off)
|
||||||
select * from tenk1 t1 left join
|
select * from tenk1 t1 left join
|
||||||
(tenk1 t2 join tenk1 t3 on t2.thousand = t3.unique2)
|
(tenk1 t2 join tenk1 t3 on t2.thousand = t3.unique2)
|
||||||
|
|
Loading…
Reference in New Issue