aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/src/sgml/func.sgml28
-rw-r--r--src/backend/backup/walsummaryfuncs.c39
-rw-r--r--src/backend/postmaster/walsummarizer.c65
-rw-r--r--src/include/catalog/catversion.h2
-rw-r--r--src/include/catalog/pg_proc.dat9
-rw-r--r--src/include/postmaster/walsummarizer.h4
6 files changed, 146 insertions, 1 deletions
diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml
index de78d58d4bc..0f7d409e601 100644
--- a/doc/src/sgml/func.sgml
+++ b/doc/src/sgml/func.sgml
@@ -26554,6 +26554,34 @@ SELECT collation for ('foo' COLLATE "de_DE");
<literal>relblocknumber</literal> will be zero.
</para></entry>
</row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_get_wal_summarizer_state</primary>
+ </indexterm>
+ <function>pg_get_wal_summarizer_state</function> ()
+ <returnvalue>record</returnvalue>
+ ( <parameter>summarized_tli</parameter> <type>bigint</type>,
+ <parameter>summarized_lsn</parameter> <type>pg_lsn</type>,
+ <parameter>pending_lsn</parameter> <type>pg_lsn</type>,
+ <parameter>summarizer_pid</parameter> <type>int</type> )
+ </para>
+ <para>
+ Returns information about the progress of the WAL summarizer. If the
+ WAL summarizer has never run since the instance was started, then
+ <literal>summarized_tli</literal> and <literal>summarized_lsn</literal>
+ will be <literal>0</literal> and <literal>0/0</literal> respectively;
+ otherwise, they will be the TLI and ending LSN of the last WAL summary
+ file written to disk. If the WAL summarizer is currently running,
+ <literal>pending_lsn</literal> will be the ending LSN of the last
+ record that it has consumed, which must always be greater than or
+ equal to <literal>summarized_lsn</literal>; if the WAL summarizer is
+ not running, it will be equal to <literal>summarized_lsn</literal>.
+ <literal>summarized_pid</literal> is the PID of the WAL summarizer
+ process, if it is running, and otherwise NULL.
+ </para></entry>
+ </row>
</tbody>
</tgroup>
</table>
diff --git a/src/backend/backup/walsummaryfuncs.c b/src/backend/backup/walsummaryfuncs.c
index 89c660c6969..f082488b33f 100644
--- a/src/backend/backup/walsummaryfuncs.c
+++ b/src/backend/backup/walsummaryfuncs.c
@@ -16,11 +16,13 @@
#include "common/blkreftable.h"
#include "funcapi.h"
#include "miscadmin.h"
+#include "postmaster/walsummarizer.h"
#include "utils/fmgrprotos.h"
#include "utils/pg_lsn.h"
#define NUM_WS_ATTS 3
#define NUM_SUMMARY_ATTS 6
+#define NUM_STATE_ATTS 4
#define MAX_BLOCKS_PER_CALL 256
/*
@@ -167,3 +169,40 @@ pg_wal_summary_contents(PG_FUNCTION_ARGS)
return (Datum) 0;
}
+
+/*
+ * Returns information about the state of the WAL summarizer process.
+ */
+Datum
+pg_get_wal_summarizer_state(PG_FUNCTION_ARGS)
+{
+ Datum values[NUM_STATE_ATTS];
+ bool nulls[NUM_STATE_ATTS];
+ TimeLineID summarized_tli;
+ XLogRecPtr summarized_lsn;
+ XLogRecPtr pending_lsn;
+ int summarizer_pid;
+ TupleDesc tupdesc;
+ HeapTuple htup;
+
+ GetWalSummarizerState(&summarized_tli, &summarized_lsn, &pending_lsn,
+ &summarizer_pid);
+
+ if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
+ elog(ERROR, "return type must be a row type");
+
+ memset(nulls, 0, sizeof(nulls));
+
+ values[0] = Int64GetDatum((int64) summarized_tli);
+ values[1] = LSNGetDatum(summarized_lsn);
+ values[2] = LSNGetDatum(pending_lsn);
+
+ if (summarizer_pid < 0)
+ nulls[3] = true;
+ else
+ values[3] = Int32GetDatum(summarizer_pid);
+
+ htup = heap_form_tuple(tupdesc, values, nulls);
+
+ PG_RETURN_DATUM(HeapTupleGetDatum(htup));
+}
diff --git a/src/backend/postmaster/walsummarizer.c b/src/backend/postmaster/walsummarizer.c
index f828cc436a6..7287f07529e 100644
--- a/src/backend/postmaster/walsummarizer.c
+++ b/src/backend/postmaster/walsummarizer.c
@@ -142,6 +142,7 @@ static XLogRecPtr redo_pointer_at_last_summary_removal = InvalidXLogRecPtr;
bool summarize_wal = false;
int wal_summary_keep_time = 10 * 24 * 60;
+static void WalSummarizerShutdown(int code, Datum arg);
static XLogRecPtr GetLatestLSN(TimeLineID *tli);
static void HandleWalSummarizerInterrupts(void);
static XLogRecPtr SummarizeWAL(TimeLineID tli, XLogRecPtr start_lsn,
@@ -245,6 +246,7 @@ WalSummarizerMain(void)
pqsignal(SIGUSR2, SIG_IGN); /* not used */
/* Advertise ourselves. */
+ on_shmem_exit(WalSummarizerShutdown, (Datum) 0);
LWLockAcquire(WALSummarizerLock, LW_EXCLUSIVE);
WalSummarizerCtl->summarizer_pgprocno = MyProc->pgprocno;
LWLockRelease(WALSummarizerLock);
@@ -418,6 +420,57 @@ WalSummarizerMain(void)
}
/*
+ * Get information about the state of the WAL summarizer.
+ */
+void
+GetWalSummarizerState(TimeLineID *summarized_tli, XLogRecPtr *summarized_lsn,
+ XLogRecPtr *pending_lsn, int *summarizer_pid)
+{
+ LWLockAcquire(WALSummarizerLock, LW_SHARED);
+ if (!WalSummarizerCtl->initialized)
+ {
+ /*
+ * If initialized is false, the rest of the structure contents are
+ * undefined.
+ */
+ *summarized_tli = 0;
+ *summarized_lsn = InvalidXLogRecPtr;
+ *pending_lsn = InvalidXLogRecPtr;
+ *summarizer_pid = -1;
+ }
+ else
+ {
+ int summarizer_pgprocno = WalSummarizerCtl->summarizer_pgprocno;
+
+ *summarized_tli = WalSummarizerCtl->summarized_tli;
+ *summarized_lsn = WalSummarizerCtl->summarized_lsn;
+ if (summarizer_pgprocno == INVALID_PGPROCNO)
+ {
+ /*
+ * If the summarizer has exited, the fact that it had processed
+ * beyond summarized_lsn is irrelevant now.
+ */
+ *pending_lsn = WalSummarizerCtl->summarized_lsn;
+ *summarizer_pid = -1;
+ }
+ else
+ {
+ *pending_lsn = WalSummarizerCtl->pending_lsn;
+
+ /*
+ * We're not fussed about inexact answers here, since they could
+ * become stale instantly, so we don't bother taking the lock, but
+ * make sure that invalid PID values are normalized to -1.
+ */
+ *summarizer_pid = GetPGProcByNumber(summarizer_pgprocno)->pid;
+ if (*summarizer_pid <= 0)
+ *summarizer_pid = -1;
+ }
+ }
+ LWLockRelease(WALSummarizerLock);
+}
+
+/*
* Get the oldest LSN in this server's timeline history that has not yet been
* summarized.
*
@@ -623,6 +676,18 @@ WaitForWalSummarization(XLogRecPtr lsn, long timeout, XLogRecPtr *pending_lsn)
}
/*
+ * On exit, update shared memory to make it clear that we're no longer
+ * running.
+ */
+static void
+WalSummarizerShutdown(int code, Datum arg)
+{
+ LWLockAcquire(WALSummarizerLock, LW_EXCLUSIVE);
+ WalSummarizerCtl->summarizer_pgprocno = INVALID_PGPROCNO;
+ LWLockRelease(WALSummarizerLock);
+}
+
+/*
* Get the latest LSN that is eligible to be summarized, and set *tli to the
* corresponding timeline.
*/
diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h
index 686667a0f88..a94dcdc2713 100644
--- a/src/include/catalog/catversion.h
+++ b/src/include/catalog/catversion.h
@@ -57,6 +57,6 @@
*/
/* yyyymmddN */
-#define CATALOG_VERSION_NO 202401041
+#define CATALOG_VERSION_NO 202401111
#endif
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index 7979392776d..58811a6530b 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -12142,5 +12142,14 @@
proargmodes => '{i,i,i,o,o,o,o,o,o}',
proargnames => '{tli,start_lsn,end_lsn,relfilenode,reltablespace,reldatabase,relforknumber,relblocknumber,is_limit_block}',
prosrc => 'pg_wal_summary_contents' },
+{ oid => '8438',
+ descr => 'WAL summarizer state',
+ proname => 'pg_get_wal_summarizer_state',
+ provolatile => 'v', proparallel => 's',
+ prorettype => 'record', proargtypes => '',
+ proallargtypes => '{int8,pg_lsn,pg_lsn,int4}',
+ proargmodes => '{o,o,o,o}',
+ proargnames => '{summarized_tli,summarized_lsn,pending_lsn,summarizer_pid}',
+ prosrc => 'pg_get_wal_summarizer_state' },
]
diff --git a/src/include/postmaster/walsummarizer.h b/src/include/postmaster/walsummarizer.h
index 75cb1d709fc..d6e61b59ac7 100644
--- a/src/include/postmaster/walsummarizer.h
+++ b/src/include/postmaster/walsummarizer.h
@@ -23,6 +23,10 @@ extern Size WalSummarizerShmemSize(void);
extern void WalSummarizerShmemInit(void);
extern void WalSummarizerMain(void) pg_attribute_noreturn();
+extern void GetWalSummarizerState(TimeLineID *summarized_tli,
+ XLogRecPtr *summarized_lsn,
+ XLogRecPtr *pending_lsn,
+ int *summarizer_pid);
extern XLogRecPtr GetOldestUnsummarizedLSN(TimeLineID *tli,
bool *lsn_is_exact,
bool reset_pending_lsn);