On Wed, Jan 22, 2020 at 02:34:57PM +0900, Michael Paquier wrote:
> From patch 0003:
> /*
> + * Indent multi-line DETAIL if being sent to client (verbose)
> + * We don't know if it's sent to the client (client_min_messages);
> + * Also, that affects output to the logfile, too; assume that it's
> more
> + * important to format messages requested by the client than to make
> + * verbose logs pretty when also sent to the logfile.
> + */
> + msgprefix = elevel==INFO ? "!\t" : "";
> Such stuff gets a -1 from me. This is not project-like, and you make
> the translation of those messages much harder than they should be.
I don't see why its harder to translate ? Do you mean because it changes the
strings by adding %s ?
- appendStringInfo(&sbuf, ngettext("%u page is entirely empty.\n",
- "%u
pages are entirely empty.\n",
+ appendStringInfo(&sbuf, ngettext("%s%u page is entirely empty.\n",
+ "%s%u
pages are entirely empty.\n",
...
I did raise two questions regarding translation:
I'm not sure why this one doesn't use get ngettext() ? Seems to have been
missed at a8d585c0.
|appendStringInfo(&buf, _("There were %.0f unused item identifiers.\n"),
Or why this one does use _/gettext() ? (580ddcec suggests that I'm missing
something, but I just experimented, and it really seems to do nothing, since
"%s" shouldn't be translated).
|appendStringInfo(&buf, _("%s."), pg_rusage_show(&ru0));
Also, I realized it's possible to write different strings to the log vs the
client (with and without a prefix) by calling errdetail_internal() and
errdetail_log().
Here's a version rebased on top of f942dfb9, and making use of errdetail_log.
I'm not sure if it address your concern about translation, but it doesn't
change strings.
I think it's not needed or desirable to change what's written to the logfile,
since CSV logs have a separate "detail" field, and text logs are indented. The
server log is unchanged:
> 2020-01-25 23:08:40.451 CST [13971] INFO: "t": removed 0, found 160
> nonremovable row versions in 1 out of 888 pages
> 2020-01-25 23:08:40.451 CST [13971] DETAIL: 0 dead row versions cannot be
> removed yet, oldest xmin: 781
> There were 0 unused item identifiers.
> Skipped 0 pages due to buffer pins, 444 frozen pages.
> 0 pages are entirely empty.
> CPU: user: 0.00 s, system: 0.00 s, elapsed: 0.01 s.
If VERBOSE, then the client log has ! prefixes, with the style borrowed from
ShowUsage:
> INFO: "t": removed 0, found 160 nonremovable row versions in 1 out of 888
> pages
> DETAIL: ! 0 dead row versions cannot be removed yet, oldest xmin: 781
> ! There were 0 unused item identifiers.
> ! Skipped 0 pages due to buffer pins, 444 frozen pages.
> ! 0 pages are entirely empty.
> ! CPU: user: 0.00 s, system: 0.00 s, elapsed: 0.01 s.
I mentioned before that maybe the client's messages with newlines should be
indented similarly to how the they're done in the text logfile. I looked,
that's append_with_tabs() in elog.c. So that's a different possible
implementation, which would apply to any message with newlines (or possibly
just DETAIL).
I'll also fork the allvisible/frozen/hintbits patches to a separate thread.
Thanks,
Justin
>From a3d0b41435655615ab13f808ec7c30e53e596e50 Mon Sep 17 00:00:00 2001
From: Justin Pryzby <[email protected]>
Date: Sat, 25 Jan 2020 21:25:37 -0600
Subject: [PATCH v3 1/4] Remove gettext erronously readded at 580ddce
---
src/backend/access/heap/vacuumlazy.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/backend/access/heap/vacuumlazy.c b/src/backend/access/heap/vacuumlazy.c
index 8ce5011..8e8ea9d 100644
--- a/src/backend/access/heap/vacuumlazy.c
+++ b/src/backend/access/heap/vacuumlazy.c
@@ -1690,7 +1690,7 @@ lazy_scan_heap(Relation onerel, VacuumParams *params, LVRelStats *vacrelstats,
"%u pages are entirely empty.\n",
empty_pages),
empty_pages);
- appendStringInfo(&buf, _("%s."), pg_rusage_show(&ru0));
+ appendStringInfo(&buf, "%s.", pg_rusage_show(&ru0));
ereport(elevel,
(errmsg("\"%s\": found %.0f removable, %.0f nonremovable row versions in %u out of %u pages",
--
2.7.4
>From 2db7c4e3482120b2a83cda74603f2454da7eaa03 Mon Sep 17 00:00:00 2001
From: Justin Pryzby <[email protected]>
Date: Sat, 25 Jan 2020 22:50:46 -0600
Subject: [PATCH v3 2/4] vacuum verbose: use ngettext() everywhere possible
---
src/backend/access/heap/vacuumlazy.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/src/backend/access/heap/vacuumlazy.c b/src/backend/access/heap/vacuumlazy.c
index 8e8ea9d..eb903d5 100644
--- a/src/backend/access/heap/vacuumlazy.c
+++ b/src/backend/access/heap/vacuumlazy.c
@@ -1673,10 +1673,13 @@ lazy_scan_heap(Relation onerel, VacuumParams *params, LVRelStats *vacrelstats,
* individual parts of the message when not applicable.
*/
initStringInfo(&buf);
- appendStringInfo(&buf,
- _("%.0f dead row versions cannot be removed yet, oldest xmin: %u\n"),
+ appendStringInfo(&buf, ngettext("%.0f dead row version cannot be removed yet, oldest xmin: %u\n",
+ "%.0f dead row versions cannot be removed yet, oldest xmin: %u\n",
+ nkeep),
nkeep, OldestXmin);
- appendStringInfo(&buf, _("There were %.0f unused item identifiers.\n"),
+ appendStringInfo(&buf, ngettext("There was %.0f unused item identifier.\n",
+ "There were %.0f unused item identifiers.\n",
+ nunused),
nunused);
appendStringInfo(&buf, ngettext("Skipped %u page due to buffer pins, ",
"Skipped %u pages due to buffer pins, ",
--
2.7.4
>From 3467bf485972065f73c25a8f1e66c7c4f0bd5d23 Mon Sep 17 00:00:00 2001
From: Justin Pryzby <[email protected]>
Date: Sat, 25 Jan 2020 21:47:05 -0600
Subject: [PATCH v3 3/4] vacuum verbose: prefix write multi-line output to
client..
..but do not change output to logfile, which isn't unclear.
I borrowed the format from ShowUsage.
TODO: lazy_cleanup_index
---
src/backend/access/heap/vacuumlazy.c | 58 ++++++++++++++++++++++++++----------
1 file changed, 43 insertions(+), 15 deletions(-)
diff --git a/src/backend/access/heap/vacuumlazy.c b/src/backend/access/heap/vacuumlazy.c
index eb903d5..6f85af7 100644
--- a/src/backend/access/heap/vacuumlazy.c
+++ b/src/backend/access/heap/vacuumlazy.c
@@ -307,6 +307,7 @@ static BufferAccessStrategy vac_strategy;
static void lazy_scan_heap(Relation onerel, VacuumParams *params,
LVRelStats *vacrelstats, Relation *Irel, int nindexes,
bool aggressive);
+static void vacuum_msg(StringInfoData *buf, const char *prefix, LVRelStats *vacrelstats, double nkeep, double nunused, BlockNumber empty_pages, PGRUsage *ru0);
static void lazy_vacuum_heap(Relation onerel, LVRelStats *vacrelstats);
static bool lazy_check_needs_freeze(Buffer buf, bool *hastup);
static void lazy_vacuum_all_indexes(Relation onerel, Relation *Irel,
@@ -717,7 +718,8 @@ lazy_scan_heap(Relation onerel, VacuumParams *params, LVRelStats *vacrelstats,
BlockNumber next_unskippable_block;
bool skipping_blocks;
xl_heap_freeze_tuple *frozen;
- StringInfoData buf;
+ StringInfoData logdetail,
+ clientdetail;
const int initprog_index[] = {
PROGRESS_VACUUM_PHASE,
PROGRESS_VACUUM_TOTAL_HEAP_BLKS,
@@ -1668,40 +1670,66 @@ lazy_scan_heap(Relation onerel, VacuumParams *params, LVRelStats *vacrelstats,
RelationGetRelationName(onerel),
tups_vacuumed, vacuumed_pages)));
+ /* Write separate log messages to client (with prefix) and logfile (without prefix) */
+ vacuum_msg(&logdetail, "", vacrelstats, nkeep, nunused, empty_pages, &ru0);
+ vacuum_msg(&clientdetail, "! ", vacrelstats, nkeep, nunused, empty_pages, &ru0);
+
+ ereport(elevel,
+ (errmsg("\"%s\": found %.0f removable, %.0f nonremovable row versions in %u out of %u pages",
+ RelationGetRelationName(onerel),
+ tups_vacuumed, num_tuples,
+ vacrelstats->scanned_pages, nblocks),
+ errdetail_log("%s", logdetail.data),
+ errdetail_internal("%s", clientdetail.data)));
+
+ pfree(logdetail.data);
+ pfree(clientdetail.data);
+}
+
+/* Populate buf with string to be freed by caller */
+static void
+vacuum_msg(StringInfoData *buf, const char *prefix, LVRelStats *vacrelstats, double nkeep, double nunused, BlockNumber empty_pages, PGRUsage *ru0)
+{
/*
* This is pretty messy, but we split it up so that we can skip emitting
* individual parts of the message when not applicable.
*/
- initStringInfo(&buf);
- appendStringInfo(&buf, ngettext("%.0f dead row version cannot be removed yet, oldest xmin: %u\n",
+ initStringInfo(buf);
+ if (prefix)
+ appendStringInfoString(buf, prefix);
+ appendStringInfo(buf, ngettext("%.0f dead row version cannot be removed yet, oldest xmin: %u\n",
"%.0f dead row versions cannot be removed yet, oldest xmin: %u\n",
nkeep),
nkeep, OldestXmin);
- appendStringInfo(&buf, ngettext("There was %.0f unused item identifier.\n",
+
+ if (prefix)
+ appendStringInfoString(buf, prefix);
+ appendStringInfo(buf, ngettext("There was %.0f unused item identifier.\n",
"There were %.0f unused item identifiers.\n",
nunused),
nunused);
- appendStringInfo(&buf, ngettext("Skipped %u page due to buffer pins, ",
+
+ if (prefix)
+ appendStringInfoString(buf, prefix);
+ appendStringInfo(buf, ngettext("Skipped %u page due to buffer pins, ",
"Skipped %u pages due to buffer pins, ",
vacrelstats->pinskipped_pages),
vacrelstats->pinskipped_pages);
- appendStringInfo(&buf, ngettext("%u frozen page.\n",
+ appendStringInfo(buf, ngettext("%u frozen page.\n",
"%u frozen pages.\n",
vacrelstats->frozenskipped_pages),
vacrelstats->frozenskipped_pages);
- appendStringInfo(&buf, ngettext("%u page is entirely empty.\n",
+
+ if (prefix)
+ appendStringInfoString(buf, prefix);
+ appendStringInfo(buf, ngettext("%u page is entirely empty.\n",
"%u pages are entirely empty.\n",
empty_pages),
empty_pages);
- appendStringInfo(&buf, "%s.", pg_rusage_show(&ru0));
- ereport(elevel,
- (errmsg("\"%s\": found %.0f removable, %.0f nonremovable row versions in %u out of %u pages",
- RelationGetRelationName(onerel),
- tups_vacuumed, num_tuples,
- vacrelstats->scanned_pages, nblocks),
- errdetail_internal("%s", buf.data)));
- pfree(buf.data);
+ if (prefix)
+ appendStringInfoString(buf, prefix);
+ appendStringInfo(buf, "%s.", pg_rusage_show(ru0));
}
/*
--
2.7.4
>From 55fea31f5d3d99a94eba206ec5a75f94e1f43097 Mon Sep 17 00:00:00 2001
From: Justin Pryzby <[email protected]>
Date: Sun, 15 Dec 2019 17:00:29 -0600
Subject: [PATCH v3 4/4] reduce to DEBUG status logged from vacuum_heap/index..
..since they can run multiple times, which is both excessively noisy, and
confusing, due to showing multiple, multi-line messages with rusage.
Also output (at DEBUG) a message indicating the action to be taken, before
starting it. To avoid outputting a message about completion of one step, and
taking a long time before outputting anything about the next/current step.
I'm taking as a guiding principle to elog whenever calling
pgstat_progress_update_param.
---
src/backend/access/heap/vacuumlazy.c | 24 +++++++++++++++++-------
1 file changed, 17 insertions(+), 7 deletions(-)
diff --git a/src/backend/access/heap/vacuumlazy.c b/src/backend/access/heap/vacuumlazy.c
index 6f85af7..95d999f 100644
--- a/src/backend/access/heap/vacuumlazy.c
+++ b/src/backend/access/heap/vacuumlazy.c
@@ -501,6 +501,7 @@ heap_vacuum_rel(Relation onerel, VacuumParams *params,
lazy_truncate_heap(onerel, vacrelstats);
/* Report that we are now doing final cleanup */
+ elog(DEBUG1, "cleaning up");
pgstat_progress_update_param(PROGRESS_VACUUM_PHASE,
PROGRESS_VACUUM_PHASE_FINAL_CLEANUP);
@@ -1773,9 +1774,12 @@ lazy_vacuum_all_indexes(Relation onerel, Relation *Irel,
{
int idx;
- for (idx = 0; idx < nindexes; idx++)
+ for (idx = 0; idx < nindexes; idx++) {
+ ereport(DEBUG1, (errmsg("\"%s\": vacuuming index",
+ RelationGetRelationName(Irel[idx]))));
lazy_vacuum_index(Irel[idx], &stats[idx], vacrelstats->dead_tuples,
vacrelstats->old_live_tuples);
+ }
}
/* Increase and report the number of index scans */
@@ -1805,6 +1809,8 @@ lazy_vacuum_heap(Relation onerel, LVRelStats *vacrelstats)
Buffer vmbuffer = InvalidBuffer;
/* Report that we are now vacuuming the heap */
+ ereport(DEBUG1, (errmsg("\"%s\": vacuuming heap",
+ RelationGetRelationName(onerel))));
pgstat_progress_update_param(PROGRESS_VACUUM_PHASE,
PROGRESS_VACUUM_PHASE_VACUUM_HEAP);
@@ -1848,7 +1854,7 @@ lazy_vacuum_heap(Relation onerel, LVRelStats *vacrelstats)
vmbuffer = InvalidBuffer;
}
- ereport(elevel,
+ ereport(DEBUG1,
(errmsg("\"%s\": removed %d row versions in %d pages",
RelationGetRelationName(onerel),
tupindex, npages),
@@ -2093,13 +2099,13 @@ lazy_parallel_vacuum_indexes(Relation *Irel, IndexBulkDeleteResult **stats,
}
if (lps->lvshared->for_cleanup)
- ereport(elevel,
+ ereport(DEBUG1,
(errmsg(ngettext("launched %d parallel vacuum worker for index cleanup (planned: %d)",
"launched %d parallel vacuum workers for index cleanup (planned: %d)",
lps->pcxt->nworkers_launched),
lps->pcxt->nworkers_launched, nworkers)));
else
- ereport(elevel,
+ ereport(DEBUG1,
(errmsg(ngettext("launched %d parallel vacuum worker for index vacuuming (planned: %d)",
"launched %d parallel vacuum workers for index vacuuming (planned: %d)",
lps->pcxt->nworkers_launched),
@@ -2326,10 +2332,13 @@ lazy_cleanup_all_indexes(Relation *Irel, IndexBulkDeleteResult **stats,
}
else
{
- for (idx = 0; idx < nindexes; idx++)
+ for (idx = 0; idx < nindexes; idx++) {
+ ereport(DEBUG1, (errmsg("cleaning up index \"%s\"",
+ RelationGetRelationName(Irel[idx]))));
lazy_cleanup_index(Irel[idx], &stats[idx],
vacrelstats->new_rel_tuples,
vacrelstats->tupcount_pages < vacrelstats->rel_pages);
+ }
}
}
@@ -2369,7 +2378,7 @@ lazy_vacuum_index(Relation indrel, IndexBulkDeleteResult **stats,
else
msg = gettext_noop("scanned index \"%s\" to remove %d row versions");
- ereport(elevel,
+ ereport(DEBUG1,
(errmsg(msg,
RelationGetRelationName(indrel),
dead_tuples->num_tuples),
@@ -2412,7 +2421,7 @@ lazy_cleanup_index(Relation indrel,
else
msg = gettext_noop("index \"%s\" now contains %.0f row versions in %u pages");
- ereport(elevel,
+ ereport(DEBUG1,
(errmsg(msg,
RelationGetRelationName(indrel),
(*stats)->num_index_tuples,
@@ -2476,6 +2485,7 @@ lazy_truncate_heap(Relation onerel, LVRelStats *vacrelstats)
pg_rusage_init(&ru0);
/* Report that we are now truncating */
+ elog(DEBUG1, "truncating heap");
pgstat_progress_update_param(PROGRESS_VACUUM_PHASE,
PROGRESS_VACUUM_PHASE_TRUNCATE);
--
2.7.4