I've prepared a significantly simplified version of the patch. The two
main changes are
(a) it does not update the pg_stat_bgwriter anymore, it just prints an
info to the server log
(b) a new GUC is not required, it's driven by the log_checkpoints
This version will log at least 10 'checkpoint status' lines (at 10%, 20%,
30%, ...) and whenever 5 seconds since the last log elapses. The time is
not checked for each buffer but for 128 buffers.
So if the checkpoint is very slow, you'll get a message every 5 seconds,
if it's fast you'll get 10 messages.
Tomas
diff --git a/src/backend/storage/buffer/bufmgr.c
b/src/backend/storage/buffer/bufmgr.c
new file mode 100644
index 4c7cfb0..e60d304
*** a/src/backend/storage/buffer/bufmgr.c
--- b/src/backend/storage/buffer/bufmgr.c
*************** BufferSync(int flags)
*** 1175,1180 ****
--- 1175,1193 ----
int num_to_write;
int num_written;
int mask = BM_DIRTY;
+
+ int num_since_update;
+
+ long curr_secs,
+ total_secs;
+ int curr_usecs,
+ total_usecs;
+ float curr_time,
+ total_time;
+
+ TimestampTz startTimestamp, lastTimestamp;
+
+ int log_interval, check_interval;
/* Make sure we can handle the pin inside SyncOneBuffer */
ResourceOwnerEnlargeBuffers(CurrentResourceOwner);
*************** BufferSync(int flags)
*** 1238,1243 ****
--- 1251,1265 ----
buf_id = StrategySyncStart(NULL, NULL);
num_to_scan = NBuffers;
num_written = 0;
+ num_since_update = 0;
+
+ startTimestamp = GetCurrentTimestamp();
+ lastTimestamp = startTimestamp;
+
+ /* check the progress each 128 buffers or 10% */
+ log_interval = (int)round(num_to_write/10);
+ check_interval = ((log_interval < 128) && (log_interval > 0)) ?
log_interval : 128;
+
while (num_to_scan-- > 0)
{
volatile BufferDesc *bufHdr = &BufferDescriptors[buf_id];
*************** BufferSync(int flags)
*** 1261,1266 ****
--- 1283,1334 ----
TRACE_POSTGRESQL_BUFFER_SYNC_WRITTEN(buf_id);
BgWriterStats.m_buf_written_checkpoints++;
num_written++;
+ num_since_update++;
+
+ /*
+ * Every time we write enough buffers
(checkpoint_update_limit),
+ * we log a checkpoint status message and
update the bgwriter
+ * stats (so that the pg_stat_bgwriter table
may be updated).
+ *
+ * The log message contains info about total
number of buffers to
+ * write, how many buffers are already written,
average and current
+ * write speed and an estimate remaining time.
+ */
+ if ((log_checkpoints) && (num_written %
check_interval == 0)) {
+
+ TimestampDifference(lastTimestamp,
+ GetCurrentTimestamp(),
+ &curr_secs, &curr_usecs);
+
+ /* if at least 5 seconds elapsed since
the last log, log */
+ if ((curr_secs >= 5) ||
(num_since_update >= log_interval)) {
+
+
TimestampDifference(startTimestamp,
+ GetCurrentTimestamp(),
+ &total_secs,
&total_usecs);
+
+ curr_time = curr_secs +
(float)curr_usecs / 1000000;
+ total_time = total_secs +
(float)total_usecs / 1000000;
+
+ elog(LOG, "checkpoint status:
wrote %d buffers of %d (%.1f%%) in %.1f s; "
+ "average %.1f MB/s (%d
buffers, %ld.%03d s), "
+ "current %.1f MB/s (%d
buffers, %ld.%03d s), "
+ "remaining %.1f s",
+ num_written,
num_to_write, ((float) num_written * 100 / num_to_write),
+ total_time,
+ ((float)BLCKSZ *
num_written / 1024 / 1024 / total_time),
+ num_written,
total_secs, total_usecs/1000,
+ ((float)BLCKSZ *
num_since_update / 1024 / 1024 / curr_time),
+ num_since_update,
curr_secs, curr_usecs/1000,
+ (float)(num_to_write -
num_written) * total_time / (num_written));
+
+ /* reset the counter and
timestamp */
+ num_since_update = 0;
+ lastTimestamp =
GetCurrentTimestamp();
+
+ }
+
+ }
/*
* We know there are at most num_to_write
buffers with
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers