fixup_for_v7_masahiko.patch
text/x-patch
Filename: fixup_for_v7_masahiko.patch
Type: text/x-patch
Part: 0
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: unified
Series: patch v7
| File | + | − |
|---|---|---|
| doc/src/sgml/config.sgml | 18 | 11 |
| src/backend/access/transam/xlog.c | 18 | 18 |
| src/backend/commands/vacuum.c | 4 | 3 |
| src/backend/replication/slot.c | 19 | 27 |
| src/backend/storage/ipc/procarray.c | 7 | 6 |
| src/include/replication/slot.h | 1 | 1 |
| src/include/storage/procarray.h | 3 | 3 |
diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
index 46aac59cb20..9ad662b8b6f 100644
--- a/doc/src/sgml/config.sgml
+++ b/doc/src/sgml/config.sgml
@@ -4772,17 +4772,24 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows
</term>
<listitem>
<para>
- Invalidate replication slots whose <literal>xmin</literal> (the oldest
- transaction that this slot needs the database to retain) or
- <literal>catalog_xmin</literal> (the oldest transaction affecting the
- system catalogs that this slot needs the database to retain) has reached
- the age specified by this setting. This invalidation check happens
- during vacuum (both <command>VACUUM</command> command and autovacuum)
- and during checkpoints.
- A value of zero (which is default) disables this feature. Users can set
- this value anywhere from zero to two billion. This parameter can only be
- set in the <filename>postgresql.conf</filename> file or on the server
- command line.
+ Invalidate replication slots whose <structfield>xmin</structfield> age
+ or <structfield>catalog_xmin</structfield> age in the
+ <link linkend="view-pg-replication-slots">pg_replication_slots</link>
+ view has exceeded the age specified by this setting. Slot invalidation
+ due to this limit occurs during vacuum (both <command>VACUUM</command>
+ command and autovacuum) and during checkpoint.
+ A value of zero (the default) disables this feature. Users can set
+ this value anywhere from zero to two billion transactions. This parameter
+ can only be set in the <filename>postgresql.conf</filename> file or on
+ the server command line.
+ </para>
+
+ <para>
+ The current age of a slot's <literal>xmin</literal> and
+ <literal>catalog_xmin</literal> can be monitored by applying the
+ <function>age</function> function to the corresponding columns in the
+ <link linkend="view-pg-replication-slots">pg_replication_slots</link>
+ view.
</para>
<para>
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index 70c1d5c5559..1aec1bcb79e 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -7019,8 +7019,8 @@ CreateCheckPoint(int flags)
VirtualTransactionId *vxids;
int nvxids;
int oldXLogAllowed = 0;
- uint32 possibleInvalidationCauses;
- TransactionId recentXid;
+ uint32 slotInvalidationCauses;
+ TransactionId slotXidLimit;
/*
* An end-of-recovery checkpoint is really a shutdown checkpoint, just
@@ -7450,19 +7450,19 @@ CreateCheckPoint(int flags)
XLByteToSeg(RedoRecPtr, _logSegNo, wal_segment_size);
KeepLogSeg(recptr, &_logSegNo);
- possibleInvalidationCauses = RS_INVAL_WAL_REMOVED | RS_INVAL_IDLE_TIMEOUT;
- recentXid = InvalidTransactionId;
-
+ slotInvalidationCauses = RS_INVAL_WAL_REMOVED | RS_INVAL_IDLE_TIMEOUT;
+ slotXidLimit = InvalidTransactionId;
if (max_slot_xid_age > 0)
{
- possibleInvalidationCauses |= RS_INVAL_XID_AGE;
- recentXid = ReadNextTransactionId();
+ slotInvalidationCauses |= RS_INVAL_XID_AGE;
+ slotXidLimit = TransactionIdRetreatedBy(ReadNextTransactionId(),
+ max_slot_xid_age);
}
- if (InvalidateObsoleteReplicationSlots(possibleInvalidationCauses,
+ if (InvalidateObsoleteReplicationSlots(slotInvalidationCauses,
_logSegNo, InvalidOid,
InvalidTransactionId,
- recentXid))
+ slotXidLimit))
{
/*
* Some slots have been invalidated; recalculate the old-segment
@@ -7743,8 +7743,8 @@ CreateRestartPoint(int flags)
XLogRecPtr endptr;
XLogSegNo _logSegNo;
TimestampTz xtime;
- uint32 possibleInvalidationCauses;
- TransactionId recentXid;
+ uint32 slotInvalidationCauses;
+ TransactionId slotXidLimit;
/* Concurrent checkpoint/restartpoint cannot happen */
Assert(!IsUnderPostmaster || MyBackendType == B_CHECKPOINTER);
@@ -7919,19 +7919,19 @@ CreateRestartPoint(int flags)
INJECTION_POINT("restartpoint-before-slot-invalidation", NULL);
- possibleInvalidationCauses = RS_INVAL_WAL_REMOVED | RS_INVAL_IDLE_TIMEOUT;
- recentXid = InvalidTransactionId;
-
+ slotInvalidationCauses = RS_INVAL_WAL_REMOVED | RS_INVAL_IDLE_TIMEOUT;
+ xidLimit = InvalidTransactionId;
if (max_slot_xid_age > 0)
{
- possibleInvalidationCauses |= RS_INVAL_XID_AGE;
- recentXid = ReadNextTransactionId();
+ slotInvalidationCauses |= RS_INVAL_XID_AGE;
+ slotXidLimit = TransactionIdRetreatedBy(ReadNextTransactionId(),
+ max_slot_xid_age);
}
- if (InvalidateObsoleteReplicationSlots(possibleInvalidationCauses,
+ if (InvalidateObsoleteReplicationSlots(slotInvalidationCauses,
_logSegNo, InvalidOid,
InvalidTransactionId,
- recentXid))
+ slotXidLimit))
{
/*
* Some slots have been invalidated; recalculate the old-segment
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 7f36f795b72..cda86b9d50f 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -1133,9 +1133,10 @@ vacuum_get_cutoffs(Relation rel, const VacuumParams *params,
* that only one vacuum process can be working on a particular table at
* any time, and that each vacuum is always an independent transaction.
*/
- cutoffs->OldestXmin = GetOldestNonRemovableTransactionIdExt(rel,
- &cutoffs->slot_xmin,
- &cutoffs->slot_catalog_xmin);
+ cutoffs->OldestXmin =
+ GetOldestNonRemovableTransactionIdWithSlotXids(rel,
+ &cutoffs->slot_xmin,
+ &cutoffs->slot_catalog_xmin);
Assert(TransactionIdIsNormal(cutoffs->OldestXmin));
diff --git a/src/backend/replication/slot.c b/src/backend/replication/slot.c
index 20729d2fb42..e6271e2a519 100644
--- a/src/backend/replication/slot.c
+++ b/src/backend/replication/slot.c
@@ -1790,7 +1790,7 @@ ReportSlotInvalidation(ReplicationSlotInvalidationCause cause,
long slot_idle_seconds,
TransactionId xmin,
TransactionId catalog_xmin,
- TransactionId recentXid)
+ TransactionId xidLimit)
{
StringInfoData err_detail;
StringInfoData err_hint;
@@ -1838,20 +1838,18 @@ ReportSlotInvalidation(ReplicationSlotInvalidationCause cause,
case RS_INVAL_XID_AGE:
{
- Assert(TransactionIdIsValid(xmin) || TransactionIdIsValid(catalog_xmin));
-
- if (TransactionIdIsValid(xmin))
- {
- /* translator: %s is a GUC variable name */
- appendStringInfo(&err_detail, _("The slot's xmin %u is %d transactions old, which exceeds the configured \"%s\" value of %d."),
- xmin, (int32) (recentXid - xmin), "max_slot_xid_age", max_slot_xid_age);
- }
- else
- {
- /* translator: %s is a GUC variable name */
- appendStringInfo(&err_detail, _("The slot's catalog_xmin %u is %d transactions old, which exceeds the configured \"%s\" value of %d."),
- catalog_xmin, (int32) (recentXid - catalog_xmin), "max_slot_xid_age", max_slot_xid_age);
- }
+ TransactionId slot_xid = TransactionIdIsValid(xmin) ? xmin : catalog_xmin;
+ int32 exceeded_by = (int32) (xidLimit - slot_xid);
+ int32 slot_age = (int32) max_slot_xid_age + exceeded_by;
+
+ Assert(TransactionIdIsValid(slot_xid));
+
+ /* translator: %s is a GUC variable name */
+ appendStringInfo(&err_detail,
+ TransactionIdIsValid(xmin)
+ ? _("The slot's xmin age of %d exceeds the configured \"%s\" of %d by %d transactions")
+ : _("The slot's catalog xmin age of %d exceeds the configured \"%s\" of %d by %d transactions"),
+ slot_age, "max_slot_xid_age", max_slot_xid_age, exceeded_by);
/* translator: %s is a GUC variable name */
appendStringInfo(&err_hint, _("You might need to increase \"%s\"."),
@@ -2033,19 +2031,13 @@ InvalidatePossiblyObsoleteSlot(uint32 possible_causes,
ReplicationSlot *s,
XLogRecPtr oldestLSN,
Oid dboid, TransactionId snapshotConflictHorizon,
- TransactionId recentXid,
+ TransactionId xidLimit,
bool *released_lock_out)
{
int last_signaled_pid = 0;
bool released_lock = false;
bool invalidated = false;
TimestampTz inactive_since = 0;
- TransactionId xidLimit = InvalidTransactionId;
-
- /* Compute the XID limit once, to avoid redundant work per slot */
- if ((possible_causes & RS_INVAL_XID_AGE) &&
- TransactionIdIsValid(recentXid))
- xidLimit = TransactionIdRetreatedBy(recentXid, max_slot_xid_age);
for (;;)
{
@@ -2187,7 +2179,7 @@ InvalidatePossiblyObsoleteSlot(uint32 possible_causes,
slotname, restart_lsn,
oldestLSN, snapshotConflictHorizon,
slot_idle_secs, s->data.xmin,
- s->data.catalog_xmin, recentXid);
+ s->data.catalog_xmin, xidLimit);
if (MyBackendType == B_STARTUP)
(void) SignalRecoveryConflict(GetPGProcByNumber(active_proc),
@@ -2241,7 +2233,7 @@ InvalidatePossiblyObsoleteSlot(uint32 possible_causes,
slotname, restart_lsn,
oldestLSN, snapshotConflictHorizon,
slot_idle_secs, s->data.xmin,
- s->data.catalog_xmin, recentXid);
+ s->data.catalog_xmin, xidLimit);
/* done with this slot for now */
break;
@@ -2284,7 +2276,7 @@ bool
InvalidateObsoleteReplicationSlots(uint32 possible_causes,
XLogSegNo oldestSegno, Oid dboid,
TransactionId snapshotConflictHorizon,
- TransactionId recentXid)
+ TransactionId xidLimit)
{
XLogRecPtr oldestLSN;
bool invalidated = false;
@@ -2323,7 +2315,7 @@ restart:
if (InvalidatePossiblyObsoleteSlot(possible_causes, s, oldestLSN,
dboid, snapshotConflictHorizon,
- recentXid, &released_lock))
+ xidLimit, &released_lock))
{
Assert(released_lock);
@@ -3391,7 +3383,7 @@ MaybeInvalidateXIDAgedSlots(TransactionId slot_xmin,
0,
InvalidOid,
InvalidTransactionId,
- recentXid);
+ xidLimit);
return invalidated;
}
diff --git a/src/backend/storage/ipc/procarray.c b/src/backend/storage/ipc/procarray.c
index 9e0acf7309d..898ef4a0833 100644
--- a/src/backend/storage/ipc/procarray.c
+++ b/src/backend/storage/ipc/procarray.c
@@ -1938,10 +1938,11 @@ GlobalVisHorizonKindForRel(Relation rel)
}
/*
- * Helper to return the appropriate oldest non-removable TransactionId from
- * pre-computed horizons, based on the relation type.
+ * A helper function to return the appropriate oldest non-removable
+ * TransactionId from the pre-computed horizons, based on the relation
+ * type.
*/
-static inline TransactionId
+static pg_attribute_always_inline TransactionId
GetOldestNonRemovableTransactionIdFromHorizons(ComputeXidHorizonsResult *horizons,
Relation rel)
{
@@ -1989,9 +1990,9 @@ GetOldestNonRemovableTransactionId(Relation rel)
* needs both values.
*/
TransactionId
-GetOldestNonRemovableTransactionIdExt(Relation rel,
- TransactionId *slot_xmin,
- TransactionId *slot_catalog_xmin)
+GetOldestNonRemovableTransactionIdWithSlotXids(Relation rel,
+ TransactionId *slot_xmin,
+ TransactionId *slot_catalog_xmin)
{
ComputeXidHorizonsResult horizons;
diff --git a/src/include/replication/slot.h b/src/include/replication/slot.h
index 0baa7112559..d143b19a7b3 100644
--- a/src/include/replication/slot.h
+++ b/src/include/replication/slot.h
@@ -371,7 +371,7 @@ extern bool InvalidateObsoleteReplicationSlots(uint32 possible_causes,
XLogSegNo oldestSegno,
Oid dboid,
TransactionId snapshotConflictHorizon,
- TransactionId recentXid);
+ TransactionId xidLimit);
extern bool MaybeInvalidateXIDAgedSlots(TransactionId slot_xmin,
TransactionId slot_catalog_xmin);
extern ReplicationSlot *SearchNamedReplicationSlot(const char *name, bool need_lock);
diff --git a/src/include/storage/procarray.h b/src/include/storage/procarray.h
index c198fd22515..a94091ce7fd 100644
--- a/src/include/storage/procarray.h
+++ b/src/include/storage/procarray.h
@@ -53,9 +53,9 @@ extern RunningTransactions GetRunningTransactionData(void);
extern bool TransactionIdIsInProgress(TransactionId xid);
extern TransactionId GetOldestNonRemovableTransactionId(Relation rel);
-extern TransactionId GetOldestNonRemovableTransactionIdExt(Relation rel,
- TransactionId *slot_xmin,
- TransactionId *slot_catalog_xmin);
+extern TransactionId GetOldestNonRemovableTransactionIdWithSlotXids(Relation rel,
+ TransactionId *slot_xmin,
+ TransactionId *slot_catalog_xmin);
extern TransactionId GetOldestTransactionIdConsideredRunning(void);
extern TransactionId GetOldestActiveTransactionId(bool inCommitOnly,
bool allDbs);