mirror of
https://github.com/postgres/postgres.git
synced 2025-07-07 00:36:50 +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:
@ -44,6 +44,7 @@
|
||||
#include "storage/predicate.h"
|
||||
#include "utils/memutils.h"
|
||||
#include "utils/rel.h"
|
||||
#include "utils/spccache.h"
|
||||
#include "utils/snapmgr.h"
|
||||
#include "utils/tqual.h"
|
||||
|
||||
@ -95,9 +96,8 @@ BitmapHeapNext(BitmapHeapScanState *node)
|
||||
* prefetching. node->prefetch_pages tracks exactly how many pages ahead
|
||||
* the prefetch iterator is. Also, node->prefetch_target tracks the
|
||||
* desired prefetch distance, which starts small and increases up to the
|
||||
* GUC-controlled maximum, target_prefetch_pages. This is to avoid doing
|
||||
* a lot of prefetching in a scan that stops after a few tuples because of
|
||||
* a LIMIT.
|
||||
* node->prefetch_maximum. This is to avoid doing a lot of prefetching in
|
||||
* a scan that stops after a few tuples because of a LIMIT.
|
||||
*/
|
||||
if (tbm == NULL)
|
||||
{
|
||||
@ -111,7 +111,7 @@ BitmapHeapNext(BitmapHeapScanState *node)
|
||||
node->tbmres = tbmres = NULL;
|
||||
|
||||
#ifdef USE_PREFETCH
|
||||
if (target_prefetch_pages > 0)
|
||||
if (node->prefetch_maximum > 0)
|
||||
{
|
||||
node->prefetch_iterator = prefetch_iterator = tbm_begin_iterate(tbm);
|
||||
node->prefetch_pages = 0;
|
||||
@ -188,10 +188,10 @@ BitmapHeapNext(BitmapHeapScanState *node)
|
||||
* page/tuple, then to one after the second tuple is fetched, then
|
||||
* it doubles as later pages are fetched.
|
||||
*/
|
||||
if (node->prefetch_target >= target_prefetch_pages)
|
||||
if (node->prefetch_target >= node->prefetch_maximum)
|
||||
/* don't increase any further */ ;
|
||||
else if (node->prefetch_target >= target_prefetch_pages / 2)
|
||||
node->prefetch_target = target_prefetch_pages;
|
||||
else if (node->prefetch_target >= node->prefetch_maximum / 2)
|
||||
node->prefetch_target = node->prefetch_maximum;
|
||||
else if (node->prefetch_target > 0)
|
||||
node->prefetch_target *= 2;
|
||||
else
|
||||
@ -211,7 +211,7 @@ BitmapHeapNext(BitmapHeapScanState *node)
|
||||
* Try to prefetch at least a few pages even before we get to the
|
||||
* second page if we don't stop reading after the first tuple.
|
||||
*/
|
||||
if (node->prefetch_target < target_prefetch_pages)
|
||||
if (node->prefetch_target < node->prefetch_maximum)
|
||||
node->prefetch_target++;
|
||||
#endif /* USE_PREFETCH */
|
||||
}
|
||||
@ -539,6 +539,7 @@ ExecInitBitmapHeapScan(BitmapHeapScan *node, EState *estate, int eflags)
|
||||
{
|
||||
BitmapHeapScanState *scanstate;
|
||||
Relation currentRelation;
|
||||
int io_concurrency;
|
||||
|
||||
/* check for unsupported flags */
|
||||
Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK)));
|
||||
@ -564,6 +565,8 @@ ExecInitBitmapHeapScan(BitmapHeapScan *node, EState *estate, int eflags)
|
||||
scanstate->prefetch_iterator = NULL;
|
||||
scanstate->prefetch_pages = 0;
|
||||
scanstate->prefetch_target = 0;
|
||||
/* may be updated below */
|
||||
scanstate->prefetch_maximum = target_prefetch_pages;
|
||||
|
||||
/*
|
||||
* Miscellaneous initialization
|
||||
@ -598,6 +601,22 @@ ExecInitBitmapHeapScan(BitmapHeapScan *node, EState *estate, int eflags)
|
||||
*/
|
||||
currentRelation = ExecOpenScanRelation(estate, node->scan.scanrelid, eflags);
|
||||
|
||||
/*
|
||||
* Determine the maximum for prefetch_target. If the tablespace has a
|
||||
* specific IO concurrency set, use that to compute the corresponding
|
||||
* maximum value; otherwise, we already initialized to the value computed
|
||||
* by the GUC machinery.
|
||||
*/
|
||||
io_concurrency =
|
||||
get_tablespace_io_concurrency(currentRelation->rd_rel->reltablespace);
|
||||
if (io_concurrency != effective_io_concurrency)
|
||||
{
|
||||
double maximum;
|
||||
|
||||
if (ComputeIoConcurrency(io_concurrency, &maximum))
|
||||
scanstate->prefetch_maximum = rint(maximum);
|
||||
}
|
||||
|
||||
scanstate->ss.ss_currentRelation = currentRelation;
|
||||
|
||||
/*
|
||||
|
Reference in New Issue
Block a user