mirror of
https://github.com/postgres/postgres.git
synced 2025-11-07 19:06:32 +03:00
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
This commit is contained in:
@@ -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;
|
||||
double new_prefetch_pages;
|
||||
|
||||
/*----------
|
||||
* 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;
|
||||
|
||||
/* 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));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user