HiguchiD - 2021-02-22

Hi,

I have found that autovacuum statistics cannot be obtained when PostgreSQL messages are output in Japanese.
I think this problem occurs not only in Japanese but also in other languages.
I found this problem when using PostgreSQL 11 and pg_statsinfo 11.

[Investigation]
This problem may be caused by that MSG_AUTOVACUUM macro, defined in "libstatsinfo.c", differs from the PostgreSQL messages.
MSG_AUTOVACUUM and the PostgreSQL "ja.po" have different message units and different variables such as "%s".
For example, PostgreSQL "ja.po" defines autovacuum messages line by line, while MSG_AUTOVACUUM defines multiple lines together.

libstatsinfo.c

#if PG_VERSION_NUM >= 100000
#define MSG_AUTOVACUUM \
        "automatic %s of table \"%s.%s.%s\": index scans: %d\n" \
        "pages: %d removed, %d remain, %d skipped due to pins, %u skipped frozen\n" \
        "tuples: %.0f removed, %.0f remain, %.0f are dead but not yet removable, oldest xmin: %u\n" \
        "buffer usage: %d hits, %d misses, %d dirtied\n" \
        "avg read rate: %.3f %s, avg write rate: %.3f %s\n" \
        "system usage: %s"

https://github.com/postgres/postgres/blob/REL_11_STABLE/src/backend/po/ja.po

#: commands/vacuumlazy.c:380
#, c-format
msgid "automatic vacuum of table \"%s.%s.%s\": index scans: %d\n"
msgstr "テーブル\"%s.%s.%s\"の自動VACUUM: インデックススキャン: %d\n"

#: commands/vacuumlazy.c:386
#, c-format
msgid "pages: %u removed, %u remain, %u skipped due to pins, %u skipped frozen\n"
msgstr "ページ: %uを削除、%uが残存、%uがピンによってスキップ、%uが凍結によってスキップ\n"

...

This means that the message of MSG_AUTOVACUUM does not exist in "ja.po", so pg_statsinfo searches the messages in English.
However, since the messages outputs Japanese, pg_statsinfo could not find autovacuum messages and obtain the statistics.

Also, when I see the comments in parse_autovacuum(), the MSG_RUSAGE macro does not be localized.
I think this means that Japanese messages are not parsed, so could not get autovacuum statistics.

parse_autovacuum()

        /*
         * Re-parse rusage output separatedly. Note that MSG_RUSAGE won't be
         * localized with any lc_messages.
         */
        str_usage = llast(params);
        if ((usage = capture(str_usage, MSG_RUSAGE, NUM_RUSAGE)) == NIL)
        {
                elog(WARNING, "cannot parse rusage: %s", str_usage);
                list_free_deep(params);
                return false;   /* should not happen */
        }

Is it a bug or limitation of pg_statsinfo?
I couldn't find any restrictions on such problem in the documentation.

Regards,
Higuchi