Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 0de37b5

Browse files
committed
Fix some inconsistencies in EXPLAIN output
0628670 added a SERIALIZE option to EXPLAIN which included showing the amount of kilobytes serialized. The calculation to convert bytes into kilobytes wasn't consistent with how that's done in the rest of EXPLAIN. Traditionally we round up to the nearest kB, but the new code rounded to the nearest kB. To fix this, invent a macro that does the conversion and use that macro everywhere that requires this conversion. Additionally, 5de890e added EXPLAIN (MEMORY) but included the memory sizes in bytes. Convert these values to kilobytes to align with the other memory related outputs. In passing, swap out a "long" type in show_hash_info() and use a uint64 instead. We do support platforms where sizeof(Size) == 8 and sizeof(long) == 4, so using a long there is questionable. Reported-by: jian he Reviewed-by: jian he Discussion: https://www.postgresql.org/message-id/CACJufxE4Sp7xvgOwhqtFx5hS85AxMKobPWDo-xZHZVTpK3EBjA@mail.gmail.com
1 parent f01e3ba commit 0de37b5

File tree

2 files changed

+30
-24
lines changed

2 files changed

+30
-24
lines changed

src/backend/commands/explain.c

+27-21
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,12 @@ typedef struct SerializeMetrics
6262
#define X_CLOSE_IMMEDIATE 2
6363
#define X_NOWHITESPACE 4
6464

65+
/*
66+
* Various places within need to convert bytes to kilobytes. Round these up
67+
* to the next whole kilobyte.
68+
*/
69+
#define BYTES_TO_KILOBYTES(b) (((b) + 1023) / 1024)
70+
6571
static void ExplainOneQuery(Query *query, int cursorOptions,
6672
IntoClause *into, ExplainState *es,
6773
const char *queryString, ParamListInfo params,
@@ -1120,11 +1126,11 @@ ExplainPrintSerialize(ExplainState *es, SerializeMetrics *metrics)
11201126
if (es->timing)
11211127
appendStringInfo(es->str, "Serialization: time=%.3f ms output=" UINT64_FORMAT "kB format=%s\n",
11221128
1000.0 * INSTR_TIME_GET_DOUBLE(metrics->timeSpent),
1123-
(metrics->bytesSent + 512) / 1024,
1129+
BYTES_TO_KILOBYTES(metrics->bytesSent),
11241130
format);
11251131
else
11261132
appendStringInfo(es->str, "Serialization: output=" UINT64_FORMAT "kB format=%s\n",
1127-
(metrics->bytesSent + 512) / 1024,
1133+
BYTES_TO_KILOBYTES(metrics->bytesSent),
11281134
format);
11291135

11301136
if (es->buffers && peek_buffer_usage(es, &metrics->bufferUsage))
@@ -1141,7 +1147,7 @@ ExplainPrintSerialize(ExplainState *es, SerializeMetrics *metrics)
11411147
1000.0 * INSTR_TIME_GET_DOUBLE(metrics->timeSpent),
11421148
3, es);
11431149
ExplainPropertyUInteger("Output Volume", "kB",
1144-
(metrics->bytesSent + 512) / 1024, es);
1150+
BYTES_TO_KILOBYTES(metrics->bytesSent), es);
11451151
ExplainPropertyText("Format", format, es);
11461152
if (es->buffers)
11471153
show_buffer_usage(es, &metrics->bufferUsage);
@@ -3275,7 +3281,7 @@ show_hash_info(HashState *hashstate, ExplainState *es)
32753281

