Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1sQ3Vc-007epG-FJ for pgsql-hackers@arkaria.postgresql.org; Sat, 06 Jul 2024 11:23:17 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.94.2) (envelope-from ) id 1sQ3Vb-002nTo-2n for pgsql-hackers@arkaria.postgresql.org; Sat, 06 Jul 2024 11:23:15 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1sQ3Va-002nTY-Mm for pgsql-hackers@lists.postgresql.org; Sat, 06 Jul 2024 11:23:14 +0000 Received: from meldrar.postgresql.org ([2a02:c0:301:0:ffff::31]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1sQ3VY-000ip6-0A for pgsql-hackers@postgresql.org; Sat, 06 Jul 2024 11:23:14 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=postgresql.org; s=20171124; h=Content-Transfer-Encoding:Content-Type: Mime-Version:From:Subject:To:Message-Id:Date:Sender:Reply-To:Cc:Content-ID: Content-Description:In-Reply-To:References; bh=CRi633lHQ+Nzdb8+rbTOy5b4PE94UwVjnQ4R5i1/rdg=; b=dhFVFD0OaLXR2p03Eps4Uywvyr +4/mz7ngPCQzZjXYk5ccLQ5uG4YvMlMWYV08O4lbtC34Q2TzE6hkyNvAnsJTj3mNY3ybXbn1AZ+Lv sjwdIEls1tYEPoD06ZQD/E6WbgylPlp5IjudSNf9dyG+rYCRVslrQnxG04D3jO+ZnMEQbzvzddqih zXGe9wi2r8deQxrsdkyTKpE776Wx8sof4W3HEQlCPioRZzpZ+kCXmWQWs61kbl+Li90DOnnMPb5Pv aAS3DSacsvbu8hDVHdoWkPLtGuz4t6CC5p7oEG5v5kyI1CaaDg5e9Agkf7HZca7EFx2wjuDljWOKC 5b5Px0fg==; Received: from [2409:11:4120:300:48bb:5fbf:4c17:ba6d] (helo=localhost) by meldrar.postgresql.org with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 (Exim 4.94.2) (envelope-from ) id 1sQ3VU-001QC4-6N for pgsql-hackers@postgresql.org; Sat, 06 Jul 2024 11:23:10 +0000 Date: Sat, 06 Jul 2024 20:22:54 +0900 (JST) Message-Id: <20240706.202254.89740021795421286.ishii@postgresql.org> To: pgsql-hackers@postgresql.org Subject: Add memory/disk usage for WindowAgg nodes in EXPLAIN From: Tatsuo Ishii X-Mailer: Mew version 6.8 on Emacs 26.3 Mime-Version: 1.0 Content-Type: Multipart/Mixed; boundary="--Next_Part(Sat_Jul__6_20_22_54_2024_404)--" Content-Transfer-Encoding: 7bit X-Host-Lookup-Failed: Reverse DNS lookup failed for 2409:11:4120:300:48bb:5fbf:4c17:ba6d (failed) List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk ----Next_Part(Sat_Jul__6_20_22_54_2024_404)-- Content-Type: Text/Plain; charset=us-ascii Content-Transfer-Encoding: 7bit 1eff8279d4 added memory/disk usage for materialize nodes in EXPLAIN ANALYZE. In the commit message: > There are a few other executor node types that use tuplestores, so we > could also consider adding these details to the EXPLAIN ANALYZE for > those nodes too. So I wanted to Add memory/disk usage for WindowAgg. Patch attached. Since WindowAgg node could create multiple tuplestore for each Window partition, we need to track each tuplestore storage usage so that the maximum storage usage is determined. For this purpose I added new fields to the WindowAggState. -- Tatsuo Ishii SRA OSS LLC English: http://www.sraoss.co.jp/index_en/ Japanese:http://www.sraoss.co.jp ----Next_Part(Sat_Jul__6_20_22_54_2024_404)-- Content-Type: Text/X-Patch; charset=us-ascii Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="v1-0001-Add-memory-disk-usage-for-WindowAgg-nodes-in-EXPL.patch" From 00c7546659e305be45dbeb13a14bcde5066be76f Mon Sep 17 00:00:00 2001 From: Tatsuo Ishii Date: Sat, 6 Jul 2024 19:48:30 +0900 Subject: [PATCH v1] Add memory/disk usage for WindowAgg nodes in EXPLAIN. --- src/backend/commands/explain.c | 37 ++++++++++++++++++++++++++++ src/backend/executor/nodeWindowAgg.c | 19 ++++++++++++++ src/include/nodes/execnodes.h | 2 ++ 3 files changed, 58 insertions(+) diff --git a/src/backend/commands/explain.c b/src/backend/commands/explain.c index 1e80fd8b68..177687ea80 100644 --- a/src/backend/commands/explain.c +++ b/src/backend/commands/explain.c @@ -126,6 +126,7 @@ static void show_incremental_sort_info(IncrementalSortState *incrsortstate, ExplainState *es); static void show_hash_info(HashState *hashstate, ExplainState *es); static void show_material_info(MaterialState *mstate, ExplainState *es); +static void show_windowagg_info(WindowAggState *winstate, ExplainState *es); static void show_memoize_info(MemoizeState *mstate, List *ancestors, ExplainState *es); static void show_hashagg_info(AggState *aggstate, ExplainState *es); @@ -2215,6 +2216,7 @@ ExplainNode(PlanState *planstate, List *ancestors, planstate, es); show_upper_qual(((WindowAgg *) plan)->runConditionOrig, "Run Condition", planstate, ancestors, es); + show_windowagg_info(castNode(WindowAggState, planstate), es); break; case T_Group: show_group_keys(castNode(GroupState, planstate), ancestors, es); @@ -3362,6 +3364,41 @@ show_material_info(MaterialState *mstate, ExplainState *es) } } +/* + * Show information on WindowAgg node, storage method and maximum memory/disk + * space used. + */ +static void +show_windowagg_info(WindowAggState *winstate, ExplainState *es) +{ + const char *storageType; + int64 spaceUsedKB; + + /* + * Nothing to show if ANALYZE option wasn't used or if execution didn't + * get as far as creating the tuplestore. + */ + if (!es->analyze || winstate->storageType == NULL) + return; + + storageType = winstate->storageType; + spaceUsedKB = BYTES_TO_KILOBYTES(winstate->storageSize); + + if (es->format != EXPLAIN_FORMAT_TEXT) + { + ExplainPropertyText("Storage", storageType, es); + ExplainPropertyInteger("Maximum Storage", "kB", spaceUsedKB, es); + } + else + { + ExplainIndentText(es); + appendStringInfo(es->str, + "Storage: %s Maximum Storage: " INT64_FORMAT "kB\n", + storageType, + spaceUsedKB); + } +} + /* * Show information on memoize hits/misses/evictions and memory usage. */ diff --git a/src/backend/executor/nodeWindowAgg.c b/src/backend/executor/nodeWindowAgg.c index 3221fa1522..bcfe144511 100644 --- a/src/backend/executor/nodeWindowAgg.c +++ b/src/backend/executor/nodeWindowAgg.c @@ -1360,7 +1360,23 @@ release_partition(WindowAggState *winstate) } if (winstate->buffer) + { + int64 spaceUsed = tuplestore_space_used(winstate->buffer); + + /* + * We want to track the max mem/disk usage so that we can use the info + * in EXPLAIN (ANALYZE). + */ + if (spaceUsed > winstate->storageSize) + { + if (winstate->storageType != NULL) + pfree(winstate->storageType); + winstate->storageType = + pstrdup(tuplestore_storage_type_name(winstate->buffer)); + winstate->storageSize = spaceUsed; + } tuplestore_end(winstate->buffer); + } winstate->buffer = NULL; winstate->partition_spooled = false; } @@ -2671,6 +2687,9 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags) winstate->partition_spooled = false; winstate->more_partitions = false; + winstate->storageType = NULL; + winstate->storageSize = 0; + return winstate; } diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h index b62c96f206..7a3dfa2bc3 100644 --- a/src/include/nodes/execnodes.h +++ b/src/include/nodes/execnodes.h @@ -2567,6 +2567,8 @@ typedef struct WindowAggState ExprState *partEqfunction; /* equality funcs for partition columns */ ExprState *ordEqfunction; /* equality funcs for ordering columns */ Tuplestorestate *buffer; /* stores rows of current partition */ + int64 storageSize; /* max storage size in buffer */ + char *storageType; /* the storage type above */ int current_ptr; /* read pointer # for current row */ int framehead_ptr; /* read pointer # for frame head, if used */ int frametail_ptr; /* read pointer # for frame tail, if used */ -- 2.25.1 ----Next_Part(Sat_Jul__6_20_22_54_2024_404)----