Limit pg_basebackup progress output to 1/second
authorMagnus Hagander
Sun, 9 Feb 2014 11:47:09 +0000 (12:47 +0100)
committerMagnus Hagander
Sun, 9 Feb 2014 11:51:42 +0000 (12:51 +0100)
This prevents pg_basebackup from generating excessive output when
dumping large clusters. The status is now updated once / second,
still making it possible to see that there is progress happening,
but limiting the total bandwidth.

Mika Eloranta, reviewed by Sawada Masahiko and Oskari Saarenmaa

src/bin/pg_basebackup/pg_basebackup.c

index a396c2fd93b7e6166ffa451f0ae550cf7953bff3..a6e320c0f2266325703449890e6d5706dd5cb3de 100644 (file)
@@ -15,6 +15,7 @@
 #include "libpq-fe.h"
 #include "pqexpbuffer.h"
 #include "pgtar.h"
+#include "pgtime.h"
 
 #include 
 #include 
@@ -46,6 +47,7 @@ static bool   streamwal = false;
 static bool    fastcheckpoint = false;
 static bool    writerecoveryconf = false;
 static int standby_message_timeout = 10 * 1000;        /* 10 sec = default */
+static pg_time_t last_progress_report = 0;
 
 /* Progress counters */
 static uint64 totalsize;
@@ -75,7 +77,7 @@ static PQExpBuffer recoveryconfcontents = NULL;
 /* Function headers */
 static void usage(void);
 static void verify_dir_is_empty_or_create(char *dirname);
-static void progress_report(int tablespacenum, const char *filename);
+static void progress_report(int tablespacenum, const char *filename, bool force);
 
 static void ReceiveTarFile(PGconn *conn, PGresult *res, int rownum);
 static void ReceiveAndUnpackTarFile(PGconn *conn, PGresult *res, int rownum);
@@ -399,13 +401,27 @@ verify_dir_is_empty_or_create(char *dirname)
 /*
  * Print a progress report based on the global variables. If verbose output
  * is enabled, also print the current file name.
+ *
+ * Progress report is written at maximum once per second, unless the
+ * force parameter is set to true.
  */
 static void
-progress_report(int tablespacenum, const char *filename)
+progress_report(int tablespacenum, const char *filename, bool force)
 {
-   int         percent = (int) ((totaldone / 1024) * 100 / totalsize);
+   int         percent;
    char        totaldone_str[32];
    char        totalsize_str[32];
+   pg_time_t   now;
+
+   if (!showprogress)
+       return;
+
+   now = time(NULL);
+   if (now == last_progress_report && !force)
+       return; /* Max once per second */
+
+   last_progress_report = now;
+   percent = totalsize ? (int) ((totaldone / 1024) * 100 / totalsize) : 0;
 
    /*
     * Avoid overflowing past 100% or the full size. This may make the total
@@ -853,9 +869,9 @@ ReceiveTarFile(PGconn *conn, PGresult *res, int rownum)
            }
        }
        totaldone += r;
-       if (showprogress)
-           progress_report(rownum, filename);
+       progress_report(rownum, filename, false);
    }                           /* while (1) */
+   progress_report(rownum, filename, true);
 
    if (copybuf != NULL)
        PQfreemem(copybuf);
@@ -1080,8 +1096,7 @@ ReceiveAndUnpackTarFile(PGconn *conn, PGresult *res, int rownum)
                disconnect_and_exit(1);
            }
            totaldone += r;
-           if (showprogress)
-               progress_report(rownum, filename);
+           progress_report(rownum, filename, false);
 
            current_len_left -= r;
            if (current_len_left == 0 && current_padding == 0)
@@ -1097,6 +1112,7 @@ ReceiveAndUnpackTarFile(PGconn *conn, PGresult *res, int rownum)
            }
        }                       /* continuing data in existing file */
    }                           /* loop over all data blocks */
+   progress_report(rownum, filename, true);
 
    if (file != NULL)
    {
@@ -1457,8 +1473,7 @@ BaseBackup(void)
    tablespacecount = PQntuples(res);
    for (i = 0; i < PQntuples(res); i++)
    {
-       if (showprogress)
-           totalsize += atol(PQgetvalue(res, i, 2));
+       totalsize += atol(PQgetvalue(res, i, 2));
 
        /*
         * Verify tablespace directories are empty. Don't bother with the
@@ -1505,7 +1520,7 @@ BaseBackup(void)
 
    if (showprogress)
    {
-       progress_report(PQntuples(res), NULL);
+       progress_report(PQntuples(res), NULL, true);
        fprintf(stderr, "\n");  /* Need to move to next line */
    }
    PQclear(res);