if (padded)
{
pgWalUsage.wal_bytes += pad_size;
+ pgWalUsage.wal_partial_pad++;
+ pgWalUsage.wal_partial_pad_bytes += pad_size;
*final_pad = XLogBytePosToEndRecPtr(endbytepos);
return true;
(uint32)(write_pos->write_init_min >> 32), (uint32) write_pos->write_init_min),
errhidestmt(true),
errhidecontext(true));
+ pgWalUsage.wal_partial_wait++;
pgaio_io_wait_ref(&partial_aio_ref, false);
}
else
errhidestmt(true),
errhidecontext(true));
+ pgWalUsage.wal_partial_wait++;
pgaio_io_wait_ref(&partial_aio_ref, false);
goto write_out_wait;
bool performed_io = false;
bool holding_lock = false;
XLogWritePos write_pos = {0};
+ bool statted = false;
bool did_wait_for_insert = false;
/* normalize request */
write_pos.flush_done_min <= LogwrtResult.FlushDone)
{
END_CRIT_SECTION();
+
+ if (!statted)
+ {
+ pgWalUsage.wal_already_done_unlocked++;
+ statted = true;
+ }
return performed_io;
}
(uint32) (LogwrtResult.WriteInit >> 32), (uint32) LogwrtResult.WriteInit);
}
+ if (!statted)
+ {
+ pgWalUsage.wal_just_wait++;
+ statted = true;
+ }
+
//elog(DEBUG1, "just needed to wait for IO");
return performed_io;
}
if (!LWLockAcquireOrWait(WALWriteLock, LW_EXCLUSIVE))
{
holding_lock = false;
+ pgWalUsage.wal_lock_wait++;
goto xlogwrite_again;
}
else
{
+ pgWalUsage.wal_lock_immed++;
holding_lock = true;
}
}
+ pgWalUsage.wal_already_done_locked++;
+
END_CRIT_SECTION();
return performed_io;
}
}
#endif
+ pgWalUsage.wal_writes++;
+
if (XLogWriteIssueWrites(&write_pos, flexible))
{
//elog(LOG, "issued writes false: ");
pg_stat_get_bgwriter_stat_reset_time() AS stats_reset;
CREATE VIEW pg_stat_wal AS
- SELECT
- w.wal_records,
- w.wal_fpi,
- w.wal_bytes,
- w.wal_buffers_full,
- w.stats_reset
+ /* FIXME: easier to maintain without column names during development */
+ SELECT w.*
FROM pg_stat_get_wal() w;
CREATE VIEW pg_stat_aio_backends AS
if (usage->wal_bytes > 0)
appendStringInfo(es->str, " bytes=" UINT64_FORMAT,
usage->wal_bytes);
+ if (usage->wal_partial_pad_bytes > 0)
+ appendStringInfo(es->str, " pad_bytes=" UINT64_FORMAT,
+ usage->wal_partial_pad_bytes);
appendStringInfoChar(es->str, '\n');
}
}
dst->wal_records += add->wal_records;
dst->wal_fpi += add->wal_fpi;
dst->wal_buffers_full += add->wal_buffers_full;
+ dst->wal_writes += add->wal_writes;
+ dst->wal_already_done_unlocked += add->wal_already_done_unlocked;
+ dst->wal_already_done_locked += add->wal_already_done_locked;
+ dst->wal_just_wait += add->wal_just_wait;
+ dst->wal_lock_immed += add->wal_lock_immed;
+ dst->wal_lock_wait += add->wal_lock_wait;
+ dst->wal_partial_wait += add->wal_partial_wait;
+ dst->wal_partial_pad += add->wal_partial_pad;
+ dst->wal_partial_pad_bytes += add->wal_partial_pad_bytes;
}
void
dst->wal_records += add->wal_records - sub->wal_records;
dst->wal_fpi += add->wal_fpi - sub->wal_fpi;
dst->wal_buffers_full += add->wal_buffers_full - sub->wal_buffers_full;
+ dst->wal_writes += add->wal_writes - sub->wal_writes;
+ dst->wal_already_done_unlocked += add->wal_already_done_unlocked - sub->wal_already_done_unlocked;
+ dst->wal_already_done_locked += add->wal_already_done_locked - sub->wal_already_done_locked;
+ dst->wal_just_wait += add->wal_just_wait - sub->wal_just_wait;
+ dst->wal_lock_immed += add->wal_lock_immed - sub->wal_lock_immed;
+ dst->wal_lock_wait += add->wal_lock_wait - sub->wal_lock_wait;
+ dst->wal_partial_wait += add->wal_partial_wait - sub->wal_partial_wait;
+ dst->wal_partial_pad += add->wal_partial_pad - sub->wal_partial_pad;
+ dst->wal_partial_pad_bytes += add->wal_partial_pad_bytes - sub->wal_partial_pad_bytes;
}
WalStats.m_wal_fpi = walusage.wal_fpi;
WalStats.m_wal_bytes = walusage.wal_bytes;
WalStats.m_wal_buffers_full = walusage.wal_buffers_full;
+ WalStats.m_wal_writes = walusage.wal_writes;
+ WalStats.m_wal_already_done_unlocked = walusage.wal_already_done_unlocked;
+ WalStats.m_wal_already_done_locked = walusage.wal_already_done_locked;
+ WalStats.m_wal_just_wait = walusage.wal_just_wait;
+ WalStats.m_wal_lock_immed = walusage.wal_lock_immed;
+ WalStats.m_wal_lock_wait = walusage.wal_lock_wait;
+ WalStats.m_wal_partial_wait = walusage.wal_partial_wait;
+ WalStats.m_wal_partial_pad = walusage.wal_partial_pad;
+ WalStats.m_wal_partial_pad_bytes = walusage.wal_partial_pad_bytes;
/*
* This function can be called even if nothing at all has happened. In
walStats.wal_fpi += msg->m_wal_fpi;
walStats.wal_bytes += msg->m_wal_bytes;
walStats.wal_buffers_full += msg->m_wal_buffers_full;
+ walStats.wal_writes += msg->m_wal_writes;
+ walStats.wal_already_done_unlocked += msg->m_wal_already_done_unlocked;
+ walStats.wal_already_done_locked += msg->m_wal_already_done_locked;
+ walStats.wal_just_wait += msg->m_wal_just_wait;
+ walStats.wal_lock_immed += msg->m_wal_lock_immed;
+ walStats.wal_lock_wait += msg->m_wal_lock_wait;
+ walStats.wal_partial_wait += msg->m_wal_partial_wait;
+ walStats.wal_partial_pad += msg->m_wal_partial_pad;
+ walStats.wal_partial_pad_bytes += msg->m_wal_partial_pad_bytes;
}
/* ----------
Datum
pg_stat_get_wal(PG_FUNCTION_ARGS)
{
-#define PG_STAT_GET_WAL_COLS 5
+#define PG_STAT_GET_WAL_COLS 14
TupleDesc tupdesc;
Datum values[PG_STAT_GET_WAL_COLS];
bool nulls[PG_STAT_GET_WAL_COLS];
NUMERICOID, -1, 0);
TupleDescInitEntry(tupdesc, (AttrNumber) 4, "wal_buffers_full",
INT8OID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) 5, "stats_reset",
+ TupleDescInitEntry(tupdesc, (AttrNumber) 5, "wal_writes",
+ INT8OID, -1, 0);
+ TupleDescInitEntry(tupdesc, (AttrNumber) 6, "wal_already_done_unlocked",
+ INT8OID, -1, 0);
+ TupleDescInitEntry(tupdesc, (AttrNumber) 7, "wal_already_done_locked",
+ INT8OID, -1, 0);
+ TupleDescInitEntry(tupdesc, (AttrNumber) 8, "wal_just_wait",
+ INT8OID, -1, 0);
+ TupleDescInitEntry(tupdesc, (AttrNumber) 9, "wal_lock_immed",
+ INT8OID, -1, 0);
+ TupleDescInitEntry(tupdesc, (AttrNumber) 10, "wal_lock_wait",
+ INT8OID, -1, 0);
+ TupleDescInitEntry(tupdesc, (AttrNumber) 11, "wal_partial_wait",
+ INT8OID, -1, 0);
+ TupleDescInitEntry(tupdesc, (AttrNumber) 12, "wal_partial_pad",
+ INT8OID, -1, 0);
+ TupleDescInitEntry(tupdesc, (AttrNumber) 13, "wal_partial_pad_bytes",
+ INT8OID, -1, 0);
+ TupleDescInitEntry(tupdesc, (AttrNumber) 14, "stats_reset",
TIMESTAMPTZOID, -1, 0);
BlessTupleDesc(tupdesc);
wal_stats = pgstat_fetch_stat_wal();
/* Fill values and NULLs */
- values[0] = Int64GetDatum(wal_stats->wal_records);
- values[1] = Int64GetDatum(wal_stats->wal_fpi);
+ values[ 0] = Int64GetDatum(wal_stats->wal_records);
+ values[ 1] = Int64GetDatum(wal_stats->wal_fpi);
/* Convert to numeric. */
snprintf(buf, sizeof buf, UINT64_FORMAT, wal_stats->wal_bytes);
- values[2] = DirectFunctionCall3(numeric_in,
+ values[ 2] = DirectFunctionCall3(numeric_in,
CStringGetDatum(buf),
ObjectIdGetDatum(0),
Int32GetDatum(-1));
- values[3] = Int64GetDatum(wal_stats->wal_buffers_full);
- values[4] = TimestampTzGetDatum(wal_stats->stat_reset_timestamp);
+ values[ 3] = Int64GetDatum(wal_stats->wal_buffers_full);
+
+ values[ 4] = Int64GetDatum(wal_stats->wal_writes);
+ values[ 5] = Int64GetDatum(wal_stats->wal_already_done_unlocked);
+ values[ 6] = Int64GetDatum(wal_stats->wal_already_done_locked);
+ values[ 7] = Int64GetDatum(wal_stats->wal_just_wait);
+ values[ 8] = Int64GetDatum(wal_stats->wal_lock_immed);
+ values[ 9] = Int64GetDatum(wal_stats->wal_lock_wait);
+ values[10] = Int64GetDatum(wal_stats->wal_partial_wait);
+ values[11] = Int64GetDatum(wal_stats->wal_partial_pad);
+ values[12] = Int64GetDatum(wal_stats->wal_partial_pad_bytes);
+
+ values[13] = TimestampTzGetDatum(wal_stats->stat_reset_timestamp);
/* Returns the record as Datum */
PG_RETURN_DATUM(HeapTupleGetDatum(heap_form_tuple(tupdesc, values, nulls)));
{ oid => '1136', descr => 'statistics: information about WAL activity',
proname => 'pg_stat_get_wal', proisstrict => 'f', provolatile => 's',
proparallel => 'r', prorettype => 'record', proargtypes => '',
- proallargtypes => '{int8,int8,numeric,int8,timestamptz}',
- proargmodes => '{o,o,o,o,o}',
- proargnames => '{wal_records,wal_fpi,wal_bytes,wal_buffers_full,stats_reset}',
+ proallargtypes => '{int8,int8,numeric,int8,int8,int8,int8,int8,int8,int8,int8,int8,int8,timestamptz}',
+ proargmodes => '{o,o,o,o,o,o,o,o,o,o,o,o,o,o}',
+ proargnames => '{wal_records,wal_fpi,wal_bytes,wal_buffers_full,wal_writes,wal_already_done_unlocked,wal_already_done_locked,wal_just_wait,wal_lock_immed,wal_lock_wait,wal_partial_wait,wal_partial_pad,wal_partial_pad_bytes,stats_reset}',
prosrc => 'pg_stat_get_wal' },
{ oid => '2306', descr => 'statistics: information about SLRU caches',
long wal_fpi; /* # of WAL full page images produced */
uint64 wal_bytes; /* size of WAL records produced */
uint64 wal_buffers_full;
+ uint64 wal_writes;
+ uint64 wal_already_done_unlocked;
+ uint64 wal_already_done_locked;
+ uint64 wal_just_wait;
+ uint64 wal_lock_immed;
+ uint64 wal_lock_wait;
+ uint64 wal_partial_wait;
+ uint64 wal_partial_pad;
+ uint64 wal_partial_pad_bytes;
} WalUsage;
/* Flag bits included in InstrAlloc's instrument_options bitmask */
PgStat_Counter m_wal_fpi;
uint64 m_wal_bytes;
PgStat_Counter m_wal_buffers_full;
+ PgStat_Counter m_wal_writes;
+ PgStat_Counter m_wal_already_done_unlocked;
+ PgStat_Counter m_wal_already_done_locked;
+ PgStat_Counter m_wal_just_wait;
+ PgStat_Counter m_wal_lock_immed;
+ PgStat_Counter m_wal_lock_wait;
+ PgStat_Counter m_wal_partial_wait;
+ PgStat_Counter m_wal_partial_pad;
+ PgStat_Counter m_wal_partial_pad_bytes;
} PgStat_MsgWal;
/* ----------
PgStat_Counter wal_fpi;
uint64 wal_bytes;
PgStat_Counter wal_buffers_full;
+ PgStat_Counter wal_writes;
+ PgStat_Counter wal_already_done_unlocked;
+ PgStat_Counter wal_already_done_locked;
+ PgStat_Counter wal_just_wait;
+ PgStat_Counter wal_lock_immed;
+ PgStat_Counter wal_lock_wait;
+ PgStat_Counter wal_partial_wait;
+ PgStat_Counter wal_partial_pad;
+ PgStat_Counter wal_partial_pad_bytes;
TimestampTz stat_reset_timestamp;
} PgStat_WalStats;
w.wal_fpi,
w.wal_bytes,
w.wal_buffers_full,
+ w.wal_writes,
+ w.wal_already_done_unlocked,
+ w.wal_already_done_locked,
+ w.wal_just_wait,
+ w.wal_lock_immed,
+ w.wal_lock_wait,
+ w.wal_partial_wait,
+ w.wal_partial_pad,
+ w.wal_partial_pad_bytes,
w.stats_reset
- FROM pg_stat_get_wal() w(wal_records, wal_fpi, wal_bytes, wal_buffers_full, stats_reset);
+ FROM pg_stat_get_wal() w(wal_records, wal_fpi, wal_bytes, wal_buffers_full, wal_writes, wal_already_done_unlocked, wal_already_done_locked, wal_just_wait, wal_lock_immed, wal_lock_wait, wal_partial_wait, wal_partial_pad, wal_partial_pad_bytes, stats_reset);
pg_stat_wal_receiver| SELECT s.pid,
s.status,
s.receive_start_lsn,