mirror of
https://github.com/postgres/postgres.git
synced 2025-05-01 01:04:50 +03:00
Fix printing last progress report line in client programs.
A number of client programs have a "--progress" option that when printing to a TTY, updates the current line by printing a '\r' and overwriting it. After the last line, '\n' needs to be printed to move the cursor to the next line. pg_basebackup and pgbench got this right, but pg_rewind and pg_checksums were slightly wrong. pg_rewind printed the newline to stdout instead of stderr, and pg_checksums printed the newline even when not printing to a TTY. Fix them, and also add a 'finished' argument to pg_basebackup's progress_report() function, to keep it consistent with the other programs. Backpatch to v12. pg_rewind's newline was broken with the logging changes in commit cc8d415117 in v12, and pg_checksums was introduced in v12. Discussion: https://www.postgresql.org/message-id/82b539e5-ae33-34b0-1aee-22b3379fd3eb@iki.fi
This commit is contained in:
parent
b4f16397af
commit
d7ec8337f9
@ -188,7 +188,8 @@ static PQExpBuffer recoveryconfcontents = NULL;
|
|||||||
/* Function headers */
|
/* Function headers */
|
||||||
static void usage(void);
|
static void usage(void);
|
||||||
static void verify_dir_is_empty_or_create(char *dirname, bool *created, bool *found);
|
static void verify_dir_is_empty_or_create(char *dirname, bool *created, bool *found);
|
||||||
static void progress_report(int tablespacenum, const char *filename, bool force);
|
static void progress_report(int tablespacenum, const char *filename, bool force,
|
||||||
|
bool finished);
|
||||||
|
|
||||||
static void ReceiveTarFile(PGconn *conn, PGresult *res, int rownum);
|
static void ReceiveTarFile(PGconn *conn, PGresult *res, int rownum);
|
||||||
static void ReceiveTarCopyChunk(size_t r, char *copybuf, void *callback_data);
|
static void ReceiveTarCopyChunk(size_t r, char *copybuf, void *callback_data);
|
||||||
@ -765,11 +766,15 @@ verify_dir_is_empty_or_create(char *dirname, bool *created, bool *found)
|
|||||||
* Print a progress report based on the global variables. If verbose output
|
* Print a progress report based on the global variables. If verbose output
|
||||||
* is enabled, also print the current file name.
|
* is enabled, also print the current file name.
|
||||||
*
|
*
|
||||||
* Progress report is written at maximum once per second, unless the
|
* Progress report is written at maximum once per second, unless the force
|
||||||
* force parameter is set to true.
|
* parameter is set to true.
|
||||||
|
*
|
||||||
|
* If finished is set to true, this is the last progress report. The cursor
|
||||||
|
* is moved to the next line.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
progress_report(int tablespacenum, const char *filename, bool force)
|
progress_report(int tablespacenum, const char *filename,
|
||||||
|
bool force, bool finished)
|
||||||
{
|
{
|
||||||
int percent;
|
int percent;
|
||||||
char totaldone_str[32];
|
char totaldone_str[32];
|
||||||
@ -780,7 +785,7 @@ progress_report(int tablespacenum, const char *filename, bool force)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
now = time(NULL);
|
now = time(NULL);
|
||||||
if (now == last_progress_report && !force)
|
if (now == last_progress_report && !force && !finished)
|
||||||
return; /* Max once per second */
|
return; /* Max once per second */
|
||||||
|
|
||||||
last_progress_report = now;
|
last_progress_report = now;
|
||||||
@ -851,10 +856,11 @@ progress_report(int tablespacenum, const char *filename, bool force)
|
|||||||
totaldone_str, totalsize_str, percent,
|
totaldone_str, totalsize_str, percent,
|
||||||
tablespacenum, tablespacecount);
|
tablespacenum, tablespacecount);
|
||||||
|
|
||||||
if (isatty(fileno(stderr)))
|
/*
|
||||||
fprintf(stderr, "\r");
|
* Stay on the same line if reporting to a terminal and we're not done
|
||||||
else
|
* yet.
|
||||||
fprintf(stderr, "\n");
|
*/
|
||||||
|
fprintf(stderr, (!finished && isatty(fileno(stderr))) ? "\r" : "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32
|
static int32
|
||||||
@ -1277,7 +1283,7 @@ ReceiveTarFile(PGconn *conn, PGresult *res, int rownum)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
progress_report(rownum, state.filename, true);
|
progress_report(rownum, state.filename, true, false);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Do not sync the resulting tar file yet, all files are synced once at
|
* Do not sync the resulting tar file yet, all files are synced once at
|
||||||
@ -1470,7 +1476,7 @@ ReceiveTarCopyChunk(size_t r, char *copybuf, void *callback_data)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
totaldone += r;
|
totaldone += r;
|
||||||
progress_report(state->tablespacenum, state->filename, false);
|
progress_report(state->tablespacenum, state->filename, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1528,7 +1534,7 @@ ReceiveAndUnpackTarFile(PGconn *conn, PGresult *res, int rownum)
|
|||||||
if (state.file)
|
if (state.file)
|
||||||
fclose(state.file);
|
fclose(state.file);
|
||||||
|
|
||||||
progress_report(rownum, state.filename, true);
|
progress_report(rownum, state.filename, true, false);
|
||||||
|
|
||||||
if (state.file != NULL)
|
if (state.file != NULL)
|
||||||
{
|
{
|
||||||
@ -1709,7 +1715,7 @@ ReceiveTarAndUnpackCopyChunk(size_t r, char *copybuf, void *callback_data)
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
totaldone += r;
|
totaldone += r;
|
||||||
progress_report(state->tablespacenum, state->filename, false);
|
progress_report(state->tablespacenum, state->filename, false, false);
|
||||||
|
|
||||||
state->current_len_left -= r;
|
state->current_len_left -= r;
|
||||||
if (state->current_len_left == 0 && state->current_padding == 0)
|
if (state->current_len_left == 0 && state->current_padding == 0)
|
||||||
@ -2027,11 +2033,7 @@ BaseBackup(void)
|
|||||||
ReceiveBackupManifest(conn);
|
ReceiveBackupManifest(conn);
|
||||||
|
|
||||||
if (showprogress)
|
if (showprogress)
|
||||||
{
|
progress_report(PQntuples(res), NULL, true, true);
|
||||||
progress_report(PQntuples(res), NULL, true);
|
|
||||||
if (isatty(fileno(stderr)))
|
|
||||||
fprintf(stderr, "\n"); /* Need to move to next line */
|
|
||||||
}
|
|
||||||
|
|
||||||
PQclear(res);
|
PQclear(res);
|
||||||
|
|
||||||
|
@ -125,7 +125,7 @@ static const struct exclude_list_item skip[] = {
|
|||||||
* src/bin/pg_basebackup/pg_basebackup.c.
|
* src/bin/pg_basebackup/pg_basebackup.c.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
progress_report(bool force)
|
progress_report(bool finished)
|
||||||
{
|
{
|
||||||
int percent;
|
int percent;
|
||||||
char total_size_str[32];
|
char total_size_str[32];
|
||||||
@ -135,7 +135,7 @@ progress_report(bool force)
|
|||||||
Assert(showprogress);
|
Assert(showprogress);
|
||||||
|
|
||||||
now = time(NULL);
|
now = time(NULL);
|
||||||
if (now == last_progress_report && !force)
|
if (now == last_progress_report && !finished)
|
||||||
return; /* Max once per second */
|
return; /* Max once per second */
|
||||||
|
|
||||||
/* Save current time */
|
/* Save current time */
|
||||||
@ -162,8 +162,11 @@ progress_report(bool force)
|
|||||||
(int) strlen(current_size_str), current_size_str, total_size_str,
|
(int) strlen(current_size_str), current_size_str, total_size_str,
|
||||||
percent);
|
percent);
|
||||||
|
|
||||||
/* Stay on the same line if reporting to a terminal */
|
/*
|
||||||
fprintf(stderr, isatty(fileno(stderr)) ? "\r" : "\n");
|
* Stay on the same line if reporting to a terminal and we're not done
|
||||||
|
* yet.
|
||||||
|
*/
|
||||||
|
fprintf(stderr, (!finished && isatty(fileno(stderr))) ? "\r" : "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
@ -624,10 +627,7 @@ main(int argc, char *argv[])
|
|||||||
(void) scan_directory(DataDir, "pg_tblspc", false);
|
(void) scan_directory(DataDir, "pg_tblspc", false);
|
||||||
|
|
||||||
if (showprogress)
|
if (showprogress)
|
||||||
{
|
|
||||||
progress_report(true);
|
progress_report(true);
|
||||||
fprintf(stderr, "\n"); /* Need to move to next line */
|
|
||||||
}
|
|
||||||
|
|
||||||
printf(_("Checksum operation completed\n"));
|
printf(_("Checksum operation completed\n"));
|
||||||
printf(_("Files scanned: %s\n"), psprintf(INT64_FORMAT, files));
|
printf(_("Files scanned: %s\n"), psprintf(INT64_FORMAT, files));
|
||||||
|
@ -422,7 +422,6 @@ main(int argc, char **argv)
|
|||||||
executeFileMap();
|
executeFileMap();
|
||||||
|
|
||||||
progress_report(true);
|
progress_report(true);
|
||||||
printf("\n");
|
|
||||||
|
|
||||||
if (showprogress)
|
if (showprogress)
|
||||||
pg_log_info("creating backup label and updating control file");
|
pg_log_info("creating backup label and updating control file");
|
||||||
@ -519,11 +518,14 @@ sanityChecks(void)
|
|||||||
/*
|
/*
|
||||||
* Print a progress report based on the fetch_size and fetch_done variables.
|
* Print a progress report based on the fetch_size and fetch_done variables.
|
||||||
*
|
*
|
||||||
* Progress report is written at maximum once per second, unless the
|
* Progress report is written at maximum once per second, except that the
|
||||||
* force parameter is set to true.
|
* last progress report is always printed.
|
||||||
|
*
|
||||||
|
* If finished is set to true, this is the last progress report. The cursor
|
||||||
|
* is moved to the next line.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
progress_report(bool force)
|
progress_report(bool finished)
|
||||||
{
|
{
|
||||||
static pg_time_t last_progress_report = 0;
|
static pg_time_t last_progress_report = 0;
|
||||||
int percent;
|
int percent;
|
||||||
@ -535,7 +537,7 @@ progress_report(bool force)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
now = time(NULL);
|
now = time(NULL);
|
||||||
if (now == last_progress_report && !force)
|
if (now == last_progress_report && !finished)
|
||||||
return; /* Max once per second */
|
return; /* Max once per second */
|
||||||
|
|
||||||
last_progress_report = now;
|
last_progress_report = now;
|
||||||
@ -565,10 +567,12 @@ progress_report(bool force)
|
|||||||
fprintf(stderr, _("%*s/%s kB (%d%%) copied"),
|
fprintf(stderr, _("%*s/%s kB (%d%%) copied"),
|
||||||
(int) strlen(fetch_size_str), fetch_done_str, fetch_size_str,
|
(int) strlen(fetch_size_str), fetch_done_str, fetch_size_str,
|
||||||
percent);
|
percent);
|
||||||
if (isatty(fileno(stderr)))
|
|
||||||
fprintf(stderr, "\r");
|
/*
|
||||||
else
|
* Stay on the same line if reporting to a terminal and we're not done
|
||||||
fprintf(stderr, "\n");
|
* yet.
|
||||||
|
*/
|
||||||
|
fprintf(stderr, (!finished && isatty(fileno(stderr))) ? "\r" : "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -53,7 +53,7 @@ extern XLogRecPtr readOneRecord(const char *datadir, XLogRecPtr ptr,
|
|||||||
int tliIndex, const char *restoreCommand);
|
int tliIndex, const char *restoreCommand);
|
||||||
|
|
||||||
/* in pg_rewind.c */
|
/* in pg_rewind.c */
|
||||||
extern void progress_report(bool force);
|
extern void progress_report(bool finished);
|
||||||
|
|
||||||
/* in timeline.c */
|
/* in timeline.c */
|
||||||
extern TimeLineHistoryEntry *rewind_parseTimeLineHistory(char *buffer,
|
extern TimeLineHistoryEntry *rewind_parseTimeLineHistory(char *buffer,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user