diff options
author | Bruce Momjian <bruce@momjian.us> | 2013-10-08 12:12:24 -0400 |
---|---|---|
committer | Bruce Momjian <bruce@momjian.us> | 2013-10-08 12:12:24 -0400 |
commit | ee1e5662d8d8330726eaef7d3110cb7add24d058 (patch) | |
tree | 07afa37af6d1043d9c16fb4961150b7a3477a18f | |
parent | d29a03192615b55593af4a89283f5b5c72f13afe (diff) | |
download | postgresql-ee1e5662d8d8330726eaef7d3110cb7add24d058.tar.gz postgresql-ee1e5662d8d8330726eaef7d3110cb7add24d058.zip |
Auto-tune effective_cache size to be 4x shared buffers
-rw-r--r-- | doc/src/sgml/config.sgml | 22 | ||||
-rw-r--r-- | src/backend/optimizer/path/costsize.c | 50 | ||||
-rw-r--r-- | src/backend/postmaster/postmaster.c | 3 | ||||
-rw-r--r-- | src/backend/utils/misc/guc.c | 4 | ||||
-rw-r--r-- | src/include/optimizer/cost.h | 2 | ||||
-rw-r--r-- | src/include/utils/guc.h | 2 | ||||
-rw-r--r-- | src/test/regress/expected/join.out | 1 | ||||
-rw-r--r-- | src/test/regress/sql/join.sql | 2 |
8 files changed, 75 insertions, 11 deletions
diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml index 697cf401374..116acd7eca1 100644 --- a/doc/src/sgml/config.sgml +++ b/doc/src/sgml/config.sgml @@ -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> diff --git a/src/backend/optimizer/path/costsize.c b/src/backend/optimizer/path/costsize.c index 0caac75ac5a..82c66f76caf 100644 --- a/src/backend/optimizer/path/costsize.c +++ b/src/backend/optimizer/path/costsize.c @@ -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 diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c index 9f721b76515..c4b54d12cb2 100644 --- a/src/backend/postmaster/postmaster.c +++ b/src/backend/postmaster/postmaster.c @@ -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 */ diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c index d9a06b4d881..833f34b1ee2 100644 --- a/src/backend/utils/misc/guc.c +++ b/src/backend/utils/misc/guc.c @@ -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 }, { diff --git a/src/include/optimizer/cost.h b/src/include/optimizer/cost.h index a052944d10c..444ab740443 100644 --- a/src/include/optimizer/cost.h +++ b/src/include/optimizer/cost.h @@ -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 { diff --git a/src/include/utils/guc.h b/src/include/utils/guc.h index 89ee40c334a..3e981b3e94b 100644 --- a/src/include/utils/guc.h +++ b/src/include/utils/guc.h @@ -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 */ diff --git a/src/test/regress/expected/join.out b/src/test/regress/expected/join.out index c94ac614af8..d46ff26d82b 100644 --- a/src/test/regress/expected/join.out +++ b/src/test/regress/expected/join.out @@ -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) diff --git a/src/test/regress/sql/join.sql b/src/test/regress/sql/join.sql index 351400f2da2..1a4dc03d18b 100644 --- a/src/test/regress/sql/join.sql +++ b/src/test/regress/sql/join.sql @@ -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) |