Add views and functions to monitor hot standby query conflicts
authorMagnus Hagander
Mon, 3 Jan 2011 11:46:03 +0000 (12:46 +0100)
committerMagnus Hagander
Mon, 3 Jan 2011 11:46:03 +0000 (12:46 +0100)
Add the view pg_stat_database_conflicts and a column to pg_stat_database,
and the underlying functions to provide the information.

doc/src/sgml/high-availability.sgml
doc/src/sgml/monitoring.sgml
src/backend/catalog/system_views.sql
src/backend/postmaster/pgstat.c
src/backend/tcop/postgres.c
src/backend/utils/adt/pgstatfuncs.c
src/include/catalog/pg_proc.h
src/include/pgstat.h
src/test/regress/expected/rules.out

index 46a97e19ce332d0fd4c82d08f721783e19e9ac1b..2c24fd9c139630c74a28971d0fd10b36aca5c49b 100644 (file)
@@ -1554,6 +1554,13 @@ if (!triggered)
     approach, since vacuum_defer_cleanup_age is measured in
     transactions executed on the primary server.
    
+
+   
+    The number of query cancels and the reason for them can be viewed using
+    the pg_stat_database_conflicts system view on the standby
+    server. The pg_stat_database system view also contains
+    summary information.
+   
   
 
   
index 5fd0213823e30be6695d679038835354b254b200..739b8a27fd98121c8ea17c9df92aa522c15ff150 100644 (file)
@@ -278,7 +278,19 @@ postgres: user database host 
       number of transactions committed and rolled back in that database,
       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, fetched, inserted, updated and deleted.
+      number of rows returned, fetched, inserted, updated and deleted, and
+      total number of queries cancelled due to conflict with recovery (on
+      standby servers).
+     
+     
+
+     
+      pg_stat_database_conflictspg_stat_database_conflicts
+      One row per database, showing database OID, database name and
+      the number of queries that have been cancelled in this database due to
+      dropped tablespaces, lock timeouts, old snapshots, pinned buffers and
+      deadlocks. Will only contain information on standby servers, since
+      conflicts do not occur on master servers.
      
      
 
@@ -599,6 +611,46 @@ postgres: user database host 
       
      
 
+     
+      pg_stat_get_db_conflict_tablespace(oid)
+      bigint
+      
+       Number of queries cancelled because of recovery conflict with dropped tablespaces in database
+      
+     
+
+     
+      pg_stat_get_db_conflict_lock(oid)
+      bigint
+      
+       Number of queries cancelled because of recovery conflict with locks in database
+      
+     
+
+     
+      pg_stat_get_db_conflict_snapshot(oid)
+      bigint
+      
+       Number of queries cancelled because of recovery conflict with old snapshots in database
+      
+     
+
+     
+      pg_stat_get_db_conflict_bufferpin(oid)
+      bigint
+      
+       Number of queries cancelled because of recovery conflict with pinned buffers in database
+      
+     
+
+     
+      pg_stat_get_db_conflict_startup_deadlock(oid)
+      bigint
+      
+       Number of queries cancelled because of recovery conflict with deadlocks in database
+      
+     
+
      
       pg_stat_get_numscans(oid)
       bigint
index ded046d9d066b5c815b7ab39fad6194b8e81df55..262b3724902cc2ff2fa6327fb0b067963fe1023e 100644 (file)
@@ -506,7 +506,19 @@ CREATE VIEW pg_stat_database AS
             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
+            pg_stat_get_db_tuples_deleted(D.oid) AS tup_deleted,
+            pg_stat_get_db_conflict_all(D.oid) AS conflicts
+    FROM pg_database D;
+
+CREATE VIEW pg_stat_database_conflicts AS
+    SELECT
+            D.oid AS datid,
+            D.datname AS datname,
+            pg_stat_get_db_conflict_tablespace(D.oid) AS confl_tablespace,
+            pg_stat_get_db_conflict_lock(D.oid) AS confl_lock,
+            pg_stat_get_db_conflict_snapshot(D.oid) AS confl_snapshot,
+            pg_stat_get_db_conflict_bufferpin(D.oid) AS confl_bufferpin,
+            pg_stat_get_db_conflict_startup_deadlock(D.oid) AS confl_deadlock
     FROM pg_database D;
 
 CREATE VIEW pg_stat_user_functions AS
index 850a543d7e768ee03d6b6203e986c3b614202072..301568f6df335270a834bee1347748cac5e3bbeb 100644 (file)
@@ -57,6 +57,7 @@
 #include "storage/ipc.h"
 #include "storage/pg_shmem.h"
 #include "storage/pmsignal.h"
