diff options
author | Alvaro Herrera <alvherre@alvh.no-ip.org> | 2015-09-08 12:51:42 -0300 |
---|---|---|
committer | Alvaro Herrera <alvherre@alvh.no-ip.org> | 2015-09-08 12:51:42 -0300 |
commit | 1aba62ec635f5852bc45ce65482366e541e61ff5 (patch) | |
tree | 1161cc00324cb8d229b831a944432646ae1552d5 /src/backend/utils | |
parent | 665a00c9e2598e3be366cb9f99c0a04a51dd8c7a (diff) | |
download | postgresql-1aba62ec635f5852bc45ce65482366e541e61ff5.tar.gz postgresql-1aba62ec635f5852bc45ce65482366e541e61ff5.zip |
Allow per-tablespace effective_io_concurrency
Per discussion, nowadays it is possible to have tablespaces that have
wildly different I/O characteristics from others. Setting different
effective_io_concurrency parameters for those has been measured to
improve performance.
Author: Julien Rouhaud
Reviewed by: Andres Freund
Diffstat (limited to 'src/backend/utils')
-rw-r--r-- | src/backend/utils/cache/spccache.c | 12 | ||||
-rw-r--r-- | src/backend/utils/misc/guc.c | 45 |
2 files changed, 15 insertions, 42 deletions
diff --git a/src/backend/utils/cache/spccache.c b/src/backend/utils/cache/spccache.c index 1a0c884b248..1c78dfe76a1 100644 --- a/src/backend/utils/cache/spccache.c +++ b/src/backend/utils/cache/spccache.c @@ -23,6 +23,7 @@ #include "commands/tablespace.h" #include "miscadmin.h" #include "optimizer/cost.h" +#include "storage/bufmgr.h" #include "utils/catcache.h" #include "utils/hsearch.h" #include "utils/inval.h" @@ -198,3 +199,14 @@ get_tablespace_page_costs(Oid spcid, *spc_seq_page_cost = spc->opts->seq_page_cost; } } + +int +get_tablespace_io_concurrency(Oid spcid) +{ + TableSpaceCacheEntry *spc = get_tablespace(spcid); + + if (!spc->opts || spc->opts->effective_io_concurrency < 0) + return effective_io_concurrency; + else + return spc->opts->effective_io_concurrency; +} diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c index b3dac51b779..8ebf4246b8e 100644 --- a/src/backend/utils/misc/guc.c +++ b/src/backend/utils/misc/guc.c @@ -490,7 +490,6 @@ static int wal_block_size; static bool data_checksums; static int wal_segment_size; static bool integer_datetimes; -static int effective_io_concurrency; static bool assert_enabled; /* should be static, but commands/variable.c needs to get at this */ @@ -2352,7 +2351,7 @@ static struct config_int ConfigureNamesInt[] = }, &effective_io_concurrency, #ifdef USE_PREFETCH - 1, 0, 1000, + 1, 0, MAX_IO_CONCURRENCY, #else 0, 0, 0, #endif @@ -9986,47 +9985,9 @@ static bool check_effective_io_concurrency(int *newval, void **extra, GucSource source) { #ifdef USE_PREFETCH - double new_prefetch_pages = 0.0; - int i; - - /*---------- - * The user-visible GUC parameter is the number of drives (spindles), - * which we need to translate to a number-of-pages-to-prefetch target. - * The target value is stashed in *extra and then assigned to the actual - * variable by assign_effective_io_concurrency. - * - * The expected number of prefetch pages needed to keep N drives busy is: - * - * drives | I/O requests - * -------+---------------- - * 1 | 1 - * 2 | 2/1 + 2/2 = 3 - * 3 | 3/1 + 3/2 + 3/3 = 5 1/2 - * 4 | 4/1 + 4/2 + 4/3 + 4/4 = 8 1/3 - * n | n * H(n) - * - * This is called the "coupon collector problem" and H(n) is called the - * harmonic series. This could be approximated by n * ln(n), but for - * reasonable numbers of drives we might as well just compute the series. - * - * Alternatively we could set the target to the number of pages necessary - * so that the expected number of active spindles is some arbitrary - * percentage of the total. This sounds the same but is actually slightly - * different. The result ends up being ln(1-P)/ln((n-1)/n) where P is - * that desired fraction. - * - * Experimental results show that both of these formulas aren't aggressive - * enough, but we don't really have any better proposals. - * - * Note that if *newval = 0 (disabled), we must set target = 0. - *---------- - */ - - for (i = 1; i <= *newval; i++) - new_prefetch_pages += (double) *newval / (double) i; + double new_prefetch_pages; - /* This range check shouldn't fail, but let's be paranoid */ - if (new_prefetch_pages >= 0.0 && new_prefetch_pages < (double) INT_MAX) + if (ComputeIoConcurrency(*newval, &new_prefetch_pages)) { int *myextra = (int *) guc_malloc(ERROR, sizeof(int)); |