diff --git a/doc/src/sgml/monitoring.sgml b/doc/src/sgml/monitoring.sgml index 4a9732fc39a7417146e4f528cbf599dd49cd5970..6e57a83df88f7ea73bb100927556c2ecc50f3009 100644 --- a/doc/src/sgml/monitoring.sgml +++ b/doc/src/sgml/monitoring.sgml @@ -1,4 +1,4 @@ -<!-- $PostgreSQL: pgsql/doc/src/sgml/monitoring.sgml,v 1.46 2007/02/07 23:11:29 tgl Exp $ --> +<!-- $PostgreSQL: pgsql/doc/src/sgml/monitoring.sgml,v 1.47 2007/03/16 17:57:35 mha Exp $ --> <chapter id="monitoring"> <title>Monitoring Database Activity</title> @@ -265,8 +265,9 @@ postgres: <replaceable>user</> <replaceable>database</> <replaceable>host</> <re <entry>One row per database, showing database OID, database name, number of active server processes connected to that database, number of transactions committed and rolled back in that database, - total disk blocks read, and total buffer hits (i.e., block - read requests avoided by finding the block already in buffer cache). + total disk blocks read, total buffer hits (i.e., block + read requests avoided by finding the block already in buffer cache), + number of rows returned, inserted, updated and deleted. </entry> </row> @@ -502,6 +503,46 @@ postgres: <replaceable>user</> <replaceable>database</> <replaceable>host</> <re </entry> </row> + <row> + <entry><literal><function>pg_stat_get_db_tuples_returned</function>(<type>oid</type>)</literal></entry> + <entry><type>bigint</type></entry> + <entry> + Number of tuples returned for database + </entry> + </row> + + <row> + <entry><literal><function>pg_stat_get_db_tuples_fetched</function>(<type>oid</type>)</literal></entry> + <entry><type>bigint</type></entry> + <entry> + Number of tuples fetched for database + </entry> + </row> + + <row> + <entry><literal><function>pg_stat_get_db_tuples_inserted</function>(<type>oid</type>)</literal></entry> + <entry><type>bigint</type></entry> + <entry> + Number of tuples inserted in database + </entry> + </row> + + <row> + <entry><literal><function>pg_stat_get_db_tuples_updated</function>(<type>oid</type>)</literal></entry> + <entry><type>bigint</type></entry> + <entry> + Number of tuples updated in database + </entry> + </row> + + <row> + <entry><literal><function>pg_stat_get_db_tuples_deleted</function>(<type>oid</type>)</literal></entry> + <entry><type>bigint</type></entry> + <entry> + Number of tuples deleted in database + </entry> + </row> + <row> <entry><literal><function>pg_stat_get_numscans</function>(<type>oid</type>)</literal></entry> <entry><type>bigint</type></entry> diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql index 589f8ebc50a3e636df01aaf40859066798d33a3e..5948db162b76babfabd26a26fbedc3fa60e4dffb 100644 --- a/src/backend/catalog/system_views.sql +++ b/src/backend/catalog/system_views.sql @@ -3,7 +3,7 @@ * * Copyright (c) 1996-2007, PostgreSQL Global Development Group * - * $PostgreSQL: pgsql/src/backend/catalog/system_views.sql,v 1.35 2007/01/05 22:19:25 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/catalog/system_views.sql,v 1.36 2007/03/16 17:57:36 mha Exp $ */ CREATE VIEW pg_roles AS @@ -357,5 +357,10 @@ CREATE VIEW pg_stat_database AS pg_stat_get_db_xact_rollback(D.oid) AS xact_rollback, pg_stat_get_db_blocks_fetched(D.oid) - pg_stat_get_db_blocks_hit(D.oid) AS blks_read, - pg_stat_get_db_blocks_hit(D.oid) AS blks_hit + pg_stat_get_db_blocks_hit(D.oid) AS blks_hit, + pg_stat_get_db_tuples_returned(D.oid) AS tup_returned, + pg_stat_get_db_tuples_fetched(D.oid) AS tup_fetched, + pg_stat_get_db_tuples_inserted(D.oid) AS tup_inserted, + pg_stat_get_db_tuples_updated(D.oid) AS tup_updated, + pg_stat_get_db_tuples_deleted(D.oid) AS tup_deleted FROM pg_database D; diff --git a/src/backend/postmaster/pgstat.c b/src/backend/postmaster/pgstat.c index 486dc6e48bfc9e1f2d736ff778befff0c687baa9..378e165707f04033e81681f2fa1f3d6548f67cc1 100644 --- a/src/backend/postmaster/pgstat.c +++ b/src/backend/postmaster/pgstat.c @@ -13,7 +13,7 @@ * * Copyright (c) 2001-2007, PostgreSQL Global Development Group * - * $PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.148 2007/03/01 20:06:56 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.149 2007/03/16 17:57:36 mha Exp $ * ---------- */ #include "postgres.h" @@ -1970,6 +1970,11 @@ pgstat_get_db_entry(Oid databaseid, bool create) result->n_xact_rollback = 0; result->n_blocks_fetched = 0; result->n_blocks_hit = 0; + result->n_tuples_returned = 0; + result->n_tuples_fetched = 0; + result->n_tuples_inserted = 0; + result->n_tuples_updated = 0; + result->n_tuples_deleted = 0; result->last_autovac_time = 0; memset(&hash_ctl, 0, sizeof(hash_ctl)); @@ -2413,6 +2418,15 @@ pgstat_recv_tabstat(PgStat_MsgTabstat *msg, int len) tabentry->blocks_hit += tabmsg[i].t_blocks_hit; } + /* + * Add table stats to the database entry. + */ + dbentry->n_tuples_returned += tabmsg[i].t_tuples_returned; + dbentry->n_tuples_fetched += tabmsg[i].t_tuples_fetched; + dbentry->n_tuples_inserted += tabmsg[i].t_tuples_inserted; + dbentry->n_tuples_updated += tabmsg[i].t_tuples_updated; + dbentry->n_tuples_deleted += tabmsg[i].t_tuples_deleted; + /* * And add the block IO to the database entry. */ diff --git a/src/backend/utils/adt/pgstatfuncs.c b/src/backend/utils/adt/pgstatfuncs.c index 50624d6e7281fbba45c43b75bb6f97d4461ebfcc..831fe6b8899d2f4dd1f22fb8dd5aae2f16b34bf8 100644 --- a/src/backend/utils/adt/pgstatfuncs.c +++ b/src/backend/utils/adt/pgstatfuncs.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/utils/adt/pgstatfuncs.c,v 1.39 2007/02/27 23:48:08 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/utils/adt/pgstatfuncs.c,v 1.40 2007/03/16 17:57:36 mha Exp $ * *------------------------------------------------------------------------- */ @@ -55,6 +55,11 @@ extern Datum pg_stat_get_db_xact_commit(PG_FUNCTION_ARGS); extern Datum pg_stat_get_db_xact_rollback(PG_FUNCTION_ARGS); extern Datum pg_stat_get_db_blocks_fetched(PG_FUNCTION_ARGS); extern Datum pg_stat_get_db_blocks_hit(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_db_tuples_returned(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_db_tuples_fetched(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_db_tuples_inserted(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_db_tuples_updated(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_db_tuples_deleted(PG_FUNCTION_ARGS); extern Datum pg_stat_clear_snapshot(PG_FUNCTION_ARGS); extern Datum pg_stat_reset(PG_FUNCTION_ARGS); @@ -672,6 +677,86 @@ pg_stat_get_db_blocks_hit(PG_FUNCTION_ARGS) } +Datum +pg_stat_get_db_tuples_returned(PG_FUNCTION_ARGS) +{ + Oid dbid = PG_GETARG_OID(0); + int64 result; + PgStat_StatDBEntry *dbentry; + + if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL) + result = 0; + else + result = (int64) (dbentry->n_tuples_returned); + + PG_RETURN_INT64(result); +} + + +Datum +pg_stat_get_db_tuples_fetched(PG_FUNCTION_ARGS) +{ + Oid dbid = PG_GETARG_OID(0); + int64 result; + PgStat_StatDBEntry *dbentry; + + if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL) + result = 0; + else + result = (int64) (dbentry->n_tuples_fetched); + + PG_RETURN_INT64(result); +} + + +Datum +pg_stat_get_db_tuples_inserted(PG_FUNCTION_ARGS) +{ + Oid dbid = PG_GETARG_OID(0); + int64 result; + PgStat_StatDBEntry *dbentry; + + if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL) + result = 0; + else + result = (int64) (dbentry->n_tuples_inserted); + + PG_RETURN_INT64(result); +} + + +Datum +pg_stat_get_db_tuples_updated(PG_FUNCTION_ARGS) +{ + Oid dbid = PG_GETARG_OID(0); + int64 result; + PgStat_StatDBEntry *dbentry; + + if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL) + result = 0; + else + result = (int64) (dbentry->n_tuples_updated); + + PG_RETURN_INT64(result); +} + + +Datum +pg_stat_get_db_tuples_deleted(PG_FUNCTION_ARGS) +{ + Oid dbid = PG_GETARG_OID(0); + int64 result; + PgStat_StatDBEntry *dbentry; + + if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL) + result = 0; + else + result = (int64) (dbentry->n_tuples_deleted); + + PG_RETURN_INT64(result); +} + + /* Discard the active statistics snapshot */ Datum pg_stat_clear_snapshot(PG_FUNCTION_ARGS) diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h index 51263557f9ef73b9ecafbab03b990604e7a812e9..206cad6ba9fec276786c234a723b1ab1704dd016 100644 --- a/src/include/catalog/catversion.h +++ b/src/include/catalog/catversion.h @@ -37,7 +37,7 @@ * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.389 2007/03/02 00:48:44 tgl Exp $ + * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.390 2007/03/16 17:57:36 mha Exp $ * *------------------------------------------------------------------------- */ @@ -53,6 +53,6 @@ */ /* yyyymmddN */ -#define CATALOG_VERSION_NO 200703011 +#define CATALOG_VERSION_NO 200703161 #endif diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h index a4b0e9c5a392e2e9a65e37aab1e26129c5126a83..6148702f5ee85e7d3cdc50d461a778a46f4a5f49 100644 --- a/src/include/catalog/pg_proc.h +++ b/src/include/catalog/pg_proc.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.447 2007/03/03 19:52:46 momjian Exp $ + * $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.448 2007/03/16 17:57:36 mha Exp $ * * NOTES * The script catalog/genbki.sh reads this file and generates .bki @@ -2974,6 +2974,16 @@ DATA(insert OID = 1944 ( pg_stat_get_db_blocks_fetched PGNSP PGUID 12 1 0 f f t DESCR("Statistics: Blocks fetched for database"); DATA(insert OID = 1945 ( pg_stat_get_db_blocks_hit PGNSP PGUID 12 1 0 f f t f s 1 20 "26" _null_ _null_ _null_ pg_stat_get_db_blocks_hit - _null_ )); DESCR("Statistics: Blocks found in cache for database"); +DATA(insert OID = 2758 ( pg_stat_get_db_tuples_returned PGNSP PGUID 12 1 0 f f t f s 1 20 "26" _null_ _null_ _null_ pg_stat_get_db_tuples_returned - _null_ )); +DESCR("Statistics: Tuples returned for database"); +DATA(insert OID = 2759 ( pg_stat_get_db_tuples_fetched PGNSP PGUID 12 1 0 f f t f s 1 20 "26" _null_ _null_ _null_ pg_stat_get_db_tuples_fetched - _null_ )); +DESCR("Statistics: Tuples fetched for database"); +DATA(insert OID = 2760 ( pg_stat_get_db_tuples_inserted PGNSP PGUID 12 1 0 f f t f s 1 20 "26" _null_ _null_ _null_ pg_stat_get_db_tuples_inserted - _null_ )); +DESCR("Statistics: Tuples inserted in database"); +DATA(insert OID = 2761 ( pg_stat_get_db_tuples_updated PGNSP PGUID 12 1 0 f f t f s 1 20 "26" _null_ _null_ _null_ pg_stat_get_db_tuples_updated - _null_ )); +DESCR("Statistics: Tuples updated in database"); +DATA(insert OID = 2762 ( pg_stat_get_db_tuples_deleted PGNSP PGUID 12 1 0 f f t f s 1 20 "26" _null_ _null_ _null_ pg_stat_get_db_tuples_deleted - _null_ )); +DESCR("Statistics: Tuples deleted in database"); DATA(insert OID = 2230 ( pg_stat_clear_snapshot PGNSP PGUID 12 1 0 f f f f v 0 2278 "" _null_ _null_ _null_ pg_stat_clear_snapshot - _null_ )); DESCR("Statistics: Discard current transaction's statistics snapshot"); DATA(insert OID = 2274 ( pg_stat_reset PGNSP PGUID 12 1 0 f f f f v 0 2278 "" _null_ _null_ _null_ pg_stat_reset - _null_ )); diff --git a/src/include/pgstat.h b/src/include/pgstat.h index e4cc6e9aec799dc88ccbb8b3684fb9feed106d0d..ce0333a787187066602cf49b55cd1375ec3e26b2 100644 --- a/src/include/pgstat.h +++ b/src/include/pgstat.h @@ -5,7 +5,7 @@ * * Copyright (c) 2001-2007, PostgreSQL Global Development Group * - * $PostgreSQL: pgsql/src/include/pgstat.h,v 1.54 2007/02/09 16:12:19 tgl Exp $ + * $PostgreSQL: pgsql/src/include/pgstat.h,v 1.55 2007/03/16 17:57:36 mha Exp $ * ---------- */ #ifndef PGSTAT_H @@ -251,6 +251,11 @@ typedef struct PgStat_StatDBEntry PgStat_Counter n_xact_rollback; PgStat_Counter n_blocks_fetched; PgStat_Counter n_blocks_hit; + PgStat_Counter n_tuples_returned; + PgStat_Counter n_tuples_fetched; + PgStat_Counter n_tuples_inserted; + PgStat_Counter n_tuples_updated; + PgStat_Counter n_tuples_deleted; TimestampTz last_autovac_time; /* diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out index 30103f5d08b7ef9c47aa6cf0b82c07aab4bbc283..6ff781e6bd5596de3c94894749bfe18a14949e46 100644 --- a/src/test/regress/expected/rules.out +++ b/src/test/regress/expected/rules.out @@ -1292,7 +1292,7 @@ SELECT viewname, definition FROM pg_views WHERE schemaname <> 'information_schem pg_stat_activity | SELECT d.oid AS datid, d.datname, pg_stat_get_backend_pid(s.backendid) AS procpid, pg_stat_get_backend_userid(s.backendid) AS usesysid, u.rolname AS usename, pg_stat_get_backend_activity(s.backendid) AS current_query, pg_stat_get_backend_waiting(s.backendid) AS waiting, pg_stat_get_backend_txn_start(s.backendid) AS txn_start, pg_stat_get_backend_activity_start(s.backendid) AS query_start, pg_stat_get_backend_start(s.backendid) AS backend_start, pg_stat_get_backend_client_addr(s.backendid) AS client_addr, pg_stat_get_backend_client_port(s.backendid) AS client_port FROM pg_database d, (SELECT pg_stat_get_backend_idset() AS backendid) s, pg_authid u WHERE ((pg_stat_get_backend_dbid(s.backendid) = d.oid) AND (pg_stat_get_backend_userid(s.backendid) = u.oid)); pg_stat_all_indexes | SELECT c.oid AS relid, i.oid AS indexrelid, n.nspname AS schemaname, c.relname, i.relname AS indexrelname, pg_stat_get_numscans(i.oid) AS idx_scan, pg_stat_get_tuples_returned(i.oid) AS idx_tup_read, pg_stat_get_tuples_fetched(i.oid) AS idx_tup_fetch FROM (((pg_class c JOIN pg_index x ON ((c.oid = x.indrelid))) JOIN pg_class i ON ((i.oid = x.indexrelid))) LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) WHERE (c.relkind = ANY (ARRAY['r'::"char", 't'::"char"])); pg_stat_all_tables | SELECT c.oid AS relid, n.nspname AS schemaname, c.relname, pg_stat_get_numscans(c.oid) AS seq_scan, pg_stat_get_tuples_returned(c.oid) AS seq_tup_read, (sum(pg_stat_get_numscans(i.indexrelid)))::bigint AS idx_scan, ((sum(pg_stat_get_tuples_fetched(i.indexrelid)))::bigint + pg_stat_get_tuples_fetched(c.oid)) AS idx_tup_fetch, pg_stat_get_tuples_inserted(c.oid) AS n_tup_ins, pg_stat_get_tuples_updated(c.oid) AS n_tup_upd, pg_stat_get_tuples_deleted(c.oid) AS n_tup_del, pg_stat_get_live_tuples(c.oid) AS n_live_tup, pg_stat_get_dead_tuples(c.oid) AS n_dead_tup, pg_stat_get_last_vacuum_time(c.oid) AS last_vacuum, pg_stat_get_last_autovacuum_time(c.oid) AS last_autovacuum, pg_stat_get_last_analyze_time(c.oid) AS last_analyze, pg_stat_get_last_autoanalyze_time(c.oid) AS last_autoanalyze FROM ((pg_class c LEFT JOIN pg_index i ON ((c.oid = i.indrelid))) LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) WHERE (c.relkind = ANY (ARRAY['r'::"char", 't'::"char"])) GROUP BY c.oid, n.nspname, c.relname; - pg_stat_database | SELECT d.oid AS datid, d.datname, pg_stat_get_db_numbackends(d.oid) AS numbackends, pg_stat_get_db_xact_commit(d.oid) AS xact_commit, pg_stat_get_db_xact_rollback(d.oid) AS xact_rollback, (pg_stat_get_db_blocks_fetched(d.oid) - pg_stat_get_db_blocks_hit(d.oid)) AS blks_read, pg_stat_get_db_blocks_hit(d.oid) AS blks_hit FROM pg_database d; + pg_stat_database | SELECT d.oid AS datid, d.datname, pg_stat_get_db_numbackends(d.oid) AS numbackends, pg_stat_get_db_xact_commit(d.oid) AS xact_commit, pg_stat_get_db_xact_rollback(d.oid) AS xact_rollback, (pg_stat_get_db_blocks_fetched(d.oid) - pg_stat_get_db_blocks_hit(d.oid)) AS blks_read, pg_stat_get_db_blocks_hit(d.oid) AS blks_hit, pg_stat_get_db_tuples_returned(d.oid) AS tup_returned, pg_stat_get_db_tuples_fetched(d.oid) AS tup_fetched, pg_stat_get_db_tuples_inserted(d.oid) AS tup_inserted, pg_stat_get_db_tuples_updated(d.oid) AS tup_updated, pg_stat_get_db_tuples_deleted(d.oid) AS tup_deleted FROM pg_database d; pg_stat_sys_indexes | SELECT pg_stat_all_indexes.relid, pg_stat_all_indexes.indexrelid, pg_stat_all_indexes.schemaname, pg_stat_all_indexes.relname, pg_stat_all_indexes.indexrelname, pg_stat_all_indexes.idx_scan, pg_stat_all_indexes.idx_tup_read, pg_stat_all_indexes.idx_tup_fetch FROM pg_stat_all_indexes WHERE (pg_stat_all_indexes.schemaname = ANY (ARRAY['pg_catalog'::"name", 'pg_toast'::"name", 'information_schema'::"name"])); pg_stat_sys_tables | SELECT pg_stat_all_tables.relid, pg_stat_all_tables.schemaname, pg_stat_all_tables.relname, pg_stat_all_tables.seq_scan, pg_stat_all_tables.seq_tup_read, pg_stat_all_tables.idx_scan, pg_stat_all_tables.idx_tup_fetch, pg_stat_all_tables.n_tup_ins, pg_stat_all_tables.n_tup_upd, pg_stat_all_tables.n_tup_del, pg_stat_all_tables.n_live_tup, pg_stat_all_tables.n_dead_tup, pg_stat_all_tables.last_vacuum, pg_stat_all_tables.last_autovacuum, pg_stat_all_tables.last_analyze, pg_stat_all_tables.last_autoanalyze FROM pg_stat_all_tables WHERE (pg_stat_all_tables.schemaname = ANY (ARRAY['pg_catalog'::"name", 'pg_toast'::"name", 'information_schema'::"name"])); pg_stat_user_indexes | SELECT pg_stat_all_indexes.relid, pg_stat_all_indexes.indexrelid, pg_stat_all_indexes.schemaname, pg_stat_all_indexes.relname, pg_stat_all_indexes.indexrelname, pg_stat_all_indexes.idx_scan, pg_stat_all_indexes.idx_tup_read, pg_stat_all_indexes.idx_tup_fetch FROM pg_stat_all_indexes WHERE (pg_stat_all_indexes.schemaname <> ALL (ARRAY['pg_catalog'::"name", 'pg_toast'::"name", 'information_schema'::"name"]));