public inbox for [email protected]
help / color / mirror / Atom feed[PATCH v10 05/17] Update BitmapAdjustPrefetchIterator parameter type to BlockNumber
37+ messages / 5 participants
[nested] [flat]
* [PATCH v10 05/17] Update BitmapAdjustPrefetchIterator parameter type to BlockNumber
@ 2024-02-13 00:04 Melanie Plageman <[email protected]>
0 siblings, 0 replies; 37+ messages in thread
From: Melanie Plageman @ 2024-02-13 00:04 UTC (permalink / raw)
BitmapAdjustPrefetchIterator() only used the blockno member of the
passed in TBMIterateResult to ensure that the prefetch iterator and
regular iterator stay in sync. Pass it the BlockNumber only. This will
allow us to move away from using the TBMIterateResult outside of table
AM specific code.
---
src/backend/executor/nodeBitmapHeapscan.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/backend/executor/nodeBitmapHeapscan.c b/src/backend/executor/nodeBitmapHeapscan.c
index 5df3b5ca46..404de0595e 100644
--- a/src/backend/executor/nodeBitmapHeapscan.c
+++ b/src/backend/executor/nodeBitmapHeapscan.c
@@ -52,7 +52,7 @@
static TupleTableSlot *BitmapHeapNext(BitmapHeapScanState *node);
static inline void BitmapDoneInitializingSharedState(ParallelBitmapHeapState *pstate);
static inline void BitmapAdjustPrefetchIterator(BitmapHeapScanState *node,
- TBMIterateResult *tbmres);
+ BlockNumber blockno);
static inline void BitmapAdjustPrefetchTarget(BitmapHeapScanState *node);
static inline void BitmapPrefetch(BitmapHeapScanState *node,
TableScanDesc scan);
@@ -230,7 +230,7 @@ BitmapHeapNext(BitmapHeapScanState *node)
break;
}
- BitmapAdjustPrefetchIterator(node, tbmres);
+ BitmapAdjustPrefetchIterator(node, tbmres->blockno);
valid = table_scan_bitmap_next_block(scan, tbmres);
@@ -341,7 +341,7 @@ BitmapDoneInitializingSharedState(ParallelBitmapHeapState *pstate)
*/
static inline void
BitmapAdjustPrefetchIterator(BitmapHeapScanState *node,
- TBMIterateResult *tbmres)
+ BlockNumber blockno)
{
#ifdef USE_PREFETCH
ParallelBitmapHeapState *pstate = node->pstate;
@@ -360,7 +360,7 @@ BitmapAdjustPrefetchIterator(BitmapHeapScanState *node,
/* Do not let the prefetch iterator get behind the main one */
TBMIterateResult *tbmpre = tbm_iterate(prefetch_iterator);
- if (tbmpre == NULL || tbmpre->blockno != tbmres->blockno)
+ if (tbmpre == NULL || tbmpre->blockno != blockno)
elog(ERROR, "prefetch and main iterators are out of sync");
}
return;
--
2.40.1
--3o7pc6dfau5a5hry
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
filename="v10-0006-table_scan_bitmap_next_block-returns-lossy-or-ex.patch"
^ permalink raw reply [nested|flat] 37+ messages in thread
* [PATCH v12 05/17] Update BitmapAdjustPrefetchIterator parameter type to BlockNumber
@ 2024-02-13 00:04 Melanie Plageman <[email protected]>
0 siblings, 0 replies; 37+ messages in thread
From: Melanie Plageman @ 2024-02-13 00:04 UTC (permalink / raw)
BitmapAdjustPrefetchIterator() only used the blockno member of the
passed in TBMIterateResult to ensure that the prefetch iterator and
regular iterator stay in sync. Pass it the BlockNumber only. This will
allow us to move away from using the TBMIterateResult outside of table
AM specific code.
---
src/backend/executor/nodeBitmapHeapscan.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/backend/executor/nodeBitmapHeapscan.c b/src/backend/executor/nodeBitmapHeapscan.c
index 5df3b5ca46d..404de0595ec 100644
--- a/src/backend/executor/nodeBitmapHeapscan.c
+++ b/src/backend/executor/nodeBitmapHeapscan.c
@@ -52,7 +52,7 @@
static TupleTableSlot *BitmapHeapNext(BitmapHeapScanState *node);
static inline void BitmapDoneInitializingSharedState(ParallelBitmapHeapState *pstate);
static inline void BitmapAdjustPrefetchIterator(BitmapHeapScanState *node,
- TBMIterateResult *tbmres);
+ BlockNumber blockno);
static inline void BitmapAdjustPrefetchTarget(BitmapHeapScanState *node);
static inline void BitmapPrefetch(BitmapHeapScanState *node,
TableScanDesc scan);
@@ -230,7 +230,7 @@ BitmapHeapNext(BitmapHeapScanState *node)
break;
}
- BitmapAdjustPrefetchIterator(node, tbmres);
+ BitmapAdjustPrefetchIterator(node, tbmres->blockno);
valid = table_scan_bitmap_next_block(scan, tbmres);
@@ -341,7 +341,7 @@ BitmapDoneInitializingSharedState(ParallelBitmapHeapState *pstate)
*/
static inline void
BitmapAdjustPrefetchIterator(BitmapHeapScanState *node,
- TBMIterateResult *tbmres)
+ BlockNumber blockno)
{
#ifdef USE_PREFETCH
ParallelBitmapHeapState *pstate = node->pstate;
@@ -360,7 +360,7 @@ BitmapAdjustPrefetchIterator(BitmapHeapScanState *node,
/* Do not let the prefetch iterator get behind the main one */
TBMIterateResult *tbmpre = tbm_iterate(prefetch_iterator);
- if (tbmpre == NULL || tbmpre->blockno != tbmres->blockno)
+ if (tbmpre == NULL || tbmpre->blockno != blockno)
elog(ERROR, "prefetch and main iterators are out of sync");
}
return;
--
2.40.1
--6jpz2j246qmht4bt
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
filename="v12-0006-table_scan_bitmap_next_block-returns-lossy-or-ex.patch"
^ permalink raw reply [nested|flat] 37+ messages in thread
* [PATCH v11 05/17] Update BitmapAdjustPrefetchIterator parameter type to BlockNumber
@ 2024-02-13 00:04 Melanie Plageman <[email protected]>
0 siblings, 0 replies; 37+ messages in thread
From: Melanie Plageman @ 2024-02-13 00:04 UTC (permalink / raw)
BitmapAdjustPrefetchIterator() only used the blockno member of the
passed in TBMIterateResult to ensure that the prefetch iterator and
regular iterator stay in sync. Pass it the BlockNumber only. This will
allow us to move away from using the TBMIterateResult outside of table
AM specific code.
---
src/backend/executor/nodeBitmapHeapscan.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/backend/executor/nodeBitmapHeapscan.c b/src/backend/executor/nodeBitmapHeapscan.c
index 5df3b5ca46..404de0595e 100644
--- a/src/backend/executor/nodeBitmapHeapscan.c
+++ b/src/backend/executor/nodeBitmapHeapscan.c
@@ -52,7 +52,7 @@
static TupleTableSlot *BitmapHeapNext(BitmapHeapScanState *node);
static inline void BitmapDoneInitializingSharedState(ParallelBitmapHeapState *pstate);
static inline void BitmapAdjustPrefetchIterator(BitmapHeapScanState *node,
- TBMIterateResult *tbmres);
+ BlockNumber blockno);
static inline void BitmapAdjustPrefetchTarget(BitmapHeapScanState *node);
static inline void BitmapPrefetch(BitmapHeapScanState *node,
TableScanDesc scan);
@@ -230,7 +230,7 @@ BitmapHeapNext(BitmapHeapScanState *node)
break;
}
- BitmapAdjustPrefetchIterator(node, tbmres);
+ BitmapAdjustPrefetchIterator(node, tbmres->blockno);
valid = table_scan_bitmap_next_block(scan, tbmres);
@@ -341,7 +341,7 @@ BitmapDoneInitializingSharedState(ParallelBitmapHeapState *pstate)
*/
static inline void
BitmapAdjustPrefetchIterator(BitmapHeapScanState *node,
- TBMIterateResult *tbmres)
+ BlockNumber blockno)
{
#ifdef USE_PREFETCH
ParallelBitmapHeapState *pstate = node->pstate;
@@ -360,7 +360,7 @@ BitmapAdjustPrefetchIterator(BitmapHeapScanState *node,
/* Do not let the prefetch iterator get behind the main one */
TBMIterateResult *tbmpre = tbm_iterate(prefetch_iterator);
- if (tbmpre == NULL || tbmpre->blockno != tbmres->blockno)
+ if (tbmpre == NULL || tbmpre->blockno != blockno)
elog(ERROR, "prefetch and main iterators are out of sync");
}
return;
--
2.40.1
--owzzsiozz6hgpp7e
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
filename="v11-0006-table_scan_bitmap_next_block-returns-lossy-or-ex.patch"
^ permalink raw reply [nested|flat] 37+ messages in thread
* [PATCH v10 05/17] Update BitmapAdjustPrefetchIterator parameter type to BlockNumber
@ 2024-02-13 00:04 Melanie Plageman <[email protected]>
0 siblings, 0 replies; 37+ messages in thread
From: Melanie Plageman @ 2024-02-13 00:04 UTC (permalink / raw)
BitmapAdjustPrefetchIterator() only used the blockno member of the
passed in TBMIterateResult to ensure that the prefetch iterator and
regular iterator stay in sync. Pass it the BlockNumber only. This will
allow us to move away from using the TBMIterateResult outside of table
AM specific code.
---
src/backend/executor/nodeBitmapHeapscan.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/backend/executor/nodeBitmapHeapscan.c b/src/backend/executor/nodeBitmapHeapscan.c
index 5df3b5ca46..404de0595e 100644
--- a/src/backend/executor/nodeBitmapHeapscan.c
+++ b/src/backend/executor/nodeBitmapHeapscan.c
@@ -52,7 +52,7 @@
static TupleTableSlot *BitmapHeapNext(BitmapHeapScanState *node);
static inline void BitmapDoneInitializingSharedState(ParallelBitmapHeapState *pstate);
static inline void BitmapAdjustPrefetchIterator(BitmapHeapScanState *node,
- TBMIterateResult *tbmres);
+ BlockNumber blockno);
static inline void BitmapAdjustPrefetchTarget(BitmapHeapScanState *node);
static inline void BitmapPrefetch(BitmapHeapScanState *node,
TableScanDesc scan);
@@ -230,7 +230,7 @@ BitmapHeapNext(BitmapHeapScanState *node)
break;
}
- BitmapAdjustPrefetchIterator(node, tbmres);
+ BitmapAdjustPrefetchIterator(node, tbmres->blockno);
valid = table_scan_bitmap_next_block(scan, tbmres);
@@ -341,7 +341,7 @@ BitmapDoneInitializingSharedState(ParallelBitmapHeapState *pstate)
*/
static inline void
BitmapAdjustPrefetchIterator(BitmapHeapScanState *node,
- TBMIterateResult *tbmres)
+ BlockNumber blockno)
{
#ifdef USE_PREFETCH
ParallelBitmapHeapState *pstate = node->pstate;
@@ -360,7 +360,7 @@ BitmapAdjustPrefetchIterator(BitmapHeapScanState *node,
/* Do not let the prefetch iterator get behind the main one */
TBMIterateResult *tbmpre = tbm_iterate(prefetch_iterator);
- if (tbmpre == NULL || tbmpre->blockno != tbmres->blockno)
+ if (tbmpre == NULL || tbmpre->blockno != blockno)
elog(ERROR, "prefetch and main iterators are out of sync");
}
return;
--
2.40.1
--3o7pc6dfau5a5hry
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
filename="v10-0006-table_scan_bitmap_next_block-returns-lossy-or-ex.patch"
^ permalink raw reply [nested|flat] 37+ messages in thread
* [PATCH v6 05/14] Update BitmapAdjustPrefetchIterator parameter type to BlockNumber
@ 2024-02-13 00:04 Melanie Plageman <[email protected]>
0 siblings, 0 replies; 37+ messages in thread
From: Melanie Plageman @ 2024-02-13 00:04 UTC (permalink / raw)
BitmapAdjustPrefetchIterator() only used the blockno member of the
passed in TBMIterateResult to ensure that the prefetch iterator and
regular iterator stay in sync. Pass it the BlockNumber only. This will
allow us to move away from using the TBMIterateResult outside of table
AM specific code.
---
src/backend/executor/nodeBitmapHeapscan.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/backend/executor/nodeBitmapHeapscan.c b/src/backend/executor/nodeBitmapHeapscan.c
index 6a34f10646a..61ffc8d0ee8 100644
--- a/src/backend/executor/nodeBitmapHeapscan.c
+++ b/src/backend/executor/nodeBitmapHeapscan.c
@@ -52,7 +52,7 @@
static TupleTableSlot *BitmapHeapNext(BitmapHeapScanState *node);
static inline void BitmapDoneInitializingSharedState(ParallelBitmapHeapState *pstate);
static inline void BitmapAdjustPrefetchIterator(BitmapHeapScanState *node,
- TBMIterateResult *tbmres);
+ BlockNumber blockno);
static inline void BitmapAdjustPrefetchTarget(BitmapHeapScanState *node);
static inline void BitmapPrefetch(BitmapHeapScanState *node,
TableScanDesc scan);
@@ -228,7 +228,7 @@ BitmapHeapNext(BitmapHeapScanState *node)
break;
}
- BitmapAdjustPrefetchIterator(node, tbmres);
+ BitmapAdjustPrefetchIterator(node, tbmres->blockno);
if (!table_scan_bitmap_next_block(scan, tbmres))
{
@@ -337,7 +337,7 @@ BitmapDoneInitializingSharedState(ParallelBitmapHeapState *pstate)
*/
static inline void
BitmapAdjustPrefetchIterator(BitmapHeapScanState *node,
- TBMIterateResult *tbmres)
+ BlockNumber blockno)
{
#ifdef USE_PREFETCH
ParallelBitmapHeapState *pstate = node->pstate;
@@ -356,7 +356,7 @@ BitmapAdjustPrefetchIterator(BitmapHeapScanState *node,
/* Do not let the prefetch iterator get behind the main one */
TBMIterateResult *tbmpre = tbm_iterate(prefetch_iterator);
- if (tbmpre == NULL || tbmpre->blockno != tbmres->blockno)
+ if (tbmpre == NULL || tbmpre->blockno != blockno)
elog(ERROR, "prefetch and main iterators are out of sync");
}
return;
--
2.40.1
--w4wcjcocxsm37usi
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
filename="v6-0006-EXPLAIN-Bitmap-table-scan-also-count-no-visible-t.patch"
^ permalink raw reply [nested|flat] 37+ messages in thread
* [PATCH v6 05/14] Update BitmapAdjustPrefetchIterator parameter type to BlockNumber
@ 2024-02-13 00:04 Melanie Plageman <[email protected]>
0 siblings, 0 replies; 37+ messages in thread
From: Melanie Plageman @ 2024-02-13 00:04 UTC (permalink / raw)
BitmapAdjustPrefetchIterator() only used the blockno member of the
passed in TBMIterateResult to ensure that the prefetch iterator and
regular iterator stay in sync. Pass it the BlockNumber only. This will
allow us to move away from using the TBMIterateResult outside of table
AM specific code.
---
src/backend/executor/nodeBitmapHeapscan.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/backend/executor/nodeBitmapHeapscan.c b/src/backend/executor/nodeBitmapHeapscan.c
index 6a34f10646a..61ffc8d0ee8 100644
--- a/src/backend/executor/nodeBitmapHeapscan.c
+++ b/src/backend/executor/nodeBitmapHeapscan.c
@@ -52,7 +52,7 @@
static TupleTableSlot *BitmapHeapNext(BitmapHeapScanState *node);
static inline void BitmapDoneInitializingSharedState(ParallelBitmapHeapState *pstate);
static inline void BitmapAdjustPrefetchIterator(BitmapHeapScanState *node,
- TBMIterateResult *tbmres);
+ BlockNumber blockno);
static inline void BitmapAdjustPrefetchTarget(BitmapHeapScanState *node);
static inline void BitmapPrefetch(BitmapHeapScanState *node,
TableScanDesc scan);
@@ -228,7 +228,7 @@ BitmapHeapNext(BitmapHeapScanState *node)
break;
}
- BitmapAdjustPrefetchIterator(node, tbmres);
+ BitmapAdjustPrefetchIterator(node, tbmres->blockno);
if (!table_scan_bitmap_next_block(scan, tbmres))
{
@@ -337,7 +337,7 @@ BitmapDoneInitializingSharedState(ParallelBitmapHeapState *pstate)
*/
static inline void
BitmapAdjustPrefetchIterator(BitmapHeapScanState *node,
- TBMIterateResult *tbmres)
+ BlockNumber blockno)
{
#ifdef USE_PREFETCH
ParallelBitmapHeapState *pstate = node->pstate;
@@ -356,7 +356,7 @@ BitmapAdjustPrefetchIterator(BitmapHeapScanState *node,
/* Do not let the prefetch iterator get behind the main one */
TBMIterateResult *tbmpre = tbm_iterate(prefetch_iterator);
- if (tbmpre == NULL || tbmpre->blockno != tbmres->blockno)
+ if (tbmpre == NULL || tbmpre->blockno != blockno)
elog(ERROR, "prefetch and main iterators are out of sync");
}
return;
--
2.40.1
--w4wcjcocxsm37usi
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
filename="v6-0006-EXPLAIN-Bitmap-table-scan-also-count-no-visible-t.patch"
^ permalink raw reply [nested|flat] 37+ messages in thread
* [PATCH v7 05/13] Update BitmapAdjustPrefetchIterator parameter type to BlockNumber
@ 2024-02-13 00:04 Melanie Plageman <[email protected]>
0 siblings, 0 replies; 37+ messages in thread
From: Melanie Plageman @ 2024-02-13 00:04 UTC (permalink / raw)
BitmapAdjustPrefetchIterator() only used the blockno member of the
passed in TBMIterateResult to ensure that the prefetch iterator and
regular iterator stay in sync. Pass it the BlockNumber only. This will
allow us to move away from using the TBMIterateResult outside of table
AM specific code.
---
src/backend/executor/nodeBitmapHeapscan.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/backend/executor/nodeBitmapHeapscan.c b/src/backend/executor/nodeBitmapHeapscan.c
index dc8c312cafb..a6b98fa12a1 100644
--- a/src/backend/executor/nodeBitmapHeapscan.c
+++ b/src/backend/executor/nodeBitmapHeapscan.c
@@ -52,7 +52,7 @@
static TupleTableSlot *BitmapHeapNext(BitmapHeapScanState *node);
static inline void BitmapDoneInitializingSharedState(ParallelBitmapHeapState *pstate);
static inline void BitmapAdjustPrefetchIterator(BitmapHeapScanState *node,
- TBMIterateResult *tbmres);
+ BlockNumber blockno);
static inline void BitmapAdjustPrefetchTarget(BitmapHeapScanState *node);
static inline void BitmapPrefetch(BitmapHeapScanState *node,
TableScanDesc scan);
@@ -230,7 +230,7 @@ BitmapHeapNext(BitmapHeapScanState *node)
break;
}
- BitmapAdjustPrefetchIterator(node, tbmres);
+ BitmapAdjustPrefetchIterator(node, tbmres->blockno);
valid = table_scan_bitmap_next_block(scan, tbmres);
@@ -341,7 +341,7 @@ BitmapDoneInitializingSharedState(ParallelBitmapHeapState *pstate)
*/
static inline void
BitmapAdjustPrefetchIterator(BitmapHeapScanState *node,
- TBMIterateResult *tbmres)
+ BlockNumber blockno)
{
#ifdef USE_PREFETCH
ParallelBitmapHeapState *pstate = node->pstate;
@@ -360,7 +360,7 @@ BitmapAdjustPrefetchIterator(BitmapHeapScanState *node,
/* Do not let the prefetch iterator get behind the main one */
TBMIterateResult *tbmpre = tbm_iterate(prefetch_iterator);
- if (tbmpre == NULL || tbmpre->blockno != tbmres->blockno)
+ if (tbmpre == NULL || tbmpre->blockno != blockno)
elog(ERROR, "prefetch and main iterators are out of sync");
}
return;
--
2.40.1
--kqqpqghcwbcc3dt5
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
filename="v7-0006-table_scan_bitmap_next_block-returns-lossy-or-exa.patch"
^ permalink raw reply [nested|flat] 37+ messages in thread
* [PATCH v8 05/17] Update BitmapAdjustPrefetchIterator parameter type to BlockNumber
@ 2024-02-13 00:04 Melanie Plageman <[email protected]>
0 siblings, 0 replies; 37+ messages in thread
From: Melanie Plageman @ 2024-02-13 00:04 UTC (permalink / raw)
BitmapAdjustPrefetchIterator() only used the blockno member of the
passed in TBMIterateResult to ensure that the prefetch iterator and
regular iterator stay in sync. Pass it the BlockNumber only. This will
allow us to move away from using the TBMIterateResult outside of table
AM specific code.
---
src/backend/executor/nodeBitmapHeapscan.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/backend/executor/nodeBitmapHeapscan.c b/src/backend/executor/nodeBitmapHeapscan.c
index 5df3b5ca46..404de0595e 100644
--- a/src/backend/executor/nodeBitmapHeapscan.c
+++ b/src/backend/executor/nodeBitmapHeapscan.c
@@ -52,7 +52,7 @@
static TupleTableSlot *BitmapHeapNext(BitmapHeapScanState *node);
static inline void BitmapDoneInitializingSharedState(ParallelBitmapHeapState *pstate);
static inline void BitmapAdjustPrefetchIterator(BitmapHeapScanState *node,
- TBMIterateResult *tbmres);
+ BlockNumber blockno);
static inline void BitmapAdjustPrefetchTarget(BitmapHeapScanState *node);
static inline void BitmapPrefetch(BitmapHeapScanState *node,
TableScanDesc scan);
@@ -230,7 +230,7 @@ BitmapHeapNext(BitmapHeapScanState *node)
break;
}
- BitmapAdjustPrefetchIterator(node, tbmres);
+ BitmapAdjustPrefetchIterator(node, tbmres->blockno);
valid = table_scan_bitmap_next_block(scan, tbmres);
@@ -341,7 +341,7 @@ BitmapDoneInitializingSharedState(ParallelBitmapHeapState *pstate)
*/
static inline void
BitmapAdjustPrefetchIterator(BitmapHeapScanState *node,
- TBMIterateResult *tbmres)
+ BlockNumber blockno)
{
#ifdef USE_PREFETCH
ParallelBitmapHeapState *pstate = node->pstate;
@@ -360,7 +360,7 @@ BitmapAdjustPrefetchIterator(BitmapHeapScanState *node,
/* Do not let the prefetch iterator get behind the main one */
TBMIterateResult *tbmpre = tbm_iterate(prefetch_iterator);
- if (tbmpre == NULL || tbmpre->blockno != tbmres->blockno)
+ if (tbmpre == NULL || tbmpre->blockno != blockno)
elog(ERROR, "prefetch and main iterators are out of sync");
}
return;
--
2.40.1
--xqq4defy3uncu6k6
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
filename="v8-0006-table_scan_bitmap_next_block-returns-lossy-or-exa.patch"
^ permalink raw reply [nested|flat] 37+ messages in thread
* [PATCH v9 05/17] Update BitmapAdjustPrefetchIterator parameter type to BlockNumber
@ 2024-02-13 00:04 Melanie Plageman <[email protected]>
0 siblings, 0 replies; 37+ messages in thread
From: Melanie Plageman @ 2024-02-13 00:04 UTC (permalink / raw)
BitmapAdjustPrefetchIterator() only used the blockno member of the
passed in TBMIterateResult to ensure that the prefetch iterator and
regular iterator stay in sync. Pass it the BlockNumber only. This will
allow us to move away from using the TBMIterateResult outside of table
AM specific code.
---
src/backend/executor/nodeBitmapHeapscan.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/backend/executor/nodeBitmapHeapscan.c b/src/backend/executor/nodeBitmapHeapscan.c
index 5df3b5ca46..404de0595e 100644
--- a/src/backend/executor/nodeBitmapHeapscan.c
+++ b/src/backend/executor/nodeBitmapHeapscan.c
@@ -52,7 +52,7 @@
static TupleTableSlot *BitmapHeapNext(BitmapHeapScanState *node);
static inline void BitmapDoneInitializingSharedState(ParallelBitmapHeapState *pstate);
static inline void BitmapAdjustPrefetchIterator(BitmapHeapScanState *node,
- TBMIterateResult *tbmres);
+ BlockNumber blockno);
static inline void BitmapAdjustPrefetchTarget(BitmapHeapScanState *node);
static inline void BitmapPrefetch(BitmapHeapScanState *node,
TableScanDesc scan);
@@ -230,7 +230,7 @@ BitmapHeapNext(BitmapHeapScanState *node)
break;
}
- BitmapAdjustPrefetchIterator(node, tbmres);
+ BitmapAdjustPrefetchIterator(node, tbmres->blockno);
valid = table_scan_bitmap_next_block(scan, tbmres);
@@ -341,7 +341,7 @@ BitmapDoneInitializingSharedState(ParallelBitmapHeapState *pstate)
*/
static inline void
BitmapAdjustPrefetchIterator(BitmapHeapScanState *node,
- TBMIterateResult *tbmres)
+ BlockNumber blockno)
{
#ifdef USE_PREFETCH
ParallelBitmapHeapState *pstate = node->pstate;
@@ -360,7 +360,7 @@ BitmapAdjustPrefetchIterator(BitmapHeapScanState *node,
/* Do not let the prefetch iterator get behind the main one */
TBMIterateResult *tbmpre = tbm_iterate(prefetch_iterator);
- if (tbmpre == NULL || tbmpre->blockno != tbmres->blockno)
+ if (tbmpre == NULL || tbmpre->blockno != blockno)
elog(ERROR, "prefetch and main iterators are out of sync");
}
return;
--
2.40.1
--7mdtsjmrzitrgzgx
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
filename="v9-0006-table_scan_bitmap_next_block-returns-lossy-or-exa.patch"
^ permalink raw reply [nested|flat] 37+ messages in thread
* [PATCH v11 05/17] Update BitmapAdjustPrefetchIterator parameter type to BlockNumber
@ 2024-02-13 00:04 Melanie Plageman <[email protected]>
0 siblings, 0 replies; 37+ messages in thread
From: Melanie Plageman @ 2024-02-13 00:04 UTC (permalink / raw)
BitmapAdjustPrefetchIterator() only used the blockno member of the
passed in TBMIterateResult to ensure that the prefetch iterator and
regular iterator stay in sync. Pass it the BlockNumber only. This will
allow us to move away from using the TBMIterateResult outside of table
AM specific code.
---
src/backend/executor/nodeBitmapHeapscan.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/backend/executor/nodeBitmapHeapscan.c b/src/backend/executor/nodeBitmapHeapscan.c
index 5df3b5ca46..404de0595e 100644
--- a/src/backend/executor/nodeBitmapHeapscan.c
+++ b/src/backend/executor/nodeBitmapHeapscan.c
@@ -52,7 +52,7 @@
static TupleTableSlot *BitmapHeapNext(BitmapHeapScanState *node);
static inline void BitmapDoneInitializingSharedState(ParallelBitmapHeapState *pstate);
static inline void BitmapAdjustPrefetchIterator(BitmapHeapScanState *node,
- TBMIterateResult *tbmres);
+ BlockNumber blockno);
static inline void BitmapAdjustPrefetchTarget(BitmapHeapScanState *node);
static inline void BitmapPrefetch(BitmapHeapScanState *node,
TableScanDesc scan);
@@ -230,7 +230,7 @@ BitmapHeapNext(BitmapHeapScanState *node)
break;
}
- BitmapAdjustPrefetchIterator(node, tbmres);
+ BitmapAdjustPrefetchIterator(node, tbmres->blockno);
valid = table_scan_bitmap_next_block(scan, tbmres);
@@ -341,7 +341,7 @@ BitmapDoneInitializingSharedState(ParallelBitmapHeapState *pstate)
*/
static inline void
BitmapAdjustPrefetchIterator(BitmapHeapScanState *node,
- TBMIterateResult *tbmres)
+ BlockNumber blockno)
{
#ifdef USE_PREFETCH
ParallelBitmapHeapState *pstate = node->pstate;
@@ -360,7 +360,7 @@ BitmapAdjustPrefetchIterator(BitmapHeapScanState *node,
/* Do not let the prefetch iterator get behind the main one */
TBMIterateResult *tbmpre = tbm_iterate(prefetch_iterator);
- if (tbmpre == NULL || tbmpre->blockno != tbmres->blockno)
+ if (tbmpre == NULL || tbmpre->blockno != blockno)
elog(ERROR, "prefetch and main iterators are out of sync");
}
return;
--
2.40.1
--owzzsiozz6hgpp7e
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
filename="v11-0006-table_scan_bitmap_next_block-returns-lossy-or-ex.patch"
^ permalink raw reply [nested|flat] 37+ messages in thread
* [PATCH v9 05/17] Update BitmapAdjustPrefetchIterator parameter type to BlockNumber
@ 2024-02-13 00:04 Melanie Plageman <[email protected]>
0 siblings, 0 replies; 37+ messages in thread
From: Melanie Plageman @ 2024-02-13 00:04 UTC (permalink / raw)
BitmapAdjustPrefetchIterator() only used the blockno member of the
passed in TBMIterateResult to ensure that the prefetch iterator and
regular iterator stay in sync. Pass it the BlockNumber only. This will
allow us to move away from using the TBMIterateResult outside of table
AM specific code.
---
src/backend/executor/nodeBitmapHeapscan.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/backend/executor/nodeBitmapHeapscan.c b/src/backend/executor/nodeBitmapHeapscan.c
index 5df3b5ca46..404de0595e 100644
--- a/src/backend/executor/nodeBitmapHeapscan.c
+++ b/src/backend/executor/nodeBitmapHeapscan.c
@@ -52,7 +52,7 @@
static TupleTableSlot *BitmapHeapNext(BitmapHeapScanState *node);
static inline void BitmapDoneInitializingSharedState(ParallelBitmapHeapState *pstate);
static inline void BitmapAdjustPrefetchIterator(BitmapHeapScanState *node,
- TBMIterateResult *tbmres);
+ BlockNumber blockno);
static inline void BitmapAdjustPrefetchTarget(BitmapHeapScanState *node);
static inline void BitmapPrefetch(BitmapHeapScanState *node,
TableScanDesc scan);
@@ -230,7 +230,7 @@ BitmapHeapNext(BitmapHeapScanState *node)
break;
}
- BitmapAdjustPrefetchIterator(node, tbmres);
+ BitmapAdjustPrefetchIterator(node, tbmres->blockno);
valid = table_scan_bitmap_next_block(scan, tbmres);
@@ -341,7 +341,7 @@ BitmapDoneInitializingSharedState(ParallelBitmapHeapState *pstate)
*/
static inline void
BitmapAdjustPrefetchIterator(BitmapHeapScanState *node,
- TBMIterateResult *tbmres)
+ BlockNumber blockno)
{
#ifdef USE_PREFETCH
ParallelBitmapHeapState *pstate = node->pstate;
@@ -360,7 +360,7 @@ BitmapAdjustPrefetchIterator(BitmapHeapScanState *node,
/* Do not let the prefetch iterator get behind the main one */
TBMIterateResult *tbmpre = tbm_iterate(prefetch_iterator);
- if (tbmpre == NULL || tbmpre->blockno != tbmres->blockno)
+ if (tbmpre == NULL || tbmpre->blockno != blockno)
elog(ERROR, "prefetch and main iterators are out of sync");
}
return;
--
2.40.1
--7mdtsjmrzitrgzgx
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
filename="v9-0006-table_scan_bitmap_next_block-returns-lossy-or-exa.patch"
^ permalink raw reply [nested|flat] 37+ messages in thread
* [PATCH v8 05/17] Update BitmapAdjustPrefetchIterator parameter type to BlockNumber
@ 2024-02-13 00:04 Melanie Plageman <[email protected]>
0 siblings, 0 replies; 37+ messages in thread
From: Melanie Plageman @ 2024-02-13 00:04 UTC (permalink / raw)
BitmapAdjustPrefetchIterator() only used the blockno member of the
passed in TBMIterateResult to ensure that the prefetch iterator and
regular iterator stay in sync. Pass it the BlockNumber only. This will
allow us to move away from using the TBMIterateResult outside of table
AM specific code.
---
src/backend/executor/nodeBitmapHeapscan.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/backend/executor/nodeBitmapHeapscan.c b/src/backend/executor/nodeBitmapHeapscan.c
index 5df3b5ca46..404de0595e 100644
--- a/src/backend/executor/nodeBitmapHeapscan.c
+++ b/src/backend/executor/nodeBitmapHeapscan.c
@@ -52,7 +52,7 @@
static TupleTableSlot *BitmapHeapNext(BitmapHeapScanState *node);
static inline void BitmapDoneInitializingSharedState(ParallelBitmapHeapState *pstate);
static inline void BitmapAdjustPrefetchIterator(BitmapHeapScanState *node,
- TBMIterateResult *tbmres);
+ BlockNumber blockno);
static inline void BitmapAdjustPrefetchTarget(BitmapHeapScanState *node);
static inline void BitmapPrefetch(BitmapHeapScanState *node,
TableScanDesc scan);
@@ -230,7 +230,7 @@ BitmapHeapNext(BitmapHeapScanState *node)
break;
}
- BitmapAdjustPrefetchIterator(node, tbmres);
+ BitmapAdjustPrefetchIterator(node, tbmres->blockno);
valid = table_scan_bitmap_next_block(scan, tbmres);
@@ -341,7 +341,7 @@ BitmapDoneInitializingSharedState(ParallelBitmapHeapState *pstate)
*/
static inline void
BitmapAdjustPrefetchIterator(BitmapHeapScanState *node,
- TBMIterateResult *tbmres)
+ BlockNumber blockno)
{
#ifdef USE_PREFETCH
ParallelBitmapHeapState *pstate = node->pstate;
@@ -360,7 +360,7 @@ BitmapAdjustPrefetchIterator(BitmapHeapScanState *node,
/* Do not let the prefetch iterator get behind the main one */
TBMIterateResult *tbmpre = tbm_iterate(prefetch_iterator);
- if (tbmpre == NULL || tbmpre->blockno != tbmres->blockno)
+ if (tbmpre == NULL || tbmpre->blockno != blockno)
elog(ERROR, "prefetch and main iterators are out of sync");
}
return;
--
2.40.1
--xqq4defy3uncu6k6
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
filename="v8-0006-table_scan_bitmap_next_block-returns-lossy-or-exa.patch"
^ permalink raw reply [nested|flat] 37+ messages in thread
* [PATCH v7 05/13] Update BitmapAdjustPrefetchIterator parameter type to BlockNumber
@ 2024-02-13 00:04 Melanie Plageman <[email protected]>
0 siblings, 0 replies; 37+ messages in thread
From: Melanie Plageman @ 2024-02-13 00:04 UTC (permalink / raw)
BitmapAdjustPrefetchIterator() only used the blockno member of the
passed in TBMIterateResult to ensure that the prefetch iterator and
regular iterator stay in sync. Pass it the BlockNumber only. This will
allow us to move away from using the TBMIterateResult outside of table
AM specific code.
---
src/backend/executor/nodeBitmapHeapscan.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/backend/executor/nodeBitmapHeapscan.c b/src/backend/executor/nodeBitmapHeapscan.c
index dc8c312cafb..a6b98fa12a1 100644
--- a/src/backend/executor/nodeBitmapHeapscan.c
+++ b/src/backend/executor/nodeBitmapHeapscan.c
@@ -52,7 +52,7 @@
static TupleTableSlot *BitmapHeapNext(BitmapHeapScanState *node);
static inline void BitmapDoneInitializingSharedState(ParallelBitmapHeapState *pstate);
static inline void BitmapAdjustPrefetchIterator(BitmapHeapScanState *node,
- TBMIterateResult *tbmres);
+ BlockNumber blockno);
static inline void BitmapAdjustPrefetchTarget(BitmapHeapScanState *node);
static inline void BitmapPrefetch(BitmapHeapScanState *node,
TableScanDesc scan);
@@ -230,7 +230,7 @@ BitmapHeapNext(BitmapHeapScanState *node)
break;
}
- BitmapAdjustPrefetchIterator(node, tbmres);
+ BitmapAdjustPrefetchIterator(node, tbmres->blockno);
valid = table_scan_bitmap_next_block(scan, tbmres);
@@ -341,7 +341,7 @@ BitmapDoneInitializingSharedState(ParallelBitmapHeapState *pstate)
*/
static inline void
BitmapAdjustPrefetchIterator(BitmapHeapScanState *node,
- TBMIterateResult *tbmres)
+ BlockNumber blockno)
{
#ifdef USE_PREFETCH
ParallelBitmapHeapState *pstate = node->pstate;
@@ -360,7 +360,7 @@ BitmapAdjustPrefetchIterator(BitmapHeapScanState *node,
/* Do not let the prefetch iterator get behind the main one */
TBMIterateResult *tbmpre = tbm_iterate(prefetch_iterator);
- if (tbmpre == NULL || tbmpre->blockno != tbmres->blockno)
+ if (tbmpre == NULL || tbmpre->blockno != blockno)
elog(ERROR, "prefetch and main iterators are out of sync");
}
return;
--
2.40.1
--kqqpqghcwbcc3dt5
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
filename="v7-0006-table_scan_bitmap_next_block-returns-lossy-or-exa.patch"
^ permalink raw reply [nested|flat] 37+ messages in thread
* [PATCH v6 05/14] Update BitmapAdjustPrefetchIterator parameter type to BlockNumber
@ 2024-02-13 00:04 Melanie Plageman <[email protected]>
0 siblings, 0 replies; 37+ messages in thread
From: Melanie Plageman @ 2024-02-13 00:04 UTC (permalink / raw)
BitmapAdjustPrefetchIterator() only used the blockno member of the
passed in TBMIterateResult to ensure that the prefetch iterator and
regular iterator stay in sync. Pass it the BlockNumber only. This will
allow us to move away from using the TBMIterateResult outside of table
AM specific code.
---
src/backend/executor/nodeBitmapHeapscan.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/backend/executor/nodeBitmapHeapscan.c b/src/backend/executor/nodeBitmapHeapscan.c
index 6a34f10646a..61ffc8d0ee8 100644
--- a/src/backend/executor/nodeBitmapHeapscan.c
+++ b/src/backend/executor/nodeBitmapHeapscan.c
@@ -52,7 +52,7 @@
static TupleTableSlot *BitmapHeapNext(BitmapHeapScanState *node);
static inline void BitmapDoneInitializingSharedState(ParallelBitmapHeapState *pstate);
static inline void BitmapAdjustPrefetchIterator(BitmapHeapScanState *node,
- TBMIterateResult *tbmres);
+ BlockNumber blockno);
static inline void BitmapAdjustPrefetchTarget(BitmapHeapScanState *node);
static inline void BitmapPrefetch(BitmapHeapScanState *node,
TableScanDesc scan);
@@ -228,7 +228,7 @@ BitmapHeapNext(BitmapHeapScanState *node)
break;
}
- BitmapAdjustPrefetchIterator(node, tbmres);
+ BitmapAdjustPrefetchIterator(node, tbmres->blockno);
if (!table_scan_bitmap_next_block(scan, tbmres))
{
@@ -337,7 +337,7 @@ BitmapDoneInitializingSharedState(ParallelBitmapHeapState *pstate)
*/
static inline void
BitmapAdjustPrefetchIterator(BitmapHeapScanState *node,
- TBMIterateResult *tbmres)
+ BlockNumber blockno)
{
#ifdef USE_PREFETCH
ParallelBitmapHeapState *pstate = node->pstate;
@@ -356,7 +356,7 @@ BitmapAdjustPrefetchIterator(BitmapHeapScanState *node,
/* Do not let the prefetch iterator get behind the main one */
TBMIterateResult *tbmpre = tbm_iterate(prefetch_iterator);
- if (tbmpre == NULL || tbmpre->blockno != tbmres->blockno)
+ if (tbmpre == NULL || tbmpre->blockno != blockno)
elog(ERROR, "prefetch and main iterators are out of sync");
}
return;
--
2.40.1
--w4wcjcocxsm37usi
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
filename="v6-0006-EXPLAIN-Bitmap-table-scan-also-count-no-visible-t.patch"
^ permalink raw reply [nested|flat] 37+ messages in thread
* [PATCH v10 05/17] Update BitmapAdjustPrefetchIterator parameter type to BlockNumber
@ 2024-02-13 00:04 Melanie Plageman <[email protected]>
0 siblings, 0 replies; 37+ messages in thread
From: Melanie Plageman @ 2024-02-13 00:04 UTC (permalink / raw)
BitmapAdjustPrefetchIterator() only used the blockno member of the
passed in TBMIterateResult to ensure that the prefetch iterator and
regular iterator stay in sync. Pass it the BlockNumber only. This will
allow us to move away from using the TBMIterateResult outside of table
AM specific code.
---
src/backend/executor/nodeBitmapHeapscan.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/backend/executor/nodeBitmapHeapscan.c b/src/backend/executor/nodeBitmapHeapscan.c
index 5df3b5ca46..404de0595e 100644
--- a/src/backend/executor/nodeBitmapHeapscan.c
+++ b/src/backend/executor/nodeBitmapHeapscan.c
@@ -52,7 +52,7 @@
static TupleTableSlot *BitmapHeapNext(BitmapHeapScanState *node);
static inline void BitmapDoneInitializingSharedState(ParallelBitmapHeapState *pstate);
static inline void BitmapAdjustPrefetchIterator(BitmapHeapScanState *node,
- TBMIterateResult *tbmres);
+ BlockNumber blockno);
static inline void BitmapAdjustPrefetchTarget(BitmapHeapScanState *node);
static inline void BitmapPrefetch(BitmapHeapScanState *node,
TableScanDesc scan);
@@ -230,7 +230,7 @@ BitmapHeapNext(BitmapHeapScanState *node)
break;
}
- BitmapAdjustPrefetchIterator(node, tbmres);
+ BitmapAdjustPrefetchIterator(node, tbmres->blockno);
valid = table_scan_bitmap_next_block(scan, tbmres);
@@ -341,7 +341,7 @@ BitmapDoneInitializingSharedState(ParallelBitmapHeapState *pstate)
*/
static inline void
BitmapAdjustPrefetchIterator(BitmapHeapScanState *node,
- TBMIterateResult *tbmres)
+ BlockNumber blockno)
{
#ifdef USE_PREFETCH
ParallelBitmapHeapState *pstate = node->pstate;
@@ -360,7 +360,7 @@ BitmapAdjustPrefetchIterator(BitmapHeapScanState *node,
/* Do not let the prefetch iterator get behind the main one */
TBMIterateResult *tbmpre = tbm_iterate(prefetch_iterator);
- if (tbmpre == NULL || tbmpre->blockno != tbmres->blockno)
+ if (tbmpre == NULL || tbmpre->blockno != blockno)
elog(ERROR, "prefetch and main iterators are out of sync");
}
return;
--
2.40.1
--3o7pc6dfau5a5hry
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
filename="v10-0006-table_scan_bitmap_next_block-returns-lossy-or-ex.patch"
^ permalink raw reply [nested|flat] 37+ messages in thread
* [PATCH v9 05/17] Update BitmapAdjustPrefetchIterator parameter type to BlockNumber
@ 2024-02-13 00:04 Melanie Plageman <[email protected]>
0 siblings, 0 replies; 37+ messages in thread
From: Melanie Plageman @ 2024-02-13 00:04 UTC (permalink / raw)
BitmapAdjustPrefetchIterator() only used the blockno member of the
passed in TBMIterateResult to ensure that the prefetch iterator and
regular iterator stay in sync. Pass it the BlockNumber only. This will
allow us to move away from using the TBMIterateResult outside of table
AM specific code.
---
src/backend/executor/nodeBitmapHeapscan.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/backend/executor/nodeBitmapHeapscan.c b/src/backend/executor/nodeBitmapHeapscan.c
index 5df3b5ca46..404de0595e 100644
--- a/src/backend/executor/nodeBitmapHeapscan.c
+++ b/src/backend/executor/nodeBitmapHeapscan.c
@@ -52,7 +52,7 @@
static TupleTableSlot *BitmapHeapNext(BitmapHeapScanState *node);
static inline void BitmapDoneInitializingSharedState(ParallelBitmapHeapState *pstate);
static inline void BitmapAdjustPrefetchIterator(BitmapHeapScanState *node,
- TBMIterateResult *tbmres);
+ BlockNumber blockno);
static inline void BitmapAdjustPrefetchTarget(BitmapHeapScanState *node);
static inline void BitmapPrefetch(BitmapHeapScanState *node,
TableScanDesc scan);
@@ -230,7 +230,7 @@ BitmapHeapNext(BitmapHeapScanState *node)
break;
}
- BitmapAdjustPrefetchIterator(node, tbmres);
+ BitmapAdjustPrefetchIterator(node, tbmres->blockno);
valid = table_scan_bitmap_next_block(scan, tbmres);
@@ -341,7 +341,7 @@ BitmapDoneInitializingSharedState(ParallelBitmapHeapState *pstate)
*/
static inline void
BitmapAdjustPrefetchIterator(BitmapHeapScanState *node,
- TBMIterateResult *tbmres)
+ BlockNumber blockno)
{
#ifdef USE_PREFETCH
ParallelBitmapHeapState *pstate = node->pstate;
@@ -360,7 +360,7 @@ BitmapAdjustPrefetchIterator(BitmapHeapScanState *node,
/* Do not let the prefetch iterator get behind the main one */
TBMIterateResult *tbmpre = tbm_iterate(prefetch_iterator);
- if (tbmpre == NULL || tbmpre->blockno != tbmres->blockno)
+ if (tbmpre == NULL || tbmpre->blockno != blockno)
elog(ERROR, "prefetch and main iterators are out of sync");
}
return;
--
2.40.1
--7mdtsjmrzitrgzgx
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
filename="v9-0006-table_scan_bitmap_next_block-returns-lossy-or-exa.patch"
^ permalink raw reply [nested|flat] 37+ messages in thread
* [PATCH v8 05/17] Update BitmapAdjustPrefetchIterator parameter type to BlockNumber
@ 2024-02-13 00:04 Melanie Plageman <[email protected]>
0 siblings, 0 replies; 37+ messages in thread
From: Melanie Plageman @ 2024-02-13 00:04 UTC (permalink / raw)
BitmapAdjustPrefetchIterator() only used the blockno member of the
passed in TBMIterateResult to ensure that the prefetch iterator and
regular iterator stay in sync. Pass it the BlockNumber only. This will
allow us to move away from using the TBMIterateResult outside of table
AM specific code.
---
src/backend/executor/nodeBitmapHeapscan.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/backend/executor/nodeBitmapHeapscan.c b/src/backend/executor/nodeBitmapHeapscan.c
index 5df3b5ca46..404de0595e 100644
--- a/src/backend/executor/nodeBitmapHeapscan.c
+++ b/src/backend/executor/nodeBitmapHeapscan.c
@@ -52,7 +52,7 @@
static TupleTableSlot *BitmapHeapNext(BitmapHeapScanState *node);
static inline void BitmapDoneInitializingSharedState(ParallelBitmapHeapState *pstate);
static inline void BitmapAdjustPrefetchIterator(BitmapHeapScanState *node,
- TBMIterateResult *tbmres);
+ BlockNumber blockno);
static inline void BitmapAdjustPrefetchTarget(BitmapHeapScanState *node);
static inline void BitmapPrefetch(BitmapHeapScanState *node,
TableScanDesc scan);
@@ -230,7 +230,7 @@ BitmapHeapNext(BitmapHeapScanState *node)
break;
}
- BitmapAdjustPrefetchIterator(node, tbmres);
+ BitmapAdjustPrefetchIterator(node, tbmres->blockno);
valid = table_scan_bitmap_next_block(scan, tbmres);
@@ -341,7 +341,7 @@ BitmapDoneInitializingSharedState(ParallelBitmapHeapState *pstate)
*/
static inline void
BitmapAdjustPrefetchIterator(BitmapHeapScanState *node,
- TBMIterateResult *tbmres)
+ BlockNumber blockno)
{
#ifdef USE_PREFETCH
ParallelBitmapHeapState *pstate = node->pstate;
@@ -360,7 +360,7 @@ BitmapAdjustPrefetchIterator(BitmapHeapScanState *node,
/* Do not let the prefetch iterator get behind the main one */
TBMIterateResult *tbmpre = tbm_iterate(prefetch_iterator);
- if (tbmpre == NULL || tbmpre->blockno != tbmres->blockno)
+ if (tbmpre == NULL || tbmpre->blockno != blockno)
elog(ERROR, "prefetch and main iterators are out of sync");
}
return;
--
2.40.1
--xqq4defy3uncu6k6
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
filename="v8-0006-table_scan_bitmap_next_block-returns-lossy-or-exa.patch"
^ permalink raw reply [nested|flat] 37+ messages in thread
* [PATCH v7 05/13] Update BitmapAdjustPrefetchIterator parameter type to BlockNumber
@ 2024-02-13 00:04 Melanie Plageman <[email protected]>
0 siblings, 0 replies; 37+ messages in thread
From: Melanie Plageman @ 2024-02-13 00:04 UTC (permalink / raw)
BitmapAdjustPrefetchIterator() only used the blockno member of the
passed in TBMIterateResult to ensure that the prefetch iterator and
regular iterator stay in sync. Pass it the BlockNumber only. This will
allow us to move away from using the TBMIterateResult outside of table
AM specific code.
---
src/backend/executor/nodeBitmapHeapscan.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/backend/executor/nodeBitmapHeapscan.c b/src/backend/executor/nodeBitmapHeapscan.c
index dc8c312cafb..a6b98fa12a1 100644
--- a/src/backend/executor/nodeBitmapHeapscan.c
+++ b/src/backend/executor/nodeBitmapHeapscan.c
@@ -52,7 +52,7 @@
static TupleTableSlot *BitmapHeapNext(BitmapHeapScanState *node);
static inline void BitmapDoneInitializingSharedState(ParallelBitmapHeapState *pstate);
static inline void BitmapAdjustPrefetchIterator(BitmapHeapScanState *node,
- TBMIterateResult *tbmres);
+ BlockNumber blockno);
static inline void BitmapAdjustPrefetchTarget(BitmapHeapScanState *node);
static inline void BitmapPrefetch(BitmapHeapScanState *node,
TableScanDesc scan);
@@ -230,7 +230,7 @@ BitmapHeapNext(BitmapHeapScanState *node)
break;
}
- BitmapAdjustPrefetchIterator(node, tbmres);
+ BitmapAdjustPrefetchIterator(node, tbmres->blockno);
valid = table_scan_bitmap_next_block(scan, tbmres);
@@ -341,7 +341,7 @@ BitmapDoneInitializingSharedState(ParallelBitmapHeapState *pstate)
*/
static inline void
BitmapAdjustPrefetchIterator(BitmapHeapScanState *node,
- TBMIterateResult *tbmres)
+ BlockNumber blockno)
{
#ifdef USE_PREFETCH
ParallelBitmapHeapState *pstate = node->pstate;
@@ -360,7 +360,7 @@ BitmapAdjustPrefetchIterator(BitmapHeapScanState *node,
/* Do not let the prefetch iterator get behind the main one */
TBMIterateResult *tbmpre = tbm_iterate(prefetch_iterator);
- if (tbmpre == NULL || tbmpre->blockno != tbmres->blockno)
+ if (tbmpre == NULL || tbmpre->blockno != blockno)
elog(ERROR, "prefetch and main iterators are out of sync");
}
return;
--
2.40.1
--kqqpqghcwbcc3dt5
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
filename="v7-0006-table_scan_bitmap_next_block-returns-lossy-or-exa.patch"
^ permalink raw reply [nested|flat] 37+ messages in thread
* Re: per backend WAL statistics
@ 2025-01-15 06:11 Michael Paquier <[email protected]>
0 siblings, 1 reply; 37+ messages in thread
From: Michael Paquier @ 2025-01-15 06:11 UTC (permalink / raw)
To: Bertrand Drouvot <[email protected]>; +Cc: [email protected]
On Fri, Jan 10, 2025 at 09:40:38AM +0000, Bertrand Drouvot wrote:
> Please find attached v4 taking into account 2c14037bb5.
+} PgStat_WalCounters;
+
+typedef struct PgStat_WalStats
+{
+ PgStat_WalCounters wal_counters;
I know that's a nit, but perhaps that could be a patch of its own,
pushing that to pg_stat_wal_build_tuple() to reduce the diffs in the
main patch.
- * Find or create a local PgStat_BackendPending entry for proc number.
+ * Find or create a local PgStat_BackendPendingIO entry for proc number.
Seems like you are undoing a change here.
+ * WAL pending statistics are incremented inside a critical section
+ * (see XLogWrite()), so we can't use pgstat_prep_pending_entry() and we rely on
+ * PendingBackendWalStats instead.
+ */
+extern PGDLLIMPORT PgStat_PendingWalStats PendingBackendWalStats;
Hmm. This makes me wonder if we should rethink a bit the way pending
entries are retrieved and if we should do it beforehand for the WAL
paths to avoid allocations in some critical sections. Isn't that also
because we avoid calling pgstat_prep_backend_pending() for the I/O
case as only backends are supported now, discarding cases like the
checkpointer where I/O could happen in a critical path? As a whole,
the approach taken by the patch is not really consistent with the
rest.
--
Michael
Attachments:
[application/pgp-signature] signature.asc (833B, ../../[email protected]/2-signature.asc)
download
^ permalink raw reply [nested|flat] 37+ messages in thread
* Re: per backend WAL statistics
@ 2025-01-16 15:59 Bertrand Drouvot <[email protected]>
parent: Michael Paquier <[email protected]>
0 siblings, 1 reply; 37+ messages in thread
From: Bertrand Drouvot @ 2025-01-16 15:59 UTC (permalink / raw)
To: Michael Paquier <[email protected]>; +Cc: [email protected]
Hi,
On Wed, Jan 15, 2025 at 03:11:32PM +0900, Michael Paquier wrote:
> On Fri, Jan 10, 2025 at 09:40:38AM +0000, Bertrand Drouvot wrote:
> > Please find attached v4 taking into account 2c14037bb5.
>
> +} PgStat_WalCounters;
> +
> +typedef struct PgStat_WalStats
> +{
> + PgStat_WalCounters wal_counters;
>
> I know that's a nit, but perhaps that could be a patch of its own,
> pushing that to pg_stat_wal_build_tuple() to reduce the diffs in the
> main patch.
Done in 0003 attached.
> - * Find or create a local PgStat_BackendPending entry for proc number.
> + * Find or create a local PgStat_BackendPendingIO entry for proc number.
>
> Seems like you are undoing a change here.
Arf, nice catch, hopefully that's only the comment.. Fixed in the attached.
> + * WAL pending statistics are incremented inside a critical section
> + * (see XLogWrite()), so we can't use pgstat_prep_pending_entry() and we rely on
> + * PendingBackendWalStats instead.
> + */
> +extern PGDLLIMPORT PgStat_PendingWalStats PendingBackendWalStats;
>
> Hmm. This makes me wonder if we should rethink a bit the way pending
> entries are retrieved and if we should do it beforehand for the WAL
> paths to avoid allocations in some critical sections. Isn't that also
> because we avoid calling pgstat_prep_backend_pending() for the I/O
> case as only backends are supported now, discarding cases like the
> checkpointer where I/O could happen in a critical path? As a whole,
> the approach taken by the patch is not really consistent with the
> rest.
I agree that's better to have a generic solution and to be consistent with
the other variable-numbered stats.
The attached is implementing in 0001 the proposition done in [1], i.e:
1. It adds a new allow_critical_section to PgStat_KindInfo for pgstats kinds
2. It ensures to set temporarly allowInCritSection to true when needed
Note that for safety reason 0001 does set allowInCritSection back to false
unconditionally (means not checking again for allow_critical_section).
While it avoids the failed assertion mentioned above and in [1] (on
the MemoryContextAllocZero() call), the TAP tests are still failing with a new
failed assertion.
If you apply the whole patch series attached, you'll see that:
make -C src/bin/pg_rewind check PROVE_TESTS=t/001_basic.pl
is failing with something like:
TRAP: failed Assert("CritSectionCount == 0"), File: "mcxt.c", Line: 1107, PID: 3295726
pg18/bin/postgres(ExceptionalCondition+0xbb)[0x59668bee1f6d]
pg18/bin/postgres(MemoryContextCreate+0x46)[0x59668bf2a8fe]
pg18/bin/postgres(AllocSetContextCreateInternal+0x1df)[0x59668bf1bb11]
pg18/bin/postgres(pgstat_prep_pending_entry+0x86)[0x59668bcff8cc]
pg18/bin/postgres(pgstat_prep_backend_pending+0x2b)[0x59668bd024a9]
This one is more problematic because we are in MemoryContextCreate() so that the
"workaround" above does not help. I need to put more thoughts on it but already
sharing the issue here (as also discussed in [1]).
[1]: https://www.postgresql.org/message-id/Z4d_eggsxtBEdJAG%40paquier.xyz
Regards,
--
Bertrand Drouvot
PostgreSQL Contributors Team
RDS Open Source Databases
Amazon Web Services: https://aws.amazon.com
Attachments:
[text/x-diff] v5-0001-Add-allow_critical_section-to-PgStat_KindInfo-for.patch (6.2K, ../../[email protected]/2-v5-0001-Add-allow_critical_section-to-PgStat_KindInfo-for.patch)
download | inline diff:
From 327160f7f96bcdc1c3779d25bb0228f25a4c2504 Mon Sep 17 00:00:00 2001
From: Bertrand Drouvot <[email protected]>
Date: Thu, 16 Jan 2025 08:51:09 +0000
Subject: [PATCH v5 1/4] Add allow_critical_section to PgStat_KindInfo for
pgstats kinds
This new field controls if a variable-numbered stats kind is allowed
to allocate memory in contexts while in a critical section.
Allocating memory in contexts while in a critical section isn't usually allowed,
but we make an exception.
It means that there's a theoretical possibility to run out of memory while
allocating the memory, which leads to a PANIC.
The memory allocation here are small (pending entries or entry reference) so
that's unlikely to happen in practice.
This is useful for a following commit that will track WAL statistics while in
a critical section (while in XLogWrite() for example).
---
src/backend/utils/activity/pgstat.c | 19 +++++++++++++++++++
src/backend/utils/activity/pgstat_shmem.c | 13 +++++++++++++
src/include/utils/pgstat_internal.h | 3 +++
.../injection_points/injection_stats.c | 1 +
4 files changed, 36 insertions(+)
89.9% src/backend/utils/activity/
7.6% src/include/utils/
diff --git a/src/backend/utils/activity/pgstat.c b/src/backend/utils/activity/pgstat.c
index 34520535d54..a942e04bb97 100644
--- a/src/backend/utils/activity/pgstat.c
+++ b/src/backend/utils/activity/pgstat.c
@@ -284,6 +284,7 @@ static const PgStat_KindInfo pgstat_kind_builtin_infos[PGSTAT_KIND_BUILTIN_SIZE]
.fixed_amount = false,
.write_to_file = true,
+ .allow_critical_section = false,
/* so pg_stat_database entries can be seen in all databases */
.accessed_across_databases = true,
@@ -301,6 +302,7 @@ static const PgStat_KindInfo pgstat_kind_builtin_infos[PGSTAT_KIND_BUILTIN_SIZE]
.fixed_amount = false,
.write_to_file = true,
+ .allow_critical_section = false,
.shared_size = sizeof(PgStatShared_Relation),
.shared_data_off = offsetof(PgStatShared_Relation, stats),
@@ -316,6 +318,7 @@ static const PgStat_KindInfo pgstat_kind_builtin_infos[PGSTAT_KIND_BUILTIN_SIZE]
.fixed_amount = false,
.write_to_file = true,
+ .allow_critical_section = false,
.shared_size = sizeof(PgStatShared_Function),
.shared_data_off = offsetof(PgStatShared_Function, stats),
@@ -330,6 +333,7 @@ static const PgStat_KindInfo pgstat_kind_builtin_infos[PGSTAT_KIND_BUILTIN_SIZE]
.fixed_amount = false,
.write_to_file = true,
+ .allow_critical_section = false,
.accessed_across_databases = true,
@@ -347,6 +351,7 @@ static const PgStat_KindInfo pgstat_kind_builtin_infos[PGSTAT_KIND_BUILTIN_SIZE]
.fixed_amount = false,
.write_to_file = true,
+ .allow_critical_section = false,
/* so pg_stat_subscription_stats entries can be seen in all databases */
.accessed_across_databases = true,
@@ -364,6 +369,7 @@ static const PgStat_KindInfo pgstat_kind_builtin_infos[PGSTAT_KIND_BUILTIN_SIZE]
.fixed_amount = false,
.write_to_file = false,
+ .allow_critical_section = false,
.accessed_across_databases = true,
@@ -1316,7 +1322,20 @@ pgstat_prep_pending_entry(PgStat_Kind kind, Oid dboid, uint64 objid, bool *creat
Assert(entrysize != (size_t) -1);
+ /*
+ * That could be done within a critical section, which isn't usually
+ * allowed, but we make an exception. It means that there's a
+ * theoretical possibility that you run out of memory while preparing
+ * the entry, which leads to a PANIC. Fortunately the pending entry is
+ * small so that's unlikely to happen in practice.
+ */
+ if (pgstat_get_kind_info(kind)->allow_critical_section)
+ MemoryContextAllowInCriticalSection(pgStatPendingContext, true);
+
entry_ref->pending = MemoryContextAllocZero(pgStatPendingContext, entrysize);
+
+ MemoryContextAllowInCriticalSection(pgStatPendingContext, false);
+
dlist_push_tail(&pgStatPending, &entry_ref->pending_node);
}
diff --git a/src/backend/utils/activity/pgstat_shmem.c b/src/backend/utils/activity/pgstat_shmem.c
index 342586397d6..cb1ad330bd4 100644
--- a/src/backend/utils/activity/pgstat_shmem.c
+++ b/src/backend/utils/activity/pgstat_shmem.c
@@ -402,9 +402,22 @@ pgstat_get_entry_ref_cached(PgStat_HashKey key, PgStat_EntryRef **entry_ref_p)
{
PgStat_EntryRef *entry_ref;
+ /*
+ * That could be done within a critical section, which isn't usually
+ * allowed, but we make an exception. It means that there's a
+ * theoretical possibility that you run out of memory while creating
+ * the entry ref, which leads to a PANIC. Fortunately the pending
+ * entry is small so that's unlikely to happen in practice.
+ */
+ if (pgstat_get_kind_info(key.kind)->allow_critical_section)
+ MemoryContextAllowInCriticalSection(pgStatSharedRefContext, true);
+
cache_entry->entry_ref = entry_ref =
MemoryContextAlloc(pgStatSharedRefContext,
sizeof(PgStat_EntryRef));
+
+ MemoryContextAllowInCriticalSection(pgStatSharedRefContext, false);
+
entry_ref->shared_stats = NULL;
entry_ref->shared_entry = NULL;
entry_ref->pending = NULL;
diff --git a/src/include/utils/pgstat_internal.h b/src/include/utils/pgstat_internal.h
index 4bb8e5c53ab..0b21603c863 100644
--- a/src/include/utils/pgstat_internal.h
+++ b/src/include/utils/pgstat_internal.h
@@ -216,6 +216,9 @@ typedef struct PgStat_KindInfo
/* Should stats be written to the on-disk stats file? */
bool write_to_file:1;
+ /* For variable-numbered stats: allow memory context in critical section */
+ bool allow_critical_section:1;
+
/*
* The size of an entry in the shared stats hash table (pointed to by
* PgStatShared_HashEntry->body). For fixed-numbered statistics, this is
diff --git a/src/test/modules/injection_points/injection_stats.c b/src/test/modules/injection_points/injection_stats.c
index 5db62bca66f..873dc88aace 100644
--- a/src/test/modules/injection_points/injection_stats.c
+++ b/src/test/modules/injection_points/injection_stats.c
@@ -40,6 +40,7 @@ static const PgStat_KindInfo injection_stats = {
.name = "injection_points",
.fixed_amount = false, /* Bounded by the number of points */
.write_to_file = true,
+ .allow_critical_section = false,
/* Injection points are system-wide */
.accessed_across_databases = true,
--
2.34.1
[text/x-diff] v5-0002-Extract-logic-filling-pg_stat_get_wal-s-tuple-int.patch (3.9K, ../../[email protected]/3-v5-0002-Extract-logic-filling-pg_stat_get_wal-s-tuple-int.patch)
download | inline diff:
From 0ff81e01d4292e575270a4bd380ebb0505c57e11 Mon Sep 17 00:00:00 2001
From: Bertrand Drouvot <[email protected]>
Date: Mon, 6 Jan 2025 07:51:27 +0000
Subject: [PATCH v5 2/4] Extract logic filling pg_stat_get_wal()'s tuple into
its own routine
This commit adds pg_stat_wal_build_tuple(), a helper routine for
pg_stat_get_wal(), that fills its tuple based on the contents
of PgStat_WalStats. This will be used in a follow-up commit that uses
the same structures as pg_stat_wal for reporting, but for the PGSTAT_KIND_BACKEND
statistics kind.
---
src/backend/utils/adt/pgstatfuncs.c | 56 ++++++++++++++++++-----------
1 file changed, 36 insertions(+), 20 deletions(-)
100.0% src/backend/utils/adt/
diff --git a/src/backend/utils/adt/pgstatfuncs.c b/src/backend/utils/adt/pgstatfuncs.c
index 0f5e0a9778d..0442be03304 100644
--- a/src/backend/utils/adt/pgstatfuncs.c
+++ b/src/backend/utils/adt/pgstatfuncs.c
@@ -1604,20 +1604,22 @@ pg_stat_get_backend_io(PG_FUNCTION_ARGS)
}
/*
- * Returns statistics of WAL activity
+ * pg_stat_wal_build_tuple
+ *
+ * Helper routine for pg_stat_get_wal() returning one tuple based on the contents
+ * of wal_stats.
*/
-Datum
-pg_stat_get_wal(PG_FUNCTION_ARGS)
+static Datum
+pg_stat_wal_build_tuple(PgStat_WalStats wal_stats)
{
-#define PG_STAT_GET_WAL_COLS 9
+#define PG_STAT_WAL_COLS 9
TupleDesc tupdesc;
- Datum values[PG_STAT_GET_WAL_COLS] = {0};
- bool nulls[PG_STAT_GET_WAL_COLS] = {0};
+ Datum values[PG_STAT_WAL_COLS] = {0};
+ bool nulls[PG_STAT_WAL_COLS] = {0};
char buf[256];
- PgStat_WalStats *wal_stats;
/* Initialise attributes information in the tuple descriptor */
- tupdesc = CreateTemplateTupleDesc(PG_STAT_GET_WAL_COLS);
+ tupdesc = CreateTemplateTupleDesc(PG_STAT_WAL_COLS);
TupleDescInitEntry(tupdesc, (AttrNumber) 1, "wal_records",
INT8OID, -1, 0);
TupleDescInitEntry(tupdesc, (AttrNumber) 2, "wal_fpi",
@@ -1639,34 +1641,48 @@ pg_stat_get_wal(PG_FUNCTION_ARGS)
BlessTupleDesc(tupdesc);
- /* Get statistics about WAL activity */
- wal_stats = pgstat_fetch_stat_wal();
-
/* Fill values and NULLs */
- values[0] = Int64GetDatum(wal_stats->wal_records);
- values[1] = Int64GetDatum(wal_stats->wal_fpi);
+ values[0] = Int64GetDatum(wal_stats.wal_records);
+ values[1] = Int64GetDatum(wal_stats.wal_fpi);
/* Convert to numeric. */
- snprintf(buf, sizeof buf, UINT64_FORMAT, wal_stats->wal_bytes);
+ snprintf(buf, sizeof buf, UINT64_FORMAT, wal_stats.wal_bytes);
values[2] = DirectFunctionCall3(numeric_in,
CStringGetDatum(buf),
ObjectIdGetDatum(0),
Int32GetDatum(-1));
- values[3] = Int64GetDatum(wal_stats->wal_buffers_full);
- values[4] = Int64GetDatum(wal_stats->wal_write);
- values[5] = Int64GetDatum(wal_stats->wal_sync);
+ values[3] = Int64GetDatum(wal_stats.wal_buffers_full);
+ values[4] = Int64GetDatum(wal_stats.wal_write);
+ values[5] = Int64GetDatum(wal_stats.wal_sync);
/* Convert counters from microsec to millisec for display */
- values[6] = Float8GetDatum(((double) wal_stats->wal_write_time) / 1000.0);
- values[7] = Float8GetDatum(((double) wal_stats->wal_sync_time) / 1000.0);
+ values[6] = Float8GetDatum(((double) wal_stats.wal_write_time) / 1000.0);
+ values[7] = Float8GetDatum(((double) wal_stats.wal_sync_time) / 1000.0);
- values[8] = TimestampTzGetDatum(wal_stats->stat_reset_timestamp);
+ if (wal_stats.stat_reset_timestamp != 0)
+ values[8] = TimestampTzGetDatum(wal_stats.stat_reset_timestamp);
+ else
+ nulls[8] = true;
/* Returns the record as Datum */
PG_RETURN_DATUM(HeapTupleGetDatum(heap_form_tuple(tupdesc, values, nulls)));
}
+/*
+ * Returns statistics of WAL activity
+ */
+Datum
+pg_stat_get_wal(PG_FUNCTION_ARGS)
+{
+ PgStat_WalStats *wal_stats;
+
+ /* Get statistics about WAL activity */
+ wal_stats = pgstat_fetch_stat_wal();
+
+ return (pg_stat_wal_build_tuple(*wal_stats));
+}
+
/*
* Returns statistics of SLRU caches.
*/
--
2.34.1
[text/x-diff] v5-0003-Adding-a-new-PgStat_WalCounters-struct.patch (5.0K, ../../[email protected]/4-v5-0003-Adding-a-new-PgStat_WalCounters-struct.patch)
download | inline diff:
From 383d186b1699ac74a53f2fea85ced5abc10cd558 Mon Sep 17 00:00:00 2001
From: Bertrand Drouvot <[email protected]>
Date: Thu, 16 Jan 2025 15:06:01 +0000
Subject: [PATCH v5 3/4] Adding a new PgStat_WalCounters struct
This new struct contains only the counters related to the WAL statistics.
This will be used in a follow-up commit that uses the same structures but
for the PGSTAT_KIND_BACKEND statistics kind.
---
src/backend/utils/activity/pgstat_wal.c | 4 ++--
src/backend/utils/adt/pgstatfuncs.c | 28 +++++++++++++------------
src/include/pgstat.h | 7 ++++++-
src/tools/pgindent/typedefs.list | 1 +
4 files changed, 24 insertions(+), 16 deletions(-)
14.1% src/backend/utils/activity/
79.8% src/backend/utils/adt/
5.0% src/include/
diff --git a/src/backend/utils/activity/pgstat_wal.c b/src/backend/utils/activity/pgstat_wal.c
index 18fa6b2936a..bfc06178a68 100644
--- a/src/backend/utils/activity/pgstat_wal.c
+++ b/src/backend/utils/activity/pgstat_wal.c
@@ -117,9 +117,9 @@ pgstat_wal_flush_cb(bool nowait)
return true;
#define WALSTAT_ACC(fld, var_to_add) \
- (stats_shmem->stats.fld += var_to_add.fld)
+ (stats_shmem->stats.wal_counters.fld += var_to_add.fld)
#define WALSTAT_ACC_INSTR_TIME(fld) \
- (stats_shmem->stats.fld += INSTR_TIME_GET_MICROSEC(PendingWalStats.fld))
+ (stats_shmem->stats.wal_counters.fld += INSTR_TIME_GET_MICROSEC(PendingWalStats.fld))
WALSTAT_ACC(wal_records, wal_usage_diff);
WALSTAT_ACC(wal_fpi, wal_usage_diff);
WALSTAT_ACC(wal_bytes, wal_usage_diff);
diff --git a/src/backend/utils/adt/pgstatfuncs.c b/src/backend/utils/adt/pgstatfuncs.c
index 0442be03304..97510d48eef 100644
--- a/src/backend/utils/adt/pgstatfuncs.c
+++ b/src/backend/utils/adt/pgstatfuncs.c
@@ -1607,10 +1607,11 @@ pg_stat_get_backend_io(PG_FUNCTION_ARGS)
* pg_stat_wal_build_tuple
*
* Helper routine for pg_stat_get_wal() returning one tuple based on the contents
- * of wal_stats.
+ * of wal_counters.
*/
static Datum
-pg_stat_wal_build_tuple(PgStat_WalStats wal_stats)
+pg_stat_wal_build_tuple(PgStat_WalCounters wal_counters,
+ TimestampTz stat_reset_timestamp)
{
#define PG_STAT_WAL_COLS 9
TupleDesc tupdesc;
@@ -1642,26 +1643,26 @@ pg_stat_wal_build_tuple(PgStat_WalStats wal_stats)
BlessTupleDesc(tupdesc);
/* Fill values and NULLs */
- values[0] = Int64GetDatum(wal_stats.wal_records);
- values[1] = Int64GetDatum(wal_stats.wal_fpi);
+ values[0] = Int64GetDatum(wal_counters.wal_records);
+ values[1] = Int64GetDatum(wal_counters.wal_fpi);
/* Convert to numeric. */
- snprintf(buf, sizeof buf, UINT64_FORMAT, wal_stats.wal_bytes);
+ snprintf(buf, sizeof buf, UINT64_FORMAT, wal_counters.wal_bytes);
values[2] = DirectFunctionCall3(numeric_in,
CStringGetDatum(buf),
ObjectIdGetDatum(0),
Int32GetDatum(-1));
- values[3] = Int64GetDatum(wal_stats.wal_buffers_full);
- values[4] = Int64GetDatum(wal_stats.wal_write);
- values[5] = Int64GetDatum(wal_stats.wal_sync);
+ values[3] = Int64GetDatum(wal_counters.wal_buffers_full);
+ values[4] = Int64GetDatum(wal_counters.wal_write);
+ values[5] = Int64GetDatum(wal_counters.wal_sync);
/* Convert counters from microsec to millisec for display */
- values[6] = Float8GetDatum(((double) wal_stats.wal_write_time) / 1000.0);
- values[7] = Float8GetDatum(((double) wal_stats.wal_sync_time) / 1000.0);
+ values[6] = Float8GetDatum(((double) wal_counters.wal_write_time) / 1000.0);
+ values[7] = Float8GetDatum(((double) wal_counters.wal_sync_time) / 1000.0);
- if (wal_stats.stat_reset_timestamp != 0)
- values[8] = TimestampTzGetDatum(wal_stats.stat_reset_timestamp);
+ if (stat_reset_timestamp != 0)
+ values[8] = TimestampTzGetDatum(stat_reset_timestamp);
else
nulls[8] = true;
@@ -1680,7 +1681,8 @@ pg_stat_get_wal(PG_FUNCTION_ARGS)
/* Get statistics about WAL activity */
wal_stats = pgstat_fetch_stat_wal();
- return (pg_stat_wal_build_tuple(*wal_stats));
+ return (pg_stat_wal_build_tuple(wal_stats->wal_counters,
+ wal_stats->stat_reset_timestamp));
}
/*
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index a878402f502..bb8e0044a47 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -463,7 +463,7 @@ typedef struct PgStat_StatTabEntry
PgStat_Counter autoanalyze_count;
} PgStat_StatTabEntry;
-typedef struct PgStat_WalStats
+typedef struct PgStat_WalCounters
{
PgStat_Counter wal_records;
PgStat_Counter wal_fpi;
@@ -473,6 +473,11 @@ typedef struct PgStat_WalStats
PgStat_Counter wal_sync;
PgStat_Counter wal_write_time;
PgStat_Counter wal_sync_time;
+} PgStat_WalCounters;
+
+typedef struct PgStat_WalStats
+{
+ PgStat_WalCounters wal_counters;
TimestampTz stat_reset_timestamp;
} PgStat_WalStats;
diff --git a/src/tools/pgindent/typedefs.list b/src/tools/pgindent/typedefs.list
index 94dc956ae8c..d8b6623ba9c 100644
--- a/src/tools/pgindent/typedefs.list
+++ b/src/tools/pgindent/typedefs.list
@@ -2176,6 +2176,7 @@ PgStat_SubXactStatus
PgStat_TableCounts
PgStat_TableStatus
PgStat_TableXactStatus
+PgStat_WalCounters
PgStat_WalStats
PgXmlErrorContext
PgXmlStrictness
--
2.34.1
[text/x-diff] v5-0004-per-backend-WAL-statistics.patch (18.6K, ../../[email protected]/5-v5-0004-per-backend-WAL-statistics.patch)
download | inline diff:
From 094bc124baea085a721f0013da290f3b92f96607 Mon Sep 17 00:00:00 2001
From: Bertrand Drouvot <[email protected]>
Date: Mon, 6 Jan 2025 10:00:00 +0000
Subject: [PATCH v5 4/4] per backend WAL statistics
Now that commit 9aea73fc61 added backend-level statistics to pgstats (and
per backend IO statistics) we can more easily add per backend statistics.
This commit adds per backend WAL statistics using the same layer as pg_stat_wal,
except that it is now possible to know how much WAL activity is happening in each
backend rather than an overall aggregate of all the activity. A function called
pg_stat_get_backend_wal() is added to access this data depending on the
PID of a backend.
Note that allow_critical_section has been enabled for the PGSTAT_KIND_BACKEND
stats kind as we are now tracking variable-numbered stats in critical section(s)
(XLogWrite() for example).
The same limitation as in 9aea73fc61 persists, meaning that Auxiliary processes
are not included in this set of statistics.
XXX: bump catalog version
---
doc/src/sgml/config.sgml | 4 +-
doc/src/sgml/monitoring.sgml | 19 +++++++
src/backend/access/transam/xlog.c | 44 +++++++++++++--
src/backend/utils/activity/pgstat.c | 2 +-
src/backend/utils/activity/pgstat_backend.c | 59 +++++++++++++++++++++
src/backend/utils/activity/pgstat_wal.c | 2 +
src/backend/utils/adt/pgstatfuncs.c | 53 +++++++++++++++++-
src/include/catalog/pg_proc.dat | 7 +++
src/include/pgstat.h | 43 ++++++++-------
src/include/utils/pgstat_internal.h | 3 +-
src/test/regress/expected/stats.out | 14 +++++
src/test/regress/sql/stats.sql | 6 +++
12 files changed, 227 insertions(+), 29 deletions(-)
14.2% doc/src/sgml/
14.9% src/backend/access/transam/
28.8% src/backend/utils/activity/
19.7% src/backend/utils/adt/
7.0% src/include/catalog/
5.1% src/include/
5.6% src/test/regress/expected/
4.3% src/test/regress/sql/
diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
index 3f41a17b1fe..075cb4fe1a8 100644
--- a/doc/src/sgml/config.sgml
+++ b/doc/src/sgml/config.sgml
@@ -8292,7 +8292,9 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv;
measure the overhead of timing on your system.
I/O timing information is
displayed in <link linkend="monitoring-pg-stat-wal-view">
- <structname>pg_stat_wal</structname></link>.
+ <structname>pg_stat_wal</structname></link> and in the output of the
+ <link linkend="pg-stat-get-backend-wal">
+ <function>pg_stat_get_backend_wal()</function></link> function.
Only superusers and users with the appropriate <literal>SET</literal>
privilege can change this setting.
</para>
diff --git a/doc/src/sgml/monitoring.sgml b/doc/src/sgml/monitoring.sgml
index e5888fae2b5..8fdf7d13f21 100644
--- a/doc/src/sgml/monitoring.sgml
+++ b/doc/src/sgml/monitoring.sgml
@@ -4824,6 +4824,25 @@ description | Waiting for a newly initialized WAL file to reach durable storage
</para></entry>
</row>
+ <row>
+ <entry id="pg-stat-get-backend-wal" role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_stat_get_backend_wal</primary>
+ </indexterm>
+ <function>pg_stat_get_backend_wal</function> ( <type>integer</type> )
+ <returnvalue>record</returnvalue>
+ </para>
+ <para>
+ Returns WAL statistics about the backend with the specified
+ process ID. The output fields are exactly the same as the ones in the
+ <structname>pg_stat_wal</structname> view.
+ </para>
+ <para>
+ The function does not return WAL statistics for the checkpointer,
+ the background writer, the startup process and the autovacuum launcher.
+ </para></entry>
+ </row>
+
<row>
<entry role="func_table_entry"><para role="func_signature">
<indexterm>
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index bf3dbda901d..d09a079bcbb 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -96,6 +96,7 @@
#include "utils/guc_hooks.h"
#include "utils/guc_tables.h"
#include "utils/injection_point.h"
+#include "utils/pgstat_internal.h"
#include "utils/ps_status.h"
#include "utils/relmapper.h"
#include "utils/snapmgr.h"
@@ -2058,6 +2059,15 @@ AdvanceXLInsertBuffer(XLogRecPtr upto, TimeLineID tli, bool opportunistic)
XLogWrite(WriteRqst, tli, false);
LWLockRelease(WALWriteLock);
PendingWalStats.wal_buffers_full++;
+
+ if (pgstat_tracks_backend_bktype(MyBackendType))
+ {
+ PgStat_BackendPending *entry_ref;
+
+ entry_ref = pgstat_prep_backend_pending(MyProcNumber);
+ entry_ref->pending_wal.wal_buffers_full++;
+ }
+
TRACE_POSTGRESQL_WAL_BUFFER_WRITE_DIRTY_DONE();
}
/* Re-acquire WALBufMappingLock and retry */
@@ -2426,11 +2436,14 @@ XLogWrite(XLogwrtRqst WriteRqst, TimeLineID tli, bool flexible)
Size nleft;
ssize_t written;
instr_time start;
+ instr_time end;
/* OK to write the page(s) */
from = XLogCtl->pages + startidx * (Size) XLOG_BLCKSZ;
nbytes = npages * (Size) XLOG_BLCKSZ;
nleft = nbytes;
+ /* keep compiler quiet */
+ INSTR_TIME_SET_ZERO(end);
do
{
errno = 0;
@@ -2451,14 +2464,24 @@ XLogWrite(XLogwrtRqst WriteRqst, TimeLineID tli, bool flexible)
*/
if (track_wal_io_timing)
{
- instr_time end;
-
INSTR_TIME_SET_CURRENT(end);
INSTR_TIME_ACCUM_DIFF(PendingWalStats.wal_write_time, end, start);
}
PendingWalStats.wal_write++;
+ if (pgstat_tracks_backend_bktype(MyBackendType))
+ {
+ PgStat_BackendPending *entry_ref;
+
+ entry_ref = pgstat_prep_backend_pending(MyProcNumber);
+ entry_ref->pending_wal.wal_write++;
+
+ if (track_wal_io_timing)
+ INSTR_TIME_ACCUM_DIFF(entry_ref->pending_wal.wal_write_time,
+ end, start);
+ }
+
if (written <= 0)
{
char xlogfname[MAXFNAMELEN];
@@ -8684,8 +8707,11 @@ issue_xlog_fsync(int fd, XLogSegNo segno, TimeLineID tli)
{
char *msg = NULL;
instr_time start;
+ instr_time end;
Assert(tli != 0);
+ /* keep compiler quiet */
+ INSTR_TIME_SET_ZERO(end);
/*
* Quick exit if fsync is disabled or write() has already synced the WAL
@@ -8751,13 +8777,23 @@ issue_xlog_fsync(int fd, XLogSegNo segno, TimeLineID tli)
*/
if (track_wal_io_timing)
{
- instr_time end;
-
INSTR_TIME_SET_CURRENT(end);
INSTR_TIME_ACCUM_DIFF(PendingWalStats.wal_sync_time, end, start);
}
PendingWalStats.wal_sync++;
+
+ if (pgstat_tracks_backend_bktype(MyBackendType))
+ {
+ PgStat_BackendPending *entry_ref;
+
+ entry_ref = pgstat_prep_backend_pending(MyProcNumber);
+ entry_ref->pending_wal.wal_sync++;
+
+ if (track_wal_io_timing)
+ INSTR_TIME_ACCUM_DIFF(entry_ref->pending_wal.wal_sync_time,
+ end, start);
+ }
}
/*
diff --git a/src/backend/utils/activity/pgstat.c b/src/backend/utils/activity/pgstat.c
index a942e04bb97..65b2f687816 100644
--- a/src/backend/utils/activity/pgstat.c
+++ b/src/backend/utils/activity/pgstat.c
@@ -369,7 +369,7 @@ static const PgStat_KindInfo pgstat_kind_builtin_infos[PGSTAT_KIND_BUILTIN_SIZE]
.fixed_amount = false,
.write_to_file = false,
- .allow_critical_section = false,
+ .allow_critical_section = true,
.accessed_across_databases = true,
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index 79e4d0a3053..94762b12f8d 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -24,6 +24,14 @@
#include "utils/pgstat_internal.h"
+/*
+ * WAL usage counters saved from pgWalUsage at the previous call to
+ * pgstat_report_wal(). This is used to calculate how much WAL usage
+ * happens between pgstat_report_wal() calls, by subtracting
+ * the previous counters from the current ones.
+ */
+static WalUsage prevBackendWalUsage;
+
/*
* Returns statistics of a backend by proc number.
*/
@@ -77,6 +85,52 @@ pgstat_flush_backend_entry_io(PgStat_EntryRef *entry_ref)
}
}
+/*
+ * Flush out locally pending backend WAL statistics. Locking is managed
+ * by the caller.
+ */
+static void
+pgstat_flush_backend_entry_wal(PgStat_EntryRef *entry_ref)
+{
+ PgStatShared_Backend *shbackendent;
+ PgStat_BackendPending *pendingent;
+ PgStat_WalCounters *bktype_shstats;
+ PgStat_PendingWalStats pending_wal;
+ WalUsage wal_usage_diff = {0};
+
+ shbackendent = (PgStatShared_Backend *) entry_ref->shared_stats;
+ pendingent = (PgStat_BackendPending *) entry_ref->pending;
+ bktype_shstats = &shbackendent->stats.wal_stats;
+ pending_wal = pendingent->pending_wal;
+
+ /*
+ * We don't update the WAL usage portion of the local WalStats elsewhere.
+ * Calculate how much WAL usage counters were increased by subtracting the
+ * previous counters from the current ones.
+ */
+ WalUsageAccumDiff(&wal_usage_diff, &pgWalUsage, &prevBackendWalUsage);
+
+#define WALSTAT_ACC(fld, var_to_add) \
+ (bktype_shstats->fld += var_to_add.fld)
+#define WALSTAT_ACC_INSTR_TIME(fld) \
+ (bktype_shstats->fld += INSTR_TIME_GET_MICROSEC(pending_wal.fld))
+ WALSTAT_ACC(wal_buffers_full, pending_wal);
+ WALSTAT_ACC(wal_write, pending_wal);
+ WALSTAT_ACC(wal_sync, pending_wal);
+ WALSTAT_ACC(wal_records, wal_usage_diff);
+ WALSTAT_ACC(wal_fpi, wal_usage_diff);
+ WALSTAT_ACC(wal_bytes, wal_usage_diff);
+ WALSTAT_ACC_INSTR_TIME(wal_write_time);
+ WALSTAT_ACC_INSTR_TIME(wal_sync_time);
+#undef WALSTAT_ACC_INSTR_TIME
+#undef WALSTAT_ACC
+
+ /*
+ * Save the current counters for the subsequent calculation of WAL usage.
+ */
+ prevBackendWalUsage = pgWalUsage;
+}
+
/*
* Wrapper routine to flush backend statistics.
*/
@@ -94,6 +148,9 @@ pgstat_flush_backend_entry(PgStat_EntryRef *entry_ref, bool nowait,
if (flags & PGSTAT_BACKEND_FLUSH_IO)
pgstat_flush_backend_entry_io(entry_ref);
+ if (flags & PGSTAT_BACKEND_FLUSH_WAL)
+ pgstat_flush_backend_entry_wal(entry_ref);
+
pgstat_unlock_entry(entry_ref);
return true;
@@ -147,6 +204,8 @@ pgstat_create_backend(ProcNumber procnum)
* e.g. if we previously used this proc number.
*/
memset(&shstatent->stats, 0, sizeof(shstatent->stats));
+
+ prevBackendWalUsage = pgWalUsage;
}
/*
diff --git a/src/backend/utils/activity/pgstat_wal.c b/src/backend/utils/activity/pgstat_wal.c
index bfc06178a68..33627642261 100644
--- a/src/backend/utils/activity/pgstat_wal.c
+++ b/src/backend/utils/activity/pgstat_wal.c
@@ -55,6 +55,8 @@ pgstat_report_wal(bool force)
/* flush wal stats */
pgstat_flush_wal(nowait);
+ pgstat_flush_backend(nowait, PGSTAT_BACKEND_FLUSH_WAL);
+
/* flush IO stats */
pgstat_flush_io(nowait);
}
diff --git a/src/backend/utils/adt/pgstatfuncs.c b/src/backend/utils/adt/pgstatfuncs.c
index 97510d48eef..52bfda4f923 100644
--- a/src/backend/utils/adt/pgstatfuncs.c
+++ b/src/backend/utils/adt/pgstatfuncs.c
@@ -1606,8 +1606,8 @@ pg_stat_get_backend_io(PG_FUNCTION_ARGS)
/*
* pg_stat_wal_build_tuple
*
- * Helper routine for pg_stat_get_wal() returning one tuple based on the contents
- * of wal_counters.
+ * Helper routine for pg_stat_get_wal() and pg_stat_get_backend_wal () returning
+ * one tuple based on the contents of wal_counters.
*/
static Datum
pg_stat_wal_build_tuple(PgStat_WalCounters wal_counters,
@@ -1670,6 +1670,55 @@ pg_stat_wal_build_tuple(PgStat_WalCounters wal_counters,
PG_RETURN_DATUM(HeapTupleGetDatum(heap_form_tuple(tupdesc, values, nulls)));
}
+/*
+ * Returns WAL statistics for a backend with given PID.
+ */
+Datum
+pg_stat_get_backend_wal(PG_FUNCTION_ARGS)
+{
+ int pid;
+ PGPROC *proc;
+ ProcNumber procNumber;
+ PgStat_Backend *backend_stats;
+ PgStat_WalCounters bktype_stats;
+ PgBackendStatus *beentry;
+
+ pid = PG_GETARG_INT32(0);
+ proc = BackendPidGetProc(pid);
+
+ /*
+ * This could be an auxiliary process but these do not report backend
+ * statistics due to pgstat_tracks_backend_bktype(), so there is no need
+ * for an extra call to AuxiliaryPidGetProc().
+ */
+ if (!proc)
+ PG_RETURN_NULL();
+
+ procNumber = GetNumberFromPGProc(proc);
+
+ beentry = pgstat_get_beentry_by_proc_number(procNumber);
+ if (!beentry)
+ PG_RETURN_NULL();
+
+ backend_stats = pgstat_fetch_stat_backend(procNumber);
+ if (!backend_stats)
+ PG_RETURN_NULL();
+
+ /* if PID does not match, leave */
+ if (beentry->st_procpid != pid)
+ PG_RETURN_NULL();
+
+ /* backend may be gone, so recheck in case */
+ if (beentry->st_backendType == B_INVALID)
+ PG_RETURN_NULL();
+
+ bktype_stats = backend_stats->wal_stats;
+
+ /* save tuples with data from this PgStat_BktypeIO */
+ return (pg_stat_wal_build_tuple(bktype_stats, backend_stats->stat_reset_timestamp));
+}
+
+
/*
* Returns statistics of WAL activity
*/
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index ba02ba53b29..9d57c69c152 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -5929,6 +5929,13 @@
proargmodes => '{o,o,o,o,o,o,o,o,o}',
proargnames => '{wal_records,wal_fpi,wal_bytes,wal_buffers_full,wal_write,wal_sync,wal_write_time,wal_sync_time,stats_reset}',
prosrc => 'pg_stat_get_wal' },
+{ oid => '8037', descr => 'statistics: backend WAL activity',
+ proname => 'pg_stat_get_backend_wal', provolatile => 'v',
+ proparallel => 'r', prorettype => 'record', proargtypes => 'int4',
+ proallargtypes => '{int4,int8,int8,numeric,int8,int8,int8,float8,float8,timestamptz}',
+ proargmodes => '{i,o,o,o,o,o,o,o,o,o}',
+ proargnames => '{backend_pid,wal_records,wal_fpi,wal_bytes,wal_buffers_full,wal_write,wal_sync,wal_write_time,wal_sync_time,stats_reset}',
+ prosrc => 'pg_stat_get_backend_wal' },
{ oid => '6248', descr => 'statistics: information about WAL prefetching',
proname => 'pg_stat_get_recovery_prefetch', prorows => '1', proretset => 't',
provolatile => 'v', prorettype => 'record', proargtypes => '',
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index bb8e0044a47..821104047a0 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -334,24 +334,6 @@ typedef struct PgStat_IO
PgStat_BktypeIO stats[BACKEND_NUM_TYPES];
} PgStat_IO;
-typedef struct PgStat_Backend
-{
- TimestampTz stat_reset_timestamp;
- PgStat_BktypeIO io_stats;
-} PgStat_Backend;
-
-/* ---------
- * PgStat_BackendPending Non-flushed backend stats.
- * ---------
- */
-typedef struct PgStat_BackendPending
-{
- /*
- * Backend statistics store the same amount of IO data as PGSTAT_KIND_IO.
- */
- PgStat_PendingIO pending_io;
-} PgStat_BackendPending;
-
typedef struct PgStat_StatDBEntry
{
PgStat_Counter xact_commit;
@@ -496,6 +478,29 @@ typedef struct PgStat_PendingWalStats
instr_time wal_sync_time;
} PgStat_PendingWalStats;
+/* ---------
+ * PgStat_BackendPending Non-flushed backend stats.
+ * ---------
+ */
+typedef struct PgStat_BackendPending
+{
+ /*
+ * Backend statistics store the same amount of IO data as PGSTAT_KIND_IO.
+ */
+ PgStat_PendingIO pending_io;
+
+ /*
+ * Backend statistics store the same amount of IO data as PGSTAT_KIND_WAL.
+ */
+ PgStat_PendingWalStats pending_wal;
+} PgStat_BackendPending;
+
+typedef struct PgStat_Backend
+{
+ TimestampTz stat_reset_timestamp;
+ PgStat_BktypeIO io_stats;
+ PgStat_WalCounters wal_stats;
+} PgStat_Backend;
/*
* Functions in pgstat.c
@@ -826,6 +831,4 @@ extern PGDLLIMPORT SessionEndType pgStatSessionEndCause;
/* updated directly by backends and background processes */
extern PGDLLIMPORT PgStat_PendingWalStats PendingWalStats;
-
-
#endif /* PGSTAT_H */
diff --git a/src/include/utils/pgstat_internal.h b/src/include/utils/pgstat_internal.h
index 0b21603c863..5a284d8c94a 100644
--- a/src/include/utils/pgstat_internal.h
+++ b/src/include/utils/pgstat_internal.h
@@ -618,7 +618,8 @@ extern void pgstat_archiver_snapshot_cb(void);
/* flags for pgstat_flush_backend() */
#define PGSTAT_BACKEND_FLUSH_IO (1 << 0) /* Flush I/O statistics */
-#define PGSTAT_BACKEND_FLUSH_ALL (PGSTAT_BACKEND_FLUSH_IO)
+#define PGSTAT_BACKEND_FLUSH_WAL (1 << 1) /* Flush WAL statistics */
+#define PGSTAT_BACKEND_FLUSH_ALL (PGSTAT_BACKEND_FLUSH_IO | PGSTAT_BACKEND_FLUSH_WAL)
extern void pgstat_flush_backend(bool nowait, bits32 flags);
extern PgStat_BackendPending *pgstat_prep_backend_pending(ProcNumber procnum);
diff --git a/src/test/regress/expected/stats.out b/src/test/regress/expected/stats.out
index a0317b7208e..cc01fdf2741 100644
--- a/src/test/regress/expected/stats.out
+++ b/src/test/regress/expected/stats.out
@@ -832,6 +832,8 @@ SELECT sessions > :db_stat_sessions FROM pg_stat_database WHERE datname = (SELEC
SELECT num_requested AS rqst_ckpts_before FROM pg_stat_checkpointer \gset
-- Test pg_stat_wal (and make a temp table so our temp schema exists)
SELECT wal_bytes AS wal_bytes_before FROM pg_stat_wal \gset
+-- Test pg_stat_get_backend_wal (and make a temp table so our temp schema exists)
+SELECT wal_bytes AS backend_wal_bytes_before from pg_stat_get_backend_wal(pg_backend_pid()) \gset
CREATE TEMP TABLE test_stats_temp AS SELECT 17;
DROP TABLE test_stats_temp;
-- Checkpoint twice: The checkpointer reports stats after reporting completion
@@ -851,6 +853,18 @@ SELECT wal_bytes > :wal_bytes_before FROM pg_stat_wal;
t
(1 row)
+SELECT pg_stat_force_next_flush();
+ pg_stat_force_next_flush
+--------------------------
+
+(1 row)
+
+SELECT wal_bytes > :backend_wal_bytes_before FROM pg_stat_get_backend_wal(pg_backend_pid());
+ ?column?
+----------
+ t
+(1 row)
+
-- Test pg_stat_get_backend_idset() and some allied functions.
-- In particular, verify that their notion of backend ID matches
-- our temp schema index.
diff --git a/src/test/regress/sql/stats.sql b/src/test/regress/sql/stats.sql
index 399c72bbcf7..28fe0a1a7d0 100644
--- a/src/test/regress/sql/stats.sql
+++ b/src/test/regress/sql/stats.sql
@@ -423,6 +423,9 @@ SELECT num_requested AS rqst_ckpts_before FROM pg_stat_checkpointer \gset
-- Test pg_stat_wal (and make a temp table so our temp schema exists)
SELECT wal_bytes AS wal_bytes_before FROM pg_stat_wal \gset
+-- Test pg_stat_get_backend_wal (and make a temp table so our temp schema exists)
+SELECT wal_bytes AS backend_wal_bytes_before from pg_stat_get_backend_wal(pg_backend_pid()) \gset
+
CREATE TEMP TABLE test_stats_temp AS SELECT 17;
DROP TABLE test_stats_temp;
@@ -435,6 +438,9 @@ CHECKPOINT;
SELECT num_requested > :rqst_ckpts_before FROM pg_stat_checkpointer;
SELECT wal_bytes > :wal_bytes_before FROM pg_stat_wal;
+SELECT pg_stat_force_next_flush();
+SELECT wal_bytes > :backend_wal_bytes_before FROM pg_stat_get_backend_wal(pg_backend_pid());
+
-- Test pg_stat_get_backend_idset() and some allied functions.
-- In particular, verify that their notion of backend ID matches
-- our temp schema index.
--
2.34.1
^ permalink raw reply [nested|flat] 37+ messages in thread
* Re: per backend WAL statistics
@ 2025-01-16 16:38 Andres Freund <[email protected]>
parent: Bertrand Drouvot <[email protected]>
0 siblings, 1 reply; 37+ messages in thread
From: Andres Freund @ 2025-01-16 16:38 UTC (permalink / raw)
To: Bertrand Drouvot <[email protected]>; +Cc: Michael Paquier <[email protected]>; [email protected]
Hi,
On 2025-01-16 15:59:31 +0000, Bertrand Drouvot wrote:
> On Wed, Jan 15, 2025 at 03:11:32PM +0900, Michael Paquier wrote:
> > On Fri, Jan 10, 2025 at 09:40:38AM +0000, Bertrand Drouvot wrote:
> > + * WAL pending statistics are incremented inside a critical section
> > + * (see XLogWrite()), so we can't use pgstat_prep_pending_entry() and we rely on
> > + * PendingBackendWalStats instead.
> > + */
> > +extern PGDLLIMPORT PgStat_PendingWalStats PendingBackendWalStats;
> >
> > Hmm. This makes me wonder if we should rethink a bit the way pending
> > entries are retrieved and if we should do it beforehand for the WAL
> > paths to avoid allocations in some critical sections. Isn't that also
> > because we avoid calling pgstat_prep_backend_pending() for the I/O
> > case as only backends are supported now, discarding cases like the
> > checkpointer where I/O could happen in a critical path? As a whole,
> > the approach taken by the patch is not really consistent with the
> > rest.
> I agree that's better to have a generic solution and to be consistent with
> the other variable-numbered stats.
>
> The attached is implementing in 0001 the proposition done in [1], i.e:
>
> 1. It adds a new allow_critical_section to PgStat_KindInfo for pgstats kinds
> 2. It ensures to set temporarly allowInCritSection to true when needed
>
> Note that for safety reason 0001 does set allowInCritSection back to false
> unconditionally (means not checking again for allow_critical_section).
This is a preposterously bad idea. The restriction to not allocate memory in
critical sections exists for a reason, why on earth should this code be
allowed to just opt out of the restriction of not allowing memory allocations
in critical sections?
The only cases where we can somewhat safely allocate memory in critical
sections is when using memory contexts with pre-reserved memory, where there's
a pretty low bound on how much memory is going to be needed. E.g. logging a
message inside a critical section, where elog.c can reset ErrorContext
afterwards.
Greetings,
Andres Freund
^ permalink raw reply [nested|flat] 37+ messages in thread
* Re: per backend WAL statistics
@ 2025-01-16 17:11 Bertrand Drouvot <[email protected]>
parent: Andres Freund <[email protected]>
0 siblings, 1 reply; 37+ messages in thread
From: Bertrand Drouvot @ 2025-01-16 17:11 UTC (permalink / raw)
To: Andres Freund <[email protected]>; +Cc: Michael Paquier <[email protected]>; [email protected]
Hi,
On Thu, Jan 16, 2025 at 11:38:47AM -0500, Andres Freund wrote:
> Hi,
>
> On 2025-01-16 15:59:31 +0000, Bertrand Drouvot wrote:
> > On Wed, Jan 15, 2025 at 03:11:32PM +0900, Michael Paquier wrote:
> > > On Fri, Jan 10, 2025 at 09:40:38AM +0000, Bertrand Drouvot wrote:
> > > + * WAL pending statistics are incremented inside a critical section
> > > + * (see XLogWrite()), so we can't use pgstat_prep_pending_entry() and we rely on
> > > + * PendingBackendWalStats instead.
> > > + */
> > > +extern PGDLLIMPORT PgStat_PendingWalStats PendingBackendWalStats;
> > >
> > > Hmm. This makes me wonder if we should rethink a bit the way pending
> > > entries are retrieved and if we should do it beforehand for the WAL
> > > paths to avoid allocations in some critical sections. Isn't that also
> > > because we avoid calling pgstat_prep_backend_pending() for the I/O
> > > case as only backends are supported now, discarding cases like the
> > > checkpointer where I/O could happen in a critical path? As a whole,
> > > the approach taken by the patch is not really consistent with the
> > > rest.
>
> > I agree that's better to have a generic solution and to be consistent with
> > the other variable-numbered stats.
> >
> > The attached is implementing in 0001 the proposition done in [1], i.e:
> >
> > 1. It adds a new allow_critical_section to PgStat_KindInfo for pgstats kinds
> > 2. It ensures to set temporarly allowInCritSection to true when needed
> >
> > Note that for safety reason 0001 does set allowInCritSection back to false
> > unconditionally (means not checking again for allow_critical_section).
>
> This is a preposterously bad idea. The restriction to not allocate memory in
> critical sections exists for a reason,
Thanks for sharing your thoughts on it. In [1], you said:
"
My view is that for IO stats no memory allocation should be required - that
used to be the case and should be the case again
"
So, do you think that the initial proposal that has been made here (See R1. in
[2]) i.e make use of a new PendingBackendWalStats variable:
"
0003 does not rely on pgstat_prep_backend_pending() for its pending statistics
but on a new PendingBackendWalStats variable. The reason is that the pending wal
statistics are incremented in a critical section (see XLogWrite(), and so
a call to pgstat_prep_pending_entry() could trigger a failed assertion:
MemoryContextAllocZero()->"CritSectionCount == 0 || (context)->allowInCritSection"
"
and implemented up to v4 is a viable approach?
[1]: https://www.postgresql.org/message-id/66efowskppsns35v5u2m7k4sdnl7yoz5bo64tdjwq7r5lhplrz%40y7dme5xwh...
[2]: https://www.postgresql.org/message-id/Z3zqc4o09dM/Ezyz%40ip-10-97-1-34.eu-west-3.compute.internal
Regards,
--
Bertrand Drouvot
PostgreSQL Contributors Team
RDS Open Source Databases
Amazon Web Services: https://aws.amazon.com
^ permalink raw reply [nested|flat] 37+ messages in thread
* Re: per backend WAL statistics
@ 2025-01-16 17:44 Andres Freund <[email protected]>
parent: Bertrand Drouvot <[email protected]>
0 siblings, 1 reply; 37+ messages in thread
From: Andres Freund @ 2025-01-16 17:44 UTC (permalink / raw)
To: Bertrand Drouvot <[email protected]>; +Cc: Michael Paquier <[email protected]>; [email protected]
Hi,
On 2025-01-16 17:11:09 +0000, Bertrand Drouvot wrote:
> On Thu, Jan 16, 2025 at 11:38:47AM -0500, Andres Freund wrote:
> > Hi,
> >
> > On 2025-01-16 15:59:31 +0000, Bertrand Drouvot wrote:
> > > On Wed, Jan 15, 2025 at 03:11:32PM +0900, Michael Paquier wrote:
> > > > On Fri, Jan 10, 2025 at 09:40:38AM +0000, Bertrand Drouvot wrote:
> > > > + * WAL pending statistics are incremented inside a critical section
> > > > + * (see XLogWrite()), so we can't use pgstat_prep_pending_entry() and we rely on
> > > > + * PendingBackendWalStats instead.
> > > > + */
> > > > +extern PGDLLIMPORT PgStat_PendingWalStats PendingBackendWalStats;
> > > >
> > > > Hmm. This makes me wonder if we should rethink a bit the way pending
> > > > entries are retrieved and if we should do it beforehand for the WAL
> > > > paths to avoid allocations in some critical sections. Isn't that also
> > > > because we avoid calling pgstat_prep_backend_pending() for the I/O
> > > > case as only backends are supported now, discarding cases like the
> > > > checkpointer where I/O could happen in a critical path? As a whole,
> > > > the approach taken by the patch is not really consistent with the
> > > > rest.
> >
> > > I agree that's better to have a generic solution and to be consistent with
> > > the other variable-numbered stats.
> > >
> > > The attached is implementing in 0001 the proposition done in [1], i.e:
> > >
> > > 1. It adds a new allow_critical_section to PgStat_KindInfo for pgstats kinds
> > > 2. It ensures to set temporarly allowInCritSection to true when needed
> > >
> > > Note that for safety reason 0001 does set allowInCritSection back to false
> > > unconditionally (means not checking again for allow_critical_section).
> >
> > This is a preposterously bad idea. The restriction to not allocate memory in
> > critical sections exists for a reason,
>
> Thanks for sharing your thoughts on it. In [1], you said:
>
> "
> My view is that for IO stats no memory allocation should be required - that
> used to be the case and should be the case again
> "
>
> So, do you think that the initial proposal that has been made here (See R1. in
> [2]) i.e make use of a new PendingBackendWalStats variable:
Well, I think this first needs be fixed for for the IO stats change made in
commit 9aea73fc61d
Author: Michael Paquier <[email protected]>
Date: 2024-12-19 13:19:22 +0900
Add backend-level statistics to pgstats
Once we have a pattern to model after, we can apply the same scheme here.
> "
> 0003 does not rely on pgstat_prep_backend_pending() for its pending statistics
> but on a new PendingBackendWalStats variable. The reason is that the pending wal
> statistics are incremented in a critical section (see XLogWrite(), and so
> a call to pgstat_prep_pending_entry() could trigger a failed assertion:
> MemoryContextAllocZero()->"CritSectionCount == 0 || (context)->allowInCritSection"
> "
>
> and implemented up to v4 is a viable approach?
Yes-ish. I think it would be better to make it slightly more general than
that, handling this for all types of backend stats, not just for WAL.
Greetings,
Andres Freund
^ permalink raw reply [nested|flat] 37+ messages in thread
* Re: per backend WAL statistics
@ 2025-01-16 23:43 Michael Paquier <[email protected]>
parent: Andres Freund <[email protected]>
0 siblings, 1 reply; 37+ messages in thread
From: Michael Paquier @ 2025-01-16 23:43 UTC (permalink / raw)
To: Andres Freund <[email protected]>; +Cc: Bertrand Drouvot <[email protected]>; [email protected]
On Thu, Jan 16, 2025 at 12:44:20PM -0500, Andres Freund wrote:
> On 2025-01-16 17:11:09 +0000, Bertrand Drouvot wrote:
>> So, do you think that the initial proposal that has been made here (See R1. in
>> [2]) i.e make use of a new PendingBackendWalStats variable:
>
> Well, I think this first needs be fixed for for the IO stats change made in
>
> Once we have a pattern to model after, we can apply the same scheme here.
Okay, thanks for the input. I was not sure what you intended
originally with all this part of the backend code, and how much would
be acceptable. The line is clear now.
>> 0003 does not rely on pgstat_prep_backend_pending() for its pending statistics
>> but on a new PendingBackendWalStats variable. The reason is that the pending wal
>> statistics are incremented in a critical section (see XLogWrite(), and so
>> a call to pgstat_prep_pending_entry() could trigger a failed assertion:
>> MemoryContextAllocZero()->"CritSectionCount == 0 || (context)->allowInCritSection"
>> "
>>
>> and implemented up to v4 is a viable approach?
>
> Yes-ish. I think it would be better to make it slightly more general than
> that, handling this for all types of backend stats, not just for WAL.
Agreed to use the same concept for all these parts of the backend
stats kind rather than two of them. Will send a reply on the original
backend I/O thread as well.
--
Michael
Attachments:
[application/pgp-signature] signature.asc (833B, ../../[email protected]/2-signature.asc)
download
^ permalink raw reply [nested|flat] 37+ messages in thread
* Re: per backend WAL statistics
@ 2025-01-21 07:19 Bertrand Drouvot <[email protected]>
parent: Michael Paquier <[email protected]>
0 siblings, 1 reply; 37+ messages in thread
From: Bertrand Drouvot @ 2025-01-21 07:19 UTC (permalink / raw)
To: Michael Paquier <[email protected]>; +Cc: Andres Freund <[email protected]>; [email protected]
Hi,
On Fri, Jan 17, 2025 at 08:43:57AM +0900, Michael Paquier wrote:
> On Thu, Jan 16, 2025 at 12:44:20PM -0500, Andres Freund wrote:
> > On 2025-01-16 17:11:09 +0000, Bertrand Drouvot wrote:
> >> So, do you think that the initial proposal that has been made here (See R1. in
> >> [2]) i.e make use of a new PendingBackendWalStats variable:
> >
> > Well, I think this first needs be fixed for for the IO stats change made in
> >
> > Once we have a pattern to model after, we can apply the same scheme here.
>
> Okay, thanks for the input. I was not sure what you intended
> originally with all this part of the backend code, and how much would
> be acceptable. The line is clear now.
>
> >> 0003 does not rely on pgstat_prep_backend_pending() for its pending statistics
> >> but on a new PendingBackendWalStats variable. The reason is that the pending wal
> >> statistics are incremented in a critical section (see XLogWrite(), and so
> >> a call to pgstat_prep_pending_entry() could trigger a failed assertion:
> >> MemoryContextAllocZero()->"CritSectionCount == 0 || (context)->allowInCritSection"
> >> "
> >>
> >> and implemented up to v4 is a viable approach?
> >
> > Yes-ish. I think it would be better to make it slightly more general than
> > that, handling this for all types of backend stats, not just for WAL.
>
> Agreed to use the same concept for all these parts of the backend
> stats kind rather than two of them. Will send a reply on the original
> backend I/O thread as well.
PFA v6 that now relies on the new PendingBackendStats variable introduced in
4feba03d8b9.
Remark: I moved PendingBackendStats back to pgstat.h because I think that the
"simple" pending stats increment that we are adding in xlog.c are not worth
an extra function call overhead (while it made more sense for the more complex IO
stats handling). So PendingBackendStats is now visible to the outside world like
PendingWalStats and friends.
Regards,
--
Bertrand Drouvot
PostgreSQL Contributors Team
RDS Open Source Databases
Amazon Web Services: https://aws.amazon.com
Attachments:
[text/x-diff] v6-0001-Extract-logic-filling-pg_stat_get_wal-s-tuple-int.patch (3.9K, ../../[email protected]/2-v6-0001-Extract-logic-filling-pg_stat_get_wal-s-tuple-int.patch)
download | inline diff:
From 4f2a197b086dd64a2723a8491cc66453012743e9 Mon Sep 17 00:00:00 2001
From: Bertrand Drouvot <[email protected]>
Date: Mon, 6 Jan 2025 07:51:27 +0000
Subject: [PATCH v6 1/3] Extract logic filling pg_stat_get_wal()'s tuple into
its own routine
This commit adds pg_stat_wal_build_tuple(), a helper routine for
pg_stat_get_wal(), that fills its tuple based on the contents
of PgStat_WalStats. This will be used in a follow-up commit that uses
the same structures as pg_stat_wal for reporting, but for the PGSTAT_KIND_BACKEND
statistics kind.
---
src/backend/utils/adt/pgstatfuncs.c | 56 ++++++++++++++++++-----------
1 file changed, 36 insertions(+), 20 deletions(-)
100.0% src/backend/utils/adt/
diff --git a/src/backend/utils/adt/pgstatfuncs.c b/src/backend/utils/adt/pgstatfuncs.c
index 0f5e0a9778d..0442be03304 100644
--- a/src/backend/utils/adt/pgstatfuncs.c
+++ b/src/backend/utils/adt/pgstatfuncs.c
@@ -1604,20 +1604,22 @@ pg_stat_get_backend_io(PG_FUNCTION_ARGS)
}
/*
- * Returns statistics of WAL activity
+ * pg_stat_wal_build_tuple
+ *
+ * Helper routine for pg_stat_get_wal() returning one tuple based on the contents
+ * of wal_stats.
*/
-Datum
-pg_stat_get_wal(PG_FUNCTION_ARGS)
+static Datum
+pg_stat_wal_build_tuple(PgStat_WalStats wal_stats)
{
-#define PG_STAT_GET_WAL_COLS 9
+#define PG_STAT_WAL_COLS 9
TupleDesc tupdesc;
- Datum values[PG_STAT_GET_WAL_COLS] = {0};
- bool nulls[PG_STAT_GET_WAL_COLS] = {0};
+ Datum values[PG_STAT_WAL_COLS] = {0};
+ bool nulls[PG_STAT_WAL_COLS] = {0};
char buf[256];
- PgStat_WalStats *wal_stats;
/* Initialise attributes information in the tuple descriptor */
- tupdesc = CreateTemplateTupleDesc(PG_STAT_GET_WAL_COLS);
+ tupdesc = CreateTemplateTupleDesc(PG_STAT_WAL_COLS);
TupleDescInitEntry(tupdesc, (AttrNumber) 1, "wal_records",
INT8OID, -1, 0);
TupleDescInitEntry(tupdesc, (AttrNumber) 2, "wal_fpi",
@@ -1639,34 +1641,48 @@ pg_stat_get_wal(PG_FUNCTION_ARGS)
BlessTupleDesc(tupdesc);
- /* Get statistics about WAL activity */
- wal_stats = pgstat_fetch_stat_wal();
-
/* Fill values and NULLs */
- values[0] = Int64GetDatum(wal_stats->wal_records);
- values[1] = Int64GetDatum(wal_stats->wal_fpi);
+ values[0] = Int64GetDatum(wal_stats.wal_records);
+ values[1] = Int64GetDatum(wal_stats.wal_fpi);
/* Convert to numeric. */
- snprintf(buf, sizeof buf, UINT64_FORMAT, wal_stats->wal_bytes);
+ snprintf(buf, sizeof buf, UINT64_FORMAT, wal_stats.wal_bytes);
values[2] = DirectFunctionCall3(numeric_in,
CStringGetDatum(buf),
ObjectIdGetDatum(0),
Int32GetDatum(-1));
- values[3] = Int64GetDatum(wal_stats->wal_buffers_full);
- values[4] = Int64GetDatum(wal_stats->wal_write);
- values[5] = Int64GetDatum(wal_stats->wal_sync);
+ values[3] = Int64GetDatum(wal_stats.wal_buffers_full);
+ values[4] = Int64GetDatum(wal_stats.wal_write);
+ values[5] = Int64GetDatum(wal_stats.wal_sync);
/* Convert counters from microsec to millisec for display */
- values[6] = Float8GetDatum(((double) wal_stats->wal_write_time) / 1000.0);
- values[7] = Float8GetDatum(((double) wal_stats->wal_sync_time) / 1000.0);
+ values[6] = Float8GetDatum(((double) wal_stats.wal_write_time) / 1000.0);
+ values[7] = Float8GetDatum(((double) wal_stats.wal_sync_time) / 1000.0);
- values[8] = TimestampTzGetDatum(wal_stats->stat_reset_timestamp);
+ if (wal_stats.stat_reset_timestamp != 0)
+ values[8] = TimestampTzGetDatum(wal_stats.stat_reset_timestamp);
+ else
+ nulls[8] = true;
/* Returns the record as Datum */
PG_RETURN_DATUM(HeapTupleGetDatum(heap_form_tuple(tupdesc, values, nulls)));
}
+/*
+ * Returns statistics of WAL activity
+ */
+Datum
+pg_stat_get_wal(PG_FUNCTION_ARGS)
+{
+ PgStat_WalStats *wal_stats;
+
+ /* Get statistics about WAL activity */
+ wal_stats = pgstat_fetch_stat_wal();
+
+ return (pg_stat_wal_build_tuple(*wal_stats));
+}
+
/*
* Returns statistics of SLRU caches.
*/
--
2.34.1
[text/x-diff] v6-0002-Adding-a-new-PgStat_WalCounters-struct.patch (5.0K, ../../[email protected]/3-v6-0002-Adding-a-new-PgStat_WalCounters-struct.patch)
download | inline diff:
From 49b4d7f60c30dfa53d7994b05ce012782f449190 Mon Sep 17 00:00:00 2001
From: Bertrand Drouvot <[email protected]>
Date: Thu, 16 Jan 2025 15:06:01 +0000
Subject: [PATCH v6 2/3] Adding a new PgStat_WalCounters struct
This new struct contains only the counters related to the WAL statistics.
This will be used in a follow-up commit that uses the same structures but
for the PGSTAT_KIND_BACKEND statistics kind.
---
src/backend/utils/activity/pgstat_wal.c | 4 ++--
src/backend/utils/adt/pgstatfuncs.c | 28 +++++++++++++------------
src/include/pgstat.h | 7 ++++++-
src/tools/pgindent/typedefs.list | 1 +
4 files changed, 24 insertions(+), 16 deletions(-)
14.1% src/backend/utils/activity/
79.8% src/backend/utils/adt/
5.0% src/include/
diff --git a/src/backend/utils/activity/pgstat_wal.c b/src/backend/utils/activity/pgstat_wal.c
index 18fa6b2936a..bfc06178a68 100644
--- a/src/backend/utils/activity/pgstat_wal.c
+++ b/src/backend/utils/activity/pgstat_wal.c
@@ -117,9 +117,9 @@ pgstat_wal_flush_cb(bool nowait)
return true;
#define WALSTAT_ACC(fld, var_to_add) \
- (stats_shmem->stats.fld += var_to_add.fld)
+ (stats_shmem->stats.wal_counters.fld += var_to_add.fld)
#define WALSTAT_ACC_INSTR_TIME(fld) \
- (stats_shmem->stats.fld += INSTR_TIME_GET_MICROSEC(PendingWalStats.fld))
+ (stats_shmem->stats.wal_counters.fld += INSTR_TIME_GET_MICROSEC(PendingWalStats.fld))
WALSTAT_ACC(wal_records, wal_usage_diff);
WALSTAT_ACC(wal_fpi, wal_usage_diff);
WALSTAT_ACC(wal_bytes, wal_usage_diff);
diff --git a/src/backend/utils/adt/pgstatfuncs.c b/src/backend/utils/adt/pgstatfuncs.c
index 0442be03304..97510d48eef 100644
--- a/src/backend/utils/adt/pgstatfuncs.c
+++ b/src/backend/utils/adt/pgstatfuncs.c
@@ -1607,10 +1607,11 @@ pg_stat_get_backend_io(PG_FUNCTION_ARGS)
* pg_stat_wal_build_tuple
*
* Helper routine for pg_stat_get_wal() returning one tuple based on the contents
- * of wal_stats.
+ * of wal_counters.
*/
static Datum
-pg_stat_wal_build_tuple(PgStat_WalStats wal_stats)
+pg_stat_wal_build_tuple(PgStat_WalCounters wal_counters,
+ TimestampTz stat_reset_timestamp)
{
#define PG_STAT_WAL_COLS 9
TupleDesc tupdesc;
@@ -1642,26 +1643,26 @@ pg_stat_wal_build_tuple(PgStat_WalStats wal_stats)
BlessTupleDesc(tupdesc);
/* Fill values and NULLs */
- values[0] = Int64GetDatum(wal_stats.wal_records);
- values[1] = Int64GetDatum(wal_stats.wal_fpi);
+ values[0] = Int64GetDatum(wal_counters.wal_records);
+ values[1] = Int64GetDatum(wal_counters.wal_fpi);
/* Convert to numeric. */
- snprintf(buf, sizeof buf, UINT64_FORMAT, wal_stats.wal_bytes);
+ snprintf(buf, sizeof buf, UINT64_FORMAT, wal_counters.wal_bytes);
values[2] = DirectFunctionCall3(numeric_in,
CStringGetDatum(buf),
ObjectIdGetDatum(0),
Int32GetDatum(-1));
- values[3] = Int64GetDatum(wal_stats.wal_buffers_full);
- values[4] = Int64GetDatum(wal_stats.wal_write);
- values[5] = Int64GetDatum(wal_stats.wal_sync);
+ values[3] = Int64GetDatum(wal_counters.wal_buffers_full);
+ values[4] = Int64GetDatum(wal_counters.wal_write);
+ values[5] = Int64GetDatum(wal_counters.wal_sync);
/* Convert counters from microsec to millisec for display */
- values[6] = Float8GetDatum(((double) wal_stats.wal_write_time) / 1000.0);
- values[7] = Float8GetDatum(((double) wal_stats.wal_sync_time) / 1000.0);
+ values[6] = Float8GetDatum(((double) wal_counters.wal_write_time) / 1000.0);
+ values[7] = Float8GetDatum(((double) wal_counters.wal_sync_time) / 1000.0);
- if (wal_stats.stat_reset_timestamp != 0)
- values[8] = TimestampTzGetDatum(wal_stats.stat_reset_timestamp);
+ if (stat_reset_timestamp != 0)
+ values[8] = TimestampTzGetDatum(stat_reset_timestamp);
else
nulls[8] = true;
@@ -1680,7 +1681,8 @@ pg_stat_get_wal(PG_FUNCTION_ARGS)
/* Get statistics about WAL activity */
wal_stats = pgstat_fetch_stat_wal();
- return (pg_stat_wal_build_tuple(*wal_stats));
+ return (pg_stat_wal_build_tuple(wal_stats->wal_counters,
+ wal_stats->stat_reset_timestamp));
}
/*
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index d0d45150977..9bbba883685 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -467,7 +467,7 @@ typedef struct PgStat_StatTabEntry
PgStat_Counter autoanalyze_count;
} PgStat_StatTabEntry;
-typedef struct PgStat_WalStats
+typedef struct PgStat_WalCounters
{
PgStat_Counter wal_records;
PgStat_Counter wal_fpi;
@@ -477,6 +477,11 @@ typedef struct PgStat_WalStats
PgStat_Counter wal_sync;
PgStat_Counter wal_write_time;
PgStat_Counter wal_sync_time;
+} PgStat_WalCounters;
+
+typedef struct PgStat_WalStats
+{
+ PgStat_WalCounters wal_counters;
TimestampTz stat_reset_timestamp;
} PgStat_WalStats;
diff --git a/src/tools/pgindent/typedefs.list b/src/tools/pgindent/typedefs.list
index d5aa5c295ae..d752e626cb0 100644
--- a/src/tools/pgindent/typedefs.list
+++ b/src/tools/pgindent/typedefs.list
@@ -2178,6 +2178,7 @@ PgStat_SubXactStatus
PgStat_TableCounts
PgStat_TableStatus
PgStat_TableXactStatus
+PgStat_WalCounters
PgStat_WalStats
PgXmlErrorContext
PgXmlStrictness
--
2.34.1
[text/x-diff] v6-0003-per-backend-WAL-statistics.patch (18.8K, ../../[email protected]/4-v6-0003-per-backend-WAL-statistics.patch)
download | inline diff:
From c00c545ed8da5c37d5590018df30b633b32b2ed7 Mon Sep 17 00:00:00 2001
From: Bertrand Drouvot <[email protected]>
Date: Mon, 6 Jan 2025 10:00:00 +0000
Subject: [PATCH v6 3/3] per backend WAL statistics
Now that commit 9aea73fc61 added backend-level statistics to pgstats (and
per backend IO statistics) we can more easily add per backend statistics.
This commit adds per backend WAL statistics using the same layer as pg_stat_wal,
except that it is now possible to know how much WAL activity is happening in each
backend rather than an overall aggregate of all the activity. A function called
pg_stat_get_backend_wal() is added to access this data depending on the
PID of a backend.
The same limitation as in 9aea73fc61 persists, meaning that Auxiliary processes
are not included in this set of statistics.
XXX: bump catalog version
---
doc/src/sgml/config.sgml | 4 +-
doc/src/sgml/monitoring.sgml | 19 +++++
src/backend/access/transam/xlog.c | 35 +++++++-
src/backend/utils/activity/pgstat_backend.c | 91 ++++++++++++++++++++-
src/backend/utils/activity/pgstat_wal.c | 2 +
src/backend/utils/adt/pgstatfuncs.c | 53 +++++++++++-
src/include/catalog/pg_proc.dat | 7 ++
src/include/pgstat.h | 48 +++++++----
src/include/utils/pgstat_internal.h | 3 +-
src/test/regress/expected/stats.out | 14 ++++
src/test/regress/sql/stats.sql | 6 ++
11 files changed, 253 insertions(+), 29 deletions(-)
12.5% doc/src/sgml/
11.2% src/backend/access/transam/
37.5% src/backend/utils/activity/
17.3% src/backend/utils/adt/
6.1% src/include/catalog/
6.3% src/include/
5.0% src/test/regress/expected/
3.8% src/test/regress/sql/
diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
index a8866292d46..5a48b427609 100644
--- a/doc/src/sgml/config.sgml
+++ b/doc/src/sgml/config.sgml
@@ -8292,7 +8292,9 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv;
measure the overhead of timing on your system.
I/O timing information is
displayed in <link linkend="monitoring-pg-stat-wal-view">
- <structname>pg_stat_wal</structname></link>.
+ <structname>pg_stat_wal</structname></link> and in the output of the
+ <link linkend="pg-stat-get-backend-wal">
+ <function>pg_stat_get_backend_wal()</function></link> function.
Only superusers and users with the appropriate <literal>SET</literal>
privilege can change this setting.
</para>
diff --git a/doc/src/sgml/monitoring.sgml b/doc/src/sgml/monitoring.sgml
index e5888fae2b5..8fdf7d13f21 100644
--- a/doc/src/sgml/monitoring.sgml
+++ b/doc/src/sgml/monitoring.sgml
@@ -4824,6 +4824,25 @@ description | Waiting for a newly initialized WAL file to reach durable storage
</para></entry>
</row>
+ <row>
+ <entry id="pg-stat-get-backend-wal" role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_stat_get_backend_wal</primary>
+ </indexterm>
+ <function>pg_stat_get_backend_wal</function> ( <type>integer</type> )
+ <returnvalue>record</returnvalue>
+ </para>
+ <para>
+ Returns WAL statistics about the backend with the specified
+ process ID. The output fields are exactly the same as the ones in the
+ <structname>pg_stat_wal</structname> view.
+ </para>
+ <para>
+ The function does not return WAL statistics for the checkpointer,
+ the background writer, the startup process and the autovacuum launcher.
+ </para></entry>
+ </row>
+
<row>
<entry role="func_table_entry"><para role="func_signature">
<indexterm>
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index bf3dbda901d..f7c5b1e5e3b 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -2058,6 +2058,11 @@ AdvanceXLInsertBuffer(XLogRecPtr upto, TimeLineID tli, bool opportunistic)
XLogWrite(WriteRqst, tli, false);
LWLockRelease(WALWriteLock);
PendingWalStats.wal_buffers_full++;
+
+ /* Add the per-backend related statistic */
+ if (pgstat_tracks_backend_bktype(MyBackendType))
+ PendingBackendStats.pending_wal.wal_buffers_full++;
+
TRACE_POSTGRESQL_WAL_BUFFER_WRITE_DIRTY_DONE();
}
/* Re-acquire WALBufMappingLock and retry */
@@ -2426,11 +2431,14 @@ XLogWrite(XLogwrtRqst WriteRqst, TimeLineID tli, bool flexible)
Size nleft;
ssize_t written;
instr_time start;
+ instr_time end;
/* OK to write the page(s) */
from = XLogCtl->pages + startidx * (Size) XLOG_BLCKSZ;
nbytes = npages * (Size) XLOG_BLCKSZ;
nleft = nbytes;
+ /* keep compiler quiet */
+ INSTR_TIME_SET_ZERO(end);
do
{
errno = 0;
@@ -2451,14 +2459,22 @@ XLogWrite(XLogwrtRqst WriteRqst, TimeLineID tli, bool flexible)
*/
if (track_wal_io_timing)
{
- instr_time end;
-
INSTR_TIME_SET_CURRENT(end);
INSTR_TIME_ACCUM_DIFF(PendingWalStats.wal_write_time, end, start);
}
PendingWalStats.wal_write++;
+ /* Add the per-backend related statistic */
+ if (pgstat_tracks_backend_bktype(MyBackendType))
+ {
+ PendingBackendStats.pending_wal.wal_write++;
+
+ if (track_wal_io_timing)
+ INSTR_TIME_ACCUM_DIFF(PendingBackendStats.pending_wal.wal_write_time,
+ end, start);
+ }
+
if (written <= 0)
{
char xlogfname[MAXFNAMELEN];
@@ -8684,8 +8700,11 @@ issue_xlog_fsync(int fd, XLogSegNo segno, TimeLineID tli)
{
char *msg = NULL;
instr_time start;
+ instr_time end;
Assert(tli != 0);
+ /* keep compiler quiet */
+ INSTR_TIME_SET_ZERO(end);
/*
* Quick exit if fsync is disabled or write() has already synced the WAL
@@ -8751,13 +8770,21 @@ issue_xlog_fsync(int fd, XLogSegNo segno, TimeLineID tli)
*/
if (track_wal_io_timing)
{
- instr_time end;
-
INSTR_TIME_SET_CURRENT(end);
INSTR_TIME_ACCUM_DIFF(PendingWalStats.wal_sync_time, end, start);
}
PendingWalStats.wal_sync++;
+
+ /* Add the per-backend related statistic */
+ if (pgstat_tracks_backend_bktype(MyBackendType))
+ {
+ PendingBackendStats.pending_wal.wal_sync++;
+
+ if (track_wal_io_timing)
+ INSTR_TIME_ACCUM_DIFF(PendingBackendStats.pending_wal.wal_sync_time,
+ end, start);
+ }
}
/*
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index bcf9e4b1487..90fb5f72bc1 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -33,11 +33,18 @@
* reported within critical sections so we use static memory in order to avoid
* memory allocation.
*/
-static PgStat_BackendPending PendingBackendStats;
+PgStat_BackendPending PendingBackendStats;
/*
- * Utility routines to report I/O stats for backends, kept here to avoid
- * exposing PendingBackendStats to the outside world.
+ * WAL usage counters saved from pgWalUsage at the previous call to
+ * pgstat_report_wal(). This is used to calculate how much WAL usage
+ * happens between pgstat_report_wal() calls, by subtracting
+ * the previous counters from the current ones.
+ */
+static WalUsage prevBackendWalUsage;
+
+/*
+ * Utility routines to report I/O stats for backends.
*/
void
pgstat_count_backend_io_op_time(IOObject io_object, IOContext io_context,
@@ -131,6 +138,79 @@ pgstat_flush_backend_entry_io(PgStat_EntryRef *entry_ref)
MemSet(&PendingBackendStats.pending_io, 0, sizeof(PgStat_PendingIO));
}
+/*
+ * To determine whether any WAL activity has occurred since last time, not
+ * only the number of generated WAL records but also the numbers of WAL
+ * writes and syncs need to be checked. Because even transaction that
+ * generates no WAL records can write or sync WAL data when flushing the
+ * data pages.
+ */
+static bool
+pgstat_backend_wal_have_pending(void)
+{
+ PgStat_PendingWalStats pending_wal;
+
+ pending_wal = PendingBackendStats.pending_wal;
+
+ return pgWalUsage.wal_records != prevBackendWalUsage.wal_records ||
+ pending_wal.wal_write != 0 || pending_wal.wal_sync != 0;
+}
+
+/*
+ * Flush out locally pending backend WAL statistics. Locking is managed
+ * by the caller.
+ */
+static void
+pgstat_flush_backend_entry_wal(PgStat_EntryRef *entry_ref)
+{
+ PgStatShared_Backend *shbackendent;
+ PgStat_WalCounters *bktype_shstats;
+ PgStat_PendingWalStats pending_wal = PendingBackendStats.pending_wal;
+ WalUsage wal_usage_diff = {0};
+
+ /*
+ * This function can be called even if nothing at all has happened. Avoid
+ * taking lock for nothing in that case.
+ */
+ if (!pgstat_backend_wal_have_pending())
+ return;
+
+ shbackendent = (PgStatShared_Backend *) entry_ref->shared_stats;
+ bktype_shstats = &shbackendent->stats.wal_stats;
+
+ /*
+ * We don't update the WAL usage portion of the local WalStats elsewhere.
+ * Calculate how much WAL usage counters were increased by subtracting the
+ * previous counters from the current ones.
+ */
+ WalUsageAccumDiff(&wal_usage_diff, &pgWalUsage, &prevBackendWalUsage);
+
+#define WALSTAT_ACC(fld, var_to_add) \
+ (bktype_shstats->fld += var_to_add.fld)
+#define WALSTAT_ACC_INSTR_TIME(fld) \
+ (bktype_shstats->fld += INSTR_TIME_GET_MICROSEC(pending_wal.fld))
+ WALSTAT_ACC(wal_buffers_full, pending_wal);
+ WALSTAT_ACC(wal_write, pending_wal);
+ WALSTAT_ACC(wal_sync, pending_wal);
+ WALSTAT_ACC(wal_records, wal_usage_diff);
+ WALSTAT_ACC(wal_fpi, wal_usage_diff);
+ WALSTAT_ACC(wal_bytes, wal_usage_diff);
+ WALSTAT_ACC_INSTR_TIME(wal_write_time);
+ WALSTAT_ACC_INSTR_TIME(wal_sync_time);
+#undef WALSTAT_ACC_INSTR_TIME
+#undef WALSTAT_ACC
+
+ /*
+ * Save the current counters for the subsequent calculation of WAL usage.
+ */
+ prevBackendWalUsage = pgWalUsage;
+
+ /*
+ * Clear out the statistics buffer, so it can be re-used.
+ */
+ MemSet(&PendingBackendStats.pending_wal, 0, sizeof(PendingWalStats));
+}
+
/*
* Flush out locally pending backend statistics
*
@@ -158,6 +238,9 @@ pgstat_flush_backend(bool nowait, bits32 flags)
if (flags & PGSTAT_BACKEND_FLUSH_IO)
pgstat_flush_backend_entry_io(entry_ref);
+ if (flags & PGSTAT_BACKEND_FLUSH_WAL)
+ pgstat_flush_backend_entry_wal(entry_ref);
+
pgstat_unlock_entry(entry_ref);
return false;
@@ -205,6 +288,8 @@ pgstat_create_backend(ProcNumber procnum)
pgstat_unlock_entry(entry_ref);
MemSet(&PendingBackendStats, 0, sizeof(PgStat_BackendPending));
+
+ prevBackendWalUsage = pgWalUsage;
}
/*
diff --git a/src/backend/utils/activity/pgstat_wal.c b/src/backend/utils/activity/pgstat_wal.c
index bfc06178a68..33627642261 100644
--- a/src/backend/utils/activity/pgstat_wal.c
+++ b/src/backend/utils/activity/pgstat_wal.c
@@ -55,6 +55,8 @@ pgstat_report_wal(bool force)
/* flush wal stats */
pgstat_flush_wal(nowait);
+ pgstat_flush_backend(nowait, PGSTAT_BACKEND_FLUSH_WAL);
+
/* flush IO stats */
pgstat_flush_io(nowait);
}
diff --git a/src/backend/utils/adt/pgstatfuncs.c b/src/backend/utils/adt/pgstatfuncs.c
index 97510d48eef..6da98bafbf2 100644
--- a/src/backend/utils/adt/pgstatfuncs.c
+++ b/src/backend/utils/adt/pgstatfuncs.c
@@ -1606,8 +1606,8 @@ pg_stat_get_backend_io(PG_FUNCTION_ARGS)
/*
* pg_stat_wal_build_tuple
*
- * Helper routine for pg_stat_get_wal() returning one tuple based on the contents
- * of wal_counters.
+ * Helper routine for pg_stat_get_wal() and pg_stat_get_backend_wal() returning
+ * one tuple based on the contents of wal_counters.
*/
static Datum
pg_stat_wal_build_tuple(PgStat_WalCounters wal_counters,
@@ -1670,6 +1670,55 @@ pg_stat_wal_build_tuple(PgStat_WalCounters wal_counters,
PG_RETURN_DATUM(HeapTupleGetDatum(heap_form_tuple(tupdesc, values, nulls)));
}
+/*
+ * Returns WAL statistics for a backend with given PID.
+ */
+Datum
+pg_stat_get_backend_wal(PG_FUNCTION_ARGS)
+{
+ int pid;
+ PGPROC *proc;
+ ProcNumber procNumber;
+ PgStat_Backend *backend_stats;
+ PgStat_WalCounters bktype_stats;
+ PgBackendStatus *beentry;
+
+ pid = PG_GETARG_INT32(0);
+ proc = BackendPidGetProc(pid);
+
+ /*
+ * This could be an auxiliary process but these do not report backend
+ * statistics due to pgstat_tracks_backend_bktype(), so there is no need
+ * for an extra call to AuxiliaryPidGetProc().
+ */
+ if (!proc)
+ PG_RETURN_NULL();
+
+ procNumber = GetNumberFromPGProc(proc);
+
+ beentry = pgstat_get_beentry_by_proc_number(procNumber);
+ if (!beentry)
+ PG_RETURN_NULL();
+
+ backend_stats = pgstat_fetch_stat_backend(procNumber);
+ if (!backend_stats)
+ PG_RETURN_NULL();
+
+ /* if PID does not match, leave */
+ if (beentry->st_procpid != pid)
+ PG_RETURN_NULL();
+
+ /* backend may be gone, so recheck in case */
+ if (beentry->st_backendType == B_INVALID)
+ PG_RETURN_NULL();
+
+ bktype_stats = backend_stats->wal_stats;
+
+ /* save tuples with data from this PgStat_BktypeIO */
+ return (pg_stat_wal_build_tuple(bktype_stats, backend_stats->stat_reset_timestamp));
+}
+
+
/*
* Returns statistics of WAL activity
*/
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index 18560755d26..ca60af1e434 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -5929,6 +5929,13 @@
proargmodes => '{o,o,o,o,o,o,o,o,o}',
proargnames => '{wal_records,wal_fpi,wal_bytes,wal_buffers_full,wal_write,wal_sync,wal_write_time,wal_sync_time,stats_reset}',
prosrc => 'pg_stat_get_wal' },
+{ oid => '8037', descr => 'statistics: backend WAL activity',
+ proname => 'pg_stat_get_backend_wal', provolatile => 'v',
+ proparallel => 'r', prorettype => 'record', proargtypes => 'int4',
+ proallargtypes => '{int4,int8,int8,numeric,int8,int8,int8,float8,float8,timestamptz}',
+ proargmodes => '{i,o,o,o,o,o,o,o,o,o}',
+ proargnames => '{backend_pid,wal_records,wal_fpi,wal_bytes,wal_buffers_full,wal_write,wal_sync,wal_write_time,wal_sync_time,stats_reset}',
+ prosrc => 'pg_stat_get_backend_wal' },
{ oid => '6248', descr => 'statistics: information about WAL prefetching',
proname => 'pg_stat_get_recovery_prefetch', prorows => '1', proretset => 't',
provolatile => 'v', prorettype => 'record', proargtypes => '',
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 9bbba883685..27a0053ea21 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -338,24 +338,6 @@ typedef struct PgStat_IO
PgStat_BktypeIO stats[BACKEND_NUM_TYPES];
} PgStat_IO;
-typedef struct PgStat_Backend
-{
- TimestampTz stat_reset_timestamp;
- PgStat_BktypeIO io_stats;
-} PgStat_Backend;
-
-/* ---------
- * PgStat_BackendPending Non-flushed backend stats.
- * ---------
- */
-typedef struct PgStat_BackendPending
-{
- /*
- * Backend statistics store the same amount of IO data as PGSTAT_KIND_IO.
- */
- PgStat_PendingIO pending_io;
-} PgStat_BackendPending;
-
typedef struct PgStat_StatDBEntry
{
PgStat_Counter xact_commit;
@@ -500,6 +482,30 @@ typedef struct PgStat_PendingWalStats
instr_time wal_sync_time;
} PgStat_PendingWalStats;
+/* ---------
+ * PgStat_BackendPending Non-flushed backend stats.
+ * ---------
+ */
+typedef struct PgStat_BackendPending
+{
+ /*
+ * Backend statistics store the same amount of IO data as PGSTAT_KIND_IO.
+ */
+ PgStat_PendingIO pending_io;
+
+ /*
+ * Backend statistics store the same amount of WAL data as
+ * PGSTAT_KIND_WAL.
+ */
+ PgStat_PendingWalStats pending_wal;
+} PgStat_BackendPending;
+
+typedef struct PgStat_Backend
+{
+ TimestampTz stat_reset_timestamp;
+ PgStat_BktypeIO io_stats;
+ PgStat_WalCounters wal_stats;
+} PgStat_Backend;
/*
* Functions in pgstat.c
@@ -840,5 +846,11 @@ extern PGDLLIMPORT SessionEndType pgStatSessionEndCause;
/* updated directly by backends and background processes */
extern PGDLLIMPORT PgStat_PendingWalStats PendingWalStats;
+/*
+ * Variables in pgstat_backend.c
+ */
+
+/* updated directly by backends */
+extern PGDLLIMPORT PgStat_BackendPending PendingBackendStats;
#endif /* PGSTAT_H */
diff --git a/src/include/utils/pgstat_internal.h b/src/include/utils/pgstat_internal.h
index a3d39d2b725..6155a3fc983 100644
--- a/src/include/utils/pgstat_internal.h
+++ b/src/include/utils/pgstat_internal.h
@@ -622,7 +622,8 @@ extern void pgstat_archiver_snapshot_cb(void);
/* flags for pgstat_flush_backend() */
#define PGSTAT_BACKEND_FLUSH_IO (1 << 0) /* Flush I/O statistics */
-#define PGSTAT_BACKEND_FLUSH_ALL (PGSTAT_BACKEND_FLUSH_IO)
+#define PGSTAT_BACKEND_FLUSH_WAL (1 << 1) /* Flush WAL statistics */
+#define PGSTAT_BACKEND_FLUSH_ALL (PGSTAT_BACKEND_FLUSH_IO | PGSTAT_BACKEND_FLUSH_WAL)
extern bool pgstat_flush_backend(bool nowait, bits32 flags);
extern bool pgstat_backend_flush_cb(bool nowait);
diff --git a/src/test/regress/expected/stats.out b/src/test/regress/expected/stats.out
index a0317b7208e..cc01fdf2741 100644
--- a/src/test/regress/expected/stats.out
+++ b/src/test/regress/expected/stats.out
@@ -832,6 +832,8 @@ SELECT sessions > :db_stat_sessions FROM pg_stat_database WHERE datname = (SELEC
SELECT num_requested AS rqst_ckpts_before FROM pg_stat_checkpointer \gset
-- Test pg_stat_wal (and make a temp table so our temp schema exists)
SELECT wal_bytes AS wal_bytes_before FROM pg_stat_wal \gset
+-- Test pg_stat_get_backend_wal (and make a temp table so our temp schema exists)
+SELECT wal_bytes AS backend_wal_bytes_before from pg_stat_get_backend_wal(pg_backend_pid()) \gset
CREATE TEMP TABLE test_stats_temp AS SELECT 17;
DROP TABLE test_stats_temp;
-- Checkpoint twice: The checkpointer reports stats after reporting completion
@@ -851,6 +853,18 @@ SELECT wal_bytes > :wal_bytes_before FROM pg_stat_wal;
t
(1 row)
+SELECT pg_stat_force_next_flush();
+ pg_stat_force_next_flush
+--------------------------
+
+(1 row)
+
+SELECT wal_bytes > :backend_wal_bytes_before FROM pg_stat_get_backend_wal(pg_backend_pid());
+ ?column?
+----------
+ t
+(1 row)
+
-- Test pg_stat_get_backend_idset() and some allied functions.
-- In particular, verify that their notion of backend ID matches
-- our temp schema index.
diff --git a/src/test/regress/sql/stats.sql b/src/test/regress/sql/stats.sql
index 399c72bbcf7..28fe0a1a7d0 100644
--- a/src/test/regress/sql/stats.sql
+++ b/src/test/regress/sql/stats.sql
@@ -423,6 +423,9 @@ SELECT num_requested AS rqst_ckpts_before FROM pg_stat_checkpointer \gset
-- Test pg_stat_wal (and make a temp table so our temp schema exists)
SELECT wal_bytes AS wal_bytes_before FROM pg_stat_wal \gset
+-- Test pg_stat_get_backend_wal (and make a temp table so our temp schema exists)
+SELECT wal_bytes AS backend_wal_bytes_before from pg_stat_get_backend_wal(pg_backend_pid()) \gset
+
CREATE TEMP TABLE test_stats_temp AS SELECT 17;
DROP TABLE test_stats_temp;
@@ -435,6 +438,9 @@ CHECKPOINT;
SELECT num_requested > :rqst_ckpts_before FROM pg_stat_checkpointer;
SELECT wal_bytes > :wal_bytes_before FROM pg_stat_wal;
+SELECT pg_stat_force_next_flush();
+SELECT wal_bytes > :backend_wal_bytes_before FROM pg_stat_get_backend_wal(pg_backend_pid());
+
-- Test pg_stat_get_backend_idset() and some allied functions.
-- In particular, verify that their notion of backend ID matches
-- our temp schema index.
--
2.34.1
^ permalink raw reply [nested|flat] 37+ messages in thread
* Re: per backend WAL statistics
@ 2025-01-23 08:05 Michael Paquier <[email protected]>
parent: Bertrand Drouvot <[email protected]>
0 siblings, 1 reply; 37+ messages in thread
From: Michael Paquier @ 2025-01-23 08:05 UTC (permalink / raw)
To: Bertrand Drouvot <[email protected]>; +Cc: Andres Freund <[email protected]>; [email protected]
On Tue, Jan 21, 2025 at 07:19:55AM +0000, Bertrand Drouvot wrote:
> PFA v6 that now relies on the new PendingBackendStats variable introduced in
> 4feba03d8b9.
>
> Remark: I moved PendingBackendStats back to pgstat.h because I think that the
> "simple" pending stats increment that we are adding in xlog.c are not worth
> an extra function call overhead (while it made more sense for the more complex IO
> stats handling). So PendingBackendStats is now visible to the outside world like
> PendingWalStats and friends.
You are re-doing here a pattern I was trying to avoid so as we don't
copy-paste more checks based on pgstat_tracks_backend_bktype more than
necessary. I am wondering if we should think harder about the
interface used to register WAL stats, and make it more consistent with
the way pg_stat_io is handled, avoiding the hardcoded attribute
numbers if we have an enum to control which field to update in some
input routine.
As we have only five counters in PgStat_PendingWalStats, the result
you have is not that invasive, true.
Are you sure that the interactions between pgWalUsage, prevWalUsage
and prevBackendWalUsage are correct? As far I got it from a code
read, prevWalUsage, prevBackendWalUsage and their local trackings in
pgstat_backend.c and pgstat_wal.c rely on instrument.c as the primary
source, as pgWalUsage can never be reset. Is that right?
--
Michael
Attachments:
[application/pgp-signature] signature.asc (833B, ../../[email protected]/2-signature.asc)
download
^ permalink raw reply [nested|flat] 37+ messages in thread
* Re: per backend WAL statistics
@ 2025-01-23 09:57 Bertrand Drouvot <[email protected]>
parent: Michael Paquier <[email protected]>
0 siblings, 1 reply; 37+ messages in thread
From: Bertrand Drouvot @ 2025-01-23 09:57 UTC (permalink / raw)
To: Michael Paquier <[email protected]>; +Cc: Andres Freund <[email protected]>; [email protected]
Hi,
On Thu, Jan 23, 2025 at 05:05:30PM +0900, Michael Paquier wrote:
> On Tue, Jan 21, 2025 at 07:19:55AM +0000, Bertrand Drouvot wrote:
> > PFA v6 that now relies on the new PendingBackendStats variable introduced in
> > 4feba03d8b9.
> >
> > Remark: I moved PendingBackendStats back to pgstat.h because I think that the
> > "simple" pending stats increment that we are adding in xlog.c are not worth
> > an extra function call overhead (while it made more sense for the more complex IO
> > stats handling). So PendingBackendStats is now visible to the outside world like
> > PendingWalStats and friends.
>
> You are re-doing here a pattern I was trying to avoid so as we don't
> copy-paste more checks based on pgstat_tracks_backend_bktype more than
> necessary.
I'm not sure I get it. pgstat_tracks_backend_bktype() is also called in
pgstat_count_backend_io_op() and pgstat_count_backend_io_op_time(). What issue
do you see with the extra calls part of this patch?
> I am wondering if we should think harder about the
> interface used to register WAL stats, and make it more consistent with
> the way pg_stat_io is handled, avoiding the hardcoded attribute
> numbers if we have an enum to control which field to update in some
> input routine.
Not sure as WAL stats just tracks a single dimension unlike IO stats which track
both IOObject and IOContext. What would be the benefit(s)?
> As we have only five counters in PgStat_PendingWalStats, the result
> you have is not that invasive, true.
And only one dimension.
> Are you sure that the interactions between pgWalUsage, prevWalUsage
> and prevBackendWalUsage are correct?
I think so and according to my testing I can see WalUsage values
that correlate nicely between pg_stat_wal() and pg_stat_get_backend_wal().
> As far I got it from a code
> read, prevWalUsage, prevBackendWalUsage and their local trackings in
> pgstat_backend.c and pgstat_wal.c rely on instrument.c as the primary
> source, as pgWalUsage can never be reset. Is that right?
yeah, IIUC pgWalUsage acts as the primary source that both prevWalUsage and
prevBackendWalUsage diff against to calculate incremental stats.
Regards,
--
Bertrand Drouvot
PostgreSQL Contributors Team
RDS Open Source Databases
Amazon Web Services: https://aws.amazon.com
^ permalink raw reply [nested|flat] 37+ messages in thread
* Re: per backend WAL statistics
@ 2025-02-04 08:49 Bertrand Drouvot <[email protected]>
parent: Bertrand Drouvot <[email protected]>
0 siblings, 1 reply; 37+ messages in thread
From: Bertrand Drouvot @ 2025-02-04 08:49 UTC (permalink / raw)
To: Michael Paquier <[email protected]>; +Cc: Andres Freund <[email protected]>; [email protected]
Hi,
On Thu, Jan 23, 2025 at 09:57:50AM +0000, Bertrand Drouvot wrote:
> On Thu, Jan 23, 2025 at 05:05:30PM +0900, Michael Paquier wrote:
> > As far I got it from a code
> > read, prevWalUsage, prevBackendWalUsage and their local trackings in
> > pgstat_backend.c and pgstat_wal.c rely on instrument.c as the primary
> > source, as pgWalUsage can never be reset. Is that right?
>
> yeah, IIUC pgWalUsage acts as the primary source that both prevWalUsage and
> prevBackendWalUsage diff against to calculate incremental stats.
>
Now that a051e71e28a is in, I think that we can reduce the scope of this patch
(i.e reduce the number of stats provided by pg_stat_get_backend_wal()).
I think we can keep:
wal_records
wal_fpi
wal_bytes (because it differs from write_bytes in pg_stat_get_backend_io())
wal_buffers_full
The first 3 are in the WalUsage struct.
I think that:
wal_write (and wal_write_time)
wal_sync (and wal_sync_time)
can be extracted from pg_stat_get_backend_io(), so there is no need to duplicate
this information. The same comment could be done for pg_stat_wal and pg_stat_io
though, but pg_stat_wal already exists so removing fields has not the same
effect.
What are you thoughts about keeping in pg_stat_get_backend_wal() only the
4 stats mentioned above?
Regards,
--
Bertrand Drouvot
PostgreSQL Contributors Team
RDS Open Source Databases
Amazon Web Services: https://aws.amazon.com
^ permalink raw reply [nested|flat] 37+ messages in thread
* Re: per backend WAL statistics
@ 2025-02-05 02:16 Michael Paquier <[email protected]>
parent: Bertrand Drouvot <[email protected]>
0 siblings, 1 reply; 37+ messages in thread
From: Michael Paquier @ 2025-02-05 02:16 UTC (permalink / raw)
To: Bertrand Drouvot <[email protected]>; +Cc: Andres Freund <[email protected]>; [email protected]
On Tue, Feb 04, 2025 at 08:49:41AM +0000, Bertrand Drouvot wrote:
> I think that:
>
> wal_write (and wal_write_time)
> wal_sync (and wal_sync_time)
Right. We are not able to get this data from XLogWrite() and
issue_xlog_fsync(), so there is no need to duplicate that anymore in
your patch.
> can be extracted from pg_stat_get_backend_io(), so there is no need to duplicate
> this information. The same comment could be done for pg_stat_wal and pg_stat_io
> though, but pg_stat_wal already exists so removing fields has not the same
> effect.
>
> What are you thoughts about keeping in pg_stat_get_backend_wal() only the
> 4 stats mentioned above?
wal_buffers_full is incremented in AdvanceXLInsertBuffer(), part of
PendingWalStats. wal_records, wal_fpi and wal_bytes are part of the
instrumentation field. It looks to me that if you discard the
wal_buffers_full part, the implementation of the data in the backend
could just be tied to the fields coming from WalUsage.
Actually, could it actually be useful to have wal_buffers_full be
available in WalUsage, so as it would show up in EXPLAIN in a
per-query basis with show_wal_usage()? Consolidating that would make
what you are trying it a bit easier, because we would have the
WalUsage and the pg_stat_io parts without any of the PendingWalStats
part. And it is just a counter not that expensive to handle, like the
data for records, fpis and bytes. This extra information could be
useful to have in the context of an EXPLAIN.
--
Michael
Attachments:
[application/pgp-signature] signature.asc (833B, ../../[email protected]/2-signature.asc)
download
^ permalink raw reply [nested|flat] 37+ messages in thread
* Re: per backend WAL statistics
@ 2025-02-05 10:22 Bertrand Drouvot <[email protected]>
parent: Michael Paquier <[email protected]>
0 siblings, 1 reply; 37+ messages in thread
From: Bertrand Drouvot @ 2025-02-05 10:22 UTC (permalink / raw)
To: Michael Paquier <[email protected]>; +Cc: Andres Freund <[email protected]>; [email protected]
Hi,
On Wed, Feb 05, 2025 at 11:16:15AM +0900, Michael Paquier wrote:
> On Tue, Feb 04, 2025 at 08:49:41AM +0000, Bertrand Drouvot wrote:
> > can be extracted from pg_stat_get_backend_io(), so there is no need to duplicate
> > this information. The same comment could be done for pg_stat_wal and pg_stat_io
> > though, but pg_stat_wal already exists so removing fields has not the same
> > effect.
> >
> > What are you thoughts about keeping in pg_stat_get_backend_wal() only the
> > 4 stats mentioned above?
>
> wal_buffers_full is incremented in AdvanceXLInsertBuffer(), part of
> PendingWalStats. wal_records, wal_fpi and wal_bytes are part of the
> instrumentation field. It looks to me that if you discard the
> wal_buffers_full part, the implementation of the data in the backend
> could just be tied to the fields coming from WalUsage.
Yup.
> Actually, could it actually be useful to have wal_buffers_full be
> available in WalUsage, so as it would show up in EXPLAIN in a
> per-query basis with show_wal_usage()?
Yeah, that might help. One could not be 100% sure that the statement being
explained is fully responsible of the wal buffer being full (as it could just be
a "victim" of an already almost full wal buffer). But OTOH that might help to
understand why an EXPLAIN analyze is slower than another one (i.e one generating
wal buffer full and the other not). Also I think it could be added to
pg_stat_statements and could also provide valuable information.
> Consolidating that would make
> what you are trying it a bit easier, because we would have the
> WalUsage and the pg_stat_io parts without any of the PendingWalStats
> part. And it is just a counter not that expensive to handle, like the
> data for records, fpis and bytes. This extra information could be
> useful to have in the context of an EXPLAIN.
Yeah, I did a bit of archeology to try to understand why it's not already the
case. From what I can see, in commit time order:
1. df3b181499 introduced the WalUsage structure
2. 6b466bf5f2 added the wal usage in pg_stat_statements
3. 33e05f89c5 added the wal usage in EXPLAIN
4. 8d9a935965f added pg_stat_wal (and wal_buffers_full)
5. 01469241b2f added the wal usage in pg_stat_wal
So, wal_buffers_full has been introduced after the WalUsage structure was
there but I don't see any reason in the emails as to why it's not in the WalUsage
structure (I might have missed it though).
I think that this proposal makes sense but would need a dedicated thread,
thoughts?
Regards,
--
Bertrand Drouvot
PostgreSQL Contributors Team
RDS Open Source Databases
Amazon Web Services: https://aws.amazon.com
^ permalink raw reply [nested|flat] 37+ messages in thread
* Re: per backend WAL statistics
@ 2025-02-05 10:31 Michael Paquier <[email protected]>
parent: Bertrand Drouvot <[email protected]>
0 siblings, 1 reply; 37+ messages in thread
From: Michael Paquier @ 2025-02-05 10:31 UTC (permalink / raw)
To: Bertrand Drouvot <[email protected]>; +Cc: Andres Freund <[email protected]>; [email protected]
On Wed, Feb 05, 2025 at 10:22:55AM +0000, Bertrand Drouvot wrote:
> So, wal_buffers_full has been introduced after the WalUsage structure was
> there but I don't see any reason in the emails as to why it's not in the WalUsage
> structure (I might have missed it though).
>
> I think that this proposal makes sense but would need a dedicated thread,
> thoughts?
Using a separate thread for a change like that makes sense to me. I
have to admit that the simplifications in terms of designs for what
we're discussing here makes such a change more valuable. Adding this
information to WalUsage is one thing. Showing it in EXPLAIN is a
second thing. Doing the former simplifies the patch you are proposing
here. We don't necessarily have to do the latter, but I don't see a
reason to not do it, either.
--
Michael
Attachments:
[application/pgp-signature] signature.asc (833B, ../../[email protected]/2-signature.asc)
download
^ permalink raw reply [nested|flat] 37+ messages in thread
* Re: per backend WAL statistics
@ 2025-02-05 14:28 Bertrand Drouvot <[email protected]>
parent: Michael Paquier <[email protected]>
0 siblings, 1 reply; 37+ messages in thread
From: Bertrand Drouvot @ 2025-02-05 14:28 UTC (permalink / raw)
To: Michael Paquier <[email protected]>; +Cc: Andres Freund <[email protected]>; [email protected]
Hi,
On Wed, Feb 05, 2025 at 07:31:13PM +0900, Michael Paquier wrote:
> On Wed, Feb 05, 2025 at 10:22:55AM +0000, Bertrand Drouvot wrote:
> > So, wal_buffers_full has been introduced after the WalUsage structure was
> > there but I don't see any reason in the emails as to why it's not in the WalUsage
> > structure (I might have missed it though).
> >
> > I think that this proposal makes sense but would need a dedicated thread,
> > thoughts?
>
> Using a separate thread for a change like that makes sense to me. I
> have to admit that the simplifications in terms of designs for what
> we're discussing here makes such a change more valuable. Adding this
> information to WalUsage is one thing. Showing it in EXPLAIN is a
> second thing. Doing the former simplifies the patch you are proposing
> here. We don't necessarily have to do the latter, but I don't see a
> reason to not do it, either.
Agree, I'll start a dedicated thread for that.
Regards,
--
Bertrand Drouvot
PostgreSQL Contributors Team
RDS Open Source Databases
Amazon Web Services: https://aws.amazon.com
^ permalink raw reply [nested|flat] 37+ messages in thread
* Re: per backend WAL statistics
@ 2025-02-06 01:38 Michael Paquier <[email protected]>
parent: Bertrand Drouvot <[email protected]>
0 siblings, 1 reply; 37+ messages in thread
From: Michael Paquier @ 2025-02-06 01:38 UTC (permalink / raw)
To: Bertrand Drouvot <[email protected]>; +Cc: Andres Freund <[email protected]>; [email protected]
On Wed, Feb 05, 2025 at 02:28:08PM +0000, Bertrand Drouvot wrote:
> Agree, I'll start a dedicated thread for that.
Thanks.
--
Michael
Attachments:
[application/pgp-signature] signature.asc (833B, ../../[email protected]/2-signature.asc)
download
^ permalink raw reply [nested|flat] 37+ messages in thread
* Re: per backend WAL statistics
@ 2025-02-06 10:28 Bertrand Drouvot <[email protected]>
parent: Michael Paquier <[email protected]>
0 siblings, 1 reply; 37+ messages in thread
From: Bertrand Drouvot @ 2025-02-06 10:28 UTC (permalink / raw)
To: Michael Paquier <[email protected]>; +Cc: Andres Freund <[email protected]>; [email protected]
Hi,
On Thu, Feb 06, 2025 at 10:38:55AM +0900, Michael Paquier wrote:
> On Wed, Feb 05, 2025 at 02:28:08PM +0000, Bertrand Drouvot wrote:
> > Agree, I'll start a dedicated thread for that.
>
> Thanks.
Done in [1].
[1]: https://www.postgresql.org/message-id/flat/Z6SOha5YFFgvpwQY%40ip-10-97-1-34.eu-west-3.compute.intern...
Regards,
--
Bertrand Drouvot
PostgreSQL Contributors Team
RDS Open Source Databases
Amazon Web Services: https://aws.amazon.com
^ permalink raw reply [nested|flat] 37+ messages in thread
* Re: per backend WAL statistics
@ 2025-02-17 06:59 Bertrand Drouvot <[email protected]>
parent: Bertrand Drouvot <[email protected]>
0 siblings, 2 replies; 37+ messages in thread
From: Bertrand Drouvot @ 2025-02-17 06:59 UTC (permalink / raw)
To: Michael Paquier <[email protected]>; +Cc: Andres Freund <[email protected]>; [email protected]; Nazir Bilal Yavuz <[email protected]>
Hi,
On Thu, Feb 06, 2025 at 10:28:48AM +0000, Bertrand Drouvot wrote:
> Hi,
>
> On Thu, Feb 06, 2025 at 10:38:55AM +0900, Michael Paquier wrote:
> > On Wed, Feb 05, 2025 at 02:28:08PM +0000, Bertrand Drouvot wrote:
> > > Agree, I'll start a dedicated thread for that.
> >
> > Thanks.
>
> Done in [1].
>
> [1]: https://www.postgresql.org/message-id/flat/Z6SOha5YFFgvpwQY%40ip-10-97-1-34.eu-west-3.compute.intern...
Thanks for having committed the work done in [1] above.
There is still something that would simplify what is done here: it's the
"the elimination of the write & sync columns for pg_stat_wal" mentioned in [2].
I'll add it in the new patch serie for this thread (that simplifies the new
pg_stat_wal_build_tuple() among other things) unless Nazir beat me to it.
[2]: https://www.postgresql.org/message-id/Z6L3ZNGCljZZouvN%40paquier.xyz
Regards,
--
Bertrand Drouvot
PostgreSQL Contributors Team
RDS Open Source Databases
Amazon Web Services: https://aws.amazon.com
^ permalink raw reply [nested|flat] 37+ messages in thread
* Re: per backend WAL statistics
@ 2025-02-17 07:08 Nazir Bilal Yavuz <[email protected]>
parent: Bertrand Drouvot <[email protected]>
1 sibling, 0 replies; 37+ messages in thread
From: Nazir Bilal Yavuz @ 2025-02-17 07:08 UTC (permalink / raw)
To: Bertrand Drouvot <[email protected]>; +Cc: Michael Paquier <[email protected]>; Andres Freund <[email protected]>; [email protected]
Hi,
Thank you for working on this!
On Mon, 17 Feb 2025 at 09:59, Bertrand Drouvot
<[email protected]> wrote:
>
> There is still something that would simplify what is done here: it's the
> "the elimination of the write & sync columns for pg_stat_wal" mentioned in [2].
>
> I'll add it in the new patch serie for this thread (that simplifies the new
> pg_stat_wal_build_tuple() among other things) unless Nazir beat me to it.
>
> [2]: https://www.postgresql.org/message-id/Z6L3ZNGCljZZouvN%40paquier.xyz
I am working on some other stuff right now. Please feel free to work on it.
--
Regards,
Nazir Bilal Yavuz
Microsoft
^ permalink raw reply [nested|flat] 37+ messages in thread
* Re: per backend WAL statistics
@ 2025-02-17 07:25 Michael Paquier <[email protected]>
parent: Bertrand Drouvot <[email protected]>
1 sibling, 0 replies; 37+ messages in thread
From: Michael Paquier @ 2025-02-17 07:25 UTC (permalink / raw)
To: Bertrand Drouvot <[email protected]>; +Cc: Andres Freund <[email protected]>; [email protected]; Nazir Bilal Yavuz <[email protected]>
On Mon, Feb 17, 2025 at 06:59:40AM +0000, Bertrand Drouvot wrote:
> There is still something that would simplify what is done here: it's the
> "the elimination of the write & sync columns for pg_stat_wal" mentioned in [2].
Yeah, still you cannot just remove them because the data tracked in
pg_stat_io is not entirely the same, right?
--
Michael
Attachments:
[application/pgp-signature] signature.asc (833B, ../../[email protected]/2-signature.asc)
download
^ permalink raw reply [nested|flat] 37+ messages in thread
end of thread, other threads:[~2025-02-17 07:25 UTC | newest]
Thread overview: 37+ messages (download: mbox mbox.gz follow: Atom feed)
-- links below jump to the message on this page --
2024-02-13 00:04 [PATCH v10 05/17] Update BitmapAdjustPrefetchIterator parameter type to BlockNumber Melanie Plageman <[email protected]>
2024-02-13 00:04 [PATCH v9 05/17] Update BitmapAdjustPrefetchIterator parameter type to BlockNumber Melanie Plageman <[email protected]>
2024-02-13 00:04 [PATCH v6 05/14] Update BitmapAdjustPrefetchIterator parameter type to BlockNumber Melanie Plageman <[email protected]>
2024-02-13 00:04 [PATCH v12 05/17] Update BitmapAdjustPrefetchIterator parameter type to BlockNumber Melanie Plageman <[email protected]>
2024-02-13 00:04 [PATCH v6 05/14] Update BitmapAdjustPrefetchIterator parameter type to BlockNumber Melanie Plageman <[email protected]>
2024-02-13 00:04 [PATCH v10 05/17] Update BitmapAdjustPrefetchIterator parameter type to BlockNumber Melanie Plageman <[email protected]>
2024-02-13 00:04 [PATCH v8 05/17] Update BitmapAdjustPrefetchIterator parameter type to BlockNumber Melanie Plageman <[email protected]>
2024-02-13 00:04 [PATCH v11 05/17] Update BitmapAdjustPrefetchIterator parameter type to BlockNumber Melanie Plageman <[email protected]>
2024-02-13 00:04 [PATCH v10 05/17] Update BitmapAdjustPrefetchIterator parameter type to BlockNumber Melanie Plageman <[email protected]>
2024-02-13 00:04 [PATCH v11 05/17] Update BitmapAdjustPrefetchIterator parameter type to BlockNumber Melanie Plageman <[email protected]>
2024-02-13 00:04 [PATCH v9 05/17] Update BitmapAdjustPrefetchIterator parameter type to BlockNumber Melanie Plageman <[email protected]>
2024-02-13 00:04 [PATCH v8 05/17] Update BitmapAdjustPrefetchIterator parameter type to BlockNumber Melanie Plageman <[email protected]>
2024-02-13 00:04 [PATCH v7 05/13] Update BitmapAdjustPrefetchIterator parameter type to BlockNumber Melanie Plageman <[email protected]>
2024-02-13 00:04 [PATCH v9 05/17] Update BitmapAdjustPrefetchIterator parameter type to BlockNumber Melanie Plageman <[email protected]>
2024-02-13 00:04 [PATCH v7 05/13] Update BitmapAdjustPrefetchIterator parameter type to BlockNumber Melanie Plageman <[email protected]>
2024-02-13 00:04 [PATCH v6 05/14] Update BitmapAdjustPrefetchIterator parameter type to BlockNumber Melanie Plageman <[email protected]>
2024-02-13 00:04 [PATCH v7 05/13] Update BitmapAdjustPrefetchIterator parameter type to BlockNumber Melanie Plageman <[email protected]>
2024-02-13 00:04 [PATCH v8 05/17] Update BitmapAdjustPrefetchIterator parameter type to BlockNumber Melanie Plageman <[email protected]>
2025-01-15 06:11 Re: per backend WAL statistics Michael Paquier <[email protected]>
2025-01-16 15:59 ` Re: per backend WAL statistics Bertrand Drouvot <[email protected]>
2025-01-16 16:38 ` Re: per backend WAL statistics Andres Freund <[email protected]>
2025-01-16 17:11 ` Re: per backend WAL statistics Bertrand Drouvot <[email protected]>
2025-01-16 17:44 ` Re: per backend WAL statistics Andres Freund <[email protected]>
2025-01-16 23:43 ` Re: per backend WAL statistics Michael Paquier <[email protected]>
2025-01-21 07:19 ` Re: per backend WAL statistics Bertrand Drouvot <[email protected]>
2025-01-23 08:05 ` Re: per backend WAL statistics Michael Paquier <[email protected]>
2025-01-23 09:57 ` Re: per backend WAL statistics Bertrand Drouvot <[email protected]>
2025-02-04 08:49 ` Re: per backend WAL statistics Bertrand Drouvot <[email protected]>
2025-02-05 02:16 ` Re: per backend WAL statistics Michael Paquier <[email protected]>
2025-02-05 10:22 ` Re: per backend WAL statistics Bertrand Drouvot <[email protected]>
2025-02-05 10:31 ` Re: per backend WAL statistics Michael Paquier <[email protected]>
2025-02-05 14:28 ` Re: per backend WAL statistics Bertrand Drouvot <[email protected]>
2025-02-06 01:38 ` Re: per backend WAL statistics Michael Paquier <[email protected]>
2025-02-06 10:28 ` Re: per backend WAL statistics Bertrand Drouvot <[email protected]>
2025-02-17 06:59 ` Re: per backend WAL statistics Bertrand Drouvot <[email protected]>
2025-02-17 07:08 ` Re: per backend WAL statistics Nazir Bilal Yavuz <[email protected]>
2025-02-17 07:25 ` Re: per backend WAL statistics Michael Paquier <[email protected]>
This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox