Skip to content

Commit 13823ad

Browse files
author
Amit Kapila
committed
Allow parallel create index to accumulate buffer usage stats.
Currently, we don't account for buffer usage incurred by parallel workers for parallel create index.  This commit allows each worker to record the buffer usage stats and leader backend to accumulate that stats at the end of the operation.  This will allow pg_stat_statements to display correct buffer usage stats for (parallel) create index command. Reported-by: Julien Rouhaud Author: Sawada Masahiko Reviewed-by: Dilip Kumar, Julien Rouhaud and Amit Kapila Backpatch-through: 11, where this was introduced Discussion: https://postgr.es/m/20200328151721.GB12854@nol
1 parent 41b4b2a commit 13823ad

File tree

1 file changed

+39
-0
lines changed

1 file changed

+39
-0
lines changed

src/backend/access/nbtree/nbtsort.c

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@
6767
#include "access/xloginsert.h"
6868
#include "catalog/index.h"
6969
#include "commands/progress.h"
70+
#include "executor/instrument.h"
7071
#include "miscadmin.h"
7172
#include "pgstat.h"
7273
#include "storage/smgr.h"
@@ -81,6 +82,7 @@
8182
#define PARALLEL_KEY_TUPLESORT UINT64CONST(0xA000000000000002)
8283
#define PARALLEL_KEY_TUPLESORT_SPOOL2 UINT64CONST(0xA000000000000003)
8384
#define PARALLEL_KEY_QUERY_TEXT UINT64CONST(0xA000000000000004)
85+
#define PARALLEL_KEY_BUFFER_USAGE UINT64CONST(0xA000000000000005)
8486

8587
/*
8688
* DISABLE_LEADER_PARTICIPATION disables the leader's participation in
@@ -203,6 +205,7 @@ typedef struct BTLeader
203205
Sharedsort *sharedsort;
204206
Sharedsort *sharedsort2;
205207
Snapshot snapshot;
208+
BufferUsage *bufferusage;
206209
} BTLeader;
207210

208211
/*
@@ -1336,6 +1339,7 @@ _bt_begin_parallel(BTBuildState *buildstate, bool isconcurrent, int request)
13361339
Sharedsort *sharedsort2;
13371340
BTSpool *btspool = buildstate->spool;
13381341
BTLeader *btleader = (BTLeader *) palloc0(sizeof(BTLeader));
1342+
BufferUsage *bufferusage;
13391343
bool leaderparticipates = true;
13401344
char *sharedquery;
13411345
int querylen;
@@ -1388,6 +1392,17 @@ _bt_begin_parallel(BTBuildState *buildstate, bool isconcurrent, int request)
13881392
shm_toc_estimate_keys(&pcxt->estimator, 3);
13891393
}
13901394

1395+
/*
1396+
* Estimate space for BufferUsage -- PARALLEL_KEY_BUFFER_USAGE.
1397+
*
1398+
* If there are no extensions loaded that care, we could skip this. We
1399+
* have no way of knowing whether anyone's looking at pgBufferUsage, so do
1400+
* it unconditionally.
1401+
*/
1402+
shm_toc_estimate_chunk(&pcxt->estimator,
1403+
mul_size(sizeof(BufferUsage), pcxt->nworkers));
1404+
shm_toc_estimate_keys(&pcxt->estimator, 1);
1405+
13911406
/* Finally, estimate PARALLEL_KEY_QUERY_TEXT space */
13921407
querylen = strlen(debug_query_string);
13931408
shm_toc_estimate_chunk(&pcxt->estimator, querylen + 1);
@@ -1459,6 +1474,11 @@ _bt_begin_parallel(BTBuildState *buildstate, bool isconcurrent, int request)
14591474
memcpy(sharedquery, debug_query_string, querylen + 1);
14601475
shm_toc_insert(pcxt->toc, PARALLEL_KEY_QUERY_TEXT, sharedquery);
14611476

1477+
/* Allocate space for each worker's BufferUsage; no need to initialize */
1478+
bufferusage = shm_toc_allocate(pcxt->toc,
1479+
mul_size(sizeof(BufferUsage), pcxt->nworkers));
1480+
shm_toc_insert(pcxt->toc, PARALLEL_KEY_BUFFER_USAGE, bufferusage);
1481+
14621482
/* Launch workers, saving status for leader/caller */
14631483
LaunchParallelWorkers(pcxt);
14641484
btleader->pcxt = pcxt;
@@ -1469,6 +1489,7 @@ _bt_begin_parallel(BTBuildState *buildstate, bool isconcurrent, int request)
14691489
btleader->sharedsort = sharedsort;
14701490
btleader->sharedsort2 = sharedsort2;
14711491
btleader->snapshot = snapshot;
1492+
btleader->bufferusage = bufferusage;
14721493

14731494
/* If no workers were successfully launched, back out (do serial build) */
14741495
if (pcxt->nworkers_launched == 0)
@@ -1497,8 +1518,18 @@ _bt_begin_parallel(BTBuildState *buildstate, bool isconcurrent, int request)
14971518
static void
14981519
_bt_end_parallel(BTLeader *btleader)
14991520
{
1521+
int i;
1522+
15001523
/* Shutdown worker processes */
15011524
WaitForParallelWorkersToFinish(btleader->pcxt);
1525+
1526+
/*
1527+
* Next, accumulate buffer usage. (This must wait for the workers to
1528+
* finish, or we might get incomplete data.)
1529+
*/
1530+
for (i = 0; i < btleader->pcxt->nworkers_launched; i++)
1531+
InstrAccumParallelQuery(&btleader->bufferusage[i]);
1532+
15021533
/* Free last reference to MVCC snapshot, if one was used */
15031534
if (IsMVCCSnapshot(btleader->snapshot))
15041535
UnregisterSnapshot(btleader->snapshot);
@@ -1629,6 +1660,7 @@ _bt_parallel_build_main(dsm_segment *seg, shm_toc *toc)
16291660
Relation indexRel;
16301661
LOCKMODE heapLockmode;
16311662
LOCKMODE indexLockmode;
1663+
BufferUsage *bufferusage;
16321664
int sortmem;
16331665

16341666
#ifdef BTREE_BUILD_STATS
@@ -1690,11 +1722,18 @@ _bt_parallel_build_main(dsm_segment *seg, shm_toc *toc)
16901722
tuplesort_attach_shared(sharedsort2, seg);
16911723
}
16921724

1725+
/* Prepare to track buffer usage during parallel execution */
1726+
InstrStartParallelQuery();
1727+
16931728
/* Perform sorting of spool, and possibly a spool2 */
16941729
sortmem = maintenance_work_mem / btshared->scantuplesortstates;
16951730
_bt_parallel_scan_and_sort(btspool, btspool2, btshared, sharedsort,
16961731
sharedsort2, sortmem, false);
16971732

1733+
/* Report buffer usage during parallel execution */
1734+
bufferusage = shm_toc_lookup(toc, PARALLEL_KEY_BUFFER_USAGE, false);
1735+
InstrEndParallelQuery(&bufferusage[ParallelWorkerNumber]);
1736+
16981737
#ifdef BTREE_BUILD_STATS
16991738
if (log_btree_build_stats)
17001739
{

0 commit comments

Comments
 (0)