From: | Andres Freund <andres(at)anarazel(dot)de> |
---|---|
To: | Vik Fearing <vik(dot)fearing(at)2ndquadrant(dot)com> |
Cc: | PostgreSQL Hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org> |
Subject: | Re: Logging transaction IDs for DDL. |
Date: | 2018-06-13 22:45:25 |
Message-ID: | 20180613224525.mgcg4puppbot4a6w@alap3.anarazel.de |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | 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
From | Date | Subject | |
---|---|---|---|
Next Message | Maksim Milyutin | 2018-06-13 23:04:26 | Re: Slow planning time for simple query |
Previous Message | Vik Fearing | 2018-06-13 22:34:54 | Logging transaction IDs for DDL. |