aboutsummaryrefslogtreecommitdiff
path: root/src/backend/storage/buffer/bufmgr.c
diff options
context:
space:
mode:
authorThomas Munro <tmunro@postgresql.org>2020-03-16 11:43:18 +1300
committerThomas Munro <tmunro@postgresql.org>2020-03-16 17:14:26 +1300
commitb09ff53667ffc986371ec8ffa372916ad460220d (patch)
tree511cc574dc192acb6cd7dba4be35968ba188b961 /src/backend/storage/buffer/bufmgr.c
parentf207bb0b8f13999c91b405a2e6c8526225470816 (diff)
downloadpostgresql-b09ff53667ffc986371ec8ffa372916ad460220d.tar.gz
postgresql-b09ff53667ffc986371ec8ffa372916ad460220d.zip
Simplify the effective_io_concurrency setting.
The effective_io_concurrency GUC and equivalent tablespace option were previously passed through a formula based on a theory about RAID spindles and probabilities, to arrive at the number of pages to prefetch in bitmap heap scans. Tomas Vondra, Andres Freund and others argued that it was anachronistic and hard to justify, and commit 558a9165e08 already started down the path of bypassing it in new code. We agreed to drop that logic and use the value directly. For the default setting of 1, there is no change in effect. Higher settings can be converted from the old meaning to the new with: select round(sum(OLD / n::float)) from generate_series(1, OLD) s(n); We might want to consider renaming the GUC before the next release given the change in meaning, but it's not clear that many users had set it very carefully anyway. That decision is deferred for now. Discussion: https://postgr.es/m/CA%2BhUKGJUw08dPs_3EUcdO6M90GnjofPYrWp4YSLaBkgYwS-AqA%40mail.gmail.com
Diffstat (limited to 'src/backend/storage/buffer/bufmgr.c')
-rw-r--r--src/backend/storage/buffer/bufmgr.c74
1 files changed, 7 insertions, 67 deletions
diff --git a/src/backend/storage/buffer/bufmgr.c b/src/backend/storage/buffer/bufmgr.c
index 58800542454..7a7748b6955 100644
--- a/src/backend/storage/buffer/bufmgr.c
+++ b/src/backend/storage/buffer/bufmgr.c
@@ -110,6 +110,13 @@ bool zero_damaged_pages = false;
int bgwriter_lru_maxpages = 100;
double bgwriter_lru_multiplier = 2.0;
bool track_io_timing = false;
+
+/*
+ * How many buffers PrefetchBuffer callers should try to stay ahead of their
+ * ReadBuffer calls by. Zero means "never prefetch". This value is only used
+ * for buffers not belonging to tablespaces that have their
+ * effective_io_concurrency parameter set.
+ */
int effective_io_concurrency = 0;
/*
@@ -120,15 +127,6 @@ int checkpoint_flush_after = 0;
int bgwriter_flush_after = 0;
int backend_flush_after = 0;
-/*
- * How many buffers PrefetchBuffer callers should try to stay ahead of their
- * ReadBuffer calls by. This is maintained by the assign hook for
- * effective_io_concurrency. Zero means "never prefetch". This value is
- * only used for buffers not belonging to tablespaces that have their
- * effective_io_concurrency parameter set.
- */
-int target_prefetch_pages = 0;
-
/* local state for StartBufferIO and related functions */
static BufferDesc *InProgressBuf = NULL;
static bool IsForInput;
@@ -462,64 +460,6 @@ static int ts_ckpt_progress_comparator(Datum a, Datum b, void *arg);
/*
- * ComputeIoConcurrency -- get the number of pages to prefetch for a given
- * number of spindles.
- */
-bool
-ComputeIoConcurrency(int io_concurrency, double *target)
-{
- double new_prefetch_pages = 0.0;
- int i;
-
- /*
- * Make sure the io_concurrency value is within valid range; it may have
- * been forced with a manual pg_tablespace update.
- */
- io_concurrency = Min(Max(io_concurrency, 0), MAX_IO_CONCURRENCY);
-
- /*----------
- * 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 io_concurrency = 0 (disabled), we must set target = 0.
- *----------
- */
-
- for (i = 1; i <= io_concurrency; i++)
- new_prefetch_pages += (double) io_concurrency / (double) i;
-
- *target = new_prefetch_pages;
-
- /* This range check shouldn't fail, but let's be paranoid */
- return (new_prefetch_pages >= 0.0 && new_prefetch_pages < (double) INT_MAX);
-}
-
-/*
* PrefetchBuffer -- initiate asynchronous read of a block of a relation
*
* This is named by analogy to ReadBuffer but doesn't actually allocate a