*** a/doc/src/sgml/monitoring.sgml --- b/doc/src/sgml/monitoring.sgml *************** *** 278,283 **** postgres: user database host + pg_stat_socketpg_stat_socket + One row only, showing statistics about the + cluster's communication socket activity. See + for details. + + + + pg_stat_databasepg_stat_database One row per database, showing database-wide statistics. See for details. *************** *** 627,632 **** postgres: user database host + + bytes_sent + bigint + Number of bytes sent over this backend's client connection + + + bytes_received + bigint + Number of bytes received over this backend's client connection + *************** *** 735,740 **** postgres: user database host + + <structname>pg_stat_socket</structname> View + + + + + Column + Type + Description + + + + + + bytes_sent_total + bigint + + Number of bytes sent over client connections (includes user backends and WAL senders). + + + + bytes_received_total + bigint + + Number of bytes received over client connections (includes user backends and WAL senders). + + + + bytes_sent_backend + bigint + + Number of bytes sent over client connections to a user backend. + + + + bytes_received_backend + bigint + + Number of bytes received over client connections by a user backend. + + + + bytes_sent_walsender + bigint + + Number of bytes sent over client connections to a WAL sender. + + + + bytes_received_walsender + bigint + + Number of bytes received over client connections by a WAL sender. + + + + conn_received + bigint + + Number of client connections received. + + + + conn_backend + bigint + + Number of client connections successfully established to a user backend. + + + + conn_walsender + bigint + + Number of client connections successfully established to a WAL sender. + + + + stats_reset + timestamp with time zone + Time at which these statistics were last reset + + + +
+ + + The pg_stat_socket view will always have a + single row, containing global data for the cluster. + Only sockets created from inbound client connections are tracked (Unix sockets and TCP). + Streaming replication traffic is counted on the master, but not on the slave (See for details.) + + <structname>pg_stat_database</structname> View *************** *** 859,864 **** postgres: user database host + bytes_sent + bigint + Number of bytes sent over connections to user backends in this database + + + bytes_received + bigint + Number of bytes received over connections to user backends in this database + + + connections + bigint + Number of client connections successfully established in this database + + stats_reset timestamp with time zone Time at which these statistics were last reset *************** *** 1417,1422 **** postgres: user database host + bytes_sent + bigint + Number of bytes sent over this WAL sender's connection + + + bytes_received + bigint + Number of bytes received over this WAL sender's connection + + state text Current WAL sender state *************** *** 1613,1618 **** postgres: user database host pg_stat_reset_shared('bgwriter') will zero all the counters shown in the pg_stat_bgwriter view. + Calling pg_stat_reset_shared('socket') will zero all the + counters shown in the pg_stat_socket view. *** 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,646 ---- 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_connections(D.oid) AS connections, pg_stat_get_db_stat_reset_time(D.oid) AS stats_reset FROM pg_database D; *************** *** 686,691 **** CREATE VIEW pg_stat_bgwriter AS --- 693,711 ---- pg_stat_get_buf_alloc() AS buffers_alloc, pg_stat_get_bgwriter_stat_reset_time() AS stats_reset; + CREATE VIEW pg_stat_socket AS + SELECT + pg_stat_get_bytes_sent() AS bytes_sent_total, + pg_stat_get_bytes_received() AS bytes_received_total, + pg_stat_get_bytes_sent_backend() AS bytes_sent_backend, + pg_stat_get_bytes_received_backend() AS bytes_received_backend, + pg_stat_get_bytes_sent_walsender() AS bytes_sent_walsender, + pg_stat_get_bytes_received_walsender() AS bytes_received_walsender, + pg_stat_get_conn_received() AS conn_received, + pg_stat_get_conn_backend() AS conn_backend, + pg_stat_get_conn_walsender() AS conn_walsender, + pg_stat_get_socket_stat_reset_time() AS stats_reset; + CREATE VIEW pg_user_mappings AS SELECT U.oid AS umid, *** 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_bytesreceived(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_bytessent(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_bytesreceived(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_bytessent(res); + } return res; } *** a/src/backend/postmaster/pgstat.c --- b/src/backend/postmaster/pgstat.c *************** *** 48,53 **** --- 48,54 ---- #include "postmaster/autovacuum.h" #include "postmaster/fork_process.h" #include "postmaster/postmaster.h" + #include "replication/walsender.h" #include "storage/backendid.h" #include "storage/fd.h" #include "storage/ipc.h" *************** *** 298,303 **** static void pgstat_recv_funcpurge(PgStat_MsgFuncpurge *msg, int len); --- 299,308 ---- 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_bytessent(PgStat_MsgBytesTransferred *msg, int len); + static void pgstat_recv_bytesreceived(PgStat_MsgBytesTransferred *msg, int len); + static void pgstat_recv_connreceived(PgStat_MsgConnReceived *msg, int len); + static void pgstat_recv_connsucceeded(PgStat_MsgConnSucceeded *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)); --- 1254,1266 ---- 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) --- 2538,2545 ---- 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); *************** *** 2541,2546 **** pgstat_bestart(void) --- 2550,2558 ---- /* Update app name to current GUC setting */ if (application_name) pgstat_report_appname(application_name); + + if (MyProcPort) + pgstat_report_connsucceeded(); } /* *************** *** 2738,2743 **** pgstat_report_waiting(bool waiting) --- 2750,2857 ---- beentry->st_waiting = waiting; } + /* -------- + * pgstat_report_bytessent() - + * + * Tell the collector about data sent over a socket. + * It is the caller's responsibility not invoke with a negative len + * -------- + */ + void + pgstat_report_bytessent(int count) + { + volatile PgBackendStatus *beentry = MyBEEntry; + PgStat_MsgBytesTransferred 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_BYTESSENT); + /* MyDatabaseId might be invalid, we'll check it in the msg receiver */ + msg.m_databaseid = MyDatabaseId; + msg.m_bytes_transferred = count; + msg.m_walsender = am_walsender; + pgstat_send(&msg, sizeof(msg)); + } + + /* -------- + * pgstat_report_bytesreceived() - + * + * Tell the collector about data received from a socket. + * It is the caller's responsibility not invoke with a negative len + * -------- + */ + void + pgstat_report_bytesreceived(int count) + { + volatile PgBackendStatus *beentry = MyBEEntry; + PgStat_MsgBytesTransferred 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_BYTESRECEIVED); + /* MyDatabaseId might be invalid, we'll check it in the msg receiver */ + msg.m_databaseid = MyDatabaseId; + msg.m_bytes_transferred = count; + msg.m_walsender = am_walsender; + pgstat_send(&msg, sizeof(msg)); + } + + /* -------- + * pgstat_report_connreceived() - + * + * Tell the collector about a client connection that was received. + * -------- + */ + void + pgstat_report_connreceived(void) + { + PgStat_MsgConnReceived msg; + + if (pgStatSock == PGINVALID_SOCKET || !pgstat_track_counts) + return; + + pgstat_setheader(&msg.m_hdr, PGSTAT_MTYPE_CONNRECEIVED); + pgstat_send(&msg, sizeof(msg)); + } + + /* -------- + * pgstat_report_connsucceeded() - + * + * Tell the collector about a client connection that was successfully established. + * -------- + */ + void + pgstat_report_connsucceeded(void) + { + PgStat_MsgConnSucceeded msg; + + if (pgStatSock == PGINVALID_SOCKET || !pgstat_track_counts) + return; + + pgstat_setheader(&msg.m_hdr, PGSTAT_MTYPE_CONNSUCCEEDED); + /* MyDatabaseId might be invalid, we'll check it in the msg receiver */ + msg.m_databaseid = MyDatabaseId; + msg.m_walsender = am_walsender; + pgstat_send(&msg, sizeof(msg)); + } /* ---------- * pgstat_read_current_status() - *************** *** 3290,3295 **** PgstatCollectorMain(int argc, char *argv[]) --- 3404,3425 ---- pgstat_recv_tempfile((PgStat_MsgTempFile *) &msg, len); break; + case PGSTAT_MTYPE_BYTESSENT: + pgstat_recv_bytessent((PgStat_MsgBytesTransferred *) &msg, len); + break; + + case PGSTAT_MTYPE_BYTESRECEIVED: + pgstat_recv_bytesreceived((PgStat_MsgBytesTransferred *) &msg, len); + break; + + case PGSTAT_MTYPE_CONNRECEIVED: + pgstat_recv_connreceived((PgStat_MsgConnReceived *) &msg, len); + break; + + case PGSTAT_MTYPE_CONNSUCCEEDED: + pgstat_recv_connsucceeded((PgStat_MsgConnSucceeded *) &msg, len); + break; + default: break; } *************** *** 3390,3395 **** reset_dbentry_counters(PgStat_StatDBEntry *dbentry) --- 3520,3528 ---- 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->n_connections = 0; dbentry->stat_reset_timestamp = GetCurrentTimestamp(); dbentry->stats_timestamp = 0; *************** *** 3798,3803 **** pgstat_read_statsfiles(Oid onlydb, bool permanent, bool deep) --- 3931,3937 ---- 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 --- 3959,3967 ---- * 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(); } /* --- 4858,4891 ---- { 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.bytes_sent_backend = 0; ! globalStats.bytes_received_backend = 0; ! globalStats.bytes_sent_walsender = 0; ! globalStats.bytes_received_walsender = 0; ! globalStats.conn_received = 0; ! globalStats.conn_backend = 0; ! globalStats.conn_walsender = 0; ! globalStats.socket_stat_reset_timestamp = GetCurrentTimestamp(); } /* *************** *** 4951,4956 **** pgstat_recv_tempfile(PgStat_MsgTempFile *msg, int len) --- 5112,5201 ---- } /* ---------- + * pgstat_recv_bytessent() - + * + * Process a BYTESSENT message. + * ---------- + */ + static void + pgstat_recv_bytessent(PgStat_MsgBytesTransferred *msg, int len) + { + PgStat_StatDBEntry *dbentry; + + globalStats.bytes_sent += msg->m_bytes_transferred; + + if (msg->m_walsender) + globalStats.bytes_sent_walsender += msg->m_bytes_transferred; + + /* can be called before we have connected to a specific database or by walsender */ + if (OidIsValid(msg->m_databaseid)) { + globalStats.bytes_sent_backend += msg->m_bytes_transferred; + + dbentry = pgstat_get_db_entry(msg->m_databaseid, true); + dbentry->n_bytes_sent += msg->m_bytes_transferred; + } + } + + /* ---------- + * pgstat_recv_bytesreceived() - + * + * Process a BYTESRECEIVED message. + * ---------- + */ + static void + pgstat_recv_bytesreceived(PgStat_MsgBytesTransferred *msg, int len) + { + PgStat_StatDBEntry *dbentry; + + globalStats.bytes_received += msg->m_bytes_transferred; + + if (msg->m_walsender) + globalStats.bytes_received_walsender += msg->m_bytes_transferred; + + /* can be called before we have connected to a specific database or by walsender */ + if (OidIsValid(msg->m_databaseid)) { + globalStats.bytes_received_backend += msg->m_bytes_transferred; + + dbentry = pgstat_get_db_entry(msg->m_databaseid, true); + dbentry->n_bytes_received += msg->m_bytes_transferred; + } + } + + /* ---------- + * pgstat_recv_connreceived() - + * + * Process a CONNRECEIVED message. + * ---------- + */ + static void + pgstat_recv_connreceived(PgStat_MsgConnReceived *msg, int len) + { + globalStats.conn_received += 1; + } + + /* ---------- + * pgstat_recv_connsucceeded() - + * + * Process a CONNSUCCEEDED message. + * ---------- + */ + static void + pgstat_recv_connsucceeded(PgStat_MsgConnSucceeded *msg, int len) + { + PgStat_StatDBEntry *dbentry; + + if (msg->m_walsender) + globalStats.conn_walsender += 1; + else + globalStats.conn_backend += 1; + + if (OidIsValid(msg->m_databaseid)) { + dbentry = pgstat_get_db_entry(msg->m_databaseid, true); + dbentry->n_connections += 1; + } + } + + /* ---------- * 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_bytessent(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_bytessent(rc); } *************** *** 3930,3935 **** BackendInitialize(Port *port) --- 3935,3942 ---- else snprintf(remote_ps_data, sizeof(remote_ps_data), "%s(%s)", remote_host, remote_port); + pgstat_report_connreceived(); + if (Log_connections) { if (remote_port[0]) *** 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,94 ---- 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_db_connections(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); --- 102,118 ---- 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_bytes_sent_backend(PG_FUNCTION_ARGS); + extern Datum pg_stat_get_bytes_received_backend(PG_FUNCTION_ARGS); + extern Datum pg_stat_get_bytes_sent_walsender(PG_FUNCTION_ARGS); + extern Datum pg_stat_get_bytes_received_walsender(PG_FUNCTION_ARGS); + extern Datum pg_stat_get_conn_received(PG_FUNCTION_ARGS); + extern Datum pg_stat_get_conn_backend(PG_FUNCTION_ARGS); + extern Datum pg_stat_get_conn_walsender(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", --- 548,554 ---- 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) --- 577,586 ---- 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; --- 632,639 ---- 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) --- 791,798 ---- 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) --- 807,814 ---- 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) --- 1429,1479 ---- } 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_db_connections(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_connections; + + 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 --- 1520,1526 ---- 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) --- 1542,1607 ---- } 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_bytes_sent_backend(PG_FUNCTION_ARGS) + { + PG_RETURN_INT64(pgstat_fetch_global()->bytes_sent_backend); + } + + Datum + pg_stat_get_bytes_received_backend(PG_FUNCTION_ARGS) + { + PG_RETURN_INT64(pgstat_fetch_global()->bytes_received_backend); + } + + Datum + pg_stat_get_bytes_sent_walsender(PG_FUNCTION_ARGS) + { + PG_RETURN_INT64(pgstat_fetch_global()->bytes_sent_walsender); + } + + Datum + pg_stat_get_bytes_received_walsender(PG_FUNCTION_ARGS) + { + PG_RETURN_INT64(pgstat_fetch_global()->bytes_received_walsender); + } + + Datum + pg_stat_get_conn_received(PG_FUNCTION_ARGS) + { + PG_RETURN_INT64(pgstat_fetch_global()->conn_received); + } + + Datum + pg_stat_get_conn_backend(PG_FUNCTION_ARGS) + { + PG_RETURN_INT64(pgstat_fetch_global()->conn_backend); + } + + Datum + pg_stat_get_conn_walsender(PG_FUNCTION_ARGS) + { + PG_RETURN_INT64(pgstat_fetch_global()->conn_walsender); + } + + 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,2707 ---- 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 client connections"); + 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 client connections"); + DATA(insert OID = 3197 ( pg_stat_get_db_connections 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_connections _null_ _null_ _null_ )); + DESCR("statistics: number of successful client connections"); 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"); --- 2725,2751 ---- 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 = 3198 ( 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: total number of bytes sent over client connections"); + DATA(insert OID = 3199 ( 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: total number of bytes received over client connections"); + DATA(insert OID = 3200 ( pg_stat_get_bytes_sent_backend 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_backend _null_ _null_ _null_ )); + DESCR("statistics: number of bytes sent over client connections to user backends"); + DATA(insert OID = 3201 ( pg_stat_get_bytes_received_backend 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_backend _null_ _null_ _null_ )); + DESCR("statistics: number of bytes received over client connections from user backends"); + DATA(insert OID = 3202 ( pg_stat_get_bytes_sent_walsender 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_walsender _null_ _null_ _null_ )); + DESCR("statistics: number of bytes sent over client connections to WAL senders"); + DATA(insert OID = 3203 ( pg_stat_get_bytes_received_walsender 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_walsender _null_ _null_ _null_ )); + DESCR("statistics: number of bytes received over client connections from WAL senders"); + DATA(insert OID = 3204 ( pg_stat_get_conn_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_conn_received _null_ _null_ _null_ )); + DESCR("statistics: number of client connections received"); + DATA(insert OID = 3205 ( pg_stat_get_conn_backend PGNSP PGUID 12 1 0 0 0 f f f f t f s 0 0 20 "" _null_ _null_ _null_ _null_ pg_stat_get_conn_backend _null_ _null_ _null_ )); + DESCR("statistics: number of successful client connections to a user backend"); + DATA(insert OID = 3206 ( pg_stat_get_conn_walsender PGNSP PGUID 12 1 0 0 0 f f f f t f s 0 0 20 "" _null_ _null_ _null_ _null_ pg_stat_get_conn_walsender _null_ _null_ _null_ )); + DESCR("statistics: number of successful client connections to a WAL sender"); + DATA(insert OID = 3207 ( 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 client connection 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,59 ---- PGSTAT_MTYPE_FUNCPURGE, PGSTAT_MTYPE_RECOVERYCONFLICT, PGSTAT_MTYPE_TEMPFILE, ! PGSTAT_MTYPE_DEADLOCK, ! PGSTAT_MTYPE_BYTESSENT, ! PGSTAT_MTYPE_BYTESRECEIVED, ! PGSTAT_MTYPE_CONNRECEIVED, ! PGSTAT_MTYPE_CONNSUCCEEDED } 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 */ --- 106,113 ---- /* 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 --- 402,446 ---- } PgStat_MsgTempFile; /* ---------- + * PgStat_MsgBytesTransferred + * + * Sent upon sending or receiving data over a client connection. + * The message header determines direction. + * ---------- + */ + typedef struct PgStat_MsgBytesTransferred + { + PgStat_MsgHdr m_hdr; + Oid m_databaseid; + int m_bytes_transferred; + bool m_walsender; + } PgStat_MsgBytesTransferred; + + /* ---------- + * PgStat_MsgConnReceived + * + * Sent upon receiving a client connection. + * ---------- + */ + typedef struct PgStat_MsgConnReceived + { + PgStat_MsgHdr m_hdr; + } PgStat_MsgConnReceived; + + /* ---------- + * PgStat_MsgConnSucceeded + * + * Sent upon client's successful connection. + * ---------- + */ + typedef struct PgStat_MsgConnSucceeded + { + PgStat_MsgHdr m_hdr; + Oid m_databaseid; + bool m_walsender; + } PgStat_MsgConnSucceeded; + + /* ---------- * 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 --- 559,565 ---- * ------------------------------------------------------------ */ ! #define PGSTAT_FILE_FORMAT_ID 0x01A5BC9C /* ---------- * PgStat_StatDBEntry The collector's data per database *************** *** 544,550 **** typedef struct PgStat_StatDBEntry PgStat_Counter n_deadlocks; PgStat_Counter n_block_read_time; /* times in microseconds */ PgStat_Counter n_block_write_time; ! TimestampTz stat_reset_timestamp; TimestampTz stats_timestamp; /* time of db stats file update */ --- 588,598 ---- 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 connections) */ ! PgStat_Counter n_bytes_sent; ! /* communication socket transfer counter in bytes (client to backend connections) */ ! PgStat_Counter n_bytes_received; ! PgStat_Counter n_connections; /* client connections succeeded */ TimestampTz stat_reset_timestamp; TimestampTz stats_timestamp; /* time of db stats file update */ *************** *** 614,619 **** typedef struct PgStat_StatFuncEntry --- 662,668 ---- 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; --- 673,690 ---- PgStat_Counter buf_written_backend; PgStat_Counter buf_fsync_backend; PgStat_Counter buf_alloc; ! TimestampTz bgwriter_stat_reset_timestamp; ! /* client connection stats */ ! PgStat_Counter bytes_sent; /* in bytes (cluster to client) */ ! PgStat_Counter bytes_received; /* in bytes (client to cluster) */ ! PgStat_Counter bytes_sent_backend; /* in bytes (backend to client) */ ! PgStat_Counter bytes_received_backend; /* in bytes (client to backend) */ ! PgStat_Counter bytes_sent_walsender; /* in bytes (walsender to client) */ ! PgStat_Counter bytes_received_walsender; /* in bytes (client to walsender) */ ! PgStat_Counter conn_received; /* client connections received */ ! PgStat_Counter conn_backend; /* successful client connections to a backend */ ! PgStat_Counter conn_walsender; /* successful client connections to a walsender */ ! TimestampTz socket_stat_reset_timestamp; } PgStat_GlobalStats; *************** *** 697,702 **** typedef struct PgBackendStatus --- 757,768 ---- /* current command string; MUST be null-terminated */ char *st_activity; + + /* communication socket transfer counter in bytes (backend to client connections) */ + unsigned long st_bytes_sent; + /* communication socket transfer counter in bytes (client to backend connections) */ + unsigned long st_bytes_received; + } PgBackendStatus; /* *************** *** 788,793 **** extern void pgstat_report_tempfile(size_t filesize); --- 854,864 ---- 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_bytessent(int count); + extern void pgstat_report_bytesreceived(int count); + extern void pgstat_report_connreceived(void); + extern void pgstat_report_connsucceeded(void); + 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,1679 ---- 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_connections(d.oid) AS connections, 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, --- 1692,1699 ---- s.client_hostname, s.client_port, s.backend_start, + s.bytes_sent, + s.bytes_received, w.state, w.sent_location, w.write_location, *************** *** 1694,1703 **** 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)); pg_stat_sys_indexes| SELECT pg_stat_all_indexes.relid, pg_stat_all_indexes.indexrelid, pg_stat_all_indexes.schemaname, --- 1701,1720 ---- 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)); + pg_stat_socket| SELECT pg_stat_get_bytes_sent() AS bytes_sent_total, + pg_stat_get_bytes_received() AS bytes_received_total, + pg_stat_get_bytes_sent_backend() AS bytes_sent_backend, + pg_stat_get_bytes_received_backend() AS bytes_received_backend, + pg_stat_get_bytes_sent_walsender() AS bytes_sent_walsender, + pg_stat_get_bytes_received_walsender() AS bytes_received_walsender, + pg_stat_get_conn_received() AS conn_received, + pg_stat_get_conn_backend() AS conn_backend, + pg_stat_get_conn_walsender() AS conn_walsender, + pg_stat_get_socket_stat_reset_time() AS stats_reset; pg_stat_sys_indexes| SELECT pg_stat_all_indexes.relid, pg_stat_all_indexes.indexrelid, pg_stat_all_indexes.schemaname,