32763282
if (hinstrument.nbatch > 0)
32773283
{
3278-
long spacePeakKb = (hinstrument.space_peak + 1023) / 1024;
3284+
uint64 spacePeakKb = BYTES_TO_KILOBYTES(hinstrument.space_peak);
32793285

32803286
if (es->format != EXPLAIN_FORMAT_TEXT)
32813287
{
@@ -3287,15 +3293,15 @@ show_hash_info(HashState *hashstate, ExplainState *es)
32873293
hinstrument.nbatch, es);
32883294
ExplainPropertyInteger("Original Hash Batches", NULL,
32893295
hinstrument.nbatch_original, es);
3290-
ExplainPropertyInteger("Peak Memory Usage", "kB",
3291-
spacePeakKb, es);
3296+
ExplainPropertyUInteger("Peak Memory Usage", "kB",
3297+
spacePeakKb, es);
32923298
}
32933299
else if (hinstrument.nbatch_original != hinstrument.nbatch ||
32943300
hinstrument.nbuckets_original != hinstrument.nbuckets)
32953301
{
32963302
ExplainIndentText(es);
32973303
appendStringInfo(es->str,
3298-
"Buckets: %d (originally %d) Batches: %d (originally %d) Memory Usage: %ldkB\n",
3304+
"Buckets: %d (originally %d) Batches: %d (originally %d) Memory Usage: " UINT64_FORMAT "kB\n",
32993305
hinstrument.nbuckets,
33003306
hinstrument.nbuckets_original,
33013307
hinstrument.nbatch,
@@ -3306,7 +3312,7 @@ show_hash_info(HashState *hashstate, ExplainState *es)
33063312
{
33073313
ExplainIndentText(es);
33083314
appendStringInfo(es->str,
3309-
"Buckets: %d Batches: %d Memory Usage: %ldkB\n",
3315+
"Buckets: %d Batches: %d Memory Usage: " UINT64_FORMAT "kB\n",
33103316
hinstrument.nbuckets, hinstrument.nbatch,
33113317
spacePeakKb);
33123318
}
@@ -3376,9 +3382,9 @@ show_memoize_info(MemoizeState *mstate, List *ancestors, ExplainState *es)
33763382
* when mem_peak is 0.
33773383
*/
33783384
if (mstate->stats.mem_peak > 0)
3379-
memPeakKb = (mstate->stats.mem_peak + 1023) / 1024;
3385+
memPeakKb = BYTES_TO_KILOBYTES(mstate->stats.mem_peak);
33803386
else
3381-
memPeakKb = (mstate->mem_used + 1023) / 1024;
3387+
memPeakKb = BYTES_TO_KILOBYTES(mstate->mem_used);
33823388

33833389
if (es->format != EXPLAIN_FORMAT_TEXT)
33843390
{
@@ -3427,7 +3433,7 @@ show_memoize_info(MemoizeState *mstate, List *ancestors, ExplainState *es)
34273433
* MemoizeInstrumentation.mem_peak field for us. No need to do the
34283434
* zero checks like we did for the serial case above.
34293435
*/
3430-
memPeakKb = (si->mem_peak + 1023) / 1024;
3436+
memPeakKb = BYTES_TO_KILOBYTES(si->mem_peak);
34313437

34323438
if (es->format == EXPLAIN_FORMAT_TEXT)
34333439
{
@@ -3464,7 +3470,7 @@ static void
34643470
show_hashagg_info(AggState *aggstate, ExplainState *es)
34653471
{
34663472
Agg *agg = (Agg *) aggstate->ss.ps.plan;
3467-
int64 memPeakKb = (aggstate->hash_mem_peak + 1023) / 1024;
3473+
int64 memPeakKb = BYTES_TO_KILOBYTES(aggstate->hash_mem_peak);
34683474

34693475
if (agg->aggstrategy != AGG_HASHED &&
34703476
agg->aggstrategy != AGG_MIXED)
@@ -3545,7 +3551,7 @@ show_hashagg_info(AggState *aggstate, ExplainState *es)
35453551
continue;
35463552
hash_disk_used = sinstrument->hash_disk_used;
35473553
hash_batches_used = sinstrument->hash_batches_used;
3548-
memPeakKb = (sinstrument->hash_mem_peak + 1023) / 1024;
3554+
memPeakKb = BYTES_TO_KILOBYTES(sinstrument->hash_mem_peak);
35493555

35503556
if (es->workers_state)
35513557
ExplainOpenWorker(n, es);
@@ -3942,22 +3948,22 @@ show_wal_usage(ExplainState *es, const WalUsage *usage)
39423948
static void
39433949
show_memory_counters(ExplainState *es, const MemoryContextCounters *mem_counters)
39443950
{
3951+
int64 memUsedkB = BYTES_TO_KILOBYTES(mem_counters->totalspace -
3952+
mem_counters->freespace);
3953+
int64 memAllocatedkB = BYTES_TO_KILOBYTES(mem_counters->totalspace);
3954+
39453955
if (es->format == EXPLAIN_FORMAT_TEXT)
39463956
{
39473957
ExplainIndentText(es);
39483958
appendStringInfo(es->str,
3949-
"Memory: used=%lld bytes allocated=%lld bytes",
3950-
(long long) (mem_counters->totalspace - mem_counters->freespace),
3951-
(long long) mem_counters->totalspace);
3959+
"Memory: used=" INT64_FORMAT "kB allocated=" INT64_FORMAT "kB",
3960+
memUsedkB, memAllocatedkB);
39523961
appendStringInfoChar(es->str, '\n');
39533962
}
39543963
else
39553964
{
3956-
ExplainPropertyInteger("Memory Used", "bytes",
3957-
mem_counters->totalspace - mem_counters->freespace,
3958-
es);
3959-
ExplainPropertyInteger("Memory Allocated", "bytes",
3960-
mem_counters->totalspace, es);
3965+
ExplainPropertyInteger("Memory Used", "kB", memUsedkB, es);
3966+
ExplainPropertyInteger("Memory Allocated", "kB", memAllocatedkB, es);
39613967
}
39623968
}
39633969

src/test/regress/expected/explain.out

+3-3
Original file line numberDiff line numberDiff line change
@@ -345,14 +345,14 @@ select explain_filter('explain (memory) select * from int8_tbl i8');
345345
explain_filter
346346
---------------------------------------------------------
347347
Seq Scan on int8_tbl i8 (cost=N.N..N.N rows=N width=N)
348-
Memory: used=N bytes allocated=N bytes
348+
Memory: used=NkB allocated=NkB
349349
(2 rows)
350350

351351
select explain_filter('explain (memory, analyze) select * from int8_tbl i8');
352352
explain_filter
353353
-----------------------------------------------------------------------------------------------
354354
Seq Scan on int8_tbl i8 (cost=N.N..N.N rows=N width=N) (actual time=N.N..N.N rows=N loops=N)
355-
Memory: used=N bytes allocated=N bytes
355+
Memory: used=NkB allocated=NkB
356356
Planning Time: N.N ms
357357
Execution Time: N.N ms
358358
(4 rows)
@@ -413,7 +413,7 @@ select explain_filter('explain (memory) execute int8_query');
413413
explain_filter
414414
---------------------------------------------------------
415415
Seq Scan on int8_tbl i8 (cost=N.N..N.N rows=N width=N)
416-
Memory: used=N bytes allocated=N bytes
416+
Memory: used=NkB allocated=NkB
417417
(2 rows)
418418

419419
-- Test EXPLAIN (GENERIC_PLAN) with partition pruning

0 commit comments

Comments
 (0)