public inbox for [email protected]help / color / mirror / Atom feed
[PATCH 03/10] Make sure published XIDs are persistent 3+ messages / 3 participants [nested] [flat]
* [PATCH 03/10] Make sure published XIDs are persistent @ 2021-03-08 06:43 Kyotaro Horiguchi <[email protected]> 0 siblings, 0 replies; 3+ messages in thread From: Kyotaro Horiguchi @ 2021-03-08 06:43 UTC (permalink / raw) pg_xact_status() premises that XIDs obtained by pg_current_xact_id(_if_assigned)() are persistent beyond a crash. But XIDs are not guaranteed to go beyond WAL buffers before commit and thus XIDs may vanish if server crashes before commit. This patch guarantees the XID shown by the functions to be flushed out to disk. Copied from: https://www.postgresql.org/message-id/20210308.173242.463790587797836129.horikyota.ntt%40gmail.com --- src/backend/access/transam/xact.c | 55 +++++++++++++++++++++++++------ src/backend/access/transam/xlog.c | 2 +- src/backend/utils/adt/xid8funcs.c | 12 ++++++- src/include/access/xact.h | 3 +- 4 files changed, 59 insertions(+), 13 deletions(-) diff --git a/src/backend/access/transam/xact.c b/src/backend/access/transam/xact.c index 6395a9b240..38e978d238 100644 --- a/src/backend/access/transam/xact.c +++ b/src/backend/access/transam/xact.c @@ -201,7 +201,7 @@ typedef struct TransactionStateData int prevSecContext; /* previous SecurityRestrictionContext */ bool prevXactReadOnly; /* entry-time xact r/o state */ bool startedInRecovery; /* did we start in recovery? */ - bool didLogXid; /* has xid been included in WAL record? */ + XLogRecPtr minLSN; /* LSN needed to reach to record the xid */ int parallelModeLevel; /* Enter/ExitParallelMode counter */ bool chain; /* start a new block after this one */ bool assigned; /* assigned to top-level XID */ @@ -520,14 +520,46 @@ GetCurrentFullTransactionIdIfAny(void) * MarkCurrentTransactionIdLoggedIfAny * * Remember that the current xid - if it is assigned - now has been wal logged. + * + * upto is the LSN up to which we need to flush WAL to ensure the current xid + * to be persistent. See EnsureCurrentTransactionIdLogged(). */ void -MarkCurrentTransactionIdLoggedIfAny(void) +MarkCurrentTransactionIdLoggedIfAny(XLogRecPtr upto) { - if (FullTransactionIdIsValid(CurrentTransactionState->fullTransactionId)) - CurrentTransactionState->didLogXid = true; + if (FullTransactionIdIsValid(CurrentTransactionState->fullTransactionId) && + XLogRecPtrIsInvalid(CurrentTransactionState->minLSN)) + CurrentTransactionState->minLSN = upto; } +/* + * EnsureCurrentTransactionIdLogged + * + * Make sure that the current top XID is WAL-logged. + */ +void +EnsureTopTransactionIdLogged(void) +{ + /* + * We need at least one WAL record for the current top transaction to be + * flushed out. Write one if we don't have one yet. + */ + if (XLogRecPtrIsInvalid(TopTransactionStateData.minLSN)) + { + xl_xact_assignment xlrec; + + xlrec.xtop = XidFromFullTransactionId(XactTopFullTransactionId); + Assert(TransactionIdIsValid(xlrec.xtop)); + xlrec.nsubxacts = 0; + + XLogBeginInsert(); + XLogRegisterData((char *) &xlrec, MinSizeOfXactAssignment); + TopTransactionStateData.minLSN = + XLogInsert(RM_XACT_ID, XLOG_XACT_ASSIGNMENT); + } + + XLogFlush(TopTransactionStateData.minLSN); +} /* * GetStableLatestTransactionId @@ -616,14 +648,14 @@ AssignTransactionId(TransactionState s) * When wal_level=logical, guarantee that a subtransaction's xid can only * be seen in the WAL stream if its toplevel xid has been logged before. * If necessary we log an xact_assignment record with fewer than - * PGPROC_MAX_CACHED_SUBXIDS. Note that it is fine if didLogXid isn't set + * PGPROC_MAX_CACHED_SUBXIDS. Note that it is fine if minLSN isn't set * for a transaction even though it appears in a WAL record, we just might * superfluously log something. That can happen when an xid is included * somewhere inside a wal record, but not in XLogRecord->xl_xid, like in * xl_standby_locks. */ if (isSubXact && XLogLogicalInfoActive() && - !TopTransactionStateData.didLogXid) + XLogRecPtrIsInvalid(TopTransactionStateData.minLSN)) log_unknown_top = true; /* @@ -693,6 +725,7 @@ AssignTransactionId(TransactionState s) log_unknown_top) { xl_xact_assignment xlrec; + XLogRecPtr endptr; /* * xtop is always set by now because we recurse up transaction @@ -707,11 +740,13 @@ AssignTransactionId(TransactionState s) XLogRegisterData((char *) unreportedXids, nUnreportedXids * sizeof(TransactionId)); - (void) XLogInsert(RM_XACT_ID, XLOG_XACT_ASSIGNMENT); + endptr = XLogInsert(RM_XACT_ID, XLOG_XACT_ASSIGNMENT); nUnreportedXids = 0; - /* mark top, not current xact as having been logged */ - TopTransactionStateData.didLogXid = true; + + /* set minLSN of top, not of current xact if not yet */ + if (XLogRecPtrIsInvalid(TopTransactionStateData.minLSN)) + TopTransactionStateData.minLSN = endptr; } } } @@ -2022,7 +2057,7 @@ StartTransaction(void) * initialize reported xid accounting */ nUnreportedXids = 0; - s->didLogXid = false; + s->minLSN = InvalidXLogRecPtr; /* * must initialize resource-management stuff first diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index 04192b7add..0183589b4d 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -1171,7 +1171,7 @@ XLogInsertRecord(XLogRecData *rdata, */ WALInsertLockRelease(); - MarkCurrentTransactionIdLoggedIfAny(); + MarkCurrentTransactionIdLoggedIfAny(EndPos); END_CRIT_SECTION(); diff --git a/src/backend/utils/adt/xid8funcs.c b/src/backend/utils/adt/xid8funcs.c index cc2b4ac797..992482f8c8 100644 --- a/src/backend/utils/adt/xid8funcs.c +++ b/src/backend/utils/adt/xid8funcs.c @@ -357,6 +357,8 @@ bad_format: Datum pg_current_xact_id(PG_FUNCTION_ARGS) { + FullTransactionId xid; + /* * Must prevent during recovery because if an xid is not assigned we try * to assign one, which would fail. Programs already rely on this function @@ -365,7 +367,12 @@ pg_current_xact_id(PG_FUNCTION_ARGS) */ PreventCommandDuringRecovery("pg_current_xact_id()"); - PG_RETURN_FULLTRANSACTIONID(GetTopFullTransactionId()); + xid = GetTopFullTransactionId(); + + /* the XID is going to be published, make sure it is psersistent */ + EnsureTopTransactionIdLogged(); + + PG_RETURN_FULLTRANSACTIONID(xid); } /* @@ -380,6 +387,9 @@ pg_current_xact_id_if_assigned(PG_FUNCTION_ARGS) if (!FullTransactionIdIsValid(topfxid)) PG_RETURN_NULL(); + /* the XID is going to be published, make sure it is psersistent */ + EnsureTopTransactionIdLogged(); + PG_RETURN_FULLTRANSACTIONID(topfxid); } diff --git a/src/include/access/xact.h b/src/include/access/xact.h index 34cfaf542c..a61e4d6da5 100644 --- a/src/include/access/xact.h +++ b/src/include/access/xact.h @@ -386,7 +386,8 @@ extern FullTransactionId GetTopFullTransactionId(void); extern FullTransactionId GetTopFullTransactionIdIfAny(void); extern FullTransactionId GetCurrentFullTransactionId(void); extern FullTransactionId GetCurrentFullTransactionIdIfAny(void); -extern void MarkCurrentTransactionIdLoggedIfAny(void); +extern void MarkCurrentTransactionIdLoggedIfAny(XLogRecPtr upto); +extern void EnsureTopTransactionIdLogged(void); extern bool SubTransactionIsActive(SubTransactionId subxid); extern CommandId GetCurrentCommandId(bool used); extern void SetParallelStartTimestamps(TimestampTz xact_ts, TimestampTz stmt_ts); -- 2.17.0 --0qVF/w3MHQqLSynd Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="0004-wal_compression_method-default-to-zlib.patch" ^ permalink raw reply [nested|flat] 3+ messages in thread
* pg_dump: Remove some dead code @ 2023-02-21 21:30 Peter Eisentraut <[email protected]> 0 siblings, 1 reply; 3+ messages in thread From: Peter Eisentraut @ 2023-02-21 21:30 UTC (permalink / raw) To: pgsql-hackers I have found that the per-column atttypmod tracking in pg_dump isn't actually used anywhere. (The values are read but not used for writing out any commands.) This is because some time ago we started formatting all types through format_type() on the server. So this dead code can be removed. From 62d5ead1cb9166730819d0d7656ef734e99e889e Mon Sep 17 00:00:00 2001 From: Peter Eisentraut <[email protected]> Date: Tue, 21 Feb 2023 22:25:18 +0100 Subject: [PATCH] pg_dump: Remove dead code Client-side tracking of atttypmod has been unused since 64f3524, when server-side format_type() started being used exclusively. --- src/bin/pg_dump/pg_dump.c | 5 ----- src/bin/pg_dump/pg_dump.h | 1 - 2 files changed, 6 deletions(-) diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index 527c7651ab..1a06eeaf6a 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -8182,7 +8182,6 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) int i_attnum; int i_attname; int i_atttypname; - int i_atttypmod; int i_attstattarget; int i_attstorage; int i_typstorage; @@ -8252,7 +8251,6 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) "a.attrelid,\n" "a.attnum,\n" "a.attname,\n" - "a.atttypmod,\n" "a.attstattarget,\n" "a.attstorage,\n" "t.typstorage,\n" @@ -8320,7 +8318,6 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) i_attnum = PQfnumber(res, "attnum"); i_attname = PQfnumber(res, "attname"); i_atttypname = PQfnumber(res, "atttypname"); - i_atttypmod = PQfnumber(res, "atttypmod"); i_attstattarget = PQfnumber(res, "attstattarget"); i_attstorage = PQfnumber(res, "attstorage"); i_typstorage = PQfnumber(res, "typstorage"); @@ -8381,7 +8378,6 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) tbinfo->numatts = numatts; tbinfo->attnames = (char **) pg_malloc(numatts * sizeof(char *)); tbinfo->atttypnames = (char **) pg_malloc(numatts * sizeof(char *)); - tbinfo->atttypmod = (int *) pg_malloc(numatts * sizeof(int)); tbinfo->attstattarget = (int *) pg_malloc(numatts * sizeof(int)); tbinfo->attstorage = (char *) pg_malloc(numatts * sizeof(char)); tbinfo->typstorage = (char *) pg_malloc(numatts * sizeof(char)); @@ -8408,7 +8404,6 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) tbinfo->dobj.name); tbinfo->attnames[j] = pg_strdup(PQgetvalue(res, r, i_attname)); tbinfo->atttypnames[j] = pg_strdup(PQgetvalue(res, r, i_atttypname)); - tbinfo->atttypmod[j] = atoi(PQgetvalue(res, r, i_atttypmod)); tbinfo->attstattarget[j] = atoi(PQgetvalue(res, r, i_attstattarget)); tbinfo->attstorage[j] = *(PQgetvalue(res, r, i_attstorage)); tbinfo->typstorage[j] = *(PQgetvalue(res, r, i_typstorage)); diff --git a/src/bin/pg_dump/pg_dump.h b/src/bin/pg_dump/pg_dump.h index e7cbd8d7ed..cdca0b993d 100644 --- a/src/bin/pg_dump/pg_dump.h +++ b/src/bin/pg_dump/pg_dump.h @@ -326,7 +326,6 @@ typedef struct _tableInfo int numatts; /* number of attributes */ char **attnames; /* the attribute names */ char **atttypnames; /* attribute type names */ - int *atttypmod; /* type-specific type modifiers */ int *attstattarget; /* attribute statistics targets */ char *attstorage; /* attribute storage scheme */ char *typstorage; /* type storage scheme */ -- 2.39.2 Attachments: [text/plain] 0001-pg_dump-Remove-dead-code.patch (3.1K, ../../[email protected]/2-0001-pg_dump-Remove-dead-code.patch) download | inline diff: From 62d5ead1cb9166730819d0d7656ef734e99e889e Mon Sep 17 00:00:00 2001 From: Peter Eisentraut <[email protected]> Date: Tue, 21 Feb 2023 22:25:18 +0100 Subject: [PATCH] pg_dump: Remove dead code Client-side tracking of atttypmod has been unused since 64f3524, when server-side format_type() started being used exclusively. --- src/bin/pg_dump/pg_dump.c | 5 ----- src/bin/pg_dump/pg_dump.h | 1 - 2 files changed, 6 deletions(-) diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index 527c7651ab..1a06eeaf6a 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -8182,7 +8182,6 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) int i_attnum; int i_attname; int i_atttypname; - int i_atttypmod; int i_attstattarget; int i_attstorage; int i_typstorage; @@ -8252,7 +8251,6 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) "a.attrelid,\n" "a.attnum,\n" "a.attname,\n" - "a.atttypmod,\n" "a.attstattarget,\n" "a.attstorage,\n" "t.typstorage,\n" @@ -8320,7 +8318,6 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) i_attnum = PQfnumber(res, "attnum"); i_attname = PQfnumber(res, "attname"); i_atttypname = PQfnumber(res, "atttypname"); - i_atttypmod = PQfnumber(res, "atttypmod"); i_attstattarget = PQfnumber(res, "attstattarget"); i_attstorage = PQfnumber(res, "attstorage"); i_typstorage = PQfnumber(res, "typstorage"); @@ -8381,7 +8378,6 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) tbinfo->numatts = numatts; tbinfo->attnames = (char **) pg_malloc(numatts * sizeof(char *)); tbinfo->atttypnames = (char **) pg_malloc(numatts * sizeof(char *)); - tbinfo->atttypmod = (int *) pg_malloc(numatts * sizeof(int)); tbinfo->attstattarget = (int *) pg_malloc(numatts * sizeof(int)); tbinfo->attstorage = (char *) pg_malloc(numatts * sizeof(char)); tbinfo->typstorage = (char *) pg_malloc(numatts * sizeof(char)); @@ -8408,7 +8404,6 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) tbinfo->dobj.name); tbinfo->attnames[j] = pg_strdup(PQgetvalue(res, r, i_attname)); tbinfo->atttypnames[j] = pg_strdup(PQgetvalue(res, r, i_atttypname)); - tbinfo->atttypmod[j] = atoi(PQgetvalue(res, r, i_atttypmod)); tbinfo->attstattarget[j] = atoi(PQgetvalue(res, r, i_attstattarget)); tbinfo->attstorage[j] = *(PQgetvalue(res, r, i_attstorage)); tbinfo->typstorage[j] = *(PQgetvalue(res, r, i_typstorage)); diff --git a/src/bin/pg_dump/pg_dump.h b/src/bin/pg_dump/pg_dump.h index e7cbd8d7ed..cdca0b993d 100644 --- a/src/bin/pg_dump/pg_dump.h +++ b/src/bin/pg_dump/pg_dump.h @@ -326,7 +326,6 @@ typedef struct _tableInfo int numatts; /* number of attributes */ char **attnames; /* the attribute names */ char **atttypnames; /* attribute type names */ - int *atttypmod; /* type-specific type modifiers */ int *attstattarget; /* attribute statistics targets */ char *attstorage; /* attribute storage scheme */ char *typstorage; /* type storage scheme */ -- 2.39.2 ^ permalink raw reply [nested|flat] 3+ messages in thread
* Re: pg_dump: Remove some dead code @ 2023-02-21 21:42 Tom Lane <[email protected]> parent: Peter Eisentraut <[email protected]> 0 siblings, 0 replies; 3+ messages in thread From: Tom Lane @ 2023-02-21 21:42 UTC (permalink / raw) To: Peter Eisentraut <[email protected]>; +Cc: pgsql-hackers Peter Eisentraut <[email protected]> writes: > I have found that the per-column atttypmod tracking in pg_dump isn't > actually used anywhere. (The values are read but not used for writing > out any commands.) This is because some time ago we started formatting > all types through format_type() on the server. So this dead code can be > removed. Good catch. LGTM. regards, tom lane ^ permalink raw reply [nested|flat] 3+ messages in thread
end of thread, other threads:[~2023-02-21 21:42 UTC | newest] Thread overview: 3+ messages (download: mbox mbox.gz follow: Atom feed) -- links below jump to the message on this page -- 2021-03-08 06:43 [PATCH 03/10] Make sure published XIDs are persistent Kyotaro Horiguchi <[email protected]> 2023-02-21 21:30 pg_dump: Remove some dead code Peter Eisentraut <[email protected]> 2023-02-21 21:42 ` Re: pg_dump: Remove some dead code Tom Lane <[email protected]>
This inbox is served by agora; see mirroring instructions for how to clone and mirror all data and code used for this inbox