@@ -46,6 +46,7 @@ InstrInitOptions(Instrumentation *instr, int instrument_options)
4646{
4747 instr -> need_bufusage = (instrument_options & INSTRUMENT_BUFFERS ) != 0 ;
4848 instr -> need_walusage = (instrument_options & INSTRUMENT_WAL ) != 0 ;
49+ instr -> need_iousage = (instrument_options & INSTRUMENT_IO ) != 0 ;
4950 instr -> need_timer = (instrument_options & INSTRUMENT_TIMER ) != 0 ;
5051}
5152
@@ -76,7 +77,7 @@ InstrStart(Instrumentation *instr)
7677 if (instr -> need_timer )
7778 InstrStartTimer (instr );
7879
79- if (instr -> need_bufusage || instr -> need_walusage )
80+ if (instr -> need_bufusage || instr -> need_walusage || instr -> need_iousage )
8081 InstrPushStack (instr );
8182}
8283
@@ -86,7 +87,7 @@ InstrStop(Instrumentation *instr)
8687 if (instr -> need_timer )
8788 InstrStopTimer (instr );
8889
89- if (instr -> need_bufusage || instr -> need_walusage )
90+ if (instr -> need_bufusage || instr -> need_walusage || instr -> need_iousage )
9091 InstrPopStack (instr );
9192}
9293
@@ -197,7 +198,9 @@ InstrQueryAlloc(int instrument_options)
197198 * survives transaction abort — ResourceOwner release needs to access
198199 * it.
199200 */
200- if ((instrument_options & INSTRUMENT_BUFFERS ) != 0 || (instrument_options & INSTRUMENT_WAL ) != 0 )
201+ if ((instrument_options & INSTRUMENT_BUFFERS ) != 0 ||
202+ (instrument_options & INSTRUMENT_WAL ) != 0 ||
203+ (instrument_options & INSTRUMENT_IO ) != 0 )
201204 instr = MemoryContextAllocZero (TopMemoryContext , sizeof (QueryInstrumentation ));
202205 else
203206 instr = palloc0 (sizeof (QueryInstrumentation ));
@@ -213,7 +216,7 @@ InstrQueryStart(QueryInstrumentation *qinstr)
213216{
214217 InstrStart (& qinstr -> instr );
215218
216- if (qinstr -> instr .need_bufusage || qinstr -> instr .need_walusage )
219+ if (qinstr -> instr .need_bufusage || qinstr -> instr .need_walusage || qinstr -> instr . need_iousage )
217220 {
218221 Assert (CurrentResourceOwner != NULL );
219222 qinstr -> owner = CurrentResourceOwner ;
@@ -228,7 +231,7 @@ InstrQueryStop(QueryInstrumentation *qinstr)
228231{
229232 InstrStop (& qinstr -> instr );
230233
231- if (qinstr -> instr .need_bufusage || qinstr -> instr .need_walusage )
234+ if (qinstr -> instr .need_bufusage || qinstr -> instr .need_walusage || qinstr -> instr . need_iousage )
232235 {
233236 Assert (qinstr -> owner != NULL );
234237 ResourceOwnerForgetInstrumentation (qinstr -> owner , qinstr );
@@ -243,7 +246,7 @@ InstrQueryStopFinalize(QueryInstrumentation *qinstr)
243246
244247 InstrStopFinalize (& qinstr -> instr );
245248
246- if (!qinstr -> instr .need_bufusage && !qinstr -> instr .need_walusage )
249+ if (!qinstr -> instr .need_bufusage && !qinstr -> instr .need_walusage && ! qinstr -> instr . need_iousage )
247250 return qinstr ;
248251
249252 Assert (qinstr -> owner != NULL );
@@ -270,15 +273,15 @@ InstrQueryStopFinalize(QueryInstrumentation *qinstr)
270273void
271274InstrQueryRememberNode (QueryInstrumentation * parent , NodeInstrumentation * child )
272275{
273- if (child -> instr .need_bufusage || child -> instr .need_walusage )
276+ if (child -> instr .need_bufusage || child -> instr .need_walusage || child -> instr . need_iousage )
274277 dlist_push_head (& parent -> unfinalized_children , & child -> unfinalized_node );
275278}
276279
277280/* start instrumentation during parallel executor startup */
278281QueryInstrumentation *
279282InstrStartParallelQuery (void )
280283{
281- QueryInstrumentation * qinstr = InstrQueryAlloc (INSTRUMENT_BUFFERS | INSTRUMENT_WAL );
284+ QueryInstrumentation * qinstr = InstrQueryAlloc (INSTRUMENT_BUFFERS | INSTRUMENT_WAL | INSTRUMENT_IO );
282285
283286 InstrQueryStart (qinstr );
284287 return qinstr ;
@@ -291,6 +294,7 @@ InstrEndParallelQuery(QueryInstrumentation *qinstr, Instrumentation *dst)
291294 qinstr = InstrQueryStopFinalize (qinstr );
292295 memcpy (& dst -> bufusage , & qinstr -> instr .bufusage , sizeof (BufferUsage ));
293296 memcpy (& dst -> walusage , & qinstr -> instr .walusage , sizeof (WalUsage ));
297+ memcpy (& dst -> iousage , & qinstr -> instr .iousage , sizeof (IOUsage ));
294298}
295299
296300/*
@@ -310,6 +314,7 @@ InstrAccumParallelQuery(Instrumentation *instr)
310314{
311315 BufferUsageAdd (& instr_stack .current -> bufusage , & instr -> bufusage );
312316 WalUsageAdd (& instr_stack .current -> walusage , & instr -> walusage );
317+ IOUsageAdd (& instr_stack .current -> iousage , & instr -> iousage );
313318
314319 WalUsageAdd (& pgWalUsage , & instr -> walusage );
315320}
@@ -329,7 +334,9 @@ InstrAllocNode(int instrument_options, bool async_mode)
329334 * utility commands that restart transactions, which would require a
330335 * context that survives longer (EXPLAIN ANALYZE is fine).
331336 */
332- if ((instrument_options & INSTRUMENT_BUFFERS ) != 0 || (instrument_options & INSTRUMENT_WAL ) != 0 )
337+ if ((instrument_options & INSTRUMENT_BUFFERS ) != 0 ||
338+ (instrument_options & INSTRUMENT_WAL ) != 0 ||
339+ (instrument_options & INSTRUMENT_IO ) != 0 )
333340 instr = MemoryContextAlloc (TopTransactionContext , sizeof (NodeInstrumentation ));
334341 else
335342 instr = palloc (sizeof (NodeInstrumentation ));
@@ -392,7 +399,7 @@ InstrStopNode(NodeInstrumentation *instr, double nTuples)
392399 InstrStopNodeTimer (instr );
393400
394401 /* Only pop the stack, accumulation runs in InstrFinalizeNode */
395- if (instr -> instr .need_bufusage || instr -> instr .need_walusage )
402+ if (instr -> instr .need_bufusage || instr -> instr .need_walusage || instr -> instr . need_iousage )
396403 InstrPopStack (& instr -> instr );
397404
398405 instr -> running = true;
@@ -407,7 +414,7 @@ InstrFinalizeNode(NodeInstrumentation *instr, Instrumentation *parent)
407414 NodeInstrumentation * dst ;
408415
409416 /* If we didn't use stack based instrumentation, nothing to be done */
410- if (!instr -> instr .need_bufusage && !instr -> instr .need_walusage )
417+ if (!instr -> instr .need_bufusage && !instr -> instr .need_walusage && ! instr -> instr . need_iousage )
411418 return instr ;
412419
413420 /* Copy into per-query memory context */
@@ -418,7 +425,7 @@ InstrFinalizeNode(NodeInstrumentation *instr, Instrumentation *parent)
418425 InstrAccum (parent , & dst -> instr );
419426
420427 /* Unregister from query's unfinalized list before freeing */
421- if (instr -> instr .need_bufusage || instr -> instr .need_walusage )
428+ if (instr -> instr .need_bufusage || instr -> instr .need_walusage || instr -> instr . need_iousage )
422429 dlist_delete (& instr -> unfinalized_node );
423430
424431 pfree (instr );
@@ -489,6 +496,9 @@ InstrAggNode(NodeInstrumentation *dst, NodeInstrumentation *add)
489496
490497 if (dst -> instr .need_walusage )
491498 WalUsageAdd (& dst -> instr .walusage , & add -> instr .walusage );
499+
500+ if (dst -> instr .need_iousage )
501+ IOUsageAdd (& dst -> instr .iousage , & add -> instr .iousage );
492502}
493503
494504/*
@@ -598,7 +608,8 @@ InstrNodeSetupExecProcNode(NodeInstrumentation *instr)
598608{
599609 bool need_timer = instr -> instr .need_timer ;
600610 bool need_buf = (instr -> instr .need_bufusage ||
601- instr -> instr .need_walusage );
611+ instr -> instr .need_walusage ||
612+ instr -> instr .need_iousage );
602613
603614 if (need_timer && need_buf )
604615 return ExecProcNodeInstrFull ;
@@ -649,6 +660,7 @@ InstrAccum(Instrumentation *dst, Instrumentation *add)
649660
650661 BufferUsageAdd (& dst -> bufusage , & add -> bufusage );
651662 WalUsageAdd (& dst -> walusage , & add -> walusage );
663+ IOUsageAdd (& dst -> iousage , & add -> iousage );
652664}
653665
654666/* dst += add */
@@ -684,6 +696,22 @@ WalUsageAdd(WalUsage *dst, const WalUsage *add)
684696 dst -> wal_buffers_full += add -> wal_buffers_full ;
685697}
686698
699+ /* dst += add (using max semantics for distance_max and distance_capacity) */
700+ void
701+ IOUsageAdd (IOUsage * dst , const IOUsage * add )
702+ {
703+ dst -> count += add -> count ;
704+ dst -> distance_sum += add -> distance_sum ;
705+ if (add -> distance_max > dst -> distance_max )
706+ dst -> distance_max = add -> distance_max ;
707+ if (add -> distance_capacity > dst -> distance_capacity )
708+ dst -> distance_capacity = add -> distance_capacity ;
709+ dst -> stall_count += add -> stall_count ;
710+ dst -> io_count += add -> io_count ;
711+ dst -> io_blocks += add -> io_blocks ;
712+ dst -> ios_in_progress += add -> ios_in_progress ;
713+ }
714+
687715void
688716WalUsageAccumDiff (WalUsage * dst , const WalUsage * add , const WalUsage * sub )
689717{
0 commit comments