+#include "storage/procsignal.h"
 #include "utils/guc.h"
 #include "utils/memutils.h"
 #include "utils/ps_status.h"
@@ -278,6 +279,7 @@ static void pgstat_recv_analyze(PgStat_MsgAnalyze *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);
+static void pgstat_recv_recoveryconflict(PgStat_MsgRecoveryConflict *msg, int len);
 
 
 /* ------------------------------------------------------------
@@ -1314,6 +1316,25 @@ pgstat_report_analyze(Relation rel, bool adopt_counts,
    pgstat_send(&msg, sizeof(msg));
 }
 
+/* --------
+ * pgstat_report_recovery_conflict() -
+ *
+ *  Tell the collector about a Hot Standby recovery conflict.
+ * --------
+ */
+void
+pgstat_report_recovery_conflict(int reason)
+{
+   PgStat_MsgRecoveryConflict msg;
+
+   if (pgStatSock == PGINVALID_SOCKET || !pgstat_track_counts)
+       return;
+
+   pgstat_setheader(&msg.m_hdr, PGSTAT_MTYPE_RECOVERYCONFLICT);
+   msg.m_databaseid = MyDatabaseId;
+   msg.m_reason = reason;
+   pgstat_send(&msg, sizeof(msg));
+}
 
 /* ----------
  * pgstat_ping() -
@@ -3053,6 +3074,10 @@ PgstatCollectorMain(int argc, char *argv[])
                    pgstat_recv_funcpurge((PgStat_MsgFuncpurge *) &msg, len);
                    break;
 
+               case PGSTAT_MTYPE_RECOVERYCONFLICT:
+                   pgstat_recv_recoveryconflict((PgStat_MsgRecoveryConflict *) &msg, len);
+                   break;
+
                default:
                    break;
            }
@@ -3129,6 +3154,11 @@ pgstat_get_db_entry(Oid databaseid, bool create)
        result->n_tuples_updated = 0;
        result->n_tuples_deleted = 0;
        result->last_autovac_time = 0;
+       result->n_conflict_tablespace = 0;
+       result->n_conflict_lock = 0;
+       result->n_conflict_snapshot = 0;
+       result->n_conflict_bufferpin = 0;
+       result->n_conflict_startup_deadlock = 0;
 
        memset(&hash_ctl, 0, sizeof(hash_ctl));
        hash_ctl.keysize = sizeof(Oid);
@@ -4203,6 +4233,45 @@ pgstat_recv_bgwriter(PgStat_MsgBgWriter *msg, int len)
    globalStats.buf_alloc += msg->m_buf_alloc;
 }
 
+/* ----------
+ * pgstat_recv_recoveryconflict() -
+ *
+ *  Process as RECOVERYCONFLICT message.
+ * ----------
+ */
+static void
+pgstat_recv_recoveryconflict(PgStat_MsgRecoveryConflict *msg, int len)
+{
+   PgStat_StatDBEntry *dbentry;
+   dbentry = pgstat_get_db_entry(msg->m_databaseid, true);
+
+   switch (msg->m_reason)
+   {
+       case PROCSIG_RECOVERY_CONFLICT_DATABASE:
+           /*
+            * Since we drop the information about the database as soon
+            * as it replicates, there is no point in counting these
+            * conflicts.
+            */
+           break;
+       case PROCSIG_RECOVERY_CONFLICT_TABLESPACE:
+           dbentry->n_conflict_tablespace++;
+           break;
+       case PROCSIG_RECOVERY_CONFLICT_LOCK:
+           dbentry->n_conflict_lock++;
+           break;
+       case PROCSIG_RECOVERY_CONFLICT_SNAPSHOT:
+           dbentry->n_conflict_snapshot++;
+           break;
+       case PROCSIG_RECOVERY_CONFLICT_BUFFERPIN:
+           dbentry->n_conflict_bufferpin++;
+           break;
+       case PROCSIG_RECOVERY_CONFLICT_STARTUP_DEADLOCK:
+           dbentry->n_conflict_startup_deadlock++;
+           break;
+   }
+}
+
 /* ----------
  * pgstat_recv_funcstat() -
  *
index 4bfc674f8fa9e5de37361df18ad3f60e8e3a5b92..b227e6ce4f8712c08f60cb0e62473c5930d2c6ac 100644 (file)
@@ -2903,15 +2903,21 @@ ProcessInterrupts(void)
                    (errcode(ERRCODE_ADMIN_SHUTDOWN),
                     errmsg("terminating autovacuum process due to administrator command")));
        else if (RecoveryConflictPending && RecoveryConflictRetryable)
+       {
+           pgstat_report_recovery_conflict(RecoveryConflictReason);
            ereport(FATAL,
                    (errcode(ERRCODE_T_R_SERIALIZATION_FAILURE),
              errmsg("terminating connection due to conflict with recovery"),
                     errdetail_recovery_conflict()));
+       }
        else if (RecoveryConflictPending)
+       {
+           pgstat_report_recovery_conflict(RecoveryConflictReason);
            ereport(FATAL,
                    (errcode(ERRCODE_ADMIN_SHUTDOWN),
              errmsg("terminating connection due to conflict with recovery"),
                     errdetail_recovery_conflict()));
+       }
        else
            ereport(FATAL,
                    (errcode(ERRCODE_ADMIN_SHUTDOWN),
@@ -2956,6 +2962,7 @@ ProcessInterrupts(void)
            RecoveryConflictPending = false;
            DisableNotifyInterrupt();
            DisableCatchupInterrupt();
+           pgstat_report_recovery_conflict(RecoveryConflictReason);
            if (DoingCommandRead)
                ereport(FATAL,
                        (errcode(ERRCODE_T_R_SERIALIZATION_FAILURE),
index d357b5c8b5ddac362e63ca376bb0e2605645d79b..a95ba8b3eb385de70bff4f5ef5daf6edd8c5aed0 100644 (file)
@@ -71,6 +71,12 @@ 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_get_db_conflict_tablespace(PG_FUNCTION_ARGS);
+extern Datum pg_stat_get_db_conflict_lock(PG_FUNCTION_ARGS);
+extern Datum pg_stat_get_db_conflict_snapshot(PG_FUNCTION_ARGS);
+extern Datum pg_stat_get_db_conflict_bufferpin(PG_FUNCTION_ARGS);
+extern Datum pg_stat_get_db_conflict_startup_deadlock(PG_FUNCTION_ARGS);
+extern Datum pg_stat_get_db_conflict_all(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);
@@ -1129,6 +1135,101 @@ pg_stat_get_db_tuples_deleted(PG_FUNCTION_ARGS)
    PG_RETURN_INT64(result);
 }
 
+Datum
+pg_stat_get_db_conflict_tablespace(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_conflict_tablespace);
+
+   PG_RETURN_INT64(result);
+}
+
+Datum
+pg_stat_get_db_conflict_lock(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_conflict_lock);
+
+   PG_RETURN_INT64(result);
+}
+
+Datum
+pg_stat_get_db_conflict_snapshot(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_conflict_snapshot);
+
+   PG_RETURN_INT64(result);
+}
+
+Datum
+pg_stat_get_db_conflict_bufferpin(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_conflict_bufferpin);
+
+   PG_RETURN_INT64(result);
+}
+
+Datum
+pg_stat_get_db_conflict_startup_deadlock(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_conflict_startup_deadlock);
+
+   PG_RETURN_INT64(result);
+}
+
+Datum
+pg_stat_get_db_conflict_all(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_conflict_tablespace +
+           dbentry->n_conflict_lock +
+           dbentry->n_conflict_snapshot +
+           dbentry->n_conflict_bufferpin +
+           dbentry->n_conflict_startup_deadlock);
+
+   PG_RETURN_INT64(result);
+}
+
 Datum
 pg_stat_get_bgwriter_timed_checkpoints(PG_FUNCTION_ARGS)
 {
index 080a7fde6ff16389e930c2d09907a3e254f104f3..d6ed60a421426130e12377c75e8f16dffdd3e02b 100644 (file)
@@ -3117,6 +3117,18 @@ DATA(insert OID = 2761 (  pg_stat_get_db_tuples_updated PGNSP PGUID 12 1 0 0 f f
 DESCR("statistics: tuples updated in database");
 DATA(insert OID = 2762 (  pg_stat_get_db_tuples_deleted PGNSP PGUID 12 1 0 0 f f f t f s 1 0 20 "26" _null_ _null_ _null_ _null_ pg_stat_get_db_tuples_deleted _null_ _null_ _null_ ));
 DESCR("statistics: tuples deleted in database");
+DATA(insert OID = 3065 (  pg_stat_get_db_conflict_tablespace PGNSP PGUID 12 1 0 0 f f f t f s 1 0 20 "26" _null_ _null_ _null_ _null_ pg_stat_get_db_conflict_tablespace _null_ _null_ _null_ ));
+DESCR("statistics: recovery conflicts in database caused by drop tablespace");
+DATA(insert OID = 3066 (  pg_stat_get_db_conflict_lock PGNSP PGUID 12 1 0 0 f f f t f s 1 0 20 "26" _null_ _null_ _null_ _null_ pg_stat_get_db_conflict_lock _null_ _null_ _null_ ));
+DESCR("statistics: recovery conflicts in database caused by relation lock");
+DATA(insert OID = 3067 (  pg_stat_get_db_conflict_snapshot PGNSP PGUID 12 1 0 0 f f f t f s 1 0 20 "26" _null_ _null_ _null_ _null_ pg_stat_get_db_conflict_snapshot _null_ _null_ _null_ ));
+DESCR("statistics: recovery conflicts in database caused by snapshot expiry");
+DATA(insert OID = 3068 (  pg_stat_get_db_conflict_bufferpin PGNSP PGUID 12 1 0 0 f f f t f s 1 0 20 "26" _null_ _null_ _null_ _null_ pg_stat_get_db_conflict_bufferpin _null_ _null_ _null_ ));
+DESCR("statistics: recovery conflicts in database caused by shared buffer pin");
+DATA(insert OID = 3069 (  pg_stat_get_db_conflict_startup_deadlock PGNSP PGUID 12 1 0 0 f f f t f s 1 0 20 "26" _null_ _null_ _null_ _null_ pg_stat_get_db_conflict_startup_deadlock _null_ _null_ _null_ ));
+DESCR("statistics: recovery conflicts in database caused by buffer deadlock");
+DATA(insert OID = 3070 (  pg_stat_get_db_conflict_all PGNSP PGUID 12 1 0 0 f f f t f s 1 0 20 "26" _null_ _null_ _null_ _null_ pg_stat_get_db_conflict_all _null_ _null_ _null_ ));
+DESCR("statistics: recovery conflicts in database");
 DATA(insert OID = 2769 ( pg_stat_get_bgwriter_timed_checkpoints PGNSP PGUID 12 1 0 0 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 f f f t f s 0 0 20 "" _null_ _null_ _null_ _null_ pg_stat_get_bgwriter_requested_checkpoints _null_ _null_ _null_ ));
index 053dd4de0d1a2f4c92c4b5ebb35d89ff3e084c38..9f4e0cac9b8dc7d13072d486dc57bdab4374d3d5 100644 (file)
@@ -45,7 +45,8 @@ typedef enum StatMsgType
    PGSTAT_MTYPE_ANALYZE,
    PGSTAT_MTYPE_BGWRITER,
    PGSTAT_MTYPE_FUNCSTAT,
-   PGSTAT_MTYPE_FUNCPURGE
+   PGSTAT_MTYPE_FUNCPURGE,
+   PGSTAT_MTYPE_RECOVERYCONFLICT
 } StatMsgType;
 
 /* ----------
@@ -364,6 +365,17 @@ typedef struct PgStat_MsgBgWriter
    PgStat_Counter m_buf_alloc;
 } PgStat_MsgBgWriter;
 
+/* ----------
+ * PgStat_MsgRecoveryConflict  Sent by the backend upon recovery conflict
+ * ----------
+ */
+typedef struct PgStat_MsgRecoveryConflict
+{
+   PgStat_MsgHdr m_hdr;
+
+   Oid         m_databaseid;
+   int         m_reason;
+} PgStat_MsgRecoveryConflict;
 
 /* ----------
  * PgStat_FunctionCounts   The actual per-function counts kept by a backend
@@ -460,6 +472,7 @@ typedef union PgStat_Msg
    PgStat_MsgBgWriter msg_bgwriter;
    PgStat_MsgFuncstat msg_funcstat;
    PgStat_MsgFuncpurge msg_funcpurge;
+   PgStat_MsgRecoveryConflict msg_recoveryconflict;
 } PgStat_Msg;
 
 
@@ -490,6 +503,12 @@ typedef struct PgStat_StatDBEntry
    PgStat_Counter n_tuples_updated;
    PgStat_Counter n_tuples_deleted;
    TimestampTz last_autovac_time;
+   PgStat_Counter n_conflict_tablespace;
+   PgStat_Counter n_conflict_lock;
+   PgStat_Counter n_conflict_snapshot;
+   PgStat_Counter n_conflict_bufferpin;
+   PgStat_Counter n_conflict_startup_deadlock;
+
 
    /*
     * tables and functions must be last in the struct, because we don't write
@@ -689,6 +708,8 @@ extern void pgstat_report_vacuum(Oid tableoid, bool shared, bool adopt_counts,
 extern void pgstat_report_analyze(Relation rel, bool adopt_counts,
                      PgStat_Counter livetuples, PgStat_Counter deadtuples);
 
+extern void pgstat_report_recovery_conflict(int reason);
+
 extern void pgstat_initialize(void);
 extern void pgstat_bestart(void);
 
index 22e4c99fe666d04aac55c99261ddf7a4f5769711..a6baae242b68bd40b2e464d53acd48eaf882b988 100644 (file)
@@ -1294,7 +1294,8 @@ SELECT viewname, definition FROM pg_views WHERE schemaname <> 'information_schem
  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_tuples_hot_updated(c.oid) AS n_tup_hot_upd, 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, pg_stat_get_vacuum_count(c.oid) AS vacuum_count, pg_stat_get_autovacuum_count(c.oid) AS autovacuum_count, pg_stat_get_analyze_count(c.oid) AS analyze_count, pg_stat_get_autoanalyze_count(c.oid) AS autoanalyze_count 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_bgwriter            | SELECT pg_stat_get_bgwriter_timed_checkpoints() AS checkpoints_timed, pg_stat_get_bgwriter_requested_checkpoints() AS checkpoints_req, pg_stat_get_bgwriter_buf_written_checkpoints() AS buffers_checkpoint, pg_stat_get_bgwriter_buf_written_clean() AS buffers_clean, pg_stat_get_bgwriter_maxwritten_clean() AS maxwritten_clean, pg_stat_get_buf_written_backend() AS buffers_backend, pg_stat_get_buf_fsync_backend() AS buffers_backend_fsync, pg_stat_get_buf_alloc() AS buffers_alloc;
- 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_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, pg_stat_get_db_conflict_all(d.oid) AS conflicts FROM pg_database d;
+ pg_stat_database_conflicts  | SELECT d.oid AS datid, d.datname, pg_stat_get_db_conflict_tablespace(d.oid) AS confl_tablespace, pg_stat_get_db_conflict_lock(d.oid) AS confl_lock, pg_stat_get_db_conflict_snapshot(d.oid) AS confl_snapshot, pg_stat_get_db_conflict_bufferpin(d.oid) AS confl_bufferpin, pg_stat_get_db_conflict_startup_deadlock(d.oid) AS confl_deadlock 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, 'information_schema'::name])) OR (pg_stat_all_indexes.schemaname ~ '^pg_toast'::text));
  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_tup_hot_upd, 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, pg_stat_all_tables.vacuum_count, pg_stat_all_tables.autovacuum_count, pg_stat_all_tables.analyze_count, pg_stat_all_tables.autoanalyze_count FROM pg_stat_all_tables WHERE ((pg_stat_all_tables.schemaname = ANY (ARRAY['pg_catalog'::name, 'information_schema'::name])) OR (pg_stat_all_tables.schemaname ~ '^pg_toast'::text));
  pg_stat_user_functions      | SELECT p.oid AS funcid, n.nspname AS schemaname, p.proname AS funcname, pg_stat_get_function_calls(p.oid) AS calls, (pg_stat_get_function_time(p.oid) / 1000) AS total_time, (pg_stat_get_function_self_time(p.oid) / 1000) AS self_time FROM (pg_proc p LEFT JOIN pg_namespace n ON ((n.oid = p.pronamespace))) WHERE ((p.prolang <> (12)::oid) AND (pg_stat_get_function_calls(p.oid) IS NOT NULL));
@@ -1334,7 +1335,7 @@ SELECT viewname, definition FROM pg_views WHERE schemaname <> 'information_schem
  shoelace_obsolete           | SELECT shoelace.sl_name, shoelace.sl_avail, shoelace.sl_color, shoelace.sl_len, shoelace.sl_unit, shoelace.sl_len_cm FROM shoelace WHERE (NOT (EXISTS (SELECT shoe.shoename FROM shoe WHERE (shoe.slcolor = shoelace.sl_color))));
  street                      | SELECT r.name, r.thepath, c.cname FROM ONLY road r, real_city c WHERE (c.outline ## r.thepath);
  toyemp                      | SELECT emp.name, emp.age, emp.location, (12 * emp.salary) AS annualsal FROM emp;
-(56 rows)
+(57 rows)
 
 SELECT tablename, rulename, definition FROM pg_rules
    ORDER BY tablename, rulename;