diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index 642c129..893acf8 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -370,6 +370,11 @@ typedef struct XLogCtlWrite { int curridx; /* cache index of next block to write */ pg_time_t lastSegSwitchTime; /* time of last xlog segment switch */ + + /* + * Counter for WAL dirty buffer writes. + */ + uint64 WalBufferWriteDirtyCount; } XLogCtlWrite; /* @@ -1504,6 +1509,8 @@ AdvanceXLInsertBuffer(bool new_segment) } else { + XLogCtlWrite *Write = &XLogCtl->Write; + /* * Have to write buffers while holding insert lock. This is * not good, so only write as much as we absolutely must. @@ -1512,6 +1519,10 @@ AdvanceXLInsertBuffer(bool new_segment) WriteRqst.Write = OldPageRqstPtr; WriteRqst.Flush = 0; XLogWrite(WriteRqst, false, false); + /* + * XLogCtrlWrite must be protected with WALWriteLock. + */ + Write->WalBufferWriteDirtyCount++; LWLockRelease(WALWriteLock); TRACE_POSTGRESQL_WAL_BUFFER_WRITE_DIRTY_DONE(); } @@ -10492,3 +10503,26 @@ SetWalWriterSleeping(bool sleeping) xlogctl->WalWriterSleeping = sleeping; SpinLockRelease(&xlogctl->info_lck); } + +uint64 +xlog_dirty_write_counter_get() +{ + XLogCtlWrite *Write = &XLogCtl->Write; + uint64 count; + + LWLockAcquire(WALWriteLock, LW_SHARED); + count = Write->WalBufferWriteDirtyCount; + LWLockRelease(WALWriteLock); + + return count; +} + +void +xlog_dirty_write_counter_reset() +{ + XLogCtlWrite *Write = &XLogCtl->Write; + + LWLockAcquire(WALWriteLock, LW_EXCLUSIVE); + Write->WalBufferWriteDirtyCount = 0; + LWLockRelease(WALWriteLock); +} diff --git a/src/backend/utils/adt/pgstatfuncs.c b/src/backend/utils/adt/pgstatfuncs.c index 7c0705a..d544a5b 100644 --- a/src/backend/utils/adt/pgstatfuncs.c +++ b/src/backend/utils/adt/pgstatfuncs.c @@ -117,6 +117,9 @@ extern Datum pg_stat_reset_shared(PG_FUNCTION_ARGS); extern Datum pg_stat_reset_single_table_counters(PG_FUNCTION_ARGS); extern Datum pg_stat_reset_single_function_counters(PG_FUNCTION_ARGS); +extern Datum pg_stat_get_xlog_dirty_write(PG_FUNCTION_ARGS); +extern Datum pg_stat_reset_xlog_dirty_write(PG_FUNCTION_ARGS); + /* Global bgwriter statistics, from bgwriter.c */ extern PgStat_MsgBgWriter bgwriterStats; @@ -1700,3 +1703,16 @@ pg_stat_reset_single_function_counters(PG_FUNCTION_ARGS) PG_RETURN_VOID(); } + +Datum +pg_stat_get_xlog_dirty_write(PG_FUNCTION_ARGS) +{ + PG_RETURN_INT64(xlog_dirty_write_counter_get()); +} + +Datum +pg_stat_reset_xlog_dirty_write(PG_FUNCTION_ARGS) +{ + xlog_dirty_write_counter_reset(); + PG_RETURN_VOID(); +} diff --git a/src/include/access/xlog.h b/src/include/access/xlog.h index ec79870..01343b9 100644 --- a/src/include/access/xlog.h +++ b/src/include/access/xlog.h @@ -325,6 +325,9 @@ extern XLogRecPtr do_pg_start_backup(const char *backupidstr, bool fast, char ** extern XLogRecPtr do_pg_stop_backup(char *labelfile, bool waitforarchive); extern void do_pg_abort_backup(void); +extern uint64 xlog_dirty_write_counter_get(void); +extern void xlog_dirty_write_counter_reset(void); + /* File path names (all relative to $PGDATA) */ #define BACKUP_LABEL_FILE "backup_label" #define BACKUP_LABEL_OLD "backup_label.old" diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h index bee7154..e21f57e 100644 --- a/src/include/catalog/pg_proc.h +++ b/src/include/catalog/pg_proc.h @@ -2736,6 +2736,11 @@ DESCR("statistics: reset collected statistics for a single table or index in the DATA(insert OID = 3777 ( pg_stat_reset_single_function_counters PGNSP PGUID 12 1 0 0 0 f f f f f f v 1 0 2278 "26" _null_ _null_ _null_ _null_ pg_stat_reset_single_function_counters _null_ _null_ _null_ )); DESCR("statistics: reset collected statistics for a single function in the current database"); +DATA(insert OID = 3766 ( pg_stat_get_xlog_dirty_write PGNSP PGUID 12 1 0 0 0 f f f f f f v 0 0 20 "" _null_ _null_ _null_ _null_ pg_stat_get_xlog_dirty_write _null_ _null_ _null_ )); +DESCR("statistics: get xlog dirty buffer write statistics"); +DATA(insert OID = 3767 ( pg_stat_reset_xlog_dirty_write PGNSP PGUID 12 1 0 0 0 f f f f f f v 0 0 2278 "" _null_ _null_ _null_ _null_ pg_stat_reset_xlog_dirty_write _null_ _null_ _null_ )); +DESCR("statistics: reset xlog dirty buffer write statistics"); + DATA(insert OID = 3163 ( pg_trigger_depth PGNSP PGUID 12 1 0 0 0 f f f f t f s 0 0 23 "" _null_ _null_ _null_ _null_ pg_trigger_depth _null_ _null_ _null_ )); DESCR("current trigger depth");