On Thu, Jan 9, 2014 at 6:36 AM, Gabriele Bartolini <gabriele.bartol...@2ndquadrant.it> wrote: > Il 08/01/14 18:42, Simon Riggs ha scritto: >> Not sure I see why it needs to be an SRF. It only returns one row. > Attached is version 4, which removes management of SRF stages.
I have been looking at v4 a bit more, and found a couple of small things: - a warning in pgstatfuncs.c - some typos and format fixing in the sgml docs - some corrections in a couple of comments - Fixed an error message related to pg_stat_reset_shared referring only to bgwriter and not the new option archiver. Here is how the new message looks: =# select pg_stat_reset_shared('popo'); ERROR: 22023: unrecognized reset target: "popo" HINT: Target must be "bgwriter" or "archiver" A new version is attached containing those fixes. I played also with the patch and pgbench, simulating some archive failures and successes while running pgbench and the reports given by pg_stat_archiver were correct, so I am marking this patch as "Ready for committer". Regards, -- Michael
diff --git a/doc/src/sgml/monitoring.sgml b/doc/src/sgml/monitoring.sgml index 4ec6981..eb5131f 100644 --- a/doc/src/sgml/monitoring.sgml +++ b/doc/src/sgml/monitoring.sgml @@ -270,11 +270,19 @@ postgres: <replaceable>user</> <replaceable>database</> <replaceable>host</> <re </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> <entry><structname>pg_stat_bgwriter</><indexterm><primary>pg_stat_bgwriter</primary></indexterm></entry> <entry>One row only, showing statistics about the background writer process's activity. See <xref linkend="pg-stat-bgwriter-view"> for details. - </entry> + </entry> </row> <row> @@ -648,6 +656,63 @@ postgres: <replaceable>user</> <replaceable>database</> <replaceable>host</> <re </para> </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_wals</></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_wal_time</></entry> + <entry><type>timestamp with time zone</type></entry> + <entry>Time of the last successful archive operation</entry> + </row> + <row> + <entry><structfield>failed_attempts</></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_wal_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"> <title><structname>pg_stat_bgwriter</structname> View</title> @@ -1613,6 +1678,8 @@ postgres: <replaceable>user</> <replaceable>database</> <replaceable>host</> <re argument (requires superuser privileges). Calling <literal>pg_stat_reset_shared('bgwriter')</> will zero all the 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> </row> diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql index 043d118..c8a89fc 100644 --- a/src/backend/catalog/system_views.sql +++ b/src/backend/catalog/system_views.sql @@ -672,6 +672,17 @@ CREATE VIEW pg_stat_xact_user_functions AS WHERE P.prolang != 12 -- fast check to eliminate built-in functions AND pg_stat_get_xact_function_calls(P.oid) IS NOT NULL; +CREATE VIEW pg_stat_archiver AS + SELECT + s.archived_wals, + s.last_archived_wal, + s.last_archived_wal_time, + s.failed_attempts, + s.last_failed_wal, + s.last_failed_wal_time, + s.stats_reset + FROM pg_stat_get_archiver() s; + CREATE VIEW pg_stat_bgwriter AS SELECT pg_stat_get_bgwriter_timed_checkpoints() AS checkpoints_timed, diff --git a/src/backend/postmaster/pgarch.c b/src/backend/postmaster/pgarch.c index 2fd7a01..69f8600 100644 --- a/src/backend/postmaster/pgarch.c +++ b/src/backend/postmaster/pgarch.c @@ -36,6 +36,7 @@ #include "access/xlog_internal.h" #include "libpq/pqsignal.h" #include "miscadmin.h" +#include "pgstat.h" #include "postmaster/fork_process.h" #include "postmaster/pgarch.h" #include "postmaster/postmaster.h" @@ -46,6 +47,7 @@ #include "storage/pmsignal.h" #include "utils/guc.h" #include "utils/ps_status.h" +#include "utils/timestamp.h" /* ---------- @@ -647,6 +649,13 @@ pgarch_archiveXlog(char *xlog) snprintf(activitymsg, sizeof(activitymsg), "failed on %s", xlog); set_ps_display(activitymsg, false); + /* Send archiver statistics to the stats collector */ + ArchiverStats.m_failed = true; + strncpy(ArchiverStats.m_xlog, + xlog, sizeof(ArchiverStats.m_xlog)); + ArchiverStats.m_timestamp = GetCurrentTimestamp(); + pgstat_send_archiver(); + return false; } ereport(DEBUG1, @@ -755,4 +764,10 @@ pgarch_archiveDone(char *xlog) (errcode_for_file_access(), errmsg("could not rename file \"%s\" to \"%s\": %m", rlogready, rlogdone))); + /* Send archiver statistics to the stats collector */ + ArchiverStats.m_failed = false; + strncpy(ArchiverStats.m_xlog, + xlog, sizeof(ArchiverStats.m_xlog)); + ArchiverStats.m_timestamp = GetCurrentTimestamp(); + pgstat_send_archiver(); } diff --git a/src/backend/postmaster/pgstat.c b/src/backend/postmaster/pgstat.c index 1c3b481..8aa5127 100644 --- a/src/backend/postmaster/pgstat.c +++ b/src/backend/postmaster/pgstat.c @@ -123,6 +123,13 @@ char *pgstat_stat_filename = NULL; char *pgstat_stat_tmpname = NULL; /* + * Archiver global statistics counters (unused in other processes). + * Stored directly in a stats message structure so it can be sent + * without needing to copy things around. We assume this inits to zeroes. + */ +PgStat_MsgArchiver ArchiverStats; + +/* * BgWriter global statistics counters (unused in other processes). * Stored directly in a stats message structure so it can be sent * without needing to copy things around. We assume this inits to zeroes. @@ -217,6 +224,12 @@ static PgBackendStatus *localBackendStatusTable = NULL; static int localNumBackends = 0; /* + * Archiver statistics, kept in the stats collector. + * Contains statistics regarding the archiving process. + */ +static PgStat_ArchiverStats archiverStats; + +/* * Cluster wide statistics, kept in the stats collector. * Contains statistics that are not collected per database * or per table. @@ -292,6 +305,7 @@ static void pgstat_recv_resetsinglecounter(PgStat_MsgResetsinglecounter *msg, in static void pgstat_recv_autovac(PgStat_MsgAutovacStart *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_archiver(PgStat_MsgArchiver *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_funcpurge(PgStat_MsgFuncpurge *msg, int len); @@ -1257,13 +1271,15 @@ pgstat_reset_shared_counters(const char *target) (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), 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; else ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("unrecognized reset target: \"%s\"", target), - errhint("Target must be \"bgwriter\"."))); + errhint("Target must be \"bgwriter\" or \"archiver\"."))); pgstat_setheader(&msg.m_hdr, PGSTAT_MTYPE_RESETSHAREDCOUNTER); pgstat_send(&msg, sizeof(msg)); @@ -2323,6 +2339,23 @@ pgstat_fetch_stat_numbackends(void) /* * --------- + * 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() - * * Support function for the SQL-callable pgstat* functions. Returns @@ -3036,6 +3069,39 @@ pgstat_send(void *msg, int len) } /* ---------- + * pgstat_send_archiver() - + * + * Send archiver statistics to the collector + * ---------- + */ +void +pgstat_send_archiver(void) +{ + /* We assume this initializes to zeroes */ + static const PgStat_MsgArchiver all_zeroes; + + /* + * This function can be called even if nothing at all has happened. In + * this case, avoid sending a completely empty message to the stats + * collector. + */ + if (memcmp(&ArchiverStats, &all_zeroes, sizeof(PgStat_MsgArchiver)) == 0) + return; + + /* + * Prepare and send the message + */ + pgstat_setheader(&ArchiverStats.m_hdr, PGSTAT_MTYPE_ARCHIVER); + pgstat_send(&ArchiverStats, sizeof(ArchiverStats)); + + /* + * Clear out the statistics buffer, so it can be re-used. + */ + MemSet(&ArchiverStats, 0, sizeof(ArchiverStats)); +} + + +/* ---------- * pgstat_send_bgwriter() - * * Send bgwriter statistics to the collector @@ -3278,6 +3344,10 @@ PgstatCollectorMain(int argc, char *argv[]) pgstat_recv_analyze((PgStat_MsgAnalyze *) &msg, len); break; + case PGSTAT_MTYPE_ARCHIVER: + pgstat_recv_archiver((PgStat_MsgArchiver *) &msg, len); + break; + case PGSTAT_MTYPE_BGWRITER: pgstat_recv_bgwriter((PgStat_MsgBgWriter *) &msg, len); break; @@ -3548,6 +3618,7 @@ pgstat_write_statsfiles(bool permanent, bool allDbs) * Set the timestamp of the stats file. */ globalStats.stats_timestamp = GetCurrentTimestamp(); + archiverStats.stats_timestamp = globalStats.stats_timestamp; /* * Write the file header --- currently just a format ID. @@ -3563,6 +3634,12 @@ pgstat_write_statsfiles(bool permanent, bool allDbs) (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. */ hash_seq_init(&hstat, pgStatDBHash); @@ -3828,16 +3905,18 @@ pgstat_read_statsfiles(Oid onlydb, bool permanent, bool deep) HASH_ELEM | HASH_FUNCTION | HASH_CONTEXT); /* - * Clear out global statistics so they start from zero in case we can't - * load an existing statsfile. + * Clear out global and archiver statistics so they start from zero + * in case we can't load an existing statsfile. */ 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 * existing statsfile). */ 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 @@ -3875,7 +3954,17 @@ pgstat_read_statsfiles(Oid onlydb, bool permanent, bool deep) if (fread(&globalStats, 1, sizeof(globalStats), fpin) != sizeof(globalStats)) { ereport(pgStatRunningInCollector ? LOG : WARNING, - (errmsg("corrupted statistics file \"%s\"", statfile))); + (errmsg("corrupted statistics file (global) \"%s\"", statfile))); + goto done; + } + + /* + * Read archiver stats struct + */ + if (fread(&archiverStats, 1, sizeof(archiverStats), fpin) != sizeof(archiverStats)) + { + ereport(pgStatRunningInCollector ? LOG : WARNING, + (errmsg("corrupted statistics file (archiver) \"%s\"", statfile))); goto done; } @@ -4169,6 +4258,7 @@ pgstat_read_db_statsfile_timestamp(Oid databaseid, bool permanent, { PgStat_StatDBEntry dbentry; PgStat_GlobalStats myGlobalStats; + PgStat_ArchiverStats myArchiverStats; FILE *fpin; int32 format_id; const char *statfile = permanent ? PGSTAT_STAT_PERMANENT_FILENAME : pgstat_stat_filename; @@ -4211,6 +4301,18 @@ pgstat_read_db_statsfile_timestamp(Oid databaseid, bool permanent, 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. */ *ts = myGlobalStats.stats_timestamp; @@ -4738,6 +4840,12 @@ pgstat_recv_resetsharedcounter(PgStat_MsgResetsharedcounter *msg, int len) memset(&globalStats, 0, sizeof(globalStats)); 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 @@ -4868,6 +4976,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_attempts; + memcpy(archiverStats.last_failed_wal, msg->m_xlog, + sizeof(archiverStats.last_failed_wal)); + archiverStats.last_failed_wal_timestamp = msg->m_timestamp; + } + else + { + /* Successful archival operation */ + ++archiverStats.archived_wals; + memcpy(archiverStats.last_archived_wal, msg->m_xlog, + sizeof(archiverStats.last_archived_wal)); + archiverStats.last_archived_wal_timestamp = msg->m_timestamp; + } +} + +/* ---------- * pgstat_recv_bgwriter() - * * Process a BGWRITER message. diff --git a/src/backend/utils/adt/pgstatfuncs.c b/src/backend/utils/adt/pgstatfuncs.c index 2b8f5ee..0e5cd09 100644 --- a/src/backend/utils/adt/pgstatfuncs.c +++ b/src/backend/utils/adt/pgstatfuncs.c @@ -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_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_requested_checkpoints(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(); } + +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_wals", + INT8OID, -1, 0); + TupleDescInitEntry(tupdesc, (AttrNumber) 2, "last_archived_wal", + TEXTOID, -1, 0); + TupleDescInitEntry(tupdesc, (AttrNumber) 3, "last_archived_wal_time", + TIMESTAMPTZOID, -1, 0); + TupleDescInitEntry(tupdesc, (AttrNumber) 4, "failed_attempts", + INT8OID, -1, 0); + TupleDescInitEntry(tupdesc, (AttrNumber) 5, "last_failed_wal", + TEXTOID, -1, 0); + TupleDescInitEntry(tupdesc, (AttrNumber) 6, "last_failed_wal_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_wals); + if (archiver_stats->last_archived_wal == 0) + nulls[1] = true; + else + values[1] = CStringGetTextDatum(archiver_stats->last_archived_wal); + + if (archiver_stats->last_archived_wal_timestamp == 0) + nulls[2] = true; + else + values[2] = TimestampTzGetDatum(archiver_stats->last_archived_wal_timestamp); + + values[3] = Int64GetDatum(archiver_stats->failed_attempts); + if (archiver_stats->last_failed_wal == 0) + nulls[4] = true; + else + values[4] = CStringGetTextDatum(archiver_stats->last_failed_wal); + + if (archiver_stats->last_failed_wal_timestamp == 0) + nulls[5] = true; + else + values[5] = TimestampTzGetDatum(archiver_stats->last_failed_wal_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))); +} diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h index ad9774c..e81ef2e 100644 --- a/src/include/catalog/pg_proc.h +++ b/src/include/catalog/pg_proc.h @@ -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"); 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"); +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_wals,last_archived_wal,last_archived_wal_time,failed_attempts,last_failed_wal,last_failed_wal_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_ )); 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_ )); diff --git a/src/include/pgstat.h b/src/include/pgstat.h index 0b458e5..d07abd2 100644 --- a/src/include/pgstat.h +++ b/src/include/pgstat.h @@ -17,6 +17,7 @@ #include "portability/instr_time.h" #include "utils/hsearch.h" #include "utils/relcache.h" +#include "access/xlog_internal.h" /* Values for track_functions GUC variable --- order is significant! */ @@ -44,6 +45,7 @@ typedef enum StatMsgType PGSTAT_MTYPE_AUTOVAC_START, PGSTAT_MTYPE_VACUUM, PGSTAT_MTYPE_ANALYZE, + PGSTAT_MTYPE_ARCHIVER, PGSTAT_MTYPE_BGWRITER, PGSTAT_MTYPE_FUNCSTAT, PGSTAT_MTYPE_FUNCPURGE, @@ -102,6 +104,7 @@ typedef struct PgStat_TableCounts /* Possible targets for resetting cluster-wide shared values */ typedef enum PgStat_Shared_Reset_Target { + RESET_ARCHIVER, RESET_BGWRITER } PgStat_Shared_Reset_Target; @@ -356,6 +359,18 @@ typedef struct 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[MAXFNAMELEN]; + TimestampTz m_timestamp; +} PgStat_MsgArchiver; + +/* ---------- * PgStat_MsgBgWriter Sent by the bgwriter to update statistics. * ---------- */ @@ -502,6 +517,7 @@ typedef union PgStat_Msg PgStat_MsgAutovacStart msg_autovacuum; PgStat_MsgVacuum msg_vacuum; PgStat_MsgAnalyze msg_analyze; + PgStat_MsgArchiver msg_archiver; PgStat_MsgBgWriter msg_bgwriter; PgStat_MsgFuncstat msg_funcstat; 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 @@ -612,6 +628,21 @@ typedef struct PgStat_StatFuncEntry /* + * Archiver statistics kept in the stats collector + */ +typedef struct PgStat_ArchiverStats +{ + TimestampTz stats_timestamp; /* time of stats file update */ + PgStat_Counter archived_wals; + char last_archived_wal[MAXFNAMELEN]; /* last WAL file archived */ + TimestampTz last_archived_wal_timestamp; /* last archival success */ + PgStat_Counter failed_attempts; + char last_failed_wal[MAXFNAMELEN]; /* last WAL file involved in failure */ + TimestampTz last_failed_wal_timestamp; /* last archival failure */ + TimestampTz stat_reset_timestamp; +} PgStat_ArchiverStats; + +/* * Global statistics kept in the stats collector */ typedef struct PgStat_GlobalStats @@ -732,6 +763,11 @@ extern char *pgstat_stat_tmpname; extern char *pgstat_stat_filename; /* + * Archiver statistics counters are updated directly by pgarch + */ +extern PgStat_MsgArchiver ArchiverStats; + +/* * BgWriter statistics counters are updated directly by bgwriter and bufmgr */ extern PgStat_MsgBgWriter BgWriterStats; @@ -863,6 +899,7 @@ extern void pgstat_twophase_postcommit(TransactionId xid, uint16 info, extern void pgstat_twophase_postabort(TransactionId xid, uint16 info, void *recdata, uint32 len); +extern void pgstat_send_archiver(void); extern void pgstat_send_bgwriter(void); /* ---------- @@ -875,6 +912,7 @@ extern PgStat_StatTabEntry *pgstat_fetch_stat_tabentry(Oid relid); extern PgBackendStatus *pgstat_fetch_stat_beentry(int beid); extern PgStat_StatFuncEntry *pgstat_fetch_stat_funcentry(Oid funcid); extern int pgstat_fetch_stat_numbackends(void); +extern PgStat_ArchiverStats *pgstat_fetch_stat_archiver(void); extern PgStat_GlobalStats *pgstat_fetch_global(void); #endif /* PGSTAT_H */ diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out index 9f089e3..bffcb30 100644 --- a/src/test/regress/expected/rules.out +++ b/src/test/regress/expected/rules.out @@ -1640,6 +1640,14 @@ pg_stat_all_tables| SELECT c.oid AS relid, LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) WHERE (c.relkind = ANY (ARRAY['r'::"char", 't'::"char", 'm'::"char"])) GROUP BY c.oid, n.nspname, c.relname; +pg_stat_archiver| SELECT s.archived_wals, + s.last_archived_wal, + s.last_archived_wal_time, + s.failed_attempts, + s.last_failed_wal, + s.last_failed_wal_time, + s.stats_reset + FROM pg_stat_get_archiver() s(archived_wals, last_archived_wal, last_archived_wal_time, failed_attempts, last_failed_wal, last_failed_wal_time, stats_reset); 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_checkpoint_write_time() AS checkpoint_write_time,
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers