mirror of
https://git.postgresql.org/git/postgresql.git
synced 2025-01-06 15:24:56 +08:00
Add pg_stat_archiver statistics view.
This view shows the statistics about the WAL archiver process's activity. Gabriele Bartolini, reviewed by Michael Paquier, refactored a bit by me.
This commit is contained in:
parent
98d62c28fd
commit
9132b189bf
@ -269,6 +269,14 @@ postgres: <replaceable>user</> <replaceable>database</> <replaceable>host</> <re
|
|||||||
</entry>
|
</entry>
|
||||||
</row>
|
</row>
|
||||||
|
|
||||||
|
<row>
|
||||||
|
<entry><structname>pg_stat_archiver</><indexterm><primary>pg_stat_archiver</primary></indexterm></entry>
|
||||||
|
<entry>One row only, showing statistics about the
|
||||||
|
WAL archiver process's activity. See
|
||||||
|
<xref linkend="pg-stat-archiver-view"> for details.
|
||||||
|
</entry>
|
||||||
|
</row>
|
||||||
|
|
||||||
<row>
|
<row>
|
||||||
<entry><structname>pg_stat_bgwriter</><indexterm><primary>pg_stat_bgwriter</primary></indexterm></entry>
|
<entry><structname>pg_stat_bgwriter</><indexterm><primary>pg_stat_bgwriter</primary></indexterm></entry>
|
||||||
<entry>One row only, showing statistics about the
|
<entry>One row only, showing statistics about the
|
||||||
@ -648,6 +656,63 @@ postgres: <replaceable>user</> <replaceable>database</> <replaceable>host</> <re
|
|||||||
</para>
|
</para>
|
||||||
</note>
|
</note>
|
||||||
|
|
||||||
|
<table id="pg-stat-archiver-view" xreflabel="pg_stat_archiver">
|
||||||
|
<title><structname>pg_stat_archiver</structname> View</title>
|
||||||
|
|
||||||
|
<tgroup cols="3">
|
||||||
|
<thead>
|
||||||
|
<row>
|
||||||
|
<entry>Column</entry>
|
||||||
|
<entry>Type</entry>
|
||||||
|
<entry>Description</entry>
|
||||||
|
</row>
|
||||||
|
</thead>
|
||||||
|
|
||||||
|
<tbody>
|
||||||
|
<row>
|
||||||
|
<entry><structfield>archived_count</></entry>
|
||||||
|
<entry><type>bigint</type></entry>
|
||||||
|
<entry>Number of WAL files that have been successfully archived</entry>
|
||||||
|
</row>
|
||||||
|
<row>
|
||||||
|
<entry><structfield>last_archived_wal</></entry>
|
||||||
|
<entry><type>text</type></entry>
|
||||||
|
<entry>Name of the last WAL file successfully archived</entry>
|
||||||
|
</row>
|
||||||
|
<row>
|
||||||
|
<entry><structfield>last_archived_time</></entry>
|
||||||
|
<entry><type>timestamp with time zone</type></entry>
|
||||||
|
<entry>Time of the last successful archive operation</entry>
|
||||||
|
</row>
|
||||||
|
<row>
|
||||||
|
<entry><structfield>failed_count</></entry>
|
||||||
|
<entry><type>bigint</type></entry>
|
||||||
|
<entry>Number of failed attempts for archiving WAL files</entry>
|
||||||
|
</row>
|
||||||
|
<row>
|
||||||
|
<entry><structfield>last_failed_wal</></entry>
|
||||||
|
<entry><type>text</type></entry>
|
||||||
|
<entry>Name of the WAL file of the last failed archival operation</entry>
|
||||||
|
</row>
|
||||||
|
<row>
|
||||||
|
<entry><structfield>last_failed_time</></entry>
|
||||||
|
<entry><type>timestamp with time zone</type></entry>
|
||||||
|
<entry>Time of the last failed archival operation</entry>
|
||||||
|
</row>
|
||||||
|
<row>
|
||||||
|
<entry><structfield>stats_reset</></entry>
|
||||||
|
<entry><type>timestamp with time zone</type></entry>
|
||||||
|
<entry>Time at which these statistics were last reset</entry>
|
||||||
|
</row>
|
||||||
|
</tbody>
|
||||||
|
</tgroup>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
The <structname>pg_stat_archiver</structname> view will always have a
|
||||||
|
single row, containing data about the archiver process of the cluster.
|
||||||
|
</para>
|
||||||
|
|
||||||
<table id="pg-stat-bgwriter-view" xreflabel="pg_stat_bgwriter">
|
<table id="pg-stat-bgwriter-view" xreflabel="pg_stat_bgwriter">
|
||||||
<title><structname>pg_stat_bgwriter</structname> View</title>
|
<title><structname>pg_stat_bgwriter</structname> View</title>
|
||||||
|
|
||||||
@ -1613,6 +1678,8 @@ postgres: <replaceable>user</> <replaceable>database</> <replaceable>host</> <re
|
|||||||
argument (requires superuser privileges).
|
argument (requires superuser privileges).
|
||||||
Calling <literal>pg_stat_reset_shared('bgwriter')</> will zero all the
|
Calling <literal>pg_stat_reset_shared('bgwriter')</> will zero all the
|
||||||
counters shown in the <structname>pg_stat_bgwriter</> view.
|
counters shown in the <structname>pg_stat_bgwriter</> view.
|
||||||
|
Calling <literal>pg_stat_reset_shared('archiver')</> will zero all the
|
||||||
|
counters shown in the <structname>pg_stat_archiver</> view.
|
||||||
</entry>
|
</entry>
|
||||||
</row>
|
</row>
|
||||||
|
|
||||||
|
@ -672,6 +672,17 @@ CREATE VIEW pg_stat_xact_user_functions AS
|
|||||||
WHERE P.prolang != 12 -- fast check to eliminate built-in functions
|
WHERE P.prolang != 12 -- fast check to eliminate built-in functions
|
||||||
AND pg_stat_get_xact_function_calls(P.oid) IS NOT NULL;
|
AND pg_stat_get_xact_function_calls(P.oid) IS NOT NULL;
|
||||||
|
|
||||||
|
CREATE VIEW pg_stat_archiver AS
|
||||||
|
SELECT
|
||||||
|
s.archived_count,
|
||||||
|
s.last_archived_wal,
|
||||||
|
s.last_archived_time,
|
||||||
|
s.failed_count,
|
||||||
|
s.last_failed_wal,
|
||||||
|
s.last_failed_time,
|
||||||
|
s.stats_reset
|
||||||
|
FROM pg_stat_get_archiver() s;
|
||||||
|
|
||||||
CREATE VIEW pg_stat_bgwriter AS
|
CREATE VIEW pg_stat_bgwriter AS
|
||||||
SELECT
|
SELECT
|
||||||
pg_stat_get_bgwriter_timed_checkpoints() AS checkpoints_timed,
|
pg_stat_get_bgwriter_timed_checkpoints() AS checkpoints_timed,
|
||||||
|
@ -36,6 +36,7 @@
|
|||||||
#include "access/xlog_internal.h"
|
#include "access/xlog_internal.h"
|
||||||
#include "libpq/pqsignal.h"
|
#include "libpq/pqsignal.h"
|
||||||
#include "miscadmin.h"
|
#include "miscadmin.h"
|
||||||
|
#include "pgstat.h"
|
||||||
#include "postmaster/fork_process.h"
|
#include "postmaster/fork_process.h"
|
||||||
#include "postmaster/pgarch.h"
|
#include "postmaster/pgarch.h"
|
||||||
#include "postmaster/postmaster.h"
|
#include "postmaster/postmaster.h"
|
||||||
@ -58,19 +59,6 @@
|
|||||||
#define PGARCH_RESTART_INTERVAL 10 /* How often to attempt to restart a
|
#define PGARCH_RESTART_INTERVAL 10 /* How often to attempt to restart a
|
||||||
* failed archiver; in seconds. */
|
* failed archiver; in seconds. */
|
||||||
|
|
||||||
/* ----------
|
|
||||||
* Archiver control info.
|
|
||||||
*
|
|
||||||
* We expect that archivable files within pg_xlog will have names between
|
|
||||||
* MIN_XFN_CHARS and MAX_XFN_CHARS in length, consisting only of characters
|
|
||||||
* appearing in VALID_XFN_CHARS. The status files in archive_status have
|
|
||||||
* corresponding names with ".ready" or ".done" appended.
|
|
||||||
* ----------
|
|
||||||
*/
|
|
||||||
#define MIN_XFN_CHARS 16
|
|
||||||
#define MAX_XFN_CHARS 40
|
|
||||||
#define VALID_XFN_CHARS "0123456789ABCDEF.history.backup"
|
|
||||||
|
|
||||||
#define NUM_ARCHIVE_RETRIES 3
|
#define NUM_ARCHIVE_RETRIES 3
|
||||||
|
|
||||||
|
|
||||||
@ -496,10 +484,17 @@ pgarch_ArchiverCopyLoop(void)
|
|||||||
{
|
{
|
||||||
/* successful */
|
/* successful */
|
||||||
pgarch_archiveDone(xlog);
|
pgarch_archiveDone(xlog);
|
||||||
|
|
||||||
|
/* Tell the collector about the WAL file that we successfully archived */
|
||||||
|
pgstat_send_archiver(xlog, false);
|
||||||
|
|
||||||
break; /* out of inner retry loop */
|
break; /* out of inner retry loop */
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
/* Tell the collector about the WAL file that we failed to archive */
|
||||||
|
pgstat_send_archiver(xlog, true);
|
||||||
|
|
||||||
if (++failures >= NUM_ARCHIVE_RETRIES)
|
if (++failures >= NUM_ARCHIVE_RETRIES)
|
||||||
{
|
{
|
||||||
ereport(WARNING,
|
ereport(WARNING,
|
||||||
|
@ -221,6 +221,7 @@ static int localNumBackends = 0;
|
|||||||
* Contains statistics that are not collected per database
|
* Contains statistics that are not collected per database
|
||||||
* or per table.
|
* or per table.
|
||||||
*/
|
*/
|
||||||
|
static PgStat_ArchiverStats archiverStats;
|
||||||
static PgStat_GlobalStats globalStats;
|
static PgStat_GlobalStats globalStats;
|
||||||
|
|
||||||
/* Write request info for each database */
|
/* Write request info for each database */
|
||||||
@ -292,6 +293,7 @@ static void pgstat_recv_resetsinglecounter(PgStat_MsgResetsinglecounter *msg, in
|
|||||||
static void pgstat_recv_autovac(PgStat_MsgAutovacStart *msg, int len);
|
static void pgstat_recv_autovac(PgStat_MsgAutovacStart *msg, int len);
|
||||||
static void pgstat_recv_vacuum(PgStat_MsgVacuum *msg, int len);
|
static void pgstat_recv_vacuum(PgStat_MsgVacuum *msg, int len);
|
||||||
static void pgstat_recv_analyze(PgStat_MsgAnalyze *msg, int len);
|
static void pgstat_recv_analyze(PgStat_MsgAnalyze *msg, int len);
|
||||||
|
static void pgstat_recv_archiver(PgStat_MsgArchiver *msg, int len);
|
||||||
static void pgstat_recv_bgwriter(PgStat_MsgBgWriter *msg, int len);
|
static void pgstat_recv_bgwriter(PgStat_MsgBgWriter *msg, int len);
|
||||||
static void pgstat_recv_funcstat(PgStat_MsgFuncstat *msg, int len);
|
static void pgstat_recv_funcstat(PgStat_MsgFuncstat *msg, int len);
|
||||||
static void pgstat_recv_funcpurge(PgStat_MsgFuncpurge *msg, int len);
|
static void pgstat_recv_funcpurge(PgStat_MsgFuncpurge *msg, int len);
|
||||||
@ -1257,13 +1259,15 @@ pgstat_reset_shared_counters(const char *target)
|
|||||||
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
|
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
|
||||||
errmsg("must be superuser to reset statistics counters")));
|
errmsg("must be superuser to reset statistics counters")));
|
||||||
|
|
||||||
if (strcmp(target, "bgwriter") == 0)
|
if (strcmp(target, "archiver") == 0)
|
||||||
|
msg.m_resettarget = RESET_ARCHIVER;
|
||||||
|
else if (strcmp(target, "bgwriter") == 0)
|
||||||
msg.m_resettarget = RESET_BGWRITER;
|
msg.m_resettarget = RESET_BGWRITER;
|
||||||
else
|
else
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||||
errmsg("unrecognized reset target: \"%s\"", target),
|
errmsg("unrecognized reset target: \"%s\"", target),
|
||||||
errhint("Target must be \"bgwriter\".")));
|
errhint("Target must be \"archiver\" or \"bgwriter\".")));
|
||||||
|
|
||||||
pgstat_setheader(&msg.m_hdr, PGSTAT_MTYPE_RESETSHAREDCOUNTER);
|
pgstat_setheader(&msg.m_hdr, PGSTAT_MTYPE_RESETSHAREDCOUNTER);
|
||||||
pgstat_send(&msg, sizeof(msg));
|
pgstat_send(&msg, sizeof(msg));
|
||||||
@ -2321,6 +2325,23 @@ pgstat_fetch_stat_numbackends(void)
|
|||||||
return localNumBackends;
|
return localNumBackends;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ---------
|
||||||
|
* pgstat_fetch_stat_archiver() -
|
||||||
|
*
|
||||||
|
* Support function for the SQL-callable pgstat* functions. Returns
|
||||||
|
* a pointer to the archiver statistics struct.
|
||||||
|
* ---------
|
||||||
|
*/
|
||||||
|
PgStat_ArchiverStats *
|
||||||
|
pgstat_fetch_stat_archiver(void)
|
||||||
|
{
|
||||||
|
backend_read_statsfile();
|
||||||
|
|
||||||
|
return &archiverStats;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ---------
|
* ---------
|
||||||
* pgstat_fetch_global() -
|
* pgstat_fetch_global() -
|
||||||
@ -3035,6 +3056,28 @@ pgstat_send(void *msg, int len)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ----------
|
||||||
|
* pgstat_send_archiver() -
|
||||||
|
*
|
||||||
|
* Tell the collector about the WAL file that we successfully
|
||||||
|
* archived or failed to archive.
|
||||||
|
* ----------
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
pgstat_send_archiver(const char *xlog, bool failed)
|
||||||
|
{
|
||||||
|
PgStat_MsgArchiver msg;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Prepare and send the message
|
||||||
|
*/
|
||||||
|
pgstat_setheader(&msg.m_hdr, PGSTAT_MTYPE_ARCHIVER);
|
||||||
|
msg.m_failed = failed;
|
||||||
|
strncpy(msg.m_xlog, xlog, sizeof(msg.m_xlog));
|
||||||
|
msg.m_timestamp = GetCurrentTimestamp();
|
||||||
|
pgstat_send(&msg, sizeof(msg));
|
||||||
|
}
|
||||||
|
|
||||||
/* ----------
|
/* ----------
|
||||||
* pgstat_send_bgwriter() -
|
* pgstat_send_bgwriter() -
|
||||||
*
|
*
|
||||||
@ -3278,6 +3321,10 @@ PgstatCollectorMain(int argc, char *argv[])
|
|||||||
pgstat_recv_analyze((PgStat_MsgAnalyze *) &msg, len);
|
pgstat_recv_analyze((PgStat_MsgAnalyze *) &msg, len);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case PGSTAT_MTYPE_ARCHIVER:
|
||||||
|
pgstat_recv_archiver((PgStat_MsgArchiver *) &msg, len);
|
||||||
|
break;
|
||||||
|
|
||||||
case PGSTAT_MTYPE_BGWRITER:
|
case PGSTAT_MTYPE_BGWRITER:
|
||||||
pgstat_recv_bgwriter((PgStat_MsgBgWriter *) &msg, len);
|
pgstat_recv_bgwriter((PgStat_MsgBgWriter *) &msg, len);
|
||||||
break;
|
break;
|
||||||
@ -3562,6 +3609,12 @@ pgstat_write_statsfiles(bool permanent, bool allDbs)
|
|||||||
rc = fwrite(&globalStats, sizeof(globalStats), 1, fpout);
|
rc = fwrite(&globalStats, sizeof(globalStats), 1, fpout);
|
||||||
(void) rc; /* we'll check for error with ferror */
|
(void) rc; /* we'll check for error with ferror */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Write archiver stats struct
|
||||||
|
*/
|
||||||
|
rc = fwrite(&archiverStats, sizeof(archiverStats), 1, fpout);
|
||||||
|
(void) rc; /* we'll check for error with ferror */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Walk through the database table.
|
* Walk through the database table.
|
||||||
*/
|
*/
|
||||||
@ -3828,16 +3881,18 @@ pgstat_read_statsfiles(Oid onlydb, bool permanent, bool deep)
|
|||||||
HASH_ELEM | HASH_FUNCTION | HASH_CONTEXT);
|
HASH_ELEM | HASH_FUNCTION | HASH_CONTEXT);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Clear out global statistics so they start from zero in case we can't
|
* Clear out global and archiver statistics so they start from zero
|
||||||
* load an existing statsfile.
|
* in case we can't load an existing statsfile.
|
||||||
*/
|
*/
|
||||||
memset(&globalStats, 0, sizeof(globalStats));
|
memset(&globalStats, 0, sizeof(globalStats));
|
||||||
|
memset(&archiverStats, 0, sizeof(archiverStats));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set the current timestamp (will be kept only in case we can't load an
|
* Set the current timestamp (will be kept only in case we can't load an
|
||||||
* existing statsfile).
|
* existing statsfile).
|
||||||
*/
|
*/
|
||||||
globalStats.stat_reset_timestamp = GetCurrentTimestamp();
|
globalStats.stat_reset_timestamp = GetCurrentTimestamp();
|
||||||
|
archiverStats.stat_reset_timestamp = globalStats.stat_reset_timestamp;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Try to open the stats file. If it doesn't exist, the backends simply
|
* Try to open the stats file. If it doesn't exist, the backends simply
|
||||||
@ -3879,6 +3934,16 @@ pgstat_read_statsfiles(Oid onlydb, bool permanent, bool deep)
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Read archiver stats struct
|
||||||
|
*/
|
||||||
|
if (fread(&archiverStats, 1, sizeof(archiverStats), fpin) != sizeof(archiverStats))
|
||||||
|
{
|
||||||
|
ereport(pgStatRunningInCollector ? LOG : WARNING,
|
||||||
|
(errmsg("corrupted statistics file \"%s\"", statfile)));
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We found an existing collector stats file. Read it and put all the
|
* We found an existing collector stats file. Read it and put all the
|
||||||
* hashtable entries into place.
|
* hashtable entries into place.
|
||||||
@ -4159,7 +4224,7 @@ done:
|
|||||||
* stats_timestamp value.
|
* stats_timestamp value.
|
||||||
*
|
*
|
||||||
* - if there's no db stat entry (e.g. for a new or inactive database),
|
* - if there's no db stat entry (e.g. for a new or inactive database),
|
||||||
* there's no stat_timestamp value, but also nothing to write so we return
|
* there's no stats_timestamp value, but also nothing to write so we return
|
||||||
* the timestamp of the global statfile.
|
* the timestamp of the global statfile.
|
||||||
* ----------
|
* ----------
|
||||||
*/
|
*/
|
||||||
@ -4169,6 +4234,7 @@ pgstat_read_db_statsfile_timestamp(Oid databaseid, bool permanent,
|
|||||||
{
|
{
|
||||||
PgStat_StatDBEntry dbentry;
|
PgStat_StatDBEntry dbentry;
|
||||||
PgStat_GlobalStats myGlobalStats;
|
PgStat_GlobalStats myGlobalStats;
|
||||||
|
PgStat_ArchiverStats myArchiverStats;
|
||||||
FILE *fpin;
|
FILE *fpin;
|
||||||
int32 format_id;
|
int32 format_id;
|
||||||
const char *statfile = permanent ? PGSTAT_STAT_PERMANENT_FILENAME : pgstat_stat_filename;
|
const char *statfile = permanent ? PGSTAT_STAT_PERMANENT_FILENAME : pgstat_stat_filename;
|
||||||
@ -4211,6 +4277,18 @@ pgstat_read_db_statsfile_timestamp(Oid databaseid, bool permanent,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Read archiver stats struct
|
||||||
|
*/
|
||||||
|
if (fread(&myArchiverStats, 1, sizeof(myArchiverStats),
|
||||||
|
fpin) != sizeof(myArchiverStats))
|
||||||
|
{
|
||||||
|
ereport(pgStatRunningInCollector ? LOG : WARNING,
|
||||||
|
(errmsg("corrupted statistics file \"%s\"", statfile)));
|
||||||
|
FreeFile(fpin);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/* By default, we're going to return the timestamp of the global file. */
|
/* By default, we're going to return the timestamp of the global file. */
|
||||||
*ts = myGlobalStats.stats_timestamp;
|
*ts = myGlobalStats.stats_timestamp;
|
||||||
|
|
||||||
@ -4738,6 +4816,12 @@ pgstat_recv_resetsharedcounter(PgStat_MsgResetsharedcounter *msg, int len)
|
|||||||
memset(&globalStats, 0, sizeof(globalStats));
|
memset(&globalStats, 0, sizeof(globalStats));
|
||||||
globalStats.stat_reset_timestamp = GetCurrentTimestamp();
|
globalStats.stat_reset_timestamp = GetCurrentTimestamp();
|
||||||
}
|
}
|
||||||
|
else if (msg->m_resettarget == RESET_ARCHIVER)
|
||||||
|
{
|
||||||
|
/* Reset the archiver statistics for the cluster. */
|
||||||
|
memset(&archiverStats, 0, sizeof(archiverStats));
|
||||||
|
archiverStats.stat_reset_timestamp = GetCurrentTimestamp();
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Presumably the sender of this message validated the target, don't
|
* Presumably the sender of this message validated the target, don't
|
||||||
@ -4867,6 +4951,33 @@ pgstat_recv_analyze(PgStat_MsgAnalyze *msg, int len)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ----------
|
||||||
|
* pgstat_recv_archiver() -
|
||||||
|
*
|
||||||
|
* Process a ARCHIVER message.
|
||||||
|
* ----------
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
pgstat_recv_archiver(PgStat_MsgArchiver *msg, int len)
|
||||||
|
{
|
||||||
|
if (msg->m_failed)
|
||||||
|
{
|
||||||
|
/* Failed archival attempt */
|
||||||
|
++archiverStats.failed_count;
|
||||||
|
memcpy(archiverStats.last_failed_wal, msg->m_xlog,
|
||||||
|
sizeof(archiverStats.last_failed_wal));
|
||||||
|
archiverStats.last_failed_timestamp = msg->m_timestamp;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Successful archival operation */
|
||||||
|
++archiverStats.archived_count;
|
||||||
|
memcpy(archiverStats.last_archived_wal, msg->m_xlog,
|
||||||
|
sizeof(archiverStats.last_archived_wal));
|
||||||
|
archiverStats.last_archived_timestamp = msg->m_timestamp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* ----------
|
/* ----------
|
||||||
* pgstat_recv_bgwriter() -
|
* pgstat_recv_bgwriter() -
|
||||||
*
|
*
|
||||||
|
@ -87,6 +87,8 @@ extern Datum pg_stat_get_db_temp_bytes(PG_FUNCTION_ARGS);
|
|||||||
extern Datum pg_stat_get_db_blk_read_time(PG_FUNCTION_ARGS);
|
extern Datum pg_stat_get_db_blk_read_time(PG_FUNCTION_ARGS);
|
||||||
extern Datum pg_stat_get_db_blk_write_time(PG_FUNCTION_ARGS);
|
extern Datum pg_stat_get_db_blk_write_time(PG_FUNCTION_ARGS);
|
||||||
|
|
||||||
|
extern Datum pg_stat_get_archiver(PG_FUNCTION_ARGS);
|
||||||
|
|
||||||
extern Datum pg_stat_get_bgwriter_timed_checkpoints(PG_FUNCTION_ARGS);
|
extern Datum pg_stat_get_bgwriter_timed_checkpoints(PG_FUNCTION_ARGS);
|
||||||
extern Datum pg_stat_get_bgwriter_requested_checkpoints(PG_FUNCTION_ARGS);
|
extern Datum pg_stat_get_bgwriter_requested_checkpoints(PG_FUNCTION_ARGS);
|
||||||
extern Datum pg_stat_get_checkpoint_write_time(PG_FUNCTION_ARGS);
|
extern Datum pg_stat_get_checkpoint_write_time(PG_FUNCTION_ARGS);
|
||||||
@ -1712,3 +1714,70 @@ pg_stat_reset_single_function_counters(PG_FUNCTION_ARGS)
|
|||||||
|
|
||||||
PG_RETURN_VOID();
|
PG_RETURN_VOID();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Datum
|
||||||
|
pg_stat_get_archiver(PG_FUNCTION_ARGS)
|
||||||
|
{
|
||||||
|
TupleDesc tupdesc;
|
||||||
|
Datum values[7];
|
||||||
|
bool nulls[7];
|
||||||
|
PgStat_ArchiverStats *archiver_stats;
|
||||||
|
|
||||||
|
/* Initialise values and NULL flags arrays */
|
||||||
|
MemSet(values, 0, sizeof(values));
|
||||||
|
MemSet(nulls, 0, sizeof(nulls));
|
||||||
|
|
||||||
|
/* Initialise attributes information in the tuple descriptor */
|
||||||
|
tupdesc = CreateTemplateTupleDesc(7, false);
|
||||||
|
TupleDescInitEntry(tupdesc, (AttrNumber) 1, "archived_count",
|
||||||
|
INT8OID, -1, 0);
|
||||||
|
TupleDescInitEntry(tupdesc, (AttrNumber) 2, "last_archived_wal",
|
||||||
|
TEXTOID, -1, 0);
|
||||||
|
TupleDescInitEntry(tupdesc, (AttrNumber) 3, "last_archived_time",
|
||||||
|
TIMESTAMPTZOID, -1, 0);
|
||||||
|
TupleDescInitEntry(tupdesc, (AttrNumber) 4, "failed_count",
|
||||||
|
INT8OID, -1, 0);
|
||||||
|
TupleDescInitEntry(tupdesc, (AttrNumber) 5, "last_failed_wal",
|
||||||
|
TEXTOID, -1, 0);
|
||||||
|
TupleDescInitEntry(tupdesc, (AttrNumber) 6, "last_failed_time",
|
||||||
|
TIMESTAMPTZOID, -1, 0);
|
||||||
|
TupleDescInitEntry(tupdesc, (AttrNumber) 7, "stats_reset",
|
||||||
|
TIMESTAMPTZOID, -1, 0);
|
||||||
|
|
||||||
|
BlessTupleDesc(tupdesc);
|
||||||
|
|
||||||
|
/* Get statistics about the archiver process */
|
||||||
|
archiver_stats = pgstat_fetch_stat_archiver();
|
||||||
|
|
||||||
|
/* Fill values and NULLs */
|
||||||
|
values[0] = Int64GetDatum(archiver_stats->archived_count);
|
||||||
|
if (archiver_stats->last_archived_wal == 0)
|
||||||
|
nulls[1] = true;
|
||||||
|
else
|
||||||
|
values[1] = CStringGetTextDatum(archiver_stats->last_archived_wal);
|
||||||
|
|
||||||
|
if (archiver_stats->last_archived_timestamp == 0)
|
||||||
|
nulls[2] = true;
|
||||||
|
else
|
||||||
|
values[2] = TimestampTzGetDatum(archiver_stats->last_archived_timestamp);
|
||||||
|
|
||||||
|
values[3] = Int64GetDatum(archiver_stats->failed_count);
|
||||||
|
if (archiver_stats->last_failed_wal == 0)
|
||||||
|
nulls[4] = true;
|
||||||
|
else
|
||||||
|
values[4] = CStringGetTextDatum(archiver_stats->last_failed_wal);
|
||||||
|
|
||||||
|
if (archiver_stats->last_failed_timestamp == 0)
|
||||||
|
nulls[5] = true;
|
||||||
|
else
|
||||||
|
values[5] = TimestampTzGetDatum(archiver_stats->last_failed_timestamp);
|
||||||
|
|
||||||
|
if (archiver_stats->stat_reset_timestamp == 0)
|
||||||
|
nulls[6] = true;
|
||||||
|
else
|
||||||
|
values[6] = TimestampTzGetDatum(archiver_stats->stat_reset_timestamp);
|
||||||
|
|
||||||
|
/* Returns the record as Datum */
|
||||||
|
PG_RETURN_DATUM(HeapTupleGetDatum(
|
||||||
|
heap_form_tuple(tupdesc, values, nulls)));
|
||||||
|
}
|
||||||
|
@ -2702,6 +2702,8 @@ DATA(insert OID = 2844 ( pg_stat_get_db_blk_read_time PGNSP PGUID 12 1 0 0 0 f
|
|||||||
DESCR("statistics: block read time, in msec");
|
DESCR("statistics: block read time, in msec");
|
||||||
DATA(insert OID = 2845 ( pg_stat_get_db_blk_write_time PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 701 "26" _null_ _null_ _null_ _null_ pg_stat_get_db_blk_write_time _null_ _null_ _null_ ));
|
DATA(insert OID = 2845 ( pg_stat_get_db_blk_write_time PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 701 "26" _null_ _null_ _null_ _null_ pg_stat_get_db_blk_write_time _null_ _null_ _null_ ));
|
||||||
DESCR("statistics: block write time, in msec");
|
DESCR("statistics: block write time, in msec");
|
||||||
|
DATA(insert OID = 3195 ( pg_stat_get_archiver PGNSP PGUID 12 1 0 0 0 f f f f f f s 0 0 2249 "" "{20,25,1184,20,25,1184,1184}" "{o,o,o,o,o,o,o}" "{archived_count,last_archived_wal,last_archived_time,failed_count,last_failed_wal,last_failed_time,stats_reset}" _null_ pg_stat_get_archiver _null_ _null_ _null_ ));
|
||||||
|
DESCR("statistics: information about WAL archiver");
|
||||||
DATA(insert OID = 2769 ( pg_stat_get_bgwriter_timed_checkpoints PGNSP PGUID 12 1 0 0 0 f f f f t f s 0 0 20 "" _null_ _null_ _null_ _null_ pg_stat_get_bgwriter_timed_checkpoints _null_ _null_ _null_ ));
|
DATA(insert OID = 2769 ( pg_stat_get_bgwriter_timed_checkpoints PGNSP PGUID 12 1 0 0 0 f f f f t f s 0 0 20 "" _null_ _null_ _null_ _null_ pg_stat_get_bgwriter_timed_checkpoints _null_ _null_ _null_ ));
|
||||||
DESCR("statistics: number of timed checkpoints started by the bgwriter");
|
DESCR("statistics: number of timed checkpoints started by the bgwriter");
|
||||||
DATA(insert OID = 2770 ( pg_stat_get_bgwriter_requested_checkpoints PGNSP PGUID 12 1 0 0 0 f f f f t f s 0 0 20 "" _null_ _null_ _null_ _null_ pg_stat_get_bgwriter_requested_checkpoints _null_ _null_ _null_ ));
|
DATA(insert OID = 2770 ( pg_stat_get_bgwriter_requested_checkpoints PGNSP PGUID 12 1 0 0 0 f f f f t f s 0 0 20 "" _null_ _null_ _null_ _null_ pg_stat_get_bgwriter_requested_checkpoints _null_ _null_ _null_ ));
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#include "fmgr.h"
|
#include "fmgr.h"
|
||||||
#include "libpq/pqcomm.h"
|
#include "libpq/pqcomm.h"
|
||||||
#include "portability/instr_time.h"
|
#include "portability/instr_time.h"
|
||||||
|
#include "postmaster/pgarch.h"
|
||||||
#include "utils/hsearch.h"
|
#include "utils/hsearch.h"
|
||||||
#include "utils/relcache.h"
|
#include "utils/relcache.h"
|
||||||
|
|
||||||
@ -44,6 +45,7 @@ typedef enum StatMsgType
|
|||||||
PGSTAT_MTYPE_AUTOVAC_START,
|
PGSTAT_MTYPE_AUTOVAC_START,
|
||||||
PGSTAT_MTYPE_VACUUM,
|
PGSTAT_MTYPE_VACUUM,
|
||||||
PGSTAT_MTYPE_ANALYZE,
|
PGSTAT_MTYPE_ANALYZE,
|
||||||
|
PGSTAT_MTYPE_ARCHIVER,
|
||||||
PGSTAT_MTYPE_BGWRITER,
|
PGSTAT_MTYPE_BGWRITER,
|
||||||
PGSTAT_MTYPE_FUNCSTAT,
|
PGSTAT_MTYPE_FUNCSTAT,
|
||||||
PGSTAT_MTYPE_FUNCPURGE,
|
PGSTAT_MTYPE_FUNCPURGE,
|
||||||
@ -102,6 +104,7 @@ typedef struct PgStat_TableCounts
|
|||||||
/* Possible targets for resetting cluster-wide shared values */
|
/* Possible targets for resetting cluster-wide shared values */
|
||||||
typedef enum PgStat_Shared_Reset_Target
|
typedef enum PgStat_Shared_Reset_Target
|
||||||
{
|
{
|
||||||
|
RESET_ARCHIVER,
|
||||||
RESET_BGWRITER
|
RESET_BGWRITER
|
||||||
} PgStat_Shared_Reset_Target;
|
} PgStat_Shared_Reset_Target;
|
||||||
|
|
||||||
@ -355,6 +358,18 @@ typedef struct PgStat_MsgAnalyze
|
|||||||
} PgStat_MsgAnalyze;
|
} PgStat_MsgAnalyze;
|
||||||
|
|
||||||
|
|
||||||
|
/* ----------
|
||||||
|
* PgStat_MsgArchiver Sent by the archiver to update statistics.
|
||||||
|
* ----------
|
||||||
|
*/
|
||||||
|
typedef struct PgStat_MsgArchiver
|
||||||
|
{
|
||||||
|
PgStat_MsgHdr m_hdr;
|
||||||
|
bool m_failed; /* Failed attempt */
|
||||||
|
char m_xlog[MAX_XFN_CHARS + 1];
|
||||||
|
TimestampTz m_timestamp;
|
||||||
|
} PgStat_MsgArchiver;
|
||||||
|
|
||||||
/* ----------
|
/* ----------
|
||||||
* PgStat_MsgBgWriter Sent by the bgwriter to update statistics.
|
* PgStat_MsgBgWriter Sent by the bgwriter to update statistics.
|
||||||
* ----------
|
* ----------
|
||||||
@ -502,6 +517,7 @@ typedef union PgStat_Msg
|
|||||||
PgStat_MsgAutovacStart msg_autovacuum;
|
PgStat_MsgAutovacStart msg_autovacuum;
|
||||||
PgStat_MsgVacuum msg_vacuum;
|
PgStat_MsgVacuum msg_vacuum;
|
||||||
PgStat_MsgAnalyze msg_analyze;
|
PgStat_MsgAnalyze msg_analyze;
|
||||||
|
PgStat_MsgArchiver msg_archiver;
|
||||||
PgStat_MsgBgWriter msg_bgwriter;
|
PgStat_MsgBgWriter msg_bgwriter;
|
||||||
PgStat_MsgFuncstat msg_funcstat;
|
PgStat_MsgFuncstat msg_funcstat;
|
||||||
PgStat_MsgFuncpurge msg_funcpurge;
|
PgStat_MsgFuncpurge msg_funcpurge;
|
||||||
@ -518,7 +534,7 @@ typedef union PgStat_Msg
|
|||||||
* ------------------------------------------------------------
|
* ------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define PGSTAT_FILE_FORMAT_ID 0x01A5BC9B
|
#define PGSTAT_FILE_FORMAT_ID 0x01A5BC9C
|
||||||
|
|
||||||
/* ----------
|
/* ----------
|
||||||
* PgStat_StatDBEntry The collector's data per database
|
* PgStat_StatDBEntry The collector's data per database
|
||||||
@ -611,6 +627,20 @@ typedef struct PgStat_StatFuncEntry
|
|||||||
} PgStat_StatFuncEntry;
|
} PgStat_StatFuncEntry;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Archiver statistics kept in the stats collector
|
||||||
|
*/
|
||||||
|
typedef struct PgStat_ArchiverStats
|
||||||
|
{
|
||||||
|
PgStat_Counter archived_count; /* archival successes */
|
||||||
|
char last_archived_wal[MAX_XFN_CHARS + 1]; /* last WAL file archived */
|
||||||
|
TimestampTz last_archived_timestamp; /* last archival success time */
|
||||||
|
PgStat_Counter failed_count; /* failed archival attempts */
|
||||||
|
char last_failed_wal[MAX_XFN_CHARS + 1]; /* WAL file involved in last failure */
|
||||||
|
TimestampTz last_failed_timestamp; /* last archival failure time */
|
||||||
|
TimestampTz stat_reset_timestamp;
|
||||||
|
} PgStat_ArchiverStats;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Global statistics kept in the stats collector
|
* Global statistics kept in the stats collector
|
||||||
*/
|
*/
|
||||||
@ -863,6 +893,7 @@ extern void pgstat_twophase_postcommit(TransactionId xid, uint16 info,
|
|||||||
extern void pgstat_twophase_postabort(TransactionId xid, uint16 info,
|
extern void pgstat_twophase_postabort(TransactionId xid, uint16 info,
|
||||||
void *recdata, uint32 len);
|
void *recdata, uint32 len);
|
||||||
|
|
||||||
|
extern void pgstat_send_archiver(const char *xlog, bool failed);
|
||||||
extern void pgstat_send_bgwriter(void);
|
extern void pgstat_send_bgwriter(void);
|
||||||
|
|
||||||
/* ----------
|
/* ----------
|
||||||
@ -875,6 +906,7 @@ extern PgStat_StatTabEntry *pgstat_fetch_stat_tabentry(Oid relid);
|
|||||||
extern PgBackendStatus *pgstat_fetch_stat_beentry(int beid);
|
extern PgBackendStatus *pgstat_fetch_stat_beentry(int beid);
|
||||||
extern PgStat_StatFuncEntry *pgstat_fetch_stat_funcentry(Oid funcid);
|
extern PgStat_StatFuncEntry *pgstat_fetch_stat_funcentry(Oid funcid);
|
||||||
extern int pgstat_fetch_stat_numbackends(void);
|
extern int pgstat_fetch_stat_numbackends(void);
|
||||||
|
extern PgStat_ArchiverStats *pgstat_fetch_stat_archiver(void);
|
||||||
extern PgStat_GlobalStats *pgstat_fetch_global(void);
|
extern PgStat_GlobalStats *pgstat_fetch_global(void);
|
||||||
|
|
||||||
#endif /* PGSTAT_H */
|
#endif /* PGSTAT_H */
|
||||||
|
@ -13,6 +13,19 @@
|
|||||||
#ifndef _PGARCH_H
|
#ifndef _PGARCH_H
|
||||||
#define _PGARCH_H
|
#define _PGARCH_H
|
||||||
|
|
||||||
|
/* ----------
|
||||||
|
* Archiver control info.
|
||||||
|
*
|
||||||
|
* We expect that archivable files within pg_xlog will have names between
|
||||||
|
* MIN_XFN_CHARS and MAX_XFN_CHARS in length, consisting only of characters
|
||||||
|
* appearing in VALID_XFN_CHARS. The status files in archive_status have
|
||||||
|
* corresponding names with ".ready" or ".done" appended.
|
||||||
|
* ----------
|
||||||
|
*/
|
||||||
|
#define MIN_XFN_CHARS 16
|
||||||
|
#define MAX_XFN_CHARS 40
|
||||||
|
#define VALID_XFN_CHARS "0123456789ABCDEF.history.backup"
|
||||||
|
|
||||||
/* ----------
|
/* ----------
|
||||||
* Functions called from postmaster
|
* Functions called from postmaster
|
||||||
* ----------
|
* ----------
|
||||||
|
@ -1640,6 +1640,14 @@ pg_stat_all_tables| SELECT c.oid AS relid,
|
|||||||
LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
|
LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
|
||||||
WHERE (c.relkind = ANY (ARRAY['r'::"char", 't'::"char", 'm'::"char"]))
|
WHERE (c.relkind = ANY (ARRAY['r'::"char", 't'::"char", 'm'::"char"]))
|
||||||
GROUP BY c.oid, n.nspname, c.relname;
|
GROUP BY c.oid, n.nspname, c.relname;
|
||||||
|
pg_stat_archiver| SELECT s.archived_count,
|
||||||
|
s.last_archived_wal,
|
||||||
|
s.last_archived_time,
|
||||||
|
s.failed_count,
|
||||||
|
s.last_failed_wal,
|
||||||
|
s.last_failed_time,
|
||||||
|
s.stats_reset
|
||||||
|
FROM pg_stat_get_archiver() s(archived_count, last_archived_wal, last_archived_time, failed_count, last_failed_wal, last_failed_time, stats_reset);
|
||||||
pg_stat_bgwriter| SELECT pg_stat_get_bgwriter_timed_checkpoints() AS checkpoints_timed,
|
pg_stat_bgwriter| SELECT pg_stat_get_bgwriter_timed_checkpoints() AS checkpoints_timed,
|
||||||
pg_stat_get_bgwriter_requested_checkpoints() AS checkpoints_req,
|
pg_stat_get_bgwriter_requested_checkpoints() AS checkpoints_req,
|
||||||
pg_stat_get_checkpoint_write_time() AS checkpoint_write_time,
|
pg_stat_get_checkpoint_write_time() AS checkpoint_write_time,
|
||||||
|
Loading…
Reference in New Issue
Block a user