67
67
#include "access/xloginsert.h"
68
68
#include "catalog/index.h"
69
69
#include "commands/progress.h"
70
+ #include "executor/instrument.h"
70
71
#include "miscadmin.h"
71
72
#include "pgstat.h"
72
73
#include "storage/smgr.h"
81
82
#define PARALLEL_KEY_TUPLESORT UINT64CONST(0xA000000000000002)
82
83
#define PARALLEL_KEY_TUPLESORT_SPOOL2 UINT64CONST(0xA000000000000003)
83
84
#define PARALLEL_KEY_QUERY_TEXT UINT64CONST(0xA000000000000004)
85
+ #define PARALLEL_KEY_BUFFER_USAGE UINT64CONST(0xA000000000000005)
84
86
85
87
/*
86
88
* DISABLE_LEADER_PARTICIPATION disables the leader's participation in
@@ -203,6 +205,7 @@ typedef struct BTLeader
203
205
Sharedsort * sharedsort ;
204
206
Sharedsort * sharedsort2 ;
205
207
Snapshot snapshot ;
208
+ BufferUsage * bufferusage ;
206
209
} BTLeader ;
207
210
208
211
/*
@@ -1336,6 +1339,7 @@ _bt_begin_parallel(BTBuildState *buildstate, bool isconcurrent, int request)
1336
1339
Sharedsort * sharedsort2 ;
1337
1340
BTSpool * btspool = buildstate -> spool ;
1338
1341
BTLeader * btleader = (BTLeader * ) palloc0 (sizeof (BTLeader ));
1342
+ BufferUsage * bufferusage ;
1339
1343
bool leaderparticipates = true;
1340
1344
char * sharedquery ;
1341
1345
int querylen ;
@@ -1388,6 +1392,17 @@ _bt_begin_parallel(BTBuildState *buildstate, bool isconcurrent, int request)
1388
1392
shm_toc_estimate_keys (& pcxt -> estimator , 3 );
1389
1393
}
1390
1394
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
+
1391
1406
/* Finally, estimate PARALLEL_KEY_QUERY_TEXT space */
1392
1407
querylen = strlen (debug_query_string );
1393
1408
shm_toc_estimate_chunk (& pcxt -> estimator , querylen + 1 );
@@ -1459,6 +1474,11 @@ _bt_begin_parallel(BTBuildState *buildstate, bool isconcurrent, int request)
1459
1474
memcpy (sharedquery , debug_query_string , querylen + 1 );
1460
1475
shm_toc_insert (pcxt -> toc , PARALLEL_KEY_QUERY_TEXT , sharedquery );
1461
1476
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
+
1462
1482
/* Launch workers, saving status for leader/caller */
1463
1483
LaunchParallelWorkers (pcxt );
1464
1484
btleader -> pcxt = pcxt ;
@@ -1469,6 +1489,7 @@ _bt_begin_parallel(BTBuildState *buildstate, bool isconcurrent, int request)
1469
1489
btleader -> sharedsort = sharedsort ;
1470
1490
btleader -> sharedsort2 = sharedsort2 ;
1471
1491
btleader -> snapshot = snapshot ;
1492
+ btleader -> bufferusage = bufferusage ;
1472
1493
1473
1494
/* If no workers were successfully launched, back out (do serial build) */
1474
1495
if (pcxt -> nworkers_launched == 0 )
@@ -1497,8 +1518,18 @@ _bt_begin_parallel(BTBuildState *buildstate, bool isconcurrent, int request)
1497
1518
static void
1498
1519
_bt_end_parallel (BTLeader * btleader )
1499
1520
{
1521
+ int i ;
1522
+
1500
1523
/* Shutdown worker processes */
1501
1524
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
+
1502
1533
/* Free last reference to MVCC snapshot, if one was used */
1503
1534
if (IsMVCCSnapshot (btleader -> snapshot ))
1504
1535
UnregisterSnapshot (btleader -> snapshot );
@@ -1629,6 +1660,7 @@ _bt_parallel_build_main(dsm_segment *seg, shm_toc *toc)
1629
1660
Relation indexRel ;
1630
1661
LOCKMODE heapLockmode ;
1631
1662
LOCKMODE indexLockmode ;
1663
+ BufferUsage * bufferusage ;
1632
1664
int sortmem ;
1633
1665
1634
1666
#ifdef BTREE_BUILD_STATS
@@ -1690,11 +1722,18 @@ _bt_parallel_build_main(dsm_segment *seg, shm_toc *toc)
1690
1722
tuplesort_attach_shared (sharedsort2 , seg );
1691
1723
}
1692
1724
1725
+ /* Prepare to track buffer usage during parallel execution */
1726
+ InstrStartParallelQuery ();
1727
+
1693
1728
/* Perform sorting of spool, and possibly a spool2 */
1694
1729
sortmem = maintenance_work_mem / btshared -> scantuplesortstates ;
1695
1730
_bt_parallel_scan_and_sort (btspool , btspool2 , btshared , sharedsort ,
1696
1731
sharedsort2 , sortmem , false);
1697
1732
1733
+ /* Report buffer usage during parallel execution */
1734
+ bufferusage = shm_toc_lookup (toc , PARALLEL_KEY_BUFFER_USAGE , false);
1735
+ InstrEndParallelQuery (& bufferusage [ParallelWorkerNumber ]);
1736
+
1698
1737
#ifdef BTREE_BUILD_STATS
1699
1738
if (log_btree_build_stats )
1700
1739
{
0 commit comments