Re: Logging transaction IDs for DDL.

Поиск
Список
Период
Сортировка
От Andres Freund
Тема Re: Logging transaction IDs for DDL.
Дата
Msg-id 20180613224525.mgcg4puppbot4a6w@alap3.anarazel.de
обсуждение исходный текст
Ответ на Logging transaction IDs for DDL.  (Vik Fearing <vik.fearing@2ndquadrant.com>)
Список pgsql-hackers
Hi,

On 2018-06-14 00:34:54 +0200, Vik Fearing wrote:
> I just noticed a problem with log_statement = 'ddl' and log_line_prefix
> containing '%x'.  If the statement is the first in the transaction, it
> will be logged before it is executed, and more importantly, before a
> transaction ID is assigned.  That means that %x will be 0.

This isn't particularly related to DDL, no? It's a general weakness of
how %x is handled. What's even worse is that by
log_min_duration_statement time the xid is already cleared out, when
using a single-statement transaction.


> If the administrator has configured postgres like this in order to ease
> PITR on bad DDL, it's actually of no use whatsoever and they'll have to
> use pg_waldump to try to figure things out.

To me that part seems like it'd be better handled if we had an option
that allows to log at a time where the xid is already assigned. Making
log_statement assign xids imo has a number of problems, but preserving
the xid for logging at the *end* of a statement should be much less
problematic.


> I'm undecided whether this is a bugfix or an improvement.  I'm leaning
> towards bugfix.

It's been reported a couple times, without anybody working to fix
it. Your fix has a noticable regression potential, so I'm not
immediately in favor of backpatching.


> -- 
> Vik Fearing                                          +33 6 46 75 15 36
> http://2ndQuadrant.fr     PostgreSQL : Expertise, Formation et Support

> diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
> index f4133953be..27027a0fa8 100644
> --- a/src/backend/tcop/postgres.c
> +++ b/src/backend/tcop/postgres.c
> @@ -38,6 +38,7 @@
>  
>  #include "access/parallel.h"
>  #include "access/printtup.h"
> +#include "access/transam.h"
>  #include "access/xact.h"
>  #include "catalog/pg_type.h"
>  #include "commands/async.h"
> @@ -2098,16 +2099,31 @@ check_log_statement(List *stmt_list)
>  
>      if (log_statement == LOGSTMT_NONE)
>          return false;
> -    if (log_statement == LOGSTMT_ALL)
> +
> +    /*
> +     * If we're supposed to log mod or ddl statements, we need to make sure we
> +     * have a TransactionId so it appears in log_line_prefix's %x wildcard.
> +     * If the user is logging all statements, we can fast-track out if we
> +     * already have a TransactionId, otherwise we need to loop through the
> +     * statements.
> +     */
> +    if (log_statement == LOGSTMT_ALL && TransactionIdIsValid(GetTopTransactionIdIfAny()))
>          return true;
>
>      /* Else we have to inspect the statement(s) to see whether to log */
>      foreach(stmt_item, stmt_list)
>      {
>          Node       *stmt = (Node *) lfirst(stmt_item);
> +        LogStmtLevel level = GetCommandLogLevel(stmt);
> +
> +        if (level <= log_statement)
> +        {
> +            /* Make sure we have a TransactionId for mod and ddl statements. */
> +            if (level == LOGSTMT_DDL || level == LOGSTMT_MOD)
> +                (void) GetTopTransactionId();
>  
> -        if (GetCommandLogLevel(stmt) <= log_statement)
>              return true;
> +        }
>      }

I'm not at all on board with this.  For one this'll break in a number of
weird ways on a standby (wrong error messages at the least). For another
it increases the overhead of logging quite noticably. Thirdly moving
transaction assignment to a different place based on logging settings
seems like it'll be very confusing too.

Greetings,

Andres Freund


В списке pgsql-hackers по дате отправления:

Предыдущее
От: Vik Fearing
Дата:
Сообщение: Logging transaction IDs for DDL.
Следующее
От: Michael Paquier
Дата:
Сообщение: Re: commitfest 2018-07