>
> So, for now, the counters only track sockets created from an inbound
> (client to server) connection.
here's v3 of the patch (rebase and cleanup).
-nigel.
*** a/src/backend/catalog/system_views.sql
--- b/src/backend/catalog/system_views.sql
***************
*** 586,592 **** CREATE VIEW pg_stat_activity AS
S.state_change,
S.waiting,
S.state,
! S.query
FROM pg_database D, pg_stat_get_activity(NULL) AS S, pg_authid U
WHERE S.datid = D.oid AND
S.usesysid = U.oid;
--- 586,594 ----
S.state_change,
S.waiting,
S.state,
! S.query,
! S.bytes_sent,
! S.bytes_received
FROM pg_database D, pg_stat_get_activity(NULL) AS S, pg_authid U
WHERE S.datid = D.oid AND
S.usesysid = U.oid;
***************
*** 601,606 **** CREATE VIEW pg_stat_replication AS
--- 603,610 ----
S.client_hostname,
S.client_port,
S.backend_start,
+ S.bytes_sent,
+ S.bytes_received,
W.state,
W.sent_location,
W.write_location,
***************
*** 634,639 **** CREATE VIEW pg_stat_database AS
--- 638,645 ----
pg_stat_get_db_deadlocks(D.oid) AS deadlocks,
pg_stat_get_db_blk_read_time(D.oid) AS blk_read_time,
pg_stat_get_db_blk_write_time(D.oid) AS blk_write_time,
+ pg_stat_get_db_bytes_sent(D.oid) AS bytes_sent,
+ pg_stat_get_db_bytes_received(D.oid) AS bytes_received,
pg_stat_get_db_stat_reset_time(D.oid) AS stats_reset
FROM pg_database D;
*** a/src/backend/libpq/be-secure.c
--- b/src/backend/libpq/be-secure.c
***************
*** 74,80 ****
#include "libpq/libpq.h"
#include "tcop/tcopprot.h"
#include "utils/memutils.h"
!
#ifdef USE_SSL
--- 74,80 ----
#include "libpq/libpq.h"
#include "tcop/tcopprot.h"
#include "utils/memutils.h"
! #include "pgstat.h"
#ifdef USE_SSL
***************
*** 307,312 **** rloop:
--- 307,318 ----
n = recv(port->sock, ptr, len, 0);
client_read_ended();
+
+ if (n > 0)
+ {
+ /* we received data from the socket that needs to be reported */
+ pgstat_report_commreceived(n);
+ }
}
return n;
***************
*** 441,447 **** wloop:
--- 447,460 ----
}
else
#endif
+ {
n = send(port->sock, ptr, len, 0);
+ if (n > 0)
+ {
+ /* we sent data over the socket that needs to be reported */
+ pgstat_report_commsent(n);
+ }
+ }
return n;
}
***************
*** 488,493 **** my_sock_read(BIO *h, char *buf, int size)
--- 501,512 ----
client_read_ended();
+ if (res > 0)
+ {
+ /* we received data from the socket that needs to be reported */
+ pgstat_report_commreceived(res);
+ }
+
return res;
}
***************
*** 504,509 **** my_sock_write(BIO *h, const char *buf, int size)
--- 523,533 ----
BIO_set_retry_write(h);
}
}
+ else
+ {
+ /* we sent data over the socket that needs to be reported */
+ pgstat_report_commsent(res);
+ }
return res;
}
*** a/src/backend/postmaster/pgstat.c
--- b/src/backend/postmaster/pgstat.c
***************
*** 298,303 **** static void pgstat_recv_funcpurge(PgStat_MsgFuncpurge *msg, int len);
--- 298,305 ----
static void pgstat_recv_recoveryconflict(PgStat_MsgRecoveryConflict *msg, int len);
static void pgstat_recv_deadlock(PgStat_MsgDeadlock *msg, int len);
static void pgstat_recv_tempfile(PgStat_MsgTempFile *msg, int len);
+ static void pgstat_recv_commsent(PgStat_MsgComm *msg, int len);
+ static void pgstat_recv_commreceived(PgStat_MsgComm *msg, int len);
/* ------------------------------------------------------------
* Public functions called from postmaster follow
***************
*** 1249,1259 **** pgstat_reset_shared_counters(const char *target)
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\".")));
pgstat_setheader(&msg.m_hdr, PGSTAT_MTYPE_RESETSHAREDCOUNTER);
pgstat_send(&msg, sizeof(msg));
--- 1251,1263 ----
if (strcmp(target, "bgwriter") == 0)
msg.m_resettarget = RESET_BGWRITER;
+ else if (strcmp(target, "socket") == 0)
+ msg.m_resettarget = RESET_SOCKET;
else
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("unrecognized reset target: \"%s\"", target),
! errhint("Target must be \"bgwriter\" or \"socket\".")));
pgstat_setheader(&msg.m_hdr, PGSTAT_MTYPE_RESETSHAREDCOUNTER);
pgstat_send(&msg, sizeof(msg));
***************
*** 2531,2536 **** pgstat_bestart(void)
--- 2535,2542 ----
beentry->st_clienthostname[NAMEDATALEN - 1] = '\0';
beentry->st_appname[NAMEDATALEN - 1] = '\0';
beentry->st_activity[pgstat_track_activity_query_size - 1] = '\0';
+ beentry->st_bytes_sent = 0;
+ beentry->st_bytes_received = 0;
beentry->st_changecount++;
Assert((beentry->st_changecount & 1) == 0);
***************
*** 2738,2743 **** pgstat_report_waiting(bool waiting)
--- 2744,2811 ----
beentry->st_waiting = waiting;
}
+ /* --------
+ * pgstat_report_commsent() -
+ *
+ * Tell the collector about data sent over a socket.
+ * It is the caller's responsibility not invoke with a negative len
+ * --------
+ */
+ void
+ pgstat_report_commsent(int count)
+ {
+ volatile PgBackendStatus *beentry = MyBEEntry;
+ PgStat_MsgComm msg;
+
+ if (pgStatSock == PGINVALID_SOCKET || !pgstat_track_counts)
+ return;
+
+ /* this function can be called by the postmaster */
+ if (beentry != NULL) {
+ beentry->st_changecount++;
+ beentry->st_bytes_sent += count;
+ beentry->st_changecount++;
+ Assert((beentry->st_changecount & 1) == 0);
+ }
+
+ pgstat_setheader(&msg.m_hdr, PGSTAT_MTYPE_COMMSENT);
+ /* MyDatabaseId might be invalid, we'll check it in the msg receiver */
+ msg.m_databaseid = MyDatabaseId;
+ msg.m_bytes_transferred = count;
+ pgstat_send(&msg, sizeof(msg));
+ }
+
+ /* --------
+ * pgstat_report_commreceived() -
+ *
+ * Tell the collector about data received from a socket.
+ * It is the caller's responsibility not invoke with a negative len
+ * --------
+ */
+ void
+ pgstat_report_commreceived(int count)
+ {
+ volatile PgBackendStatus *beentry = MyBEEntry;
+ PgStat_MsgComm msg;
+
+ if (pgStatSock == PGINVALID_SOCKET || !pgstat_track_counts)
+ return;
+
+ /* this function can be called by the postmaster */
+ if (beentry != NULL) {
+ beentry->st_changecount++;
+ beentry->st_bytes_received += count;
+ beentry->st_changecount++;
+ Assert((beentry->st_changecount & 1) == 0);
+ }
+
+ pgstat_setheader(&msg.m_hdr, PGSTAT_MTYPE_COMMRECEIVED);
+ /* MyDatabaseId might be invalid, we'll check it in the msg receiver */
+ msg.m_databaseid = MyDatabaseId;
+ msg.m_bytes_transferred = count;
+ pgstat_send(&msg, sizeof(msg));
+ }
+
/* ----------
* pgstat_read_current_status() -
***************
*** 3290,3295 **** PgstatCollectorMain(int argc, char *argv[])
--- 3358,3371 ----
pgstat_recv_tempfile((PgStat_MsgTempFile *) &msg, len);
break;
+ case PGSTAT_MTYPE_COMMSENT:
+ pgstat_recv_commsent((PgStat_MsgComm *) &msg, len);
+ break;
+
+ case PGSTAT_MTYPE_COMMRECEIVED:
+ pgstat_recv_commreceived((PgStat_MsgComm *) &msg, len);
+ break;
+
default:
break;
}
***************
*** 3390,3395 **** reset_dbentry_counters(PgStat_StatDBEntry *dbentry)
--- 3466,3473 ----
dbentry->n_deadlocks = 0;
dbentry->n_block_read_time = 0;
dbentry->n_block_write_time = 0;
+ dbentry->n_bytes_sent = 0;
+ dbentry->n_bytes_received = 0;
dbentry->stat_reset_timestamp = GetCurrentTimestamp();
dbentry->stats_timestamp = 0;
***************
*** 3798,3803 **** pgstat_read_statsfiles(Oid onlydb, bool permanent, bool deep)
--- 3876,3882 ----
int32 format_id;
bool found;
const char *statfile = permanent ? PGSTAT_STAT_PERMANENT_FILENAME : pgstat_stat_filename;
+ TimestampTz now;
/*
* The tables will live in pgStatLocalContext.
***************
*** 3825,3831 **** pgstat_read_statsfiles(Oid onlydb, bool permanent, bool deep)
* Set the current timestamp (will be kept only in case we can't load an
* existing statsfile).
*/
! globalStats.stat_reset_timestamp = GetCurrentTimestamp();
/*
* Try to open the stats file. If it doesn't exist, the backends simply
--- 3904,3912 ----
* Set the current timestamp (will be kept only in case we can't load an
* existing statsfile).
*/
! now = GetCurrentTimestamp();
! globalStats.bgwriter_stat_reset_timestamp = now;
! globalStats.socket_stat_reset_timestamp = now;
/*
* Try to open the stats file. If it doesn't exist, the backends simply
***************
*** 4722,4730 **** pgstat_recv_resetsharedcounter(PgStat_MsgResetsharedcounter *msg, int len)
{
if (msg->m_resettarget == RESET_BGWRITER)
{
/* Reset the global background writer statistics for the cluster. */
! memset(&globalStats, 0, sizeof(globalStats));
! globalStats.stat_reset_timestamp = GetCurrentTimestamp();
}
/*
--- 4803,4829 ----
{
if (msg->m_resettarget == RESET_BGWRITER)
{
+ globalStats.stats_timestamp = 0;
/* Reset the global background writer statistics for the cluster. */
! globalStats.timed_checkpoints = 0;
! globalStats.requested_checkpoints = 0;
! globalStats.checkpoint_write_time = 0;
! globalStats.checkpoint_sync_time = 0;
! globalStats.buf_written_checkpoints = 0;
! globalStats.buf_written_clean = 0;
! globalStats.maxwritten_clean = 0;
! globalStats.buf_written_backend = 0;
! globalStats.buf_fsync_backend = 0;
! globalStats.buf_alloc = 0;
! globalStats.bgwriter_stat_reset_timestamp = GetCurrentTimestamp();
! }
! else if (msg->m_resettarget == RESET_SOCKET)
! {
! globalStats.stats_timestamp = 0;
! /* Reset the global socket transfer statistics for the cluster. */
! globalStats.bytes_sent = 0;
! globalStats.bytes_received = 0;
! globalStats.socket_stat_reset_timestamp = GetCurrentTimestamp();
}
/*
***************
*** 4951,4956 **** pgstat_recv_tempfile(PgStat_MsgTempFile *msg, int len)
--- 5050,5095 ----
}
/* ----------
+ * pgstat_recv_commsent() -
+ *
+ * Process a COMMSENT message.
+ * ----------
+ */
+ static void
+ pgstat_recv_commsent(PgStat_MsgComm *msg, int len)
+ {
+ PgStat_StatDBEntry *dbentry;
+
+ globalStats.bytes_sent += msg->m_bytes_transferred;
+
+ /* can be called before we have connected to a specific database or by walsender */
+ if (OidIsValid(msg->m_databaseid)) {
+ dbentry = pgstat_get_db_entry(msg->m_databaseid, true);
+ dbentry->n_bytes_sent += msg->m_bytes_transferred;
+ }
+ }
+
+ /* ----------
+ * pgstat_recv_commreceived() -
+ *
+ * Process a COMMRECEIVED message.
+ * ----------
+ */
+ static void
+ pgstat_recv_commreceived(PgStat_MsgComm *msg, int len)
+ {
+ PgStat_StatDBEntry *dbentry;
+
+ globalStats.bytes_received += msg->m_bytes_transferred;
+
+ /* can be called before we have connected to a specific database or by walsender */
+ if (OidIsValid(msg->m_databaseid)) {
+ dbentry = pgstat_get_db_entry(msg->m_databaseid, true);
+ dbentry->n_bytes_received += msg->m_bytes_transferred;
+ }
+ }
+
+ /* ----------
* pgstat_recv_funcstat() -
*
* Count what the backend has done.
*** a/src/backend/postmaster/postmaster.c
--- b/src/backend/postmaster/postmaster.c
***************
*** 1825,1830 **** retry1:
--- 1825,1832 ----
errmsg("failed to send SSL negotiation response: %m")));
return STATUS_ERROR; /* close the connection */
}
+ else
+ pgstat_report_commsent(1);
#ifdef USE_SSL
if (SSLok == 'S' && secure_open_server(port) == -1)
***************
*** 3839,3844 **** report_fork_failure_to_client(Port *port, int errnum)
--- 3841,3849 ----
{
rc = send(port->sock, buffer, strlen(buffer) + 1, 0);
} while (rc < 0 && errno == EINTR);
+
+ if (rc > 0)
+ pgstat_report_commsent(rc);
}
*** a/src/backend/utils/adt/pgstatfuncs.c
--- b/src/backend/utils/adt/pgstatfuncs.c
***************
*** 86,91 **** extern Datum pg_stat_get_db_temp_files(PG_FUNCTION_ARGS);
--- 86,93 ----
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_db_bytes_sent(PG_FUNCTION_ARGS);
+ extern Datum pg_stat_get_db_bytes_received(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);
***************
*** 99,104 **** extern Datum pg_stat_get_buf_written_backend(PG_FUNCTION_ARGS);
--- 101,110 ----
extern Datum pg_stat_get_buf_fsync_backend(PG_FUNCTION_ARGS);
extern Datum pg_stat_get_buf_alloc(PG_FUNCTION_ARGS);
+ extern Datum pg_stat_get_bytes_sent(PG_FUNCTION_ARGS);
+ extern Datum pg_stat_get_bytes_received(PG_FUNCTION_ARGS);
+ extern Datum pg_stat_get_socket_stat_reset_time(PG_FUNCTION_ARGS);
+
extern Datum pg_stat_get_xact_numscans(PG_FUNCTION_ARGS);
extern Datum pg_stat_get_xact_tuples_returned(PG_FUNCTION_ARGS);
extern Datum pg_stat_get_xact_tuples_fetched(PG_FUNCTION_ARGS);
***************
*** 534,540 **** pg_stat_get_activity(PG_FUNCTION_ARGS)
oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
! tupdesc = CreateTemplateTupleDesc(14, false);
TupleDescInitEntry(tupdesc, (AttrNumber) 1, "datid",
OIDOID, -1, 0);
TupleDescInitEntry(tupdesc, (AttrNumber) 2, "pid",
--- 540,546 ----
oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
! tupdesc = CreateTemplateTupleDesc(16, false);
TupleDescInitEntry(tupdesc, (AttrNumber) 1, "datid",
OIDOID, -1, 0);
TupleDescInitEntry(tupdesc, (AttrNumber) 2, "pid",
***************
*** 563,568 **** pg_stat_get_activity(PG_FUNCTION_ARGS)
--- 569,578 ----
TEXTOID, -1, 0);
TupleDescInitEntry(tupdesc, (AttrNumber) 14, "client_port",
INT4OID, -1, 0);
+ TupleDescInitEntry(tupdesc, (AttrNumber) 15, "bytes_sent",
+ INT8OID, -1, 0);
+ TupleDescInitEntry(tupdesc, (AttrNumber) 16, "bytes_received",
+ INT8OID, -1, 0);
funcctx->tuple_desc = BlessTupleDesc(tupdesc);
***************
*** 614,621 **** pg_stat_get_activity(PG_FUNCTION_ARGS)
if (funcctx->call_cntr < funcctx->max_calls)
{
/* for each row */
! Datum values[14];
! bool nulls[14];
HeapTuple tuple;
PgBackendStatus *beentry;
SockAddr zero_clientaddr;
--- 624,631 ----
if (funcctx->call_cntr < funcctx->max_calls)
{
/* for each row */
! Datum values[16];
! bool nulls[16];
HeapTuple tuple;
PgBackendStatus *beentry;
SockAddr zero_clientaddr;
***************
*** 773,778 **** pg_stat_get_activity(PG_FUNCTION_ARGS)
--- 783,790 ----
nulls[13] = true;
}
}
+ values[14] = Int64GetDatum(beentry->st_bytes_sent);
+ values[15] = Int64GetDatum(beentry->st_bytes_received);
}
else
{
***************
*** 787,792 **** pg_stat_get_activity(PG_FUNCTION_ARGS)
--- 799,806 ----
nulls[11] = true;
nulls[12] = true;
nulls[13] = true;
+ nulls[14] = true;
+ nulls[15] = true;
}
tuple = heap_form_tuple(funcctx->tuple_desc, values, nulls);
***************
*** 1407,1412 **** pg_stat_get_db_blk_write_time(PG_FUNCTION_ARGS)
--- 1421,1456 ----
}
Datum
+ pg_stat_get_db_bytes_sent(PG_FUNCTION_ARGS)
+ {
+ Oid dbid = PG_GETARG_OID(0);
+ double result;
+ PgStat_StatDBEntry *dbentry;
+
+ if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
+ result = 0;
+ else
+ result = dbentry->n_bytes_sent;
+
+ PG_RETURN_INT64(result);
+ }
+
+ Datum
+ pg_stat_get_db_bytes_received(PG_FUNCTION_ARGS)
+ {
+ Oid dbid = PG_GETARG_OID(0);
+ double result;
+ PgStat_StatDBEntry *dbentry;
+
+ if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
+ result = 0;
+ else
+ result = dbentry->n_bytes_received;
+
+ PG_RETURN_INT64(result);
+ }
+
+ Datum
pg_stat_get_bgwriter_timed_checkpoints(PG_FUNCTION_ARGS)
{
PG_RETURN_INT64(pgstat_fetch_global()->timed_checkpoints);
***************
*** 1453,1459 **** pg_stat_get_checkpoint_sync_time(PG_FUNCTION_ARGS)
Datum
pg_stat_get_bgwriter_stat_reset_time(PG_FUNCTION_ARGS)
{
! PG_RETURN_TIMESTAMPTZ(pgstat_fetch_global()->stat_reset_timestamp);
}
Datum
--- 1497,1503 ----
Datum
pg_stat_get_bgwriter_stat_reset_time(PG_FUNCTION_ARGS)
{
! PG_RETURN_TIMESTAMPTZ(pgstat_fetch_global()->bgwriter_stat_reset_timestamp);
}
Datum
***************
*** 1475,1480 **** pg_stat_get_buf_alloc(PG_FUNCTION_ARGS)
--- 1519,1542 ----
}
Datum
+ pg_stat_get_bytes_sent(PG_FUNCTION_ARGS)
+ {
+ PG_RETURN_INT64(pgstat_fetch_global()->bytes_sent);
+ }
+
+ Datum
+ pg_stat_get_bytes_received(PG_FUNCTION_ARGS)
+ {
+ PG_RETURN_INT64(pgstat_fetch_global()->bytes_received);
+ }
+
+ Datum
+ pg_stat_get_socket_stat_reset_time(PG_FUNCTION_ARGS)
+ {
+ PG_RETURN_TIMESTAMPTZ(pgstat_fetch_global()->socket_stat_reset_timestamp);
+ }
+
+ Datum
pg_stat_get_xact_numscans(PG_FUNCTION_ARGS)
{
Oid relid = PG_GETARG_OID(0);
*** a/src/include/catalog/pg_proc.h
--- b/src/include/catalog/pg_proc.h
***************
*** 2626,2632 **** DATA(insert OID = 3057 ( pg_stat_get_autoanalyze_count PGNSP PGUID 12 1 0 0 0 f
DESCR("statistics: number of auto analyzes for a table");
DATA(insert OID = 1936 ( pg_stat_get_backend_idset PGNSP PGUID 12 1 100 0 0 f f f f t t s 0 0 23 "" _null_ _null_ _null_ _null_ pg_stat_get_backend_idset _null_ _null_ _null_ ));
DESCR("statistics: currently active backend IDs");
! DATA(insert OID = 2022 ( pg_stat_get_activity PGNSP PGUID 12 1 100 0 0 f f f f f t s 1 0 2249 "23" "{23,26,23,26,25,25,25,16,1184,1184,1184,1184,869,25,23}" "{i,o,o,o,o,o,o,o,o,o,o,o,o,o,o}" "{pid,datid,pid,usesysid,application_name,state,query,waiting,xact_start,query_start,backend_start,state_change,client_addr,client_hostname,client_port}" _null_ pg_stat_get_activity _null_ _null_ _null_ ));
DESCR("statistics: information about currently active backends");
DATA(insert OID = 3099 ( pg_stat_get_wal_senders PGNSP PGUID 12 1 10 0 0 f f f f f t s 0 0 2249 "" "{23,25,25,25,25,25,23,25}" "{o,o,o,o,o,o,o,o}" "{pid,state,sent_location,write_location,flush_location,replay_location,sync_priority,sync_state}" _null_ pg_stat_get_wal_senders _null_ _null_ _null_ ));
DESCR("statistics: information about currently active replication");
--- 2626,2632 ----
DESCR("statistics: number of auto analyzes for a table");
DATA(insert OID = 1936 ( pg_stat_get_backend_idset PGNSP PGUID 12 1 100 0 0 f f f f t t s 0 0 23 "" _null_ _null_ _null_ _null_ pg_stat_get_backend_idset _null_ _null_ _null_ ));
DESCR("statistics: currently active backend IDs");
! DATA(insert OID = 2022 ( pg_stat_get_activity PGNSP PGUID 12 1 100 0 0 f f f f f t s 1 0 2249 "23" "{23,26,23,26,25,25,25,16,1184,1184,1184,1184,869,25,23,20,20}" "{i,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o}" "{pid,datid,pid,usesysid,application_name,state,query,waiting,xact_start,query_start,backend_start,state_change,client_addr,client_hostname,client_port,bytes_sent,bytes_received}" _null_ pg_stat_get_activity _null_ _null_ _null_ ));
DESCR("statistics: information about currently active backends");
DATA(insert OID = 3099 ( pg_stat_get_wal_senders PGNSP PGUID 12 1 10 0 0 f f f f f t s 0 0 2249 "" "{23,25,25,25,25,25,23,25}" "{o,o,o,o,o,o,o,o}" "{pid,state,sent_location,write_location,flush_location,replay_location,sync_priority,sync_state}" _null_ pg_stat_get_wal_senders _null_ _null_ _null_ ));
DESCR("statistics: information about currently active replication");
***************
*** 2696,2701 **** DATA(insert OID = 2844 ( pg_stat_get_db_blk_read_time PGNSP PGUID 12 1 0 0 0 f
--- 2696,2705 ----
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_db_bytes_sent PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 20 "26" _null_ _null_ _null_ _null_ pg_stat_get_db_bytes_sent _null_ _null_ _null_ ));
+ DESCR("statistics: number of bytes sent over communication sockets");
+ DATA(insert OID = 3196 ( pg_stat_get_db_bytes_received PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 20 "26" _null_ _null_ _null_ _null_ pg_stat_get_db_bytes_received _null_ _null_ _null_ ));
+ DESCR("statistics: number of bytes received over communication sockets");
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_ ));
***************
*** 2719,2724 **** DESCR("statistics: number of backend buffer writes that did their own fsync");
--- 2723,2735 ----
DATA(insert OID = 2859 ( pg_stat_get_buf_alloc PGNSP PGUID 12 1 0 0 0 f f f f t f s 0 0 20 "" _null_ _null_ _null_ _null_ pg_stat_get_buf_alloc _null_ _null_ _null_ ));
DESCR("statistics: number of buffer allocations");
+ DATA(insert OID = 3197 ( pg_stat_get_bytes_sent PGNSP PGUID 12 1 0 0 0 f f f f t f s 0 0 20 "" _null_ _null_ _null_ _null_ pg_stat_get_bytes_sent _null_ _null_ _null_ ));
+ DESCR("statistics: number of bytes sent over communication sockets");
+ DATA(insert OID = 3198 ( pg_stat_get_bytes_received PGNSP PGUID 12 1 0 0 0 f f f f t f s 0 0 20 "" _null_ _null_ _null_ _null_ pg_stat_get_bytes_received _null_ _null_ _null_ ));
+ DESCR("statistics: number of bytes received over communication sockets");
+ DATA(insert OID = 3199 ( pg_stat_get_socket_stat_reset_time PGNSP PGUID 12 1 0 0 0 f f f f t f s 0 0 1184 "" _null_ _null_ _null_ _null_ pg_stat_get_socket_stat_reset_time _null_ _null_ _null_ ));
+ DESCR("statistics: last reset for the communication socket statistics");
+
DATA(insert OID = 2978 ( pg_stat_get_function_calls PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 20 "26" _null_ _null_ _null_ _null_ pg_stat_get_function_calls _null_ _null_ _null_ ));
DESCR("statistics: number of function calls");
DATA(insert OID = 2979 ( pg_stat_get_function_total_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_function_total_time _null_ _null_ _null_ ));
*** a/src/include/pgstat.h
--- b/src/include/pgstat.h
***************
*** 49,55 **** typedef enum StatMsgType
PGSTAT_MTYPE_FUNCPURGE,
PGSTAT_MTYPE_RECOVERYCONFLICT,
PGSTAT_MTYPE_TEMPFILE,
! PGSTAT_MTYPE_DEADLOCK
} StatMsgType;
/* ----------
--- 49,57 ----
PGSTAT_MTYPE_FUNCPURGE,
PGSTAT_MTYPE_RECOVERYCONFLICT,
PGSTAT_MTYPE_TEMPFILE,
! PGSTAT_MTYPE_DEADLOCK,
! PGSTAT_MTYPE_COMMSENT,
! PGSTAT_MTYPE_COMMRECEIVED
} StatMsgType;
/* ----------
***************
*** 102,108 **** typedef struct PgStat_TableCounts
/* Possible targets for resetting cluster-wide shared values */
typedef enum PgStat_Shared_Reset_Target
{
! RESET_BGWRITER
} PgStat_Shared_Reset_Target;
/* Possible object types for resetting single counters */
--- 104,111 ----
/* Possible targets for resetting cluster-wide shared values */
typedef enum PgStat_Shared_Reset_Target
{
! RESET_BGWRITER,
! RESET_SOCKET
} PgStat_Shared_Reset_Target;
/* Possible object types for resetting single counters */
***************
*** 397,402 **** typedef struct PgStat_MsgTempFile
--- 400,419 ----
} PgStat_MsgTempFile;
/* ----------
+ * PgStat_MsgComm
+ *
+ * Sent upon sending or receiving data over a communication socket (header determines direction)
+ * ----------
+ */
+ typedef struct PgStat_MsgComm
+ {
+ PgStat_MsgHdr m_hdr;
+
+ Oid m_databaseid;
+ int m_bytes_transferred;
+ } PgStat_MsgComm;
+
+ /* ----------
* PgStat_FunctionCounts The actual per-function counts kept by a backend
*
* This struct should contain only actual event counters, because we memcmp
***************
*** 515,521 **** typedef union PgStat_Msg
* ------------------------------------------------------------
*/
! #define PGSTAT_FILE_FORMAT_ID 0x01A5BC9B
/* ----------
* PgStat_StatDBEntry The collector's data per database
--- 532,538 ----
* ------------------------------------------------------------
*/
! #define PGSTAT_FILE_FORMAT_ID 0x01A5BC9C
/* ----------
* PgStat_StatDBEntry The collector's data per database
***************
*** 544,549 **** typedef struct PgStat_StatDBEntry
--- 561,570 ----
PgStat_Counter n_deadlocks;
PgStat_Counter n_block_read_time; /* times in microseconds */
PgStat_Counter n_block_write_time;
+ /* communication socket transfer counter in bytes (backend to client) */
+ PgStat_Counter n_bytes_sent;
+ /* communication socket transfer counter in bytes (client to backend) */
+ PgStat_Counter n_bytes_received;
TimestampTz stat_reset_timestamp;
TimestampTz stats_timestamp; /* time of db stats file update */
***************
*** 614,619 **** typedef struct PgStat_StatFuncEntry
--- 635,641 ----
typedef struct PgStat_GlobalStats
{
TimestampTz stats_timestamp; /* time of stats file update */
+ /* bgwriter stats */
PgStat_Counter timed_checkpoints;
PgStat_Counter requested_checkpoints;
PgStat_Counter checkpoint_write_time; /* times in milliseconds */
***************
*** 624,630 **** typedef struct PgStat_GlobalStats
PgStat_Counter buf_written_backend;
PgStat_Counter buf_fsync_backend;
PgStat_Counter buf_alloc;
! TimestampTz stat_reset_timestamp;
} PgStat_GlobalStats;
--- 646,656 ----
PgStat_Counter buf_written_backend;
PgStat_Counter buf_fsync_backend;
PgStat_Counter buf_alloc;
! TimestampTz bgwriter_stat_reset_timestamp;
! /* communication socket stats */
! PgStat_Counter bytes_sent; /* in bytes (cluster to client) */
! PgStat_Counter bytes_received; /* in bytes (client to cluster) */
! TimestampTz socket_stat_reset_timestamp;
} PgStat_GlobalStats;
***************
*** 697,702 **** typedef struct PgBackendStatus
--- 723,734 ----
/* current command string; MUST be null-terminated */
char *st_activity;
+
+ /* communication socket transfer counter in bytes (backend to client) */
+ unsigned long st_bytes_sent;
+ /* communication socket transfer counter in bytes (client to backend) */
+ unsigned long st_bytes_received;
+
} PgBackendStatus;
/*
***************
*** 788,793 **** extern void pgstat_report_tempfile(size_t filesize);
--- 820,828 ----
extern void pgstat_report_appname(const char *appname);
extern void pgstat_report_xact_timestamp(TimestampTz tstamp);
extern void pgstat_report_waiting(bool waiting);
+ extern void pgstat_report_commsent(int count);
+ extern void pgstat_report_commreceived(int count);
+
extern const char *pgstat_get_backend_current_activity(int pid, bool checkUser);
extern const char *pgstat_get_crashed_backend_activity(int pid, char *buffer,
int buflen);
*** a/src/test/regress/expected/rules.out
--- b/src/test/regress/expected/rules.out
***************
*** 1595,1603 **** pg_stat_activity| SELECT s.datid,
s.state_change,
s.waiting,
s.state,
! s.query
FROM pg_database d,
! pg_stat_get_activity(NULL::integer) s(datid, pid, usesysid, application_name, state, query, waiting, xact_start, query_start, backend_start, state_change, client_addr, client_hostname, client_port),
pg_authid u
WHERE ((s.datid = d.oid) AND (s.usesysid = u.oid));
pg_stat_all_indexes| SELECT c.oid AS relid,
--- 1595,1605 ----
s.state_change,
s.waiting,
s.state,
! s.query,
! s.bytes_sent,
! s.bytes_received
FROM pg_database d,
! pg_stat_get_activity(NULL::integer) s(datid, pid, usesysid, application_name, state, query, waiting, xact_start, query_start, backend_start, state_change, client_addr, client_hostname, client_port, bytes_sent, bytes_received),
pg_authid u
WHERE ((s.datid = d.oid) AND (s.usesysid = u.oid));
pg_stat_all_indexes| SELECT c.oid AS relid,
***************
*** 1669,1674 **** pg_stat_database| SELECT d.oid AS datid,
--- 1671,1678 ----
pg_stat_get_db_deadlocks(d.oid) AS deadlocks,
pg_stat_get_db_blk_read_time(d.oid) AS blk_read_time,
pg_stat_get_db_blk_write_time(d.oid) AS blk_write_time,
+ pg_stat_get_db_bytes_sent(d.oid) AS bytes_sent,
+ pg_stat_get_db_bytes_received(d.oid) AS bytes_received,
pg_stat_get_db_stat_reset_time(d.oid) AS stats_reset
FROM pg_database d;
pg_stat_database_conflicts| SELECT d.oid AS datid,
***************
*** 1687,1692 **** pg_stat_replication| SELECT s.pid,
--- 1691,1698 ----
s.client_hostname,
s.client_port,
s.backend_start,
+ s.bytes_sent,
+ s.bytes_received,
w.state,
w.sent_location,
w.write_location,
***************
*** 1694,1700 **** pg_stat_replication| SELECT s.pid,
w.replay_location,
w.sync_priority,
w.sync_state
! FROM pg_stat_get_activity(NULL::integer) s(datid, pid, usesysid, application_name, state, query, waiting, xact_start, query_start, backend_start, state_change, client_addr, client_hostname, client_port),
pg_authid u,
pg_stat_get_wal_senders() w(pid, state, sent_location, write_location, flush_location, replay_location, sync_priority, sync_state)
WHERE ((s.usesysid = u.oid) AND (s.pid = w.pid));
--- 1700,1706 ----
w.replay_location,
w.sync_priority,
w.sync_state
! FROM pg_stat_get_activity(NULL::integer) s(datid, pid, usesysid, application_name, state, query, waiting, xact_start, query_start, backend_start, state_change, client_addr, client_hostname, client_port, bytes_sent, bytes_received),
pg_authid u,
pg_stat_get_wal_senders() w(pid, state, sent_location, write_location, flush_location, replay_location, sync_priority, sync_state)
WHERE ((s.usesysid = u.oid) AND (s.pid = w.pid));
--
Sent via pgsql-hackers mailing list ